Graphics/RenderSystem: Add supports for partial culling

This commit is contained in:
Lynix 2018-08-31 21:45:35 +02:00
parent 5e6204fad4
commit b739965b1d
3 changed files with 37 additions and 5 deletions

View File

@ -10,6 +10,7 @@
#include <Nazara/Graphics/CullingList.hpp> #include <Nazara/Graphics/CullingList.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp> #include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Utility/Node.hpp> #include <Nazara/Utility/Node.hpp>
#include <NDK/Component.hpp> #include <NDK/Component.hpp>
#include <unordered_map> #include <unordered_map>
@ -34,6 +35,7 @@ namespace Ndk
inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const; inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const;
void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) 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); inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0); void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);

View File

@ -22,6 +22,7 @@ namespace Ndk
*/ */
void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const
{ {
EnsureBoundingVolumesUpdate();
EnsureTransformMatrixUpdate(); EnsureTransformMatrixUpdate();
RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<RenderSystem>(); RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<RenderSystem>();
@ -30,7 +31,6 @@ namespace Ndk
{ {
if (!object.dataUpdated) 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.renderable->UpdateData(&object.data);
object.dataUpdated = true; 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<RenderSystem>();
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 * \brief Attaches a renderable to the entity with a specific matrix
* *
@ -274,9 +302,10 @@ namespace Ndk
{ {
const Renderable& r = m_renderables[i]; const Renderable& r = m_renderables[i];
r.boundingVolume = r.renderable->GetBoundingVolume(); 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()) 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) if (i > 0)
m_aabb.ExtendTo(r.boundingVolume.aabb); m_aabb.ExtendTo(r.boundingVolume.aabb);

View File

@ -204,9 +204,11 @@ namespace Ndk
bool forceInvalidation = false; bool forceInvalidation = false;
const Nz::Frustumf& frustum = camComponent.GetFrustum();
std::size_t visibilityHash; std::size_t visibilityHash;
if (m_isCullingEnabled) if (m_isCullingEnabled)
visibilityHash = m_drawableCulling.Cull(camComponent.GetFrustum(), &forceInvalidation); visibilityHash = m_drawableCulling.Cull(frustum, &forceInvalidation);
else else
visibilityHash = m_drawableCulling.FillWithAllEntries(&forceInvalidation); visibilityHash = m_drawableCulling.FillWithAllEntries(&forceInvalidation);
@ -220,9 +222,8 @@ namespace Ndk
for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetFullyVisibleResults()) for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetFullyVisibleResults())
gfxComponent->AddToRenderQueue(renderQueue); gfxComponent->AddToRenderQueue(renderQueue);
// FIXME: We should cull individual renderables here
for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetPartiallyVisibleResults()) for (const GraphicsComponent* gfxComponent : m_drawableCulling.GetPartiallyVisibleResults())
gfxComponent->AddToRenderQueue(renderQueue); gfxComponent->AddToRenderQueueByCulling(frustum, renderQueue);
for (const Ndk::EntityHandle& light : m_lights) for (const Ndk::EntityHandle& light : m_lights)
{ {