Hello Christoph,

Christoph Schäfer wrote:
Gerrit Voss schrieb:
yes. BTW the CSM supports parallel drawing, so it might be a reasonable
good reference. But I'm afraid not with the ping pong syncs from the
original problem ;-). That one is still unresolved or did I miss
something ?
The focus of this thread switched over to the basic problem of the example Carsten provided. The original problem within my app persists (mail in this thread 24.1.2009 18:01). I will get back to it as soon as Carstens example is running on windows and I really understand how things have to be structured to work.

attached version works for me on windows, but since it does not clean up properly after itself it may crash on exit.

Is there any other way to work on the scene graph data within two (or more) threads without Ping-Pong-Sync? I think I'll have to face this problem ;-)

it becomes easier if you can set up threads/aspects in a producer-consumer style where the render thread only picks up changes but does not modify the scenegraph itself. From what you described, that would mean you'd have to transfer the input events to aspect 0 (perhaps setting up a queue, perhaps using some mechanism built into Qt, not sure what they have there) and handle them there. Then all changes to the scene would happen on aspect 0 and you'd just sync aspect 1 whenever an update is ready.

        Hope it helps,
                Carsten

#ifdef OSG_BUILD_INTEGRATED
// Headers
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGPassiveWindow.h>
#include <OSGSimpleSceneManager.h>
#include <OSGBaseFunctions.h>
#include <OSGTransform.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>
#include <OSGFieldContainerUtils.h>

#else

// Headers
#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGPassiveWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGBaseFunctions.h>
#include <OpenSG/OSGTransform.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGSceneFileHandler.h>
#include <OpenSG/OSGFieldContainerUtils.h>

#endif

OSG_USING_NAMESPACE

struct AppArgs
{
    int    argc;
    char **argv;
};

SimpleSceneManager *mgr;

NodeMTRecPtr          root;
TransformUnrecPtr     trafo;
PassiveWindowMTRecPtr pwin;

Thread             *a0Thread;
Thread             *a1Thread;

Barrier            *syncBarrier;

volatile bool       input       = false;
volatile bool       sceneUpdate = false;


int setupGLUT(int *argc, char *argv[]);


void runAspect0(int argc, char *argv[])
{
    // PART 1: initialization

    root = makeCoredNode<Transform>(&trafo);
    NodeUnrecPtr scene;

    if(argc > 1)
    {
        scene = SceneFileHandler::the()->read(argv[1]);
    }

    if(scene == NULL)
    {
        scene = makeTorus(.5, 2, 16, 16);
    }

    root->addChild(scene);

    commitChanges();

    // PART 2: main loop

    // wait for aspect 1 -- make sure both aspects are initialized and synced
    syncBarrier->enter(2);
    syncBarrier->enter(2);

    Time t0 = getSystemTime();
    Time t1 = getSystemTime();

    while(true)
    {
        if(input == true)
        {
            syncBarrier->enter(2);

            std::cerr << "runAspect0 pulling input" << std::endl;
            a1Thread->getChangeList()->applyAndClear();
            commitChanges();

            syncBarrier->enter(2);
        }

        if(sceneUpdate == true)
        {
            syncBarrier->enter(2);
            sceneUpdate = false;
            syncBarrier->enter(2);
        }

        Time t2 = getSystemTime();

        if(t2 - t1 > 0.5f)
        {
            std::cerr << "runAspect0 updating trafo: " << (t2 - t1) << " " << (t2 - t0) << std::endl;

            Matrix m;
            m.setRotate(Quaternion(Vec3f(0,1,0), osgDegree2Rad((t2 - t0) * 5)));

            trafo->setMatrix(m);

            commitChanges();

            t1 = t2;
            sceneUpdate = true;
        }
    }
}


void runAspect1(void *args)
{
    AppArgs *appArgs = static_cast<AppArgs *>(args);

    setupGLUT(&appArgs->argc, appArgs->argv);

    // pull in changes from aspect 0
    syncBarrier->enter(2);
    a0Thread->getChangeList()->applyAndClear();
    commitChanges();
    syncBarrier->enter(2);

    pwin = PassiveWindow::create();
    pwin->init();

    mgr = new SimpleSceneManager;
    mgr->setWindow(pwin );
    mgr->setRoot  (root );
    mgr->showAll();

    glutMainLoop();
}


int main(int argc, char *argv[])
{
    AppArgs appArgs;
    appArgs.argc = argc;
    appArgs.argv = argv;

    osgInit(argc, argv);

    syncBarrier = ThreadManager::the()->getBarrier("syncBarrier");

    a0Thread = dynamic_cast<Thread *>(ThreadManager::the()->getAppThread()       );
    a1Thread = dynamic_cast<Thread *>(ThreadManager::the()->getThread("a1Thread"));

    // start thread on aspect 1
    a1Thread->runFunction(runAspect1, 1, &appArgs);

    runAspect0(argc, argv);

    return 0;
}

void display(void)
{
    commitChanges();

    // if input
    if(input == true)
    {
        // allow aspect 0 to pull changes from input
        syncBarrier->enter(2);
        input = false;
        syncBarrier->enter(2);
    }

    if(sceneUpdate == true)
    {
        commitChanges();

        syncBarrier->enter(2);

        std::cerr << "runAspect1 pulling sceneUpdate" << std::endl;
        a0Thread->getChangeList()->applyAndClear();
        commitChanges();

        syncBarrier->enter(2);
    }

    mgr->redraw();

    glutSwapBuffers();
}

void reshape(int w, int h)
{
    mgr->resize(w, h);

    input = true;
    glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{
    if(state)
        mgr->mouseButtonRelease(button, x, y);
    else
        mgr->mouseButtonPress(button, x, y);

    input = true;
    glutPostRedisplay();
}

void motion(int x, int y)
{
    mgr->mouseMove(x, y);

    input = true;
    glutPostRedisplay();
}

void keyboard(unsigned char k, int , int )
{
    switch(k)
    {
    case 'p':
    {
        SceneGraphPrinter sgp(root);
        sgp.printDownTree(std::cout);
    }
    break;
    }
}

void idle(void)
{
    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);
    glutIdleFunc(idle);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);

    return winid;
}
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to