diff --git a/examples/osgsimplepager/osgsimplepager.cpp b/examples/osgsimplepager/osgsimplepager.cpp index 0f72c5c0f..e300eccfc 100644 --- a/examples/osgsimplepager/osgsimplepager.cpp +++ b/examples/osgsimplepager/osgsimplepager.cpp @@ -122,12 +122,15 @@ int main( int argc, char **argv ) return 1; } - // create the window to draw to. - osg::ref_ptr renderSurface = new Producer::RenderSurface; - renderSurface->setWindowName("osgsimplepager"); - renderSurface->setWindowRectangle(100,100,800,600); - renderSurface->useBorder(true); - renderSurface->realize(); + // When numTimesToRun>1 allow the user to test opening and closing graphics contexts whilst + // still keep scene graph around. + unsigned int numTimesToRun = 1; + if (argc>2) + { + numTimesToRun = atoi(argv[2]); + } + + // create the view of the scene. @@ -145,86 +148,123 @@ int main( int argc, char **argv ) databasePager->setUseFrameBlock(false); // set whether to pre compile GL objects before merging new subgraphs with main scene graph - databasePager->setCompileGLObjectsForContextID(sceneView->getState()->getContextID(),true); + // databasePager->setCompileGLObjectsForContextID(sceneView->getState()->getContextID(),true); // register any PagedLOD that need to be tracked in the scene graph databasePager->registerPagedLODs(sceneView->getSceneData()); // need to register the DatabasePager with the SceneView's CullVisitor so it can pass on request // for files to be loaded. - sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager); - - - // set up a KeyboardMouse to manage the events comming in from the RenderSurface - osg::ref_ptr kbm = new Producer::KeyboardMouse(renderSurface.get()); - - // create a KeyboardMouseCallback to handle the mouse events within this applications - osg::ref_ptr kbmcb = new MyKeyboardMouseCallback(sceneView.get()); - - + sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager); + + // record the timer tick at the start of rendering. osg::Timer_t start_tick = osg::Timer::instance()->tick(); + // set the frame number count. Note, this is outside the window loop, so that + // frame numbers increment even a graphics context is closed down and another opened + // this is to ensure the record of the frame numbers in the scene graph are kept valid. unsigned int frameNum = 0; + + - // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) - while( renderSurface->isRealized() && !kbmcb->done()) + if (numTimesToRun>1) { - // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly - osg::FrameStamp* frameStamp = new osg::FrameStamp; - frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); - frameStamp->setFrameNumber(frameNum++); - - // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp - sceneView->setFrameStamp(frameStamp); - - // pass any keyboard mouse events onto the local keyboard mouse callback. - kbm->update( *kbmcb ); - - // set the view - sceneView->setViewMatrix(kbmcb->getViewMatrix()); - - // update the viewport dimensions, incase the window has been resized. - sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); - - - // tell the DatabasePager the frame number of that the scene graph is being actively used to render a frame - databasePager->signalBeginFrame(frameStamp); - - // syncronize changes required by the DatabasePager thread to the scene graph - databasePager->updateSceneGraph(frameStamp->getReferenceTime()); - - // do the update traversal the scene graph - such as updating animations - sceneView->update(); - - // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins - sceneView->cull(); - - // draw the rendering bins. - sceneView->draw(); - - - // tell the DatabasePager that the frame is complete and that scene graph is no longer be activity traversed. - databasePager->signalEndFrame(); - - // Swap Buffers - renderSurface->swapBuffers(); - - - // clean up and compile gl objects with a specified limit - double availableTime = 0.0025; // 2.5 ms - - // compile any GL objects that are required. - databasePager->compileGLObjects(*(sceneView->getState()),availableTime); - - // flush deleted GL objects. - sceneView->flushDeletedGLObjects(availableTime); - - - + // make sure the database pager doesn't unref images as otherwise they won't be around the next time + // they are needed when the a new graphics context comes up. + databasePager->setUnrefImageDataAfterApplyPolicy(true,false); } - // switch off the database pager by unreferning it. + for(unsigned int i=0;i renderSurface = new Producer::RenderSurface; + renderSurface->setWindowName("osgsimplepager"); + renderSurface->setWindowRectangle(100,100,800,600); + renderSurface->useBorder(true); + renderSurface->realize(); + + // set up a KeyboardMouse to manage the events comming in from the RenderSurface + osg::ref_ptr kbm = new Producer::KeyboardMouse(renderSurface.get()); + + // create a KeyboardMouseCallback to handle the mouse events within this applications + osg::ref_ptr kbmcb = new MyKeyboardMouseCallback(sceneView.get()); + + + + // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) + while( renderSurface->isRealized() && !kbmcb->done()) + { + + // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly + osg::FrameStamp* frameStamp = new osg::FrameStamp; + frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); + frameStamp->setFrameNumber(frameNum++); + + // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp + sceneView->setFrameStamp(frameStamp); + + // pass any keyboard mouse events onto the local keyboard mouse callback. + kbm->update( *kbmcb ); + + // set the view + sceneView->setViewMatrix(kbmcb->getViewMatrix()); + + // update the viewport dimensions, incase the window has been resized. + sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); + + + // tell the DatabasePager the frame number of that the scene graph is being actively used to render a frame + databasePager->signalBeginFrame(frameStamp); + + // syncronize changes required by the DatabasePager thread to the scene graph + databasePager->updateSceneGraph(frameStamp->getReferenceTime()); + + // do the update traversal the scene graph - such as updating animations + sceneView->update(); + + // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins + sceneView->cull(); + + // draw the rendering bins. + sceneView->draw(); + + + // tell the DatabasePager that the frame is complete and that scene graph is no longer be activity traversed. + databasePager->signalEndFrame(); + + // Swap Buffers + renderSurface->swapBuffers(); + + + // clean up and compile gl objects with a specified limit + double availableTime = 0.0025; // 2.5 ms + + // compile any GL objects that are required. + databasePager->compileGLObjects(*(sceneView->getState()),availableTime); + + // flush deleted GL objects. + sceneView->flushDeletedGLObjects(availableTime); + + + + } + + // clear the database pager so its starts a fresh on the next update/cull/draw traversals + databasePager->clear(); + + // release the GL objects stored in the scene graph. + sceneView->releaseAllGLObjects(); + + // do a flush to delete all the OpenGL objects that have been deleted or released from the scene graph. + sceneView->flushAllDeletedGLObjects(); + + // reset the osg::State so that next time its used its in a cleaned state. + sceneView->getState()->reset(); + + } + + // switch off the database pager by unreferencing it. osgDB::Registry::instance()->setDatabasePager(0); return 0;