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

Reply via email to