Hi Rene,
On Mon, 2005-06-20 at 17:59 +0200, Rene Weller wrote:
> Hello,
>
> I have a problem with multithreading in OpenSG:
>
> I used the simple multithreading-example from
> http://www.oliver-abert.de/opensg/Multithreading.html
>
> When I try to access the geometry of the geometry-node in the
> rotate-function with osg::GeometryPtr geo =
> osg::GeometryPtr::dcast(n->getCore()) the cast failes (geo.getCPtr() ==
> NULL).
> Isn`t it possible to get access to the geometry in threats?
It sure is, and I can't reproduce the problem. I attached a modified
13multithreading2.cpp that accesses the Geometry using a cast like
yours, and it works fine.
Can you compare that to your program to see what's different?
HIH
Dirk
// all needed include files
#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGThreadManager.h>
#include <qapplication.h>
#include <OpenSG/OSGQSceneGraphView_qt.h>
OSG::QSceneGraphView *pView;
QApplication *app;
OSG_USING_NAMESPACE
using namespace std;
SimpleSceneManager *mgr;
NodePtr scene;
//we will store the transformation globally - this
//is not necessary, but comfortable
TransformPtr trans;
Thread* animationThread;
Barrier *syncBarrier;
NodePtr n;
int setupGLUT( int *argc, char *argv[] );
NodePtr createScenegraph(){
// the scene must be created here
n = makeTorus(.5,2,1024,1024);
//add a simple Transformation
trans = Transform::create();
beginEditCP(trans);
Matrix m;
m.setIdentity();
trans->setMatrix(m);
endEditCP(trans);
NodePtr transNode = Node::create();
beginEditCP(transNode);
transNode->setCore(trans);
transNode->addChild(n);
endEditCP(transNode);
return transNode;
}
//this function will run in a thread and simply will
//rotate the cube by setting a new transformation matrix
void rotate(void *args) {
// we won't stop calculating new matrices....
// NEW STUFF
// Disable displaylist on new geometry
FieldContainerPtr pProto = Geometry::getClassType().getPrototype();
GeometryPtr pGeoProto = GeometryPtr::dcast(pProto);
if(pGeoProto != NullFC) {
pGeoProto->setDlistCache(false);
}
// this consumes about 40 MB
scene = createScenegraph();
mgr->setRoot(scene);
mgr->showAll();
// END NEW STUFF
GeometryPtr geo = GeometryPtr::dcast(n->getCore());
if(geo == NullFC)
{
FWARNING(("Couldn't cast!\n"));
}
else
{
FWARNING(("Cast worked!\n"));
}
if(geo.getCPtr() == NULL)
{
FWARNING(("CPtr == NULL: Couldn't cast!\n"));
}
else
{
FWARNING(("CPtr != NULL: Cast worked!\n"));
}
while(true) {
Real32 time = glutGet(GLUT_ELAPSED_TIME);
Matrix m;
m.setIdentity();
m.setRotate(Quaternion(Vec3f(0,1,0), time/1000));
beginEditCP(trans);
trans->setMatrix(m);
endEditCP(trans);
// nothing unusual until here
//well that's new...
//wait until two threads are cought in the
//same barrier
syncBarrier->enter(2);
//just the same again
syncBarrier->enter(2);
}
}
int main(int argc, char **argv)
{
app = new QApplication(argc, argv);
ChangeList::setReadWriteDefault();
osgInit(argc,argv);
int winid = setupGLUT(&argc, argv);
GLUTWindowPtr gwin = GLUTWindow::create();
beginEditCP(gwin);
gwin->setId(winid);
endEditCP(gwin);
gwin->init();
pView = new QSceneGraphView(NULL, "pView");
// in the tutorial example, the scengraph was created in the
// main/render thread.
// scene = createScenegraph();
syncBarrier = Barrier::get("Barrier");
mgr = new SimpleSceneManager;
mgr->setWindow(gwin );
//create the thread that will run generation of new matrices
animationThread = dynamic_cast<Thread *>(ThreadManager::the()
->getThread("anim"));
//do it...
animationThread->runFunction(rotate, 1, NULL);
glutMainLoop();
return 0;
}
void reshape(int w, int h)
{
mgr->resize(w, h);
glutPostRedisplay();
}
void display(void)
{
// we wait here until the animation thread enters
//the first barrier
syncBarrier->enter(2);
// now we sync data
// First time this is run, it consumes another 40 MB !!
animationThread->getChangeList()->applyAndClear();
// and again
syncBarrier->enter(2);
// now render...
mgr->redraw();
#if 0
pView->setRoot(mgr->getRoot());
app->setMainWidget(pView);
pView->show();
app->exec();
#endif
}
void mouse(int button, int state, int x, int y)
{
if (state)
mgr->mouseButtonRelease(button, x, y);
else
mgr->mouseButtonPress(button, x, y);
glutPostRedisplay();
}
void motion(int x, int y)
{
mgr->mouseMove(x, y);
glutPostRedisplay();
}
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("OpenSG First Application");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutIdleFunc(display);
return winid;
}