From 579b18468224190ac6088b8dde310699b6cb531a Mon Sep 17 00:00:00 2001 From: Evgeny Prikazchikov Date: Sun, 10 May 2026 13:27:03 +0300 Subject: [PATCH] Render system moved to groups --- engine/includes/components/baselight.h | 3 - engine/includes/components/component.h | 12 ++++ .../includes/components/postprocessvolume.h | 2 - engine/includes/components/renderable.h | 3 - engine/includes/systems/rendersystem.h | 23 ------- engine/src/components/baselight.cpp | 27 +++----- engine/src/components/component.cpp | 69 ++++++++++++++++--- engine/src/components/postprocessvolume.cpp | 13 ++-- engine/src/components/renderable.cpp | 13 +--- engine/src/components/world.cpp | 2 +- engine/src/pipelinecontext.cpp | 36 ++++++---- engine/src/systems/rendersystem.cpp | 39 ----------- 12 files changed, 109 insertions(+), 133 deletions(-) diff --git a/engine/includes/components/baselight.h b/engine/includes/components/baselight.h index a28200813..32598777c 100644 --- a/engine/includes/components/baselight.h +++ b/engine/includes/components/baselight.h @@ -65,9 +65,6 @@ class ENGINE_EXPORT BaseLight : public NativeBehaviour { virtual void cleanDirty(); -private: - void setSystem(ObjectSystem *system) override; - protected: static std::vector s_directions; diff --git a/engine/includes/components/component.h b/engine/includes/components/component.h index 16ebcbc83..5f8834722 100644 --- a/engine/includes/components/component.h +++ b/engine/includes/components/component.h @@ -22,12 +22,16 @@ class ENGINE_EXPORT Component : public Object { A_METHOD(Component *, Component::component), A_METHOD(Actor *, Component::instantiate), A_METHOD(TString, Component::tr), + A_METHOD(void, Component::addTag), + A_METHOD(void, Component::removeTag), + A_METHOD(bool, Component::hasTag), A_METHOD(void, Component::deleteLater), A_SLOT(Component::onReferenceDestroyed) ) public: Component(); + ~Component(); Actor *actor() const; Scene *scene() const; @@ -57,13 +61,21 @@ class ENGINE_EXPORT Component : public Object { TString tr(const TString &source); void addTag(const TString &tag); + void addTagByHash(uint32_t hash); + void removeTag(const TString &tag); + void removeTagByHash(uint32_t hash); + + bool hasTag(const TString &tag); + bool hasTagByHash(uint32_t hash); virtual void composeComponent(); virtual void drawGizmos(); virtual void drawGizmosSelected(); + void setParent(Object *parent, int32_t position = -1, bool force = false) override; + protected: void loadUserData(const VariantMap &data) override; VariantMap saveUserData() const override; diff --git a/engine/includes/components/postprocessvolume.h b/engine/includes/components/postprocessvolume.h index 17aabc12b..f0edc3760 100644 --- a/engine/includes/components/postprocessvolume.h +++ b/engine/includes/components/postprocessvolume.h @@ -34,8 +34,6 @@ class ENGINE_EXPORT PostProcessVolume : public Component { private: void setProperty(const char *name, const Variant &value) override; - void setSystem(ObjectSystem *system) override; - void drawGizmos() override; private: diff --git a/engine/includes/components/renderable.h b/engine/includes/components/renderable.h index e1f76fffc..edfbcaabb 100644 --- a/engine/includes/components/renderable.h +++ b/engine/includes/components/renderable.h @@ -60,9 +60,6 @@ class ENGINE_EXPORT Renderable : public NativeBehaviour { virtual void setMaterialsList(const std::list &materials); -private: - void setSystem(ObjectSystem *system) override; - protected: friend class PipelineContext; friend class PipelineTask; diff --git a/engine/includes/systems/rendersystem.h b/engine/includes/systems/rendersystem.h index 0dbdfe0cb..7086c112a 100644 --- a/engine/includes/systems/rendersystem.h +++ b/engine/includes/systems/rendersystem.h @@ -5,8 +5,6 @@ #include "system.h" class PipelineContext; -class Widget; -class BaseLight; class Renderable; class PostProcessVolume; @@ -31,21 +29,6 @@ class ENGINE_EXPORT RenderSystem : public System { PipelineContext *pipelineContext() const; void setPipelineContext(PipelineContext *context); - void addRenderable(Renderable *renderable); - void removeRenderable(Renderable *renderable); - - static std::list &renderables(); - - void addLight(BaseLight *light); - void removeLight(BaseLight *light); - - static std::list &lights(); - - void addPostProcessVolume(PostProcessVolume *volume); - void removePostProcessVolume(PostProcessVolume *volume); - - static std::list &postProcessVolumes(); - #if defined(SHARED_DEFINE) virtual QWindow *createRhiWindow(Viewport *viewport); #endif @@ -57,12 +40,6 @@ class ENGINE_EXPORT RenderSystem : public System { static void *m_windowHandle; private: - static int32_t m_registered; - - static std::list m_lightComponents; - static std::list m_renderableComponents; - static std::list m_postProcessVolumes; - PipelineContext *m_pipelineContext; bool m_frameDirty; diff --git a/engine/src/components/baselight.cpp b/engine/src/components/baselight.cpp index d8a442bb8..f4fcc6df3 100644 --- a/engine/src/components/baselight.cpp +++ b/engine/src/components/baselight.cpp @@ -33,18 +33,20 @@ Matrix4 BaseLight::s_scale = Matrix4(Vector3(0.5f), Quaternion(), Vector3(0.5f)) */ BaseLight::BaseLight() : - m_params(1.0f, 1.0f, 0.5f, 1.0f), - m_color(1.0f), - m_materialInstance(nullptr), - m_hash(0), - m_lod(0), - m_shadows(false), - m_dirty(true) { + m_params(1.0f, 1.0f, 0.5f, 1.0f), + m_color(1.0f), + m_materialInstance(nullptr), + m_hash(0), + m_lod(0), + m_shadows(false), + m_dirty(true) { + static uint32_t hash = Mathf::hashString("lights"); + addTagByHash(hash); } BaseLight::~BaseLight() { - static_cast(system())->removeLight(this); + } /*! @@ -219,15 +221,6 @@ void BaseLight::setParams(Vector4 ¶ms) { /*! \internal */ -void BaseLight::setSystem(ObjectSystem *system) { - Object::setSystem(system); - - RenderSystem *render = static_cast(system); - render->addLight(this); -} -/*! - \internal -*/ Vector4 BaseLight::gizmoColor() const { return Vector4(1.0f, 1.0f, 0.5f, 1.0f); } diff --git a/engine/src/components/component.cpp b/engine/src/components/component.cpp index 7a7052c48..bf9273f17 100644 --- a/engine/src/components/component.cpp +++ b/engine/src/components/component.cpp @@ -33,6 +33,16 @@ Component::Component() : m_enable(true) { } + +Component::~Component() { + Scene *scene = Component::scene(); + if(scene) { + for(auto it : m_tags) { + scene->removeFromGroupByHash(this, it); + } + } +} + /*! Returns an Actor which the Component is attached to. */ @@ -124,13 +134,20 @@ TString Component::tr(const TString &source) { return Engine::translate(source); } /*! - Adds a \a tag for current component. + Adds \a tag for current component. Automatically adds component to specific Scene group. */ void Component::addTag(const TString &tag) { - uint32_t hash = Mathf::hashString(tag); - auto it = std::find(m_tags.begin(), m_tags.end(), hash); - if(it == m_tags.end()) { + addTagByHash(Mathf::hashString(tag)); +} +/*! + Adds a tag for current component by tag \a hash. + Automatically adds component to specific Scene group. +*/ +void Component::addTagByHash(uint32_t hash) { + if(!hasTagByHash(hash)) { + m_tags.push_back(hash); + Scene *scene = Component::scene(); if(scene) { scene->addToGroupByHash(this, hash); @@ -138,11 +155,17 @@ void Component::addTag(const TString &tag) { } } /*! - Removes a \a tag for current component. + Removes \a tag for current component. Automatically removes component from specific Scene group. */ void Component::removeTag(const TString &tag) { - uint32_t hash = Mathf::hashString(tag); + removeTagByHash(Mathf::hashString(tag)); +} +/*! + Removes a tag for current component by tag \a hash. + Automatically removes component from specific Scene group. +*/ +void Component::removeTagByHash(uint32_t hash) { auto it = std::find(m_tags.begin(), m_tags.end(), hash); if(it != m_tags.end()) { m_tags.erase(it); @@ -153,6 +176,18 @@ void Component::removeTag(const TString &tag) { } } } +/*! + Returns true if component has a \a tag; otherwise returns false. +*/ +bool Component::hasTag(const TString &tag) { + return hasTagByHash(Mathf::hashString(tag)); +} +/*! + Returns true if component has a tag provided by its \a hash; otherwise returns false. +*/ +bool Component::hasTagByHash(uint32_t hash) { + return std::find(m_tags.begin(), m_tags.end(), hash) != m_tags.end(); +} /*! \internal */ @@ -320,6 +355,12 @@ VariantMap Component::saveUserData() const { } } return result; +} +/*! + \internal +*/ +void Component::onReferenceDestroyed() { + } /*! This method will be called automatically when \a current scene will be \a changed to a new one. @@ -329,14 +370,20 @@ void Component::changeScene(Scene *current, Scene *changed) { if(current) { current->removeFromGroupByHash(this, it); } - if(current) { + if(changed) { changed->addToGroupByHash(this, it); } } } -/*! - \internal -*/ -void Component::onReferenceDestroyed() { +void Component::setParent(Object *parent, int32_t position, bool force) { + Scene *currentScene = Component::scene(); + + Object::setParent(parent, position, force); + + Scene *changedScene = Component::scene(); + + if(currentScene != changedScene) { + changeScene(currentScene, changedScene); + } } diff --git a/engine/src/components/postprocessvolume.cpp b/engine/src/components/postprocessvolume.cpp index f1a496b49..a15fee9fd 100644 --- a/engine/src/components/postprocessvolume.cpp +++ b/engine/src/components/postprocessvolume.cpp @@ -26,10 +26,13 @@ PostProcessVolume::PostProcessVolume() : for(auto &it : m_settings->settings()) { Object::setProperty(it.first.c_str(), it.second); } + + static uint32_t hash = Mathf::hashString("postProcess"); + addTagByHash(hash); } PostProcessVolume::~PostProcessVolume() { - static_cast(system())->removePostProcessVolume(this); + } /*! Returns the priority of volume in the list. @@ -94,14 +97,6 @@ void PostProcessVolume::setProperty(const char *name, const Variant &value) { /*! \internal */ -void PostProcessVolume::setSystem(ObjectSystem *system) { - Component::setSystem(system); - - static_cast(system)->addPostProcessVolume(this); -} -/*! - \internal -*/ void PostProcessVolume::drawGizmos() { Transform *t = transform(); diff --git a/engine/src/components/renderable.cpp b/engine/src/components/renderable.cpp index 4334fd99b..0a43ab509 100644 --- a/engine/src/components/renderable.cpp +++ b/engine/src/components/renderable.cpp @@ -24,11 +24,11 @@ Renderable::Renderable() : m_lod(0), m_transformHash(0) { + static uint32_t hash = Mathf::hashString("renderable"); + addTagByHash(hash); } Renderable::~Renderable() { - static_cast(system())->removeRenderable(this); - for(auto it : m_materials) { delete it; } @@ -145,15 +145,6 @@ void Renderable::setMaterialsList(const std::list &materials) { AABBox Renderable::localBound() { return AABBox(); } -/*! - \internal -*/ -void Renderable::setSystem(ObjectSystem *system) { - Object::setSystem(system); - - RenderSystem *render = static_cast(system); - render->addRenderable(this); -} /*! Filters \a out an \a in renderable components by it's material \a layer. */ diff --git a/engine/src/components/world.cpp b/engine/src/components/world.cpp index 93013cdd8..fe0a0a35f 100644 --- a/engine/src/components/world.cpp +++ b/engine/src/components/world.cpp @@ -199,7 +199,7 @@ void World::addChild(Object *child, int32_t position) { Scene *scene = dynamic_cast(child); if(scene) { auto it = std::find(m_scenes.begin(), m_scenes.end(), scene); - if(it != m_scenes.end()) { + if(it == m_scenes.end()) { m_scenes.push_back(scene); } } diff --git a/engine/src/pipelinecontext.cpp b/engine/src/pipelinecontext.cpp index f60b84806..6eccac7a4 100644 --- a/engine/src/pipelinecontext.cpp +++ b/engine/src/pipelinecontext.cpp @@ -198,14 +198,19 @@ void PipelineContext::analizeGraph() { // Add renderables m_sceneRenderables.clear(); - for(auto it : RenderSystem::renderables()) { - if(it->world() == m_world && it->isEnabledInHierarchy()) { - if(update) { - it->update(); + static uint32_t renderableHash = Mathf::hashString("renderable"); + for(auto scene : m_world->scenes()) { + for(auto it : scene->getObjectsInGroupByHash(renderableHash)) { + Renderable *renderable = static_cast(it); + if(renderable->isEnabledInHierarchy()) { + if(update) { + renderable->update(); + } + m_sceneRenderables.push_back(renderable); } - m_sceneRenderables.push_back(it); } } + // Renderables frustum culling Frustum frustum(camera->frustum()); Matrix4 viewProjection(camera->projectionMatrix() * camera->viewMatrix()); @@ -220,22 +225,25 @@ void PipelineContext::analizeGraph() { // Add lights m_sceneLights.clear(); - for(auto it : RenderSystem::lights()) { - if(it->world() == m_world && it->isEnabledInHierarchy()) { - if(!m_frustumCulling || !it->isCulled(frustum, viewProjection)) { - m_sceneLights.push_back(it); + static uint32_t lightHash = Mathf::hashString("lights"); + for(auto scene : m_world->scenes()) { + for(auto it : scene->getObjectsInGroupByHash(lightHash)) { + BaseLight *light = static_cast(it); + if(light->isEnabledInHierarchy() && (!m_frustumCulling || !light->isCulled(frustum, viewProjection))) { + m_sceneLights.push_back(light); } } } // Add Post process volumes m_culledPostProcessSettings.clear(); - for(auto it : RenderSystem::postProcessVolumes()) { - if(it->world() == m_world && it->isEnabledInHierarchy()) { - if(!it->unbound() && !it->bound().intersect(cameraWorldPosition, camera->nearPlane())) { - continue; + static uint32_t postHash = Mathf::hashString("postProcess"); + for(auto scene : m_world->scenes()) { + for(auto it : scene->getObjectsInGroupByHash(postHash)) { + PostProcessVolume *volume = static_cast(it); + if(volume->isEnabledInHierarchy() && (volume->unbound() || volume->bound().intersect(cameraWorldPosition, camera->nearPlane()))) { + m_culledPostProcessSettings.push_back(std::make_pair(volume->settings(), volume->blendWeight())); } - m_culledPostProcessSettings.push_back(std::make_pair(it->settings(), it->blendWeight())); } } diff --git a/engine/src/systems/rendersystem.cpp b/engine/src/systems/rendersystem.cpp index 67b391564..3a56059bb 100644 --- a/engine/src/systems/rendersystem.cpp +++ b/engine/src/systems/rendersystem.cpp @@ -35,10 +35,6 @@ void *RenderSystem::m_windowHandle = nullptr; -std::list RenderSystem::m_lightComponents; -std::list RenderSystem::m_renderableComponents; -std::list RenderSystem::m_postProcessVolumes; - RenderSystem::RenderSystem() : m_pipelineContext(nullptr), m_frameDirty(true) { @@ -157,41 +153,6 @@ void RenderSystem::setPipelineContext(PipelineContext *context) { m_pipelineContext = context; } -void RenderSystem::addRenderable(Renderable *renderable) { - m_renderableComponents.push_back(renderable); -} - -void RenderSystem::removeRenderable(Renderable *renderable) { - m_renderableComponents.remove(renderable); -} - -std::list &RenderSystem::renderables() { - return m_renderableComponents; -} - -void RenderSystem::addLight(BaseLight *light) { - m_lightComponents.push_back(light); -} -void RenderSystem::removeLight(BaseLight *light) { - m_lightComponents.remove(light); -} - -std::list &RenderSystem::lights() { - return m_lightComponents; -} - -void RenderSystem::addPostProcessVolume(PostProcessVolume *volume) { - m_postProcessVolumes.push_back(volume); -} - -void RenderSystem::removePostProcessVolume(PostProcessVolume *volume) { - m_postProcessVolumes.remove(volume); -} - -std::list &RenderSystem::postProcessVolumes() { - return m_postProcessVolumes; -} - #if defined(SHARED_DEFINE) QWindow *RenderSystem::createRhiWindow(Viewport *viewport) { return nullptr;