diff --git a/Make/dependencies b/Make/dependencies index 63b0a9de4..df993827b 100644 --- a/Make/dependencies +++ b/Make/dependencies @@ -30,6 +30,8 @@ QT4_ROOT ?= /usr/local/ SDL_INSTALLED ?= no +FLTK_INSTALLED ?= no + ifeq ($(OS),Darwin) DARWIN_QUICKTIME ?= yes endif diff --git a/Make/makedirdefs b/Make/makedirdefs index 04fafd18a..668196140 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -285,6 +285,7 @@ endif ifeq ($(GLUT_INSTALLED),yes) EXAMPLE_DIRS += osgGLUTsimple EXAMPLE_DIRS += osgGLUTkeyboardmouse + EXAMPLE_DIRS += osgsimpleviewerGLUT endif ifeq ($(QT3_INSTALLED),yes) @@ -298,3 +299,11 @@ endif ifeq ($(SDL_INSTALLED),yes) EXAMPLE_DIRS += osgsimpleviewerSDL endif + +ifeq ($(FLTK_INSTALLED),yes) + EXAMPLE_DIRS += osgsimpleviewerFLTK +endif + +ifeq ($(PRODUCER_INSTALLED),yes) + EXAMPLE_DIRS += osgsimpleviewerProducer +endif diff --git a/include/osg/Drawable b/include/osg/Drawable index deeddd0d0..456b1b652 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -378,6 +378,11 @@ class OSG_EXPORT Drawable : public Object /** do customized draw code.*/ virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const { drawImplementation(*renderInfo.getState(), drawable); } + + /** release OpenGL objects in specified graphics context if State + object is passed, otherwise release OpenGL objexts for all graphics context if + State object pointer NULL.*/ + virtual void releaseGLObjects(State* =0) const {} }; /** Set the DrawCallback which allows users to attach customize the drawing of existing Drawable object.*/ diff --git a/include/osg/NodeCallback b/include/osg/NodeCallback index 1e9c64001..e1467ba3b 100644 --- a/include/osg/NodeCallback +++ b/include/osg/NodeCallback @@ -82,6 +82,12 @@ class OSG_EXPORT NodeCallback : public virtual Object { } } } + + + /** release OpenGL objects in specified graphics context if State + object is passed, otherwise release OpenGL objexts for all graphics context if + State object pointer NULL.*/ + virtual void releaseGLObjects(State* =0) const {} public: diff --git a/include/osgGA/SimpleViewer b/include/osgGA/SimpleViewer index 33a6dede8..2ecbcdec9 100644 --- a/include/osgGA/SimpleViewer +++ b/include/osgGA/SimpleViewer @@ -69,7 +69,10 @@ class OSGGA_EXPORT SimpleViewer : public osgGA::GUIActionAdapter, public osg::Re virtual void frameCullTraversal(); virtual void frameDrawTraversal(); - /** Clean up all OpenGL objects associated with this viewer scenegraph. Note, must only be called from the graphics context associated with this viewer.*/ + /** Release all OpenGL objects associated with this viewer's scenegraph. Note, does not deleted the actual OpenGL objects, it just releases them to the pending GL object delete lists which will need flushing once a valid graphics context is obtained.*/ + virtual void releaseAllGLObjects(); + + /** Clean up all OpenGL objects associated with this viewer's scenegraph. Note, must only be called from the graphics context associated with this viewer.*/ virtual void cleanup(); public: diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer index 78edec54c..dfb78d8fe 100644 --- a/include/osgProducer/Viewer +++ b/include/osgProducer/Viewer @@ -305,6 +305,12 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction /** Update internal structures w.r.t updated scene data.*/ virtual void updatedSceneData(); + /** Dispatch a clean up frame that should be called before closing a OsgCameraGroup, i.e. on exit from an app. + * The clean up frame first release all GL objects associated with all the graphics context associated with + * the camera group, then runs a special frame that does the actual OpenGL deletion of GL objects for each + * graphics context. */ + virtual void cleanup_frame(); + protected : diff --git a/include/osgProducer/ViewerEventHandler b/include/osgProducer/ViewerEventHandler index f081f9847..fb949c5cd 100644 --- a/include/osgProducer/ViewerEventHandler +++ b/include/osgProducer/ViewerEventHandler @@ -61,6 +61,11 @@ class OSGPRODUCER_EXPORT ViewerEventHandler : public osgGA::GUIEventHandler void setWriteImageFileName(const std::string& filename); const std::string& getWriteImageFileName() const { return _writeImageFileName; } + /** release OpenGL objects in specified graphics context if State + object is passed, otherwise release OpenGL objexts for all graphics context if + State object pointer NULL.*/ + virtual void releaseGLObjects(osg::State* =0) const; + protected: osgProducer::OsgCameraGroup* _cg; diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 8f5c39e10..eaec82412 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -483,6 +483,8 @@ void Drawable::releaseGLObjects(State* state) const { if (_stateset.valid()) _stateset->releaseGLObjects(state); + if (_drawCallback.valid()) _drawCallback->releaseGLObjects(state); + if (!_useDisplayList) return; if (state) diff --git a/src/osg/Node.cpp b/src/osg/Node.cpp index b41fa50e3..88df0049a 100644 --- a/src/osg/Node.cpp +++ b/src/osg/Node.cpp @@ -494,6 +494,9 @@ void Node::dirtyBound() void Node::releaseGLObjects(osg::State* state) const { if (_stateset.valid()) _stateset->releaseGLObjects(state); + if (_updateCallback.valid()) _updateCallback->releaseGLObjects(state); + if (_eventCallback.valid()) _eventCallback->releaseGLObjects(state); + if (_cullCallback.valid()) _cullCallback->releaseGLObjects(state); } diff --git a/src/osgGA/SimpleViewer.cpp b/src/osgGA/SimpleViewer.cpp index 9ed345648..d7b541e68 100644 --- a/src/osgGA/SimpleViewer.cpp +++ b/src/osgGA/SimpleViewer.cpp @@ -276,20 +276,29 @@ void SimpleViewer::frameDrawTraversal() } } -void SimpleViewer::cleanup() +void SimpleViewer::releaseAllGLObjects() { + for(EventHandlers::iterator hitr = _eventHandlers.begin(); + hitr != _eventHandlers.end(); + ++hitr) + { + (*hitr)->releaseGLObjects(_sceneView->getState()); + } + if (_databasePager.valid()) { // 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(); } + // release the GL objects stored in the scene graph. _sceneView->releaseAllGLObjects(); +} + +void SimpleViewer::cleanup() +{ + releaseAllGLObjects(); + + // do a flush to delete all the OpenGL objects that have been deleted or released from the scene graph. _sceneView->flushAllDeletedGLObjects(); } diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index b3c20ab7a..54bb97d7b 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -972,3 +972,14 @@ void Viewer::getUsage(osg::ApplicationUsage& usage) const } } +void Viewer::cleanup_frame() +{ + for(EventHandlerList::iterator itr = _eventHandlerList.begin(); + itr != _eventHandlerList.end(); + ++itr) + { + (*itr)->releaseGLObjects(); + } + + OsgCameraGroup::cleanup_frame(); +} diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index 68c2607a4..09a8fca3d 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -104,6 +104,13 @@ public: virtual void operator()( const Producer::Camera & camera); + void releaseGLObjects() const + { + { for(TextList::const_iterator itr = _descriptionList.begin(); itr != _descriptionList.end(); ++itr) (*itr)->releaseGLObjects(); } + { for(TextList::const_iterator itr = _optionList.begin(); itr != _optionList.end(); ++itr) (*itr)->releaseGLObjects(); } + { for(TextList::const_iterator itr = _explanationList.begin(); itr != _explanationList.end(); ++itr) (*itr)->releaseGLObjects(); } + } + protected: ViewerEventHandler* _veh; @@ -1238,3 +1245,8 @@ void ViewerEventHandler::getUsage(osg::ApplicationUsage& usage) const usage.addKeyboardMouseBinding("z","Start recording camera path."); usage.addKeyboardMouseBinding("Z","If recording camera path stop recording camera path, save to \"saved_animation.path\"\nThen restart camera from beginning on animation path"); } + +void ViewerEventHandler::releaseGLObjects(osg::State*) const +{ + if (_statsAndHelpDrawCallback) _statsAndHelpDrawCallback->releaseGLObjects(); +}