From 641005b317b7c1420ee868fc8f5ff5e91e47ea73 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 15 Aug 2016 18:11:36 +0200 Subject: [PATCH] Remove Camera's children before removing the Camera Should work around OSG race condition ( http://forum.openscenegraph.org/viewtopic.php?t=16077 ) --- apps/openmw/mwrender/characterpreview.cpp | 1 + apps/openmw/mwrender/globalmap.cpp | 13 ++++++++++++- apps/openmw/mwrender/globalmap.hpp | 2 ++ apps/openmw/mwrender/localmap.cpp | 16 +++++++++------- apps/openmw/mwrender/localmap.hpp | 2 ++ apps/openmw/mwrender/water.cpp | 4 ++++ components/myguiplatform/myguirendermanager.cpp | 2 ++ 7 files changed, 32 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index c858b57b7..566a8d6ba 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -147,6 +147,7 @@ namespace MWRender CharacterPreview::~CharacterPreview () { + mCamera->removeChildren(0, mCamera->getNumChildren()); mViewer->getSceneData()->asGroup()->removeChild(mCamera); } diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 4bc24c594..d5102b153 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -107,6 +107,10 @@ namespace MWRender GlobalMap::~GlobalMap() { + for (CameraVector::iterator it = mCamerasPendingRemoval.begin(); it != mCamerasPendingRemoval.end(); ++it) + removeCamera(*it); + for (CameraVector::iterator it = mActiveCameras.begin(); it != mActiveCameras.end(); ++it) + removeCamera(*it); } void GlobalMap::render (Loading::Listener* loadingListener) @@ -507,7 +511,8 @@ namespace MWRender void GlobalMap::cleanupCameras() { for (CameraVector::iterator it = mCamerasPendingRemoval.begin(); it != mCamerasPendingRemoval.end(); ++it) - mRoot->removeChild(*it); + removeCamera(*it); + mCamerasPendingRemoval.clear(); for (ImageDestVector::iterator it = mPendingImageDest.begin(); it != mPendingImageDest.end();) @@ -524,4 +529,10 @@ namespace MWRender it = mPendingImageDest.erase(it); } } + + void GlobalMap::removeCamera(osg::Camera *cam) + { + cam->removeChildren(0, cam->getNumChildren()); + mRoot->removeChild(cam); + } } diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp index 07ae7cdae..df8aa9962 100644 --- a/apps/openmw/mwrender/globalmap.hpp +++ b/apps/openmw/mwrender/globalmap.hpp @@ -56,6 +56,8 @@ namespace MWRender */ void cleanupCameras(); + void removeCamera(osg::Camera* cam); + /** * Mark a camera for cleanup in the next update. For internal use only. */ diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 8340ab78a..833e2717b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -88,9 +88,9 @@ LocalMap::LocalMap(osgViewer::Viewer* viewer) LocalMap::~LocalMap() { for (CameraVector::iterator it = mActiveCameras.begin(); it != mActiveCameras.end(); ++it) - mRoot->removeChild(*it); + removeCamera(*it); for (CameraVector::iterator it = mCamerasPendingRemoval.begin(); it != mCamerasPendingRemoval.end(); ++it) - mRoot->removeChild(*it); + removeCamera(*it); } const osg::Vec2f LocalMap::rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle) @@ -275,6 +275,12 @@ osg::ref_ptr LocalMap::getFogOfWarTexture(int x, int y) return found->second.mFogOfWarTexture; } +void LocalMap::removeCamera(osg::Camera *cam) +{ + cam->removeChildren(0, cam->getNumChildren()); + mRoot->removeChild(cam); +} + void LocalMap::markForRemoval(osg::Camera *cam) { CameraVector::iterator found = std::find(mActiveCameras.begin(), mActiveCameras.end(), cam); @@ -293,11 +299,7 @@ void LocalMap::cleanupCameras() return; for (CameraVector::iterator it = mCamerasPendingRemoval.begin(); it != mCamerasPendingRemoval.end(); ++it) - { - (*it)->removeChildren(0, (*it)->getNumChildren()); - (*it)->setGraphicsContext(NULL); - mRoot->removeChild(*it); - } + removeCamera(*it); mCamerasPendingRemoval.clear(); } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index d946f4c2b..2516c063e 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -63,6 +63,8 @@ namespace MWRender osg::ref_ptr getFogOfWarTexture (int x, int y); + void removeCamera(osg::Camera* cam); + /** * Indicates a camera has been queued for rendering and can be cleaned up in the next frame. For internal use only. */ diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 532e5cedc..f6b7a0d86 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -443,11 +443,13 @@ void Water::updateWaterMaterial() { if (mReflection) { + mReflection->removeChildren(0, mReflection->getNumChildren()); mParent->removeChild(mReflection); mReflection = NULL; } if (mRefraction) { + mRefraction->removeChildren(0, mRefraction->getNumChildren()); mParent->removeChild(mRefraction); mRefraction = NULL; } @@ -572,11 +574,13 @@ Water::~Water() if (mReflection) { + mReflection->removeChildren(0, mReflection->getNumChildren()); mParent->removeChild(mReflection); mReflection = NULL; } if (mRefraction) { + mRefraction->removeChildren(0, mRefraction->getNumChildren()); mParent->removeChild(mRefraction); mRefraction = NULL; } diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index 7654a2821..9d1f7100f 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -412,6 +412,8 @@ void RenderManager::initialise() void RenderManager::shutdown() { + mGuiRoot->removeChildren(0, mGuiRoot->getNumChildren()); + mSceneRoot->removeChild(mGuiRoot); } MyGUI::IVertexBuffer* RenderManager::createVertexBuffer()