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/InstancedRenderable.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Utility/Node.hpp>
#include <NDK/Component.hpp>
#include <unordered_map>
@ -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);

View File

@ -22,6 +22,7 @@ namespace Ndk
*/
void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const
{
EnsureBoundingVolumesUpdate();
EnsureTransformMatrixUpdate();
RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<RenderSystem>();
@ -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<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
*
@ -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);

View File

@ -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)
{