I'm working on a game where there may be heaps of particle effects going on - possibly hundreds of ParticleSystems, using the same template script, on the screen at any one time. Although the systems are often using the same template script each one represents an extra CPU->GPU batch which I don't want.
What I've done to get around this is to have a single static (C++ static that is) ParticleSystem in the relevant class and then have instances of the class create ParticleEmitter http://www.ogre3d.org/docs/api/html/classOgre_1_1ParticleEmitter.html instances which the class instances manage themselves . For example, a particular projectile in my game has a unique explosion effect - the C++ class that defines this projectile has a ParticleSystem that is initialised once when the first object of this type is instantiated. Each object of the class creates a ParticleEmitter via the static ParticleSystem.
Here's the static initialisation code (done once)
Code: Select all
m_pHitParticlesSystem = m_pSceneMgr->createParticleSystem("RocketProjectileClassExplosions", "particleTemplateName"); //setup the ParticleSystem in the normal way
m_pHitParticleSystem->getEmitter(0)->setEnabled(false); //disable any emitters that the template defines
m_HitParticleOriginalQuota = m_pHitParticles->getParticleQuota(); //we store the count of particles that the system would use for a single object - we'll be adding this to the quota for every new object
m_pSceneMgr->getRootSceneNode()->attachObject(m_pHitParticleSystem); //attach it the world origin as the position of emitters are an offset from the owning ParticleSystem
Here's what each new object does
Code: Select all
m_pHitParticleEmitter = m_pHitParticleSystem->addEmitter("Point"); //create a new emitter
m_pHitParticleSystem->getEmitter(0)->copyParametersTo(m_pHitParticleEmitter); //copy the default emitter's config to the newly created emitter
m_pHitParticlesystem->setParticleQuota(m_pHitParticleSystem->getParticleQuota() + m_HitParticleOriginalQuota); // each new object means our ParticleSystem must be able to handle more particles overall
This is all well and good, I can have huge numbers of the same effect going on and all in one batch, yay.
However, there is a problem (not a big one though), there's no great method for removing the particle emitters when the owning object gets deconstructed. The ParticleSystem class allows me to create an emitter but its removeEmitter function takes only an integer index to the emitter, this is fine if you're defining each emitter 'explicitly' and you know exactly where each emitter is in the ParticleSystem's 'list' of emitters but if stuff is happening randomly at runtime then you can get gaps in the list and indexes cease to be relevant (assumption!). There's no way to get the index of an emitter and no function like removeEmitter(Emitter *) which is what I'm needing.
I don't understand how Ogre's ParticleSystems work under the hood, I haven't even looked at the source, but I'm hoping someone can come to the rescue here - perhaps it'd be an easy addition to make to the API? As I say it's not causing me any problems whatsoever but it is gnawing away at my mind as it's a (small in my case) memory leak and possibly a performance problem over a long enough time scale. I am using pooling where appropriate which mitigates some problems but that's not
the point dagnamit.
Anyway, I hope this might help someone else who is wanting more particle awesomeness but is worried about batch count.