Index: source/graphics/ParticleEmitter.h =================================================================== --- source/graphics/ParticleEmitter.h +++ source/graphics/ParticleEmitter.h @@ -120,6 +120,12 @@ void PrepareForRendering(); /** + * Upload the vertex data to the backend. + */ + void UploadData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + + /** * Bind rendering state (textures and blend modes). */ void Bind( Index: source/graphics/ParticleEmitter.cpp =================================================================== --- source/graphics/ParticleEmitter.cpp +++ source/graphics/ParticleEmitter.cpp @@ -174,6 +174,12 @@ m_VertexArray.PrepareForRendering(); } +void CParticleEmitter::UploadData( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + m_VertexArray.UploadIfNeeded(deviceCommandContext); +} + void CParticleEmitter::Bind( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Renderer::Backend::IShaderProgram* shader) @@ -206,9 +212,6 @@ if (m_Particles.empty()) return; - m_VertexArray.UploadIfNeeded(deviceCommandContext); - m_IndexArray.UploadIfNeeded(deviceCommandContext); - const uint32_t stride = m_VertexArray.GetStride(); const uint32_t firstVertexOffset = m_VertexArray.GetOffset() * stride; @@ -259,8 +262,6 @@ { m_EntityVariables[name] = value; } - - CModelParticleEmitter::CModelParticleEmitter(const CParticleEmitterTypePtr& type) : m_Type(type) Index: source/renderer/ParticleRenderer.h =================================================================== --- source/renderer/ParticleRenderer.h +++ source/renderer/ParticleRenderer.h @@ -48,6 +48,13 @@ void PrepareForRendering(const CShaderDefines& context); /** + * Upload internal data to the backend. Must be called after the data is + * prepared and before any rendering calls. + */ + void Upload( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + + /** * Reset the list of submitted overlays. */ void EndFrame(); Index: source/renderer/ParticleRenderer.cpp =================================================================== --- source/renderer/ParticleRenderer.cpp +++ source/renderer/ParticleRenderer.cpp @@ -106,9 +106,8 @@ for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) { PROFILE("update emitters"); - for (size_t i = 0; i < m->emitters[cullGroup].size(); ++i) + for (CParticleEmitter* emitter : m->emitters[cullGroup]) { - CParticleEmitter* emitter = m->emitters[cullGroup][i]; emitter->UpdateArrayData(m->frameNumber); emitter->PrepareForRendering(); } @@ -124,6 +123,14 @@ } // TODO: should batch by texture here when possible, maybe +} + +void ParticleRenderer::Upload( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) + for (CParticleEmitter* emitter : m->emitters[cullGroup]) + emitter->UploadData(deviceCommandContext); } void ParticleRenderer::RenderParticles( Index: source/renderer/SceneRenderer.cpp =================================================================== --- source/renderer/SceneRenderer.cpp +++ source/renderer/SceneRenderer.cpp @@ -808,6 +808,8 @@ m->overlayRenderer.Upload(deviceCommandContext); + m->particleRenderer.Upload(deviceCommandContext); + if (g_RenderingOptions.GetShadows()) { RenderShadowMap(deviceCommandContext, context);