fixed: auto_ptr -> unique_ptr
[opensg.git] / Examples / Tutorial / 13multithreading2.cpp
blob57d838b289680032e0afaa0c150d549be17184fa
1 // all needed include files
2 #ifdef OSG_BUILD_ACTIVE
3 #include <OSGGLUT.h>
4 #include <OSGConfig.h>
5 #include <OSGSimpleGeometry.h>
6 #include <OSGGLUTWindow.h>
7 #include <OSGSimpleSceneManager.h>
9 #include <OSGThreadManager.h>
10 #else
11 #include <OpenSG/OSGGLUT.h>
12 #include <OpenSG/OSGConfig.h>
13 #include <OpenSG/OSGSimpleGeometry.h>
14 #include <OpenSG/OSGGLUTWindow.h>
15 #include <OpenSG/OSGSimpleSceneManager.h>
17 #include <OpenSG/OSGThreadManager.h>
18 #endif
20 OSG::SimpleSceneManagerRefPtr mgr;
22 // we will store the transformation globally - this
23 // is not necessary, but comfortable
24 // Note that these global objects are accessed from different aspects,
25 // therefore you need to use MTRecPtr here, so that you get a pointer to the
26 // correct aspect copy of the object.
28 OSG::TransformMTRecPtr trans;
29 OSG::NodeMTRecPtr scene;
30 OSG::ThreadRefPtr animationThread;
31 OSG::ThreadRefPtr applicationThread;
32 OSG::BarrierRefPtr syncBarrier;
34 int setupGLUT(int *argc, char *argv[]);
36 OSG::NodeTransitPtr createScenegraph(void)
38 // the scene must be created here
39 OSG::NodeRecPtr n = OSG::makeTorus(.5,2,16,16);
41 //add a simple Transformation
42 trans = OSG::Transform::create();
43 OSG::Matrix m;
44 m.setIdentity();
45 trans->setMatrix(m);
47 OSG::NodeRecPtr transNode = OSG::Node::create();
48 transNode->setCore(trans);
49 transNode->addChild(n);
51 return OSG::NodeTransitPtr(transNode);
54 //this function will run in a thread and simply will
55 //rotate the cube by setting a new transformation matrix
56 void rotate(void *args)
58 // sync this thread to the main thread, i.e. pull in all changes done
59 // during scene construction
60 syncBarrier->enter(2);
61 applicationThread->getChangeList()->applyAndClear();
62 syncBarrier->enter(2);
64 // clear the local changelist as we only want to sync the
65 // real changes we make back.
66 OSG::commitChanges();
67 animationThread->getChangeList()->clear();
70 // we won't stop calculating new matrices....
71 while(true)
73 OSG::Real32 time = glutGet(GLUT_ELAPSED_TIME);
74 OSG::Matrix m;
75 m.setIdentity();
76 m.setRotate(OSG::Quaternion(OSG::Vec3f(0,1,0), time/1000));
78 trans->setMatrix(m);
79 // nothing unusual until here
81 // sleep to simulate a more complex update and show that
82 // the render thread is not affected
83 OSG::osgSleep(1000);
85 // we are done with changing this aspect copy (for this iteration),
86 // committing the changes makes sure they are being picked up when
87 // the render thread syncronizes the next time.
88 OSG::commitChanges();
90 //well that's new...
92 //wait until two threads are cought in the
93 //same barrier
94 syncBarrier->enter(2); // barrier (1)
96 //just the same again
97 syncBarrier->enter(2); // barrier (2)
101 int main(int argc, char **argv)
103 OSG::ChangeList::setReadWriteDefault(true);
104 OSG::osgInit(argc,argv);
107 int winid = setupGLUT(&argc, argv);
108 OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
109 gwin->setGlutId(winid);
110 gwin->init();
112 scene = createScenegraph();
114 //create the barrier, that will be used to
115 //synchronize threads
117 //instead of NULL you could provide a name
118 syncBarrier = OSG::Barrier::get("syncBarrier", true);
120 mgr = OSG::SimpleSceneManager::create();
121 mgr->setWindow(gwin );
122 mgr->setRoot (scene);
123 mgr->showAll();
125 // store a pointer to the application thread
126 applicationThread =
127 dynamic_cast<OSG::Thread *>(OSG::ThreadManager::getAppThread());
129 //create the thread that will run generation of new matrices
130 animationThread =
131 OSG::dynamic_pointer_cast<OSG::Thread>(
132 OSG::ThreadManager::the()->getThread("anim", true));
134 //do it...
135 animationThread->runFunction(rotate, 1, NULL);
137 // wait for animationThread to complete its sync
138 syncBarrier->enter(2);
139 syncBarrier->enter(2);
141 OSG::commitChanges();
144 glutMainLoop();
146 return 0;
149 void reshape(int w, int h)
151 mgr->resize(w, h);
152 glutPostRedisplay();
155 void display(void)
157 // if the animation thread has computed an update to the scene
158 // it waits at the barrier and we copy over the changes
159 // otherwise we just keep rendering
161 if(syncBarrier->getNumWaiting() > 0)
163 // we wait here until the animation thread enters
164 // barrier (1)
165 syncBarrier->enter(2);
167 //now we sync data
168 animationThread->getChangeList()->applyAndClear();
170 // update dependend data
171 OSG::commitChanges();
173 // now wait for animation thread to enter barrier (2)
174 syncBarrier->enter(2);
177 // !!!! Attention
178 // you will find a more detailed description
179 // of what's going on here in the documentation
180 // itself!
182 // now render...
183 mgr->redraw();
186 void mouse(int button, int state, int x, int y)
188 if (state)
189 mgr->mouseButtonRelease(button, x, y);
190 else
191 mgr->mouseButtonPress(button, x, y);
193 glutPostRedisplay();
196 void motion(int x, int y)
198 mgr->mouseMove(x, y);
199 glutPostRedisplay();
202 int setupGLUT(int *argc, char *argv[])
204 glutInit(argc, argv);
205 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
207 int winid = glutCreateWindow("OpenSG First Application");
209 glutDisplayFunc(display);
210 glutMouseFunc(mouse);
211 glutMotionFunc(motion);
212 glutReshapeFunc(reshape);
213 glutIdleFunc(display);
215 return winid;