From b739965b1dfdb0f9b365b8376009122ce193ac05 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 31 Aug 2018 21:45:35 +0200 Subject: [PATCH] Graphics/RenderSystem: Add supports for partial culling --- .../NDK/Components/GraphicsComponent.hpp | 2 ++ SDK/src/NDK/Components/GraphicsComponent.cpp | 33 +++++++++++++++++-- SDK/src/NDK/Systems/RenderSystem.cpp | 7 ++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index d55ad0035..177dbbb1f 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ namespace Ndk inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const; void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const; + void AddToRenderQueueByCulling(const Nz::Frustumf& frustum, Nz::AbstractRenderQueue* renderQueue) const; inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0); diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 41c25fb90..6b2b2880a 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -22,6 +22,7 @@ namespace Ndk */ void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const { + EnsureBoundingVolumesUpdate(); EnsureTransformMatrixUpdate(); RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem(); @@ -30,7 +31,6 @@ namespace Ndk { if (!object.dataUpdated) { - object.data.transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), Nz::Matrix4f::ConcatenateAffine(object.data.localMatrix, m_transformMatrix)); object.renderable->UpdateData(&object.data); object.dataUpdated = true; } @@ -39,6 +39,34 @@ namespace Ndk } } + /*! + * \brief Adds the renderable elements to the render queue if their bounding volume intersects with the frustum + * + * \param frustum Queue to be added + * \param renderQueue Queue to be added + */ + void GraphicsComponent::AddToRenderQueueByCulling(const Nz::Frustumf& frustum, Nz::AbstractRenderQueue* renderQueue) const + { + EnsureBoundingVolumesUpdate(); + EnsureTransformMatrixUpdate(); + + RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem(); + + for (const Renderable& object : m_renderables) + { + if (frustum.Contains(object.boundingVolume)) + { + if (!object.dataUpdated) + { + object.renderable->UpdateData(&object.data); + object.dataUpdated = true; + } + + object.renderable->AddToRenderQueue(renderQueue, object.data, m_scissorRect); + } + } + } + /*! * \brief Attaches a renderable to the entity with a specific matrix * @@ -274,9 +302,10 @@ namespace Ndk { const Renderable& r = m_renderables[i]; r.boundingVolume = r.renderable->GetBoundingVolume(); + r.data.transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), Nz::Matrix4f::ConcatenateAffine(r.data.localMatrix, m_transformMatrix)); if (r.boundingVolume.IsFinite()) { - r.boundingVolume.Update(Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), Nz::Matrix4f::ConcatenateAffine(r.data.localMatrix, m_transformMatrix))); + r.boundingVolume.Update(r.data.transformMatrix); if (i > 0) m_aabb.ExtendTo(r.boundingVolume.aabb); diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index f01294865..25b8e3585 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -204,9 +204,11 @@ namespace Ndk bool forceInvalidation = false; + const Nz::Frustumf& frustum = camComponent.GetFrustum(); + std::size_t visibilityHash; if (m_isCullingEnabled) - visibilityHash = m_drawableCulling.Cull(camComponent.GetFrustum(), &forceInvalidation); + visibilityHash = m_drawableCulling.Cull(frustum, &forceInvalidation); else visibilityHash = m_drawableCulling.FillWithAllEntries(&forceInvalidation); @@ -220,9 +222,8 @@ namespace Ndk for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetFullyVisibleResults()) gfxComponent->AddToRenderQueue(renderQueue); - // FIXME: We should cull individual renderables here for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetPartiallyVisibleResults()) - gfxComponent->AddToRenderQueue(renderQueue); + gfxComponent->AddToRenderQueueByCulling(frustum, renderQueue); for (const Ndk::EntityHandle& light : m_lights) {