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;
}

Reply via email to