Index: ps/trunk/source/graphics/ParticleEmitter.h =================================================================== --- ps/trunk/source/graphics/ParticleEmitter.h +++ ps/trunk/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: ps/trunk/source/graphics/ParticleEmitter.cpp =================================================================== --- ps/trunk/source/graphics/ParticleEmitter.cpp +++ ps/trunk/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; @@ -260,8 +263,6 @@ m_EntityVariables[name] = value; } - - CModelParticleEmitter::CModelParticleEmitter(const CParticleEmitterTypePtr& type) : m_Type(type) { Index: ps/trunk/source/renderer/ParticleRenderer.h =================================================================== --- ps/trunk/source/renderer/ParticleRenderer.h +++ ps/trunk/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: ps/trunk/source/renderer/ParticleRenderer.cpp =================================================================== --- ps/trunk/source/renderer/ParticleRenderer.cpp +++ ps/trunk/source/renderer/ParticleRenderer.cpp @@ -58,8 +58,8 @@ void ParticleRenderer::EndFrame() { - for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) - m->emitters[cullGroup].clear(); + for (std::vector& cullGroupEmitters : m->emitters) + cullGroupEmitters.clear(); // this should leave the capacity unchanged, which is okay since it // won't be very large or very variable } @@ -103,29 +103,36 @@ ++m->frameNumber; - for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) + for (std::vector& cullGroupEmitters : m->emitters) { PROFILE("update emitters"); - for (size_t i = 0; i < m->emitters[cullGroup].size(); ++i) + for (CParticleEmitter* emitter : cullGroupEmitters) { - CParticleEmitter* emitter = m->emitters[cullGroup][i]; emitter->UpdateArrayData(m->frameNumber); emitter->PrepareForRendering(); } } - for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup) + CMatrix3D worldToCamera; + g_Renderer.GetSceneRenderer().GetViewCamera().GetOrientation().GetInverse(worldToCamera); + for (std::vector& cullGroupEmitters : m->emitters) { // Sort back-to-front by distance from camera PROFILE("sort emitters"); - CMatrix3D worldToCam; - g_Renderer.GetSceneRenderer().GetViewCamera().GetOrientation().GetInverse(worldToCam); - std::stable_sort(m->emitters[cullGroup].begin(), m->emitters[cullGroup].end(), SortEmitterDistance(worldToCam)); + std::stable_sort(cullGroupEmitters.begin(), cullGroupEmitters.end(), SortEmitterDistance(worldToCamera)); } // TODO: should batch by texture here when possible, maybe } +void ParticleRenderer::Upload( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + for (std::vector& cullGroupEmitters : m->emitters) + for (CParticleEmitter* emitter : cullGroupEmitters) + emitter->UploadData(deviceCommandContext); +} + void ParticleRenderer::RenderParticles( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, int cullGroup, bool wireframe) Index: ps/trunk/source/renderer/SceneRenderer.cpp =================================================================== --- ps/trunk/source/renderer/SceneRenderer.cpp +++ ps/trunk/source/renderer/SceneRenderer.cpp @@ -808,6 +808,8 @@ m->overlayRenderer.Upload(deviceCommandContext); + m->particleRenderer.Upload(deviceCommandContext); + if (g_RenderingOptions.GetShadows()) { RenderShadowMap(deviceCommandContext, context);