Added GraphicsContext::ResizedCallback and GraphicsContext::resizedImplementation.

Added message on non implementation of GraphicsContext::valid().
Added prelimary GraphicsContext clean up support.
This commit is contained in:
Robert Osfield
2007-01-08 16:20:10 +00:00
parent a3726fba66
commit 4a5eda6522
8 changed files with 143 additions and 10 deletions

View File

@@ -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 <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
int main( int, char **)
{
osgViewer::Viewer viewer;
viewer.setSceneData(osgDB::readNodeFile("cow.osg"));
viewer.run();
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("town.ive");
for(unsigned int i=0; i<5; ++i)
{
osgViewer::Viewer viewer;
viewer.setSceneData(model.get());
viewer.run();
}
}
#endif

View File

@@ -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> _graphicsThread;
ref_ptr<ResizedCallback> _resizedCallback;
};

View File

@@ -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();

View File

@@ -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."<<std::endl; return false; }
/** Realise the GraphicsContext implementation,
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."<<std::endl; return false; }

View File

@@ -16,6 +16,12 @@
#include <osg/Camera>
#include <osg/View>
#include <osg/FrameBufferObject>
#include <osg/Program>
#include <osg/Drawable>
#include <osg/FragmentProgram>
#include <osg/VertexProgram>
#include <osg/Notify>
#include <map>
@@ -165,9 +171,71 @@ bool GraphicsContext::realize()
void GraphicsContext::close(bool callCloseImplementation)
{
osg::notify(osg::NOTICE)<<"close("<<callCloseImplementation<<")"<<this<<std::endl;
// switch off the graphics thread...
setGraphicsThread(0);
if (callCloseImplementation && _state.valid() && isRealized())
{
bool sharedContextExists = false;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[_state->getContextID()]>1) sharedContextExists = true;
}
osg::notify(osg::NOTICE)<<"Closing still viable window "<<sharedContextExists<<" _state->getContextID()="<<_state->getContextID()<<std::endl;
#if 1
// release all the OpenGL objects in the scene graphs associted with this
for(Cameras::iterator itr = _cameras.begin();
itr != _cameras.end();
++itr)
{
Camera* camera = (*itr);
if (camera)
{
osg::notify(osg::NOTICE)<<"Releasing GL objects for Camera "<<camera<<std::endl;
#if 1
camera->releaseGLObjects(_state.get());
#else
camera->releaseGLObjects(0);
#endif
}
}
#endif
#if 1
osg::notify(osg::NOTICE)<<"Doing makeCurrent "<<std::endl;
makeCurrent();
osg::notify(osg::NOTICE)<<"Doing Flush"<<std::endl;
// flush all the OpenGL object buffer for this context.
double availableTime = 100.0f;
double currentTime = _state->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 "<<availableTime<<std::endl;
#endif
_state->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<OpenThreads::Thread*>(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;

View File

@@ -218,11 +218,13 @@ void TextureObjectManager::flushAllTextureObjects(unsigned int contextID)
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
Texture::TextureObjectList& tol = _textureObjectListMap[contextID];
osg::notify(osg::NOTICE)<<"Flushing texture objects num="<<tol.size()<<" contextID="<<contextID<<std::endl;
for(Texture::TextureObjectList::iterator itr=tol.begin();
itr!=tol.end();
++itr)
{
osg::notify(osg::NOTICE)<<" deleting texture object "<<(*itr)->_id<<std::endl;
glDeleteTextures( 1L, &((*itr)->_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="<<state->getContextID()<<std::endl;
else osg::notify(osg::NOTICE)<<"Texture::releaseGLObjects no State "<<std::endl;
if (!state) const_cast<Texture*>(this)->dirtyTextureObject();
else
{

View File

@@ -26,8 +26,14 @@ View::View()
View::~View()
{
// osg::notify(osg::NOTICE)<<"Destructing osg::View"<<std::endl;
osg::notify(osg::NOTICE)<<"Destructing osg::View"<<std::endl;
if (_camera.valid())
{
_camera->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"<<std::endl;
osg::notify(osg::NOTICE)<<"Done destructing osg::View"<<std::endl;
}

View File

@@ -44,7 +44,19 @@ Viewer::~Viewer()
_scene->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()"<<std::endl;
}
bool Viewer::isRealized() const
@@ -858,6 +870,7 @@ void Viewer::renderingTraversals()
{
(*itr)->makeCurrent();
(*itr)->runOperations();
(*itr)->releaseContext();
}
}
@@ -876,6 +889,7 @@ void Viewer::renderingTraversals()
{
(*itr)->makeCurrent();
(*itr)->swapBuffers();
(*itr)->releaseContext();
}
}