From 759d2f8ebde454097e4353d1f8bcf5574fb2e642 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Wed, 20 Nov 2024 19:05:46 +0100 Subject: [PATCH] Properly recreate Rectangle2D(v2) on device lost --- .../Atmosphere/include/OgreAtmosphereNpr.h | 7 ++++- .../Atmosphere/src/OgreAtmosphereNpr.cpp | 26 +++++++++++++++---- OgreMain/include/OgreRectangle2D2.h | 5 ++++ OgreMain/src/OgreRadialDensityMask.cpp | 14 +++++----- OgreMain/src/OgreRectangle2D2.cpp | 7 ++++- OgreMain/src/OgreSceneManager.cpp | 16 +++++++----- 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/Components/Atmosphere/include/OgreAtmosphereNpr.h b/Components/Atmosphere/include/OgreAtmosphereNpr.h index 69df3c7e605..dd5471d0ce3 100644 --- a/Components/Atmosphere/include/OgreAtmosphereNpr.h +++ b/Components/Atmosphere/include/OgreAtmosphereNpr.h @@ -32,6 +32,7 @@ THE SOFTWARE. #include "OgreAtmosphereComponent.h" #include "OgreColourValue.h" +#include "OgreRenderSystem.h" #include "OgreSharedPtr.h" #include "OgreVector3.h" @@ -59,7 +60,8 @@ namespace Ogre A PBR solution is iterative and requires more resources. */ - class _OgreAtmosphereExport AtmosphereNpr final : public AtmosphereComponent + class _OgreAtmosphereExport AtmosphereNpr final : public AtmosphereComponent, + public RenderSystem::Listener { public: struct Preset @@ -202,6 +204,9 @@ namespace Ogre AtmosphereNpr( VaoManager *vaoManager ); ~AtmosphereNpr() override; + /// @see RenderSystem::Listener + void eventOccurred( const String &eventName, const NameValuePairList *parameters ) override; + void setSky( Ogre::SceneManager *sceneManager, bool bEnabled ); void destroySky( Ogre::SceneManager *sceneManager ); diff --git a/Components/Atmosphere/src/OgreAtmosphereNpr.cpp b/Components/Atmosphere/src/OgreAtmosphereNpr.cpp index 9455c632a5e..79506507f3f 100644 --- a/Components/Atmosphere/src/OgreAtmosphereNpr.cpp +++ b/Components/Atmosphere/src/OgreAtmosphereNpr.cpp @@ -77,10 +77,14 @@ namespace Ogre { mHlmsBuffer = vaoManager->createConstBuffer( sizeof( AtmoSettingsGpu ), BT_DEFAULT, 0, false ); createMaterial(); + + RenderSystem::addSharedListener( this ); } //------------------------------------------------------------------------- AtmosphereNpr::~AtmosphereNpr() { + RenderSystem::removeSharedListener( this ); + std::map::const_iterator itor = mSkies.begin(); std::map::const_iterator endt = mSkies.end(); @@ -90,7 +94,7 @@ namespace Ogre itor->first->_setAtmosphere( nullptr ); itor->second->detachFromParent(); - OGRE_DELETE itor->second; + itor->first->destroyRectangle2D( itor->second ); ++itor; } @@ -109,6 +113,20 @@ namespace Ogre mHlmsBuffer = 0; } //------------------------------------------------------------------------- + void AtmosphereNpr::eventOccurred( const String &eventName, const NameValuePairList *parameters ) + { + if( eventName == "DeviceLost" ) + { + mVaoManager->destroyConstBuffer( mHlmsBuffer ); + mHlmsBuffer = 0; + } + else if( eventName == "DeviceRestored" ) + { + mHlmsBuffer = + mVaoManager->createConstBuffer( sizeof( AtmoSettingsGpu ), BT_DEFAULT, 0, false ); + } + } + //------------------------------------------------------------------------- void AtmosphereNpr::createMaterial() { OGRE_ASSERT_LOW( !mMaterial ); @@ -226,9 +244,7 @@ namespace Ogre std::map::iterator itor = mSkies.find( sceneManager ); if( itor == mSkies.end() ) { - sky = OGRE_NEW Rectangle2D( Id::generateNewId(), - &sceneManager->_getEntityMemoryManager( SCENE_STATIC ), - sceneManager ); + sky = sceneManager->createRectangle2D( SCENE_STATIC ); // We can't use BT_DYNAMIC_* because the scene may be rendered from multiple cameras // in the same frame, and dynamic supports only one set of values per frame sky->initialize( BT_DEFAULT, @@ -259,7 +275,7 @@ namespace Ogre std::map::iterator itor = mSkies.find( sceneManager ); if( itor != mSkies.end() ) { - OGRE_DELETE itor->second; + sceneManager->destroyRectangle2D( itor->second ); mSkies.erase( itor ); } } diff --git a/OgreMain/include/OgreRectangle2D2.h b/OgreMain/include/OgreRectangle2D2.h index 8b06d29efa5..3c5c34bfa5a 100644 --- a/OgreMain/include/OgreRectangle2D2.h +++ b/OgreMain/include/OgreRectangle2D2.h @@ -81,6 +81,11 @@ namespace Ogre Rectangle2D( IdType id, ObjectMemoryManager *objectMemoryManager, SceneManager *manager ); ~Rectangle2D() override; + /** @copydoc MovableObject::_releaseManualHardwareResources */ + void _releaseManualHardwareResources() override; + /** @copydoc MovableObject::_restoreManualHardwareResources */ + void _restoreManualHardwareResources() override; + bool isQuad() const; bool isStereo() const; bool hasNormals() const; diff --git a/OgreMain/src/OgreRadialDensityMask.cpp b/OgreMain/src/OgreRadialDensityMask.cpp index d26babe03f8..8b0691550c8 100644 --- a/OgreMain/src/OgreRadialDensityMask.cpp +++ b/OgreMain/src/OgreRadialDensityMask.cpp @@ -65,9 +65,7 @@ namespace Ogre { memcpy( mRadius, radius, sizeof( mRadius ) ); - mRectangle = - OGRE_NEW Rectangle2D( Id::generateNewId(), - &sceneManager->_getEntityMemoryManager( SCENE_STATIC ), sceneManager ); + mRectangle = sceneManager->createRectangle2D( SCENE_STATIC ); mRectangle->setHollowRectRadius( mRadius[0] ); mRectangle->setGeometry( mLeftEyeCenter, mRightEyeCenter ); @@ -142,7 +140,8 @@ namespace Ogre MaterialPtr material = mRectangle->getMaterial(); MaterialManager::getSingleton().remove( material ); - OGRE_DELETE mRectangle; + SceneManager *sceneManager = mRectangle->_getManager(); + sceneManager->destroyRectangle2D( mRectangle ); mRectangle = 0; } //------------------------------------------------------------------------- @@ -224,10 +223,9 @@ namespace Ogre MaterialPtr material = mRectangle->getMaterial(); SceneManager *sceneManager = mRectangle->_getManager(); - OGRE_DELETE mRectangle; - mRectangle = OGRE_NEW Rectangle2D( Id::generateNewId(), - &sceneManager->_getEntityMemoryManager( SCENE_STATIC ), - sceneManager ); + sceneManager->destroyRectangle2D( mRectangle ); + mRectangle = 0; + mRectangle = sceneManager->createRectangle2D( SCENE_STATIC ); mRectangle->setHollowRectRadius( mRadius[0] ); mRectangle->initialize( diff --git a/OgreMain/src/OgreRectangle2D2.cpp b/OgreMain/src/OgreRectangle2D2.cpp index 9b1be0fb4de..d44247b432c 100644 --- a/OgreMain/src/OgreRectangle2D2.cpp +++ b/OgreMain/src/OgreRectangle2D2.cpp @@ -60,7 +60,9 @@ namespace Ogre mRenderables.push_back( this ); } //----------------------------------------------------------------------------------- - Rectangle2D::~Rectangle2D() + Rectangle2D::~Rectangle2D() { _releaseManualHardwareResources(); } + //----------------------------------------------------------------------------------- + void Rectangle2D::_releaseManualHardwareResources() { VaoManager *vaoManager = mManager->getDestinationRenderSystem()->getVaoManager(); @@ -88,8 +90,11 @@ namespace Ogre ++itor; } + mVaoPerLod->clear(); } //----------------------------------------------------------------------------------- + void Rectangle2D::_restoreManualHardwareResources() { createBuffers(); } + //----------------------------------------------------------------------------------- bool Rectangle2D::isQuad() const { return ( mGeometryFlags & GeometryFlagQuad ) != 0u; } //----------------------------------------------------------------------------------- bool Rectangle2D::isStereo() const { return ( mGeometryFlags & GeometryFlagStereo ) != 0u; } diff --git a/OgreMain/src/OgreSceneManager.cpp b/OgreMain/src/OgreSceneManager.cpp index c9ff9cf76a8..3d657274d38 100644 --- a/OgreMain/src/OgreSceneManager.cpp +++ b/OgreMain/src/OgreSceneManager.cpp @@ -277,8 +277,11 @@ namespace Ogre mForwardPlusSystem = 0; mForwardPlusImpl = 0; - OGRE_DELETE mSky; - mSky = 0; + if( mSky ) + { + destroyRectangle2D( mSky ); + mSky = 0; + } OGRE_DELETE mRadialDensityMask; mRadialDensityMask = 0; @@ -1080,8 +1083,7 @@ namespace Ogre { if( !mSky ) { - mSky = OGRE_NEW Rectangle2D( Id::generateNewId(), - &mEntityMemoryManager[SCENE_STATIC], this ); + mSky = createRectangle2D( SCENE_STATIC ); // We can't use BT_DYNAMIC_* because the scene may be rendered from multiple cameras // in the same frame, and dynamic supports only one set of values per frame mSky->initialize( BT_DEFAULT, @@ -1146,9 +1148,11 @@ namespace Ogre else { if( mSky ) + { mSky->detachFromParent(); - OGRE_DELETE mSky; - mSky = 0; + destroyRectangle2D( mSky ); + mSky = 0; + } if( mSkyMaterial ) { materialManager.remove( mSkyMaterial );