From 0cd5136fdb53c47dcc246bc09a4bdeb99c132d70 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 4 Nov 2024 14:41:52 +0300 Subject: [PATCH] feat: emitters random access & add ParticlesRenderer.gc() --- src/graphics/render/ParticlesRenderer.cpp | 36 +++++++++++++++++++++-- src/graphics/render/ParticlesRenderer.hpp | 17 +++++++++-- src/typedefs.hpp | 1 + 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index a15e75a8..d377773e 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -1,5 +1,7 @@ #include "ParticlesRenderer.hpp" +#include + #include "assets/Assets.hpp" #include "assets/assets_util.hpp" #include "graphics/core/Shader.hpp" @@ -119,7 +121,7 @@ void ParticlesRenderer::render(const Camera& camera, float delta) { auto iter = emitters.begin(); while (iter != emitters.end()) { - auto& emitter = **iter; + auto& emitter = *iter->second; auto texture = emitter.getTexture(); const auto& found = particles.find(texture); std::vector* vec; @@ -138,6 +140,34 @@ void ParticlesRenderer::render(const Camera& camera, float delta) { } } -void ParticlesRenderer::add(std::unique_ptr emitter) { - emitters.push_back(std::move(emitter)); +void ParticlesRenderer::gc() { + std::set usedEmitters; + for (const auto& [_, vec] : particles) { + for (const auto& particle : vec) { + usedEmitters.insert(particle.emitter); + } + } + auto iter = emitters.begin(); + while (iter != emitters.end()) { + auto emitter = iter->second.get(); + if (usedEmitters.find(emitter) == usedEmitters.end()) { + iter = emitters.erase(iter); + } else { + iter++; + } + } +} + +Emitter* ParticlesRenderer::getEmitter(u64id_t id) const { + const auto& found = emitters.find(id); + if (found == emitters.end()) { + return nullptr; + } + return found->second.get(); +} + +u64id_t ParticlesRenderer::add(std::unique_ptr emitter) { + u64id_t uid = nextEmitter++; + emitters[uid] = std::move(emitter); + return uid; } diff --git a/src/graphics/render/ParticlesRenderer.hpp b/src/graphics/render/ParticlesRenderer.hpp index 27877959..46509d96 100644 --- a/src/graphics/render/ParticlesRenderer.hpp +++ b/src/graphics/render/ParticlesRenderer.hpp @@ -5,6 +5,7 @@ #include #include "Emitter.hpp" +#include "typedefs.hpp" class Texture; class Assets; @@ -18,9 +19,11 @@ class ParticlesRenderer { const Assets& assets; const GraphicsSettings* settings; std::unordered_map> particles; - std::vector> emitters; std::unique_ptr batch; + std::unordered_map> emitters; + u64id_t nextEmitter = 1; + void renderParticles(const Camera& camera, float delta); public: ParticlesRenderer( @@ -32,7 +35,17 @@ public: void render(const Camera& camera, float delta); - void add(std::unique_ptr emitter); + u64id_t add(std::unique_ptr emitter); + + /// @brief Perform garbage collection (remove extra dead emitters). + /// @note Emitters are deleting without GC when there's no particles with same + /// texture left. + /// @note Currently unused + void gc(); + + /// @brief Get emitter by UID + /// @return Emitter or nullptr + Emitter* getEmitter(u64id_t id) const; static size_t visibleParticles; static size_t aliveEmitters; diff --git a/src/typedefs.hpp b/src/typedefs.hpp index 3925d277..b3266aea 100644 --- a/src/typedefs.hpp +++ b/src/typedefs.hpp @@ -12,6 +12,7 @@ using integer_t = int64_t; using number_t = double; using uint = unsigned int; +using u64id_t = uint64_t; /// @brief use for bytes arrays using ubyte = uint8_t;