From b71b3844de8386ae1d48fe679f2be203effc1380 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 8 Apr 2024 11:51:00 -0300 Subject: [PATCH] BillboardSets now appear on screen Fix crash on shutdown --- .../ParticleSystem/OgreBillboardSet2.h | 15 +--- .../src/ParticleSystem/OgreBillboardSet2.cpp | 57 +++++++++++++ .../OgreParticleSystemManager2.cpp | 84 ++++++++++++++----- 3 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 OgreMain/src/ParticleSystem/OgreBillboardSet2.cpp diff --git a/OgreMain/include/ParticleSystem/OgreBillboardSet2.h b/OgreMain/include/ParticleSystem/OgreBillboardSet2.h index e921e78fe7b..fb194cc69b5 100644 --- a/OgreMain/include/ParticleSystem/OgreBillboardSet2.h +++ b/OgreMain/include/ParticleSystem/OgreBillboardSet2.h @@ -63,20 +63,9 @@ namespace Ogre Renderable *getAsRenderable() { return this; } - Billboard allocBillboard() - { - const uint32 handle = allocParticle(); - - Billboard retVal( handle, this ); - retVal.setVisible( true ); - return Billboard( handle, this ); - } + Billboard allocBillboard(); - void deallocBillboard( Billboard billboard ) - { - billboard.setVisible( false ); - deallocParticle( billboard.mHandle ); - } + void deallocBillboard( Billboard billboard ); void deallocBillboard( uint32 handle ) { deallocBillboard( Billboard( handle, this ) ); } BillboardSet( IdType id, ObjectMemoryManager *objectMemoryManager, SceneManager *manager, diff --git a/OgreMain/src/ParticleSystem/OgreBillboardSet2.cpp b/OgreMain/src/ParticleSystem/OgreBillboardSet2.cpp new file mode 100644 index 00000000000..70a07a3e830 --- /dev/null +++ b/OgreMain/src/ParticleSystem/OgreBillboardSet2.cpp @@ -0,0 +1,57 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE-Next +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2024 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +#include "OgreStableHeaders.h" + +#include "ParticleSystem/OgreBillboardSet2.h" + +#include "Vao/OgreVertexArrayObject.h" + +using namespace Ogre; + +Billboard BillboardSet::allocBillboard() +{ + const uint32 handle = allocParticle(); + + Billboard retVal( handle, this ); + retVal.setVisible( true ); + + mVaoPerLod[0].back()->setPrimitiveRange( 0u, + static_cast( getParticlesToRenderTighter() * 6u ) ); + + return Billboard( handle, this ); +} +//----------------------------------------------------------------------------- +void BillboardSet::deallocBillboard( Billboard billboard ) +{ + billboard.setVisible( false ); + deallocParticle( billboard.mHandle ); + + mVaoPerLod[0].back()->setPrimitiveRange( 0u, + static_cast( getParticlesToRenderTighter() * 6u ) ); +} diff --git a/OgreMain/src/ParticleSystem/OgreParticleSystemManager2.cpp b/OgreMain/src/ParticleSystem/OgreParticleSystemManager2.cpp index 3b7e775d583..66eb480895f 100644 --- a/OgreMain/src/ParticleSystem/OgreParticleSystemManager2.cpp +++ b/OgreMain/src/ParticleSystem/OgreParticleSystemManager2.cpp @@ -716,6 +716,13 @@ void ParticleSystemManager2::destroyBillboardSet( BillboardSet *billboardSet ) //----------------------------------------------------------------------------- void ParticleSystemManager2::destroyAllBillboardSets() { + if( !mMaster ) + { + OGRE_ASSERT_LOW( mBillboardSets.empty() && + "ParticleSystemManager2 owned by Root can't create BillboardSets!" ); + return; + } + VaoManager *vaoManager = mSceneManager->getDestinationRenderSystem()->getVaoManager(); for( ParticleSystemDef *billboardSet : mBillboardSets ) { @@ -729,28 +736,58 @@ void ParticleSystemManager2::_addToRenderQueue( size_t threadIdx, size_t numThre RenderQueue *renderQueue, uint8 renderQueueId, uint32 visibilityMask, bool includeNonCasters ) const { - const size_t numSystemDefs = mActiveParticleSystemDefs.size(); - const size_t systemDefsPerThread = ( numSystemDefs + numThreads - 1u ) / numThreads; - const size_t toAdvance = std::min( threadIdx * systemDefsPerThread, numSystemDefs ); - const size_t numParticlesToProcess = std::min( systemDefsPerThread, numSystemDefs - toAdvance ); + { + const size_t numSystemDefs = mActiveParticleSystemDefs.size(); + const size_t systemDefsPerThread = ( numSystemDefs + numThreads - 1u ) / numThreads; + const size_t toAdvance = std::min( threadIdx * systemDefsPerThread, numSystemDefs ); + const size_t numParticlesToProcess = std::min( systemDefsPerThread, numSystemDefs - toAdvance ); - FastArray::const_iterator itor = mActiveParticleSystemDefs.begin() + toAdvance; - FastArray::const_iterator endt = - mActiveParticleSystemDefs.begin() + toAdvance + numParticlesToProcess; + FastArray::const_iterator itor = + mActiveParticleSystemDefs.begin() + toAdvance; + FastArray::const_iterator endt = + mActiveParticleSystemDefs.begin() + toAdvance + numParticlesToProcess; - while( itor != endt ) - { - ParticleSystemDef *systemDef = *itor; - if( systemDef->getNumSimdActiveParticles() > 0u && // - systemDef->mRenderQueueID == renderQueueId && // - systemDef->getVisibilityFlags() & visibilityMask && - ( systemDef->getCastShadows() || includeNonCasters ) ) + while( itor != endt ) { - renderQueue->addRenderableV2( threadIdx, systemDef->mRenderQueueID, false, systemDef, - systemDef ); + ParticleSystemDef *systemDef = *itor; + if( systemDef->getNumSimdActiveParticles() > 0u && // + systemDef->mRenderQueueID == renderQueueId && // + systemDef->getVisibilityFlags() & visibilityMask && + ( systemDef->getCastShadows() || includeNonCasters ) ) + { + renderQueue->addRenderableV2( threadIdx, systemDef->mRenderQueueID, false, systemDef, + systemDef ); + } + + ++itor; } + } - ++itor; + { + const size_t numBillboardSets = mBillboardSets.size(); + const size_t billboardSetsPerThread = ( numBillboardSets + numThreads - 1u ) / numThreads; + const size_t toAdvance = std::min( threadIdx * billboardSetsPerThread, numBillboardSets ); + const size_t numBillboardSetsToProcess = + std::min( billboardSetsPerThread, numBillboardSets - toAdvance ); + + FastArray::const_iterator itor = mBillboardSets.begin() + toAdvance; + FastArray::const_iterator endt = + mBillboardSets.begin() + toAdvance + numBillboardSetsToProcess; + + while( itor != endt ) + { + BillboardSet *billboardSet = *itor; + if( billboardSet->getNumSimdActiveParticles() > 0u && // + billboardSet->mRenderQueueID == renderQueueId && // + billboardSet->getVisibilityFlags() & visibilityMask && + ( billboardSet->getCastShadows() || includeNonCasters ) ) + { + renderQueue->addRenderableV2( threadIdx, billboardSet->mRenderQueueID, false, + billboardSet, billboardSet ); + } + + ++itor; + } } } //----------------------------------------------------------------------------- @@ -789,6 +826,15 @@ void ParticleSystemManager2::calculateHighestPossibleQuota( VaoManager *vaoManag highestQuota32 = std::max( quota, highestQuota32 ); } + for( const BillboardSet *billboardSet : mBillboardSets ) + { + const uint32 quota = billboardSet->getQuota() * 4u; + if( quota <= std::numeric_limits::max() ) + highestQuota16 = std::max( quota, highestQuota16 ); + else + highestQuota32 = std::max( quota, highestQuota32 ); + } + mHighestPossibleQuota16 = std::max( mHighestPossibleQuota16, highestQuota16 ); mHighestPossibleQuota32 = std::max( mHighestPossibleQuota32, highestQuota32 ); @@ -889,7 +935,7 @@ IndexBufferPacked *ParticleSystemManager2::_getSharedIndexBuffer( size_t maxQuot void ParticleSystemManager2::prepareForUpdate( const Real timeSinceLast ) { mActiveParticlesLeftToSort.clear(); - if( mActiveParticleSystemDefs.empty() ) + if( mActiveParticleSystemDefs.empty() && mBillboardSets.empty() ) return; mTimeSinceLast = timeSinceLast; @@ -911,7 +957,7 @@ void ParticleSystemManager2::prepareForUpdate( const Real timeSinceLast ) //----------------------------------------------------------------------------- void ParticleSystemManager2::update() { - if( mActiveParticleSystemDefs.empty() ) + if( mActiveParticleSystemDefs.empty() && mBillboardSets.empty() ) return; mSceneManager->_fireParticleSystemManager2Update();