[osg-users] Crash on some machines while rendering a progressive line strip

49 views
Skip to first unread message

Rakesh Prasad

unread,
Oct 4, 2019, 2:07:59 PM10/4/19
to osg-...@lists.openscenegraph.org
Hi,
I have a code which renders a progressive line strip. When the line strip is unmasked to display it crashes on some machines. I use osg 3.6.4 with MFC Visual Studio 2019 with V142. The same problem was observed on osg 3.4.0 with MFC and Visual Studio 2013 v120. I am completely clueless as why it would crash since its not on my machine. I dont have the crash stack and other variable values. I have some observations.I will list my code and try to explain as best as possible.
I migrated from osg 3.4.0 hoping 3.6.4 will resolve the issue.

createHUDClubHdPts is called to create the scenegraph with the arrays. After which every frame AddCurPtToHandClubPath is called. This function updates the point in the array. As the frames are rendered a line that progressed based on the coordinates is displayed. The render target is a MFC MDI client window. The render frames are called from a thread of class OpenThreads::Thread

While trying to debug the issue using logs. I found that when the numPtsinHandClubPath value goes to 199 it crashes. We can see that the array size is 2000. Everytime it used to crash after 200 values were updated into the coordinate vector and color vector.

It has never crashed on two of my machines so I dont have the stack and variable values. Few remote machines it has crashed.
Do let me know if there is any query or clarity required.
...

Thank you!

Cheers,
Rakesh

Code:

//following variables are defined in COSGViewer
osg::MatrixTransform* mtClubHandPath;
osg::ref_ptr<osg::Geode> osgGeodeHandClubPath;
unsigned int MaxPtsInHandCLubPath;
osg::ref_ptr<osg::Geometry> geomHandPath;
osg::ref_ptr<osg::Geometry> geomClubPath;
osg::ref_ptr<osg::Vec3Array> coordsHandPath;
osg::ref_ptr<osg::Vec3Array> coordsClubPath;
osg::ref_ptr<osg::Vec4Array> coloursHandPath;
osg::ref_ptr<osg::Vec4Array> coloursClubPath;
osg::ref_ptr<osg::DrawArrays> drawArrayHandPath;
osg::ref_ptr<osg::DrawArrays> drawArrayClubPath;


osg::MatrixTransform* COSGViewer::createHUDClubHdPts(int X0, int Y0, int X1, int Y1, int textYOffset)
{
mtClubHandPath = new osg::MatrixTransform();
osg::Matrix m;
m.makeTranslate(0, 0, 0);
mtClubHandPath->setMatrix(m);

RECT rect;
::GetWindowRect(m_hWnd, &rect);


osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
osgGeodeHandClubPath = new osg::Geode();

osg::ref_ptr<osg::StateSet> stateset = osgGeodeHandClubPath->getOrCreateStateSet();

stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

osg::ref_ptr<osg::LineWidth> linewidth = new osg::LineWidth();
linewidth->setWidth(4.0f);
stateset->setAttributeAndModes(linewidth, osg::StateAttribute::ON);

unsigned int n_points = 2000;
MaxPtsInHandCLubPath = n_points;
numPtsinHandClubPath = 0;
geomHandPath = new osg::Geometry();
geomClubPath = new osg::Geometry();

coordsHandPath = new osg::Vec3Array;// (n_points);
coordsClubPath = new osg::Vec3Array;// (n_points);
coloursHandPath = new osg::Vec4Array;// (n_points);
coloursClubPath = new osg::Vec4Array;// (n_points);


for (unsigned int j = 0; j < n_points; ++j) {

coordsHandPath->push_back(osg::Vec3(0, 0, 0));
coordsClubPath->push_back(osg::Vec3(0, 0, 0));
coloursHandPath->push_back(osg::Vec4(1.0, 0, 0, 1.0));
coloursClubPath->push_back(osg::Vec4(0, 0, 1.0, 1.0));


}


geomHandPath->setVertexArray(coordsHandPath);
geomClubPath->setVertexArray(coordsClubPath);

drawArrayHandPath = new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP);
//geomHandPath->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, n_points));
geomHandPath->addPrimitiveSet(drawArrayHandPath);

drawArrayClubPath = new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP);
geomClubPath->addPrimitiveSet(drawArrayClubPath);


geomHandPath->setColorArray(coloursHandPath, osg::Array::BIND_PER_VERTEX);
geomClubPath->setColorArray(coloursClubPath, osg::Array::BIND_PER_VERTEX);

geomHandPath->setDataVariance(osg::Object::DYNAMIC);
geomClubPath->setDataVariance(osg::Object::DYNAMIC);

osgGeodeHandClubPath->addDrawable(geomHandPath);
osgGeodeHandClubPath->addDrawable(geomClubPath);

mtClubHandPath->addChild(osgGeodeHandClubPath);
return mtClubHandPath;
}



void COSGViewer::AddCurPtToHandClubPath(int ccurFr, int cPrevFr)
{
if (ccurFr != -1)
{
if (ccurFr == cPrevFr)
return;
}

osg::Vec3Array * lcoordsHandPath = dynamic_cast<osg::Vec3Array*>(geomHandPath->getVertexArray());
osg::Vec3Array * lcoordsClubPath = dynamic_cast<osg::Vec3Array*>(geomClubPath->getVertexArray());

osg::Vec4Array * lcolorHandPath = dynamic_cast<osg::Vec4Array*>(geomHandPath->getColorArray());
osg::Vec4Array * lcolorClubPath = dynamic_cast<osg::Vec4Array*>(geomClubPath->getColorArray());

osg::Vec3 lhandVec;

float fps = 240.0f;

if (mPolhemus->mnUseG4data == 2)
fps = 120.0f;

if (((fps == 120.0f) && (mPolhemus->m_nActiveHubCount == 2)) || (fps == 240.0f))
{
if (osgViewerTrailCalib == FALSE)
{
if ((mRightHandedness == 1) || (mRightHandedness == -1))
{
lhandVec = vSensorCM[7];
}
else
{
lhandVec = vSensorCM[5];
}
}
else
{
if ((mRightHandedness == 1) || (mRightHandedness == -1))
{
lhandVec = vSensorCM[5];
}
else
{
lhandVec = vSensorCM[7];
}
}
}
else
{
lhandVec = vVMidHands;
}

(*lcoordsHandPath)[numPtsinHandClubPath] = lhandVec;
(*lcoordsClubPath)[numPtsinHandClubPath] = vVClub;

if (ccurFr == osgAddress)
{
}



if (ccurFr != -1)
{
if (ccurFr <= osgTop)
{

(*lcolorHandPath)[numPtsinHandClubPath] = hdClubPathcrKey[0];
(*lcolorClubPath)[numPtsinHandClubPath] = hdClubPathcrKey[3];
}
else if ((ccurFr > osgTop) && (ccurFr <= osgImpact))
{

(*lcolorHandPath)[numPtsinHandClubPath] = hdClubPathcrKey[1];
(*lcolorClubPath)[numPtsinHandClubPath] = hdClubPathcrKey[4];
}
else if (ccurFr > osgImpact)
{

(*lcolorHandPath)[numPtsinHandClubPath] = hdClubPathcrKey[2];
(*lcolorClubPath)[numPtsinHandClubPath] = hdClubPathcrKey[5];
}
}
else
{
(*lcolorHandPath)[numPtsinHandClubPath] = hdClubPathcrKey[0];
(*lcolorClubPath)[numPtsinHandClubPath] = hdClubPathcrKey[3];
}


unsigned int lnumEleDisp;
if (numPtsinHandClubPath > 10)
lnumEleDisp = numPtsinHandClubPath+1;
else
lnumEleDisp = numPtsinHandClubPath+1;

lcoordsHandPath->dirty();
lcoordsClubPath->dirty();

drawArrayHandPath->setFirst(0);
drawArrayHandPath->setCount(lnumEleDisp);

drawArrayClubPath->setFirst(0);
drawArrayClubPath->setCount(lnumEleDisp);

geomHandPath->setUseDisplayList(false);
geomHandPath->dirtyDisplayList();
geomHandPath->dirtyBound();

geomClubPath->setUseDisplayList(false);
geomClubPath->dirtyDisplayList();
geomClubPath->dirtyBound();

if (numPtsinHandClubPath == 200)
{
LOGD.LOGRP(FL, "State2");
}

numPtsinHandClubPath++;

if (numPtsinHandClubPath == MaxPtsInHandCLubPath)
{
ClearAnimHandClubPath(0, 0);
}

if (numPtsinHandClubPath == 200)
{
LOGD.LOGRP(FL, "State3");
}

}




------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=76790#76790



hdclubpath.jpg

Robert Osfield

unread,
Oct 9, 2019, 4:00:31 AM10/9/19
to OpenSceneGraph Users
Hi Rakesh,

I don't think we can provide much direct insight, you have the whole application and data to test against, while we just have a snippet without any wider information.  The crash could be caused by anything.

The best we can do is recommend tools/strategies to reproduce the crash or pick up on race conditions.  I only work under Linux these days and use valgrind --tool=helgrind to pick up on threading issues, this works pretty well for catching obscure difficult to catch in testing problems.  I'm sure there will be similar tools under Windows, but can't provide any guidance on this as I'm not a Windows user.

The other thing you could look at is changing the way you are implementing things.  Personally when handling this type of user interaction -> generation of scene graph in real-time I accumulate the user input in a thread safe queue then read from this in the update/event traversal, this then updates the scene graph in a synchronous way avoiding any threading issues.

The OSG also allows you create custom events and inject them in the viewer's EventQueue.  The osc plugin implements a custom event approach, with it providing a custom osgGA::Device that provide interface that the viewer can use to poll the device.  You needn't go this approach, and may just way over complicate the task, but for certain types of apps being able to decouple the device and events makes it easier mix and match devices and event handling.

Robert.


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Rakesh Prasad

unread,
Oct 24, 2019, 4:06:03 AM10/24/19
to osg-...@lists.openscenegraph.org
Hi,
I could do further investigation. I used DEBUG_FP and got the logs from both the machines one on which it works and another on which crashes. Below I am listing the some differences I see in the two logs. Both the logs are also attached.

Machine where it crashes
Warning: detected OpenGL error 'invalid enumerant' at after RenderBin::draw(..)


Working machine
Windows Error #3221684230: [Screen #0] GraphicsWindowWin32::makeCurrentImplementation() - Unable to set current OpenGL rendering context
makeCurrent did not succeed, could not do flush/deletion of OpenGL objects.
Doing discard of deleted OpenGL objects.

Sample log from machine where it crashes

draw() 0F79CAE0
draw() got SceneView 0F6BC190
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 0F79CAE0
cull()
cull() got SceneView 0F6BD380
end cull() 0F79CAE0
draw() 0F79CAE0
draw() got SceneView 0F6BD380
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 0F79CAE0
cull()
cull() got SceneView 0F6BC190
end cull() 0F79CAE0
draw() 0F79CAE0
draw() got SceneView 0F6BC190
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 0F79CAE0
cull()
cull() got SceneView 0F6BD380
end cull() 0F79CAE0


For working Machine (where it does not crash)
draw() 2B8535C0
draw() got SceneView 2B66BDF0
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 2B8535C0
cull()
cull() got SceneView 2B71CEC0
end cull() 2B8535C0
draw() 2B8535C0
draw() got SceneView 2B71CEC0
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 2B8535C0
cull()
cull() got SceneView 2B66BDF0
end cull() 2B8535C0
draw() 2B8535C0
draw() got SceneView 2B66BDF0
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
VertexArrayDispatch::dispatch(2000)
ColorArrayDispatch::dispatch(2000)
end draw() 2B8535C0
cull()
cull() got SceneView 2B71CEC0
end cull() 2B8535C0

...

Thank you!

Cheers,
Rakesh

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=76794#76794



Crashing-Log.txt
Reply all
Reply to author
Forward
0 new messages