diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index 518e92567..5e6810fa1 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -157,7 +157,9 @@ int main( int argc, char **argv ) viewer.setSceneData(loadedModel.get()); - // viewer.realize(); + // viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); + + viewer.realize(); unsigned int numFrames = 0; while(!viewer.done() && !(limitNumberOfFrames && numFrames>=maxFrames)) @@ -172,11 +174,18 @@ int main( int argc, char **argv ) #include #include +#include int main( int, char **) { - osgViewer::Viewer viewer; - viewer.setSceneData(osgDB::readNodeFile("cow.osg")); - viewer.run(); + osg::ref_ptr model = osgDB::readNodeFile("town.ive"); + + for(unsigned int i=0; i<5; ++i) + { + osgViewer::Viewer viewer; + viewer.setSceneData(model.get()); + viewer.run(); + } } + #endif diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index 2f4e3cd59..84c15ab79 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -170,7 +170,7 @@ class OSG_EXPORT GraphicsContext : public Referenced inline const Traits* getTraits() const { return _traits.get(); } /** Return whether a valid and usable GraphicsContext has been created.*/ - virtual bool valid() const { return false; } + virtual bool valid() const = 0; /** Set the State object which tracks the current OpenGL state for this graphics context.*/ @@ -278,10 +278,32 @@ class OSG_EXPORT GraphicsContext : public Referenced * Pure virtual - must be implemented by Concrate implementations of GraphicsContext. */ virtual void swapBuffersImplementation() = 0; - /** resized method should be called when the underlying window has been resized and the GraphicsWindow and associated Cameras must be updated to keep in sync with the new size. */ - void resized(int x, int y, int width, int height); + void resized(int x, int y, int width, int height) + { + if (_resizedCallback.valid()) _resizedCallback->resizedImplementation(this, x, y, width, height); + else resizedImplementation(x, y, width, height); + } + + struct ResizedCallback : public osg::Referenced + { + virtual void resizedImplementation(GraphicsContext* gc, int x, int y, int width, int height) = 0; + }; + + /** Set the resized callback which overrides the GraphicsConext::realizedImplementation(), allow developers to provide custom behavior + * in response to a window being resized.*/ + void setResizedCallback(ResizedCallback* rc) { _resizedCallback = rc; } + + /** Get the resized callback which overrides the GraphicsConext::realizedImplementation().*/ + ResizedCallback* getResizedCallback() { return _resizedCallback.get(); } + + /** Get the const resized callback which overrides the GraphicsConext::realizedImplementation().*/ + const ResizedCallback* getResizedCallback() const { return _resizedCallback.get(); } + + /** resized implementation, by default resizes the viewports and aspect ratios the cameras associated with the graphics Window. */ + virtual void resizedImplementation(int x, int y, int width, int height); + typedef std::list< osg::Camera* > Cameras; @@ -322,6 +344,8 @@ class OSG_EXPORT GraphicsContext : public Referenced ref_ptr _graphicsThread; + ref_ptr _resizedCallback; + }; diff --git a/include/osgProducer/GraphicsContextImplementation b/include/osgProducer/GraphicsContextImplementation index 57d9346ab..49031154c 100644 --- a/include/osgProducer/GraphicsContextImplementation +++ b/include/osgProducer/GraphicsContextImplementation @@ -43,6 +43,8 @@ class OSGPRODUCER_EXPORT GraphicsContextImplementation : public osg::GraphicsCon /** Return the const RenderSurface that implements the graphics context.*/ const Producer::RenderSurface* getRenderSurface() const { return _rs.get(); } + /** Return whether a valid and usable GraphicsContext has been created - assume success.*/ + virtual bool valid() const { return true; } /** Realise the GraphicsContext.*/ virtual bool realizeImplementation(); diff --git a/include/osgViewer/GraphicsWindow b/include/osgViewer/GraphicsWindow index 501895195..6db864d7c 100644 --- a/include/osgViewer/GraphicsWindow +++ b/include/osgViewer/GraphicsWindow @@ -36,6 +36,7 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG GraphicsWindow() { _eventQueue = new osgGA::EventQueue; } + void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; } osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); } const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); } @@ -56,6 +57,9 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG public: + /** Return whether a valid and usable GraphicsContext has been created.*/ + virtual bool valid() const { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."< #include +#include +#include +#include +#include +#include + #include #include @@ -165,9 +171,71 @@ bool GraphicsContext::realize() void GraphicsContext::close(bool callCloseImplementation) { + osg::notify(osg::NOTICE)<<"close("< lock(s_contextIDMapMutex); + if (s_contextIDMap[_state->getContextID()]>1) sharedContextExists = true; + } + + osg::notify(osg::NOTICE)<<"Closing still viable window "<getContextID()="<<_state->getContextID()<releaseGLObjects(_state.get()); +#else + camera->releaseGLObjects(0); +#endif + } + } +#endif + +#if 1 + osg::notify(osg::NOTICE)<<"Doing makeCurrent "<getFrameStamp()?_state->getFrameStamp()->getReferenceTime():0.0; + + osg::FrameBufferObject::flushDeletedFrameBufferObjects(_state->getContextID(),currentTime,availableTime); + osg::RenderBuffer::flushDeletedRenderBuffers(_state->getContextID(),currentTime,availableTime); + osg::Texture::flushAllDeletedTextureObjects(_state->getContextID()); + osg::Drawable::flushAllDeletedDisplayLists(_state->getContextID()); + osg::Drawable::flushDeletedVertexBufferObjects(_state->getContextID(),currentTime,availableTime); + osg::VertexProgram::flushDeletedVertexProgramObjects(_state->getContextID(),currentTime,availableTime); + osg::FragmentProgram::flushDeletedFragmentProgramObjects(_state->getContextID(),currentTime,availableTime); + osg::Program::flushDeletedGlPrograms(_state->getContextID(),currentTime,availableTime); + osg::Shader::flushDeletedGlShaders(_state->getContextID(),currentTime,availableTime); + + osg::notify(osg::NOTICE)<<"Done Flush "<reset(); + + releaseContext(); + } + if (callCloseImplementation) closeImplementation(); if (_state.valid()) @@ -218,6 +286,7 @@ void GraphicsContext::makeContextCurrent(GraphicsContext* readContext) void GraphicsContext::releaseContext() { _mutex.unlock(); + _threadOfLastMakeCurrent = reinterpret_cast(0xffff); } void GraphicsContext::swapBuffers() @@ -392,7 +461,7 @@ void GraphicsContext::removeCamera(osg::Camera* camera) } } -void GraphicsContext::resized(int x, int y, int width, int height) +void GraphicsContext::resizedImplementation(int x, int y, int width, int height) { if (!_traits) return; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index e47b6da96..811045688 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -218,11 +218,13 @@ void TextureObjectManager::flushAllTextureObjects(unsigned int contextID) OpenThreads::ScopedLock lock(_mutex); Texture::TextureObjectList& tol = _textureObjectListMap[contextID]; + osg::notify(osg::NOTICE)<<"Flushing texture objects num="<_id<_id)); } tol.clear(); @@ -1302,6 +1304,9 @@ void Texture::resizeGLObjectBuffers(unsigned int maxSize) void Texture::releaseGLObjects(State* state) const { + if (state) osg::notify(osg::NOTICE)<<"Texture::releaseGLObjects contextID="<getContextID()<(this)->dirtyTextureObject(); else { diff --git a/src/osg/View.cpp b/src/osg/View.cpp index f41634f4d..9266effdf 100644 --- a/src/osg/View.cpp +++ b/src/osg/View.cpp @@ -26,8 +26,14 @@ View::View() View::~View() { - // osg::notify(osg::NOTICE)<<"Destructing osg::View"<setView(0); + _camera->setCullCallback(0); + } + // detatch the cameras from this View to prevent dangling pointers for(Slaves::iterator itr = _slaves.begin(); itr != _slaves.end(); @@ -38,7 +44,7 @@ View::~View() cd._camera->setCullCallback(0); } - // osg::notify(osg::NOTICE)<<"Done destructing osg::View"<setDatabasePager(0); } + Contexts contexts; + getContexts(contexts); + + // clear out all the previously assigned operations + for(Contexts::iterator citr = contexts.begin(); + citr != contexts.end(); + ++citr) + { + (*citr)->close(); + } + //osg::notify(osg::NOTICE)<<"finish Viewer::~Viewer()"<makeCurrent(); (*itr)->runOperations(); + (*itr)->releaseContext(); } } @@ -876,6 +889,7 @@ void Viewer::renderingTraversals() { (*itr)->makeCurrent(); (*itr)->swapBuffers(); + (*itr)->releaseContext(); } }