diff --git a/source/graphics/ParticleEmitter.cpp b/source/graphics/ParticleEmitter.cpp index 802015f099..ab18c175a0 100644 --- a/source/graphics/ParticleEmitter.cpp +++ b/source/graphics/ParticleEmitter.cpp @@ -26,7 +26,7 @@ #include "renderer/Renderer.h" CParticleEmitter::CParticleEmitter(const CParticleEmitterTypePtr& type) : - m_Type(type), m_Active(true), m_NextParticleIdx(0), m_EmissionTimer(0.f), + m_Type(type), m_Active(true), m_NextParticleIdx(0), m_EmissionRoundingError(0.f), m_LastUpdateTime(type->m_Manager.GetCurrentTime()), m_VertexArray(GL_DYNAMIC_DRAW) { diff --git a/source/graphics/ParticleEmitter.h b/source/graphics/ParticleEmitter.h index 4bf30c934b..010f8ba394 100644 --- a/source/graphics/ParticleEmitter.h +++ b/source/graphics/ParticleEmitter.h @@ -129,7 +129,7 @@ public: size_t m_NextParticleIdx; float m_LastUpdateTime; - float m_EmissionTimer; + float m_EmissionRoundingError; private: /// Bounding box of the current particle center points diff --git a/source/graphics/ParticleEmitterType.cpp b/source/graphics/ParticleEmitterType.cpp index 7e5754cbfd..cc6d070a98 100644 --- a/source/graphics/ParticleEmitterType.cpp +++ b/source/graphics/ParticleEmitterType.cpp @@ -355,6 +355,7 @@ bool CParticleEmitterType::LoadXML(const VfsPath& path) m_BlendFuncSrc = GL_SRC_ALPHA; m_BlendFuncDst = GL_ONE_MINUS_SRC_ALPHA; m_StartFull = false; + m_Texture = g_Renderer.GetTextureManager().GetErrorTexture(); CXeromyces XeroFile; PSRETURN ret = XeroFile.Load(g_VFS, path); @@ -507,11 +508,10 @@ void CParticleEmitterType::UpdateEmitterStep(CParticleEmitter& emitter, float dt { float emissionRate = m_Variables[VAR_EMISSIONRATE]->Evaluate(emitter); - // Find how many new particles to spawn, and accumulate any rounding errors into EmissionTimer - emitter.m_EmissionTimer += dt; - int newParticles = floor(emitter.m_EmissionTimer * emissionRate); - if (newParticles) // avoid divide-by-zero if emissionRate == 0 - emitter.m_EmissionTimer -= newParticles / emissionRate; + // Find how many new particles to spawn, and accumulate any rounding errors + // (to maintain a constant emission rate even if dt is very small) + int newParticles = floor(emitter.m_EmissionRoundingError + dt*emissionRate); + emitter.m_EmissionRoundingError += dt*emissionRate - newParticles; // If dt was very large, there's no point spawning new particles that // we'll immediately overwrite, so clamp it