Hi,
thanks for your help.
Yes I'm using a cluster, I have two different display servers, here
there actually executed on the same machine, but for the final test, it
will be on other machine, this has
already been tried and it works fine.
I commented as you proposed the :
Thread::getCurrentChangeList()->merge(*(GT->getChangeList())); line.
But it only display the first geometry at the creation of my object,
the thread is running, creating geometry node, and adding it to
the scenegraph but it's not aplied on the display thread, which
only display the first geometry.
Carsten Neumann wrote:
> Hello Adrien,
>
> Adrien wrote:
>
>> Hi,
>> I'm not sure to understand who works the thread and aspects, you sayed
>> that when you merge the changelist it does not aplly the modifcation
>> made by the thread on the scene graph, that :
>>
>> It only records the changes done on some aspect so they can be
>> applied together with the changes done in the current threads aspect
>>
>
> yes. OpenSG does not really care about threads, it cares about aspects,
> i.e. on demand copies of the graph that allow concurrent modification.
> You can have many threads associated to one aspect, but then it is your
> responsibility to coordinate their operations. However, if two threads
> are associated to different aspects they may modify the same parts of
> the scene without interfering with each other. The order and direction
> in which you then apply these aspects changelists determines which
> changes will appear in the rendering.
> A common setup uses the main thread (associated to aspect 0) for
> rendering and another thread (associated to aspect 1) for updates to the
> scene. The main thread can then apply the changelist of aspect 1 to itself.
>
>
>> So when are really comitted this changes?
>>
>
> GT->getChangeList()->apply()
>
> will apply the changes recorded in the changelist of the aspect
> associated with the "GT" thread to the aspect associated to the current
> thread.
>
> I've just noted that you had written the following in your initial mail:
>
>
>> int LaunchGrimageThread(void *args){
>>
>> ... // some other stuffs not important here
>>
>> GT = dynamic_cast<Thread *>
>> (ThreadManager::the()->getThread("GrimageThread"));
>> GT->runFunction(GrimageThread,Thread::getAspect(),args);
>>
> ^^^^^^^^^^^^^^
> This associates the GrimageThread to the same
> aspect as the main thread.
>
>
>> return 1 ;
>> }
>>
>
> This means, you do not have to sync any changelists, because the main
> threads changelist and the grimage threads changelist are the same. I
> think you should comment out the
> Thread::getCurrentChangeList()->merge(*(GT->getChangeList())); line.
>
>
>> Anyway I try to protect the rendering as you said like this :
>>
>> void Display( void )
>> GTLock->aquire();
>>
>> Thread::getCurrentChangeList()->merge(*(GT->getChangeList()));
>> GT->getChangeList()->clearAll();
>> bsManager->render() ;
>> Thread::getCurrentChangeList()->clearAll() ;
>>
>> GTLock->release();
>>
>> glClear(GL_COLOR_BUFFER_BIT) ;
>> glutSwapBuffers() ;
>> }
>>
>>
> [SNIP]
>
>> And it still crash after about 40 seconds, during these 40 seconds it
>> works fine,
>> the geometry is corectly updated. Here is the crash message :
>>
>>
> [SNIP]
>
>> WARNING: Can't find container id:8065
>> WARNING: Can't find container id:8065
>> WARNING: Can't find container id:8065
>> WARNING: Can't find container id:8065
>> terminate called after throwing an instance of
>> 'osg::BinaryDataHandler::ReadError'
>> what(): BinaryDataHandler ReadError: Channel closed
>>
>
> The "Can't find container id: " warning comes from the RemoteAspect, are
> you trying to run a cluster ?
>
> I've also attached a modified tutorial program that can be used as a
> cluster client. Basically it is a combination of
> Doc/tutorial/progs/13multithreading2.cpp and
> Doc/tutorial/progs/14clustering_Client.cpp
> It uses the main thread for rendering and another one to rotate the
> scene (I don't have a cluster so this is not tested).
>
> Hope it helps,
> Carsten
>
> ------------------------------------------------------------------------
>
> // 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/OSGMultiDisplayWindow.h>
> #include <OpenSG/OSGThreadManager.h>
> #include <OpenSG/OSGSceneFileHandler.h>
>
> OSG_USING_NAMESPACE
> using namespace std;
>
> SimpleSceneManager *mgr;
> NodePtr scene;
> TransformPtr trans;
> Thread *updateThread;
> Thread *mainThread;
> Barrier *syncBarrier;
>
> int setupGLUT( int *argc, char *argv[] );
>
> NodePtr createScenegraph()
> {
> // the scene must be created here
> NodePtr n = makeTorus(.5,2,16,16);
>
> //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)
> {
> // sync this thread to the main thread, i.e. pull in all changes done
> // during scene construction
> syncBarrier->enter(2);
> mainThread->getChangeList()->applyAndClear();
> syncBarrier->enter(2);
>
> // we won't stop calculating new matrices....
> 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);
>
> //wait until two threads are cought in the
> //same barrier
> syncBarrier->enter(2); // barrier (1)
>
> //just the same again
> syncBarrier->enter(2); // barrier (2)
> }
> }
>
> int main(int argc, char **argv)
> {
> #if OSG_MINOR_VERSION > 2
> ChangeList::setReadWriteDefault();
> #endif
> osgInit(argc,argv);
>
> int winid = setupGLUT(&argc, argv);
>
> //this time we'll have not a GLUTWindow here, but this one
> MultiDisplayWindowPtr multiWindow = MultiDisplayWindow::create();
>
> //set some necessary values
> beginEditCP(multiWindow);
> // we connect via multicast
> multiWindow->setConnectionType("Multicast");
> //multiWindow->setServiceAddress("192.168.2.142");
> // we want to rendering servers...
> multiWindow->getServers().push_back("Server1");
> multiWindow->getServers().push_back("Server2");
> endEditCP(multiWindow);
>
> //any scene here
> scene = makeTorus(.5, 2, 16, 16);
>
> // and the ssm as always
> mgr = new SimpleSceneManager;
>
> mgr->setWindow(multiWindow);
> mgr->setRoot (scene);
> mgr->showAll();
>
> multiWindow->init();
>
> // store a pointer to the application thread
> mainThread = dynamic_cast<Thread *>(ThreadManager::getAppThread());
>
> // create the thread that will run generation of new matrices
> updateThread = dynamic_cast<Thread
> *>(ThreadManager::the()->getThread("anim"));
>
> // run updateThread, note that is is using aspect 1
> updateThread->runFunction(rotate, 1, NULL);
>
> // wait for updateThread to complete its sync
> syncBarrier->enter(2);
> syncBarrier->enter(2);
>
>
> glutMainLoop();
>
> return 0;
> }
>
> void display(void)
> {
> // we wait here until the animation thread enters
> // barrier (1)
> syncBarrier->enter(2);
>
> // store changes done in the updateThreads aspect in mainThreads
> changelist
> mainThread->getChangeList()->merge(*(updateThread->getChangeList()));
>
> // apply changes done in the updateThreads aspect to mainThreads aspect
> updateThread->getChangeList()->applyAndClear();
>
> // now wait for animation thread to enter barrier (2)
> syncBarrier->enter(2);
>
>
> //redrawing as usual
> mgr->redraw();
>
> // the changelist should be cleared - else things
> // could be copied multiple times
> mainThread->getChangeList()->clearAll();
>
> // to ensure a black navigation window
> glClear(GL_COLOR_BUFFER_BIT);
> glutSwapBuffers();
> }
>
> void reshape(int w, int h)
> {
> glutPostRedisplay();
> }
>
> 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");
>
> glutReshapeFunc(reshape);
> glutDisplayFunc(display);
> glutMouseFunc(mouse);
> glutMotionFunc(motion);
>
> return winid;
> }
>
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> ------------------------------------------------------------------------
>
> _______________________________________________
> Opensg-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensg-users
>
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users