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