From 5cd4faf05ba7d3a89dc92e59f500f5e96c406115 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Nov 2009 11:08:40 +0000 Subject: [PATCH] From Jason Beverage, "I posted a question on osg users about resources not being properly released when using osgTerrain databases and multiple viewers are used a few weeks ago and I've found that at least part of the problem comes down to the fact that the nodes that are traversed by the GeometryTechnique are never actually added to the scene graph, and thus don't have releaseGLObjects called on them. I'm submitting a few changes that takes care of this by allowing the TerrainTechnique to provide a releaseGLObjects implementation. I've applied these changes in osgEarth and this example program no longer crashes on the second run, although I get corrupt geometry (see attached shot) which could be down to a driver issue. If I increment the context ID for the second viewer, I no longer get the corrupt geometry. The attached changes are against OpenSceneGraph 2.8.2. //Sample program. Run against an osgEarth or VPB database based on osgTerrain. #include #include int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer* viewer = new osgViewer::Viewer(); viewer->setUpViewInWindow(100, 100,500,500); osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); viewer->setSceneData( loadedModel.get() ); viewer->run(); delete viewer; viewer = new osgViewer::Viewer(); viewer->setUpViewInWindow(100,100,500,500); loadedModel = osgDB::readNodeFiles(arguments); viewer->setSceneData( loadedModel.get() ); viewer->run(); delete viewer; }" --- include/osgTerrain/GeometryTechnique | 5 +++++ include/osgTerrain/TerrainTechnique | 5 +++++ include/osgTerrain/TerrainTile | 6 ++++++ src/osgTerrain/GeometryTechnique.cpp | 6 ++++++ src/osgTerrain/TerrainTile.cpp | 11 +++++++++++ 5 files changed, 33 insertions(+) diff --git a/include/osgTerrain/GeometryTechnique b/include/osgTerrain/GeometryTechnique index 70cb90df0..5f9829759 100644 --- a/include/osgTerrain/GeometryTechnique +++ b/include/osgTerrain/GeometryTechnique @@ -76,6 +76,11 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique void setFilterMatrixAs(FilterType filterType); + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objects + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const; + private: diff --git a/include/osgTerrain/TerrainTechnique b/include/osgTerrain/TerrainTechnique index e7f47854e..1922cddbd 100644 --- a/include/osgTerrain/TerrainTechnique +++ b/include/osgTerrain/TerrainTechnique @@ -51,6 +51,11 @@ class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object /** Traverse the terrain subgraph.*/ virtual void traverse(osg::NodeVisitor& nv); + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objects + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const {} + protected: void setDirty(bool dirty); diff --git a/include/osgTerrain/TerrainTile b/include/osgTerrain/TerrainTile index 42b7ece3a..6e49527d0 100644 --- a/include/osgTerrain/TerrainTile +++ b/include/osgTerrain/TerrainTile @@ -175,6 +175,12 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group static void setTileLoadedCallback(TileLoadedCallback* lc); static osg::ref_ptr& getTileLoadedCallback(); + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objects + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const; + + protected: virtual ~TerrainTile(); diff --git a/src/osgTerrain/GeometryTechnique.cpp b/src/osgTerrain/GeometryTechnique.cpp index 9f51e374e..602e5ce4c 100644 --- a/src/osgTerrain/GeometryTechnique.cpp +++ b/src/osgTerrain/GeometryTechnique.cpp @@ -898,3 +898,9 @@ void GeometryTechnique::cleanSceneGraph() { } +void GeometryTechnique::releaseGLObjects(osg::State* state) const +{ + if (_bufferData[0]._transform.valid()) _bufferData[0]._transform->releaseGLObjects(state); + if (_bufferData[1]._transform.valid()) _bufferData[1]._transform->releaseGLObjects(state); +} + diff --git a/src/osgTerrain/TerrainTile.cpp b/src/osgTerrain/TerrainTile.cpp index 55b213cbf..21b0c3675 100644 --- a/src/osgTerrain/TerrainTile.cpp +++ b/src/osgTerrain/TerrainTile.cpp @@ -463,3 +463,14 @@ void WhiteListTileLoadedCallback::loaded(osgTerrain::TerrainTile* tile, const os } } + +void TerrainTile::releaseGLObjects(osg::State* state) const +{ + Group::releaseGLObjects(state); + + if (_terrainTechnique.valid()) + { + _terrainTechnique->releaseGLObjects( state ); + } +} +