Graphics: Add frustum culling
Former-commit-id: 2741c465f9acb4a190de0a29db4a3853700461fd [formerly be67ee144fe577767a11be40f79f3f2e85d030c0] [formerly 302a6d2c8a3222401890d217f01c24a03db9ebc8 [formerly 762367a1144c340b84b61eee9d7577dcdaf717c6]] Former-commit-id: 6504b78e4ce04d8eea0c10e7ce27bdda4b95f2dc [formerly 8d0fba6c2dde5dcc43cbea0e6e5fd2980af4b801] Former-commit-id: 75d1deaf21035eb1b630705017462b9e059149a9
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
|
||||
#define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
|
||||
|
||||
#include <Nazara/Graphics/CullingList.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
#include <NDK/Component.hpp>
|
||||
@@ -16,6 +17,7 @@ namespace Ndk
|
||||
{
|
||||
class GraphicsComponent;
|
||||
|
||||
using GraphicsComponentCullingList = Nz::CullingList<GraphicsComponent>;
|
||||
using GraphicsComponentHandle = Nz::ObjectHandle<GraphicsComponent>;
|
||||
|
||||
class NDK_API GraphicsComponent : public Component<GraphicsComponent>, public Nz::HandledObject<GraphicsComponent>
|
||||
@@ -29,10 +31,11 @@ namespace Ndk
|
||||
inline GraphicsComponent(const GraphicsComponent& graphicsComponent);
|
||||
~GraphicsComponent() = default;
|
||||
|
||||
inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;
|
||||
inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const;
|
||||
void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;
|
||||
|
||||
inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
|
||||
inline void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);
|
||||
void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
|
||||
void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);
|
||||
|
||||
inline void Clear();
|
||||
|
||||
@@ -46,10 +49,12 @@ namespace Ndk
|
||||
|
||||
inline const Nz::BoundingVolumef& GetBoundingVolume() const;
|
||||
|
||||
inline void RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const;
|
||||
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
private:
|
||||
inline void InvalidateBoundingVolume();
|
||||
inline void InvalidateBoundingVolume() const;
|
||||
void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index);
|
||||
inline void InvalidateRenderables();
|
||||
inline void InvalidateTransformMatrix();
|
||||
@@ -72,12 +77,13 @@ namespace Ndk
|
||||
dataUpdated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Renderable(Renderable&& renderable) noexcept :
|
||||
data(std::move(renderable.data)),
|
||||
renderable(std::move(renderable.renderable)),
|
||||
dataUpdated(renderable.dataUpdated),
|
||||
renderableInvalidationSlot(std::move(renderable.renderableInvalidationSlot)),
|
||||
renderableBoundingVolumeInvalidationSlot(std::move(renderable.renderableBoundingVolumeInvalidationSlot)),
|
||||
renderableDataInvalidationSlot(std::move(renderable.renderableDataInvalidationSlot)),
|
||||
renderableReleaseSlot(std::move(renderable.renderableReleaseSlot))
|
||||
{
|
||||
}
|
||||
@@ -93,13 +99,15 @@ namespace Ndk
|
||||
data = std::move(r.data);
|
||||
dataUpdated = r.dataUpdated;
|
||||
renderable = std::move(r.renderable);
|
||||
renderableInvalidationSlot = std::move(r.renderableInvalidationSlot);
|
||||
renderableBoundingVolumeInvalidationSlot = std::move(r.renderableBoundingVolumeInvalidationSlot);
|
||||
renderableDataInvalidationSlot = std::move(r.renderableDataInvalidationSlot);
|
||||
renderableReleaseSlot = std::move(r.renderableReleaseSlot);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot);
|
||||
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateBoundingVolume, renderableBoundingVolumeInvalidationSlot);
|
||||
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableDataInvalidationSlot);
|
||||
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
|
||||
|
||||
mutable Nz::InstancedRenderable::InstanceData data;
|
||||
@@ -107,6 +115,16 @@ namespace Ndk
|
||||
mutable bool dataUpdated;
|
||||
};
|
||||
|
||||
using VolumeCullingListEntry = GraphicsComponentCullingList::VolumeEntry;
|
||||
|
||||
struct VolumeCullingEntry
|
||||
{
|
||||
VolumeCullingListEntry listEntry;
|
||||
|
||||
NazaraSlot(GraphicsComponentCullingList, OnCullingListRelease, cullingListReleaseSlot);
|
||||
};
|
||||
|
||||
mutable std::vector<VolumeCullingEntry> m_volumeCullingEntries;
|
||||
std::vector<Renderable> m_renderables;
|
||||
mutable Nz::BoundingVolumef m_boundingVolume;
|
||||
mutable Nz::Matrix4f m_transformMatrix;
|
||||
|
||||
@@ -28,52 +28,12 @@ namespace Ndk
|
||||
Attach(r.renderable, r.data.renderOrder);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the renderable elements to the render queue
|
||||
*
|
||||
* \param renderQueue Queue to be added
|
||||
*/
|
||||
|
||||
inline void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const
|
||||
inline void GraphicsComponent::AddToCullingList(GraphicsComponentCullingList* cullingList) const
|
||||
{
|
||||
EnsureTransformMatrixUpdate();
|
||||
|
||||
Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<Ndk::RenderSystem>();
|
||||
|
||||
for (const Renderable& object : m_renderables)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
object.renderable->AddToRenderQueue(renderQueue, object.data);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Attaches a renderable to the entity
|
||||
*
|
||||
* \param renderable Reference to a renderable element
|
||||
* \param renderOrder Render order of the element
|
||||
*/
|
||||
|
||||
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder)
|
||||
{
|
||||
return Attach(renderable, Nz::Matrix4f::Identity(), renderOrder);
|
||||
}
|
||||
|
||||
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder)
|
||||
{
|
||||
m_renderables.emplace_back(m_transformMatrix);
|
||||
Renderable& r = m_renderables.back();
|
||||
r.data.localMatrix = localMatrix;
|
||||
r.data.renderOrder = renderOrder;
|
||||
r.renderable = std::move(renderable);
|
||||
r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size() - 1));
|
||||
r.renderableReleaseSlot.Connect(r.renderable->OnInstancedRenderableRelease, this, &GraphicsComponent::Detach);
|
||||
m_volumeCullingEntries.emplace_back(VolumeCullingEntry{});
|
||||
VolumeCullingEntry& entry = m_volumeCullingEntries.back();
|
||||
entry.cullingListReleaseSlot.Connect(cullingList->OnCullingListRelease, this, &GraphicsComponent::RemoveFromCullingList);
|
||||
entry.listEntry = cullingList->RegisterVolumeTest(this);
|
||||
|
||||
InvalidateBoundingVolume();
|
||||
}
|
||||
@@ -167,11 +127,26 @@ namespace Ndk
|
||||
return m_boundingVolume;
|
||||
}
|
||||
|
||||
inline void GraphicsComponent::RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const
|
||||
{
|
||||
for (auto it = m_volumeCullingEntries.begin(); it != m_volumeCullingEntries.end(); ++it)
|
||||
{
|
||||
if (it->listEntry.GetParent() == cullingList)
|
||||
{
|
||||
if (m_volumeCullingEntries.size() > 1)
|
||||
*it = std::move(m_volumeCullingEntries.back());
|
||||
|
||||
m_volumeCullingEntries.pop_back();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Invalidates the bounding volume
|
||||
*/
|
||||
|
||||
inline void GraphicsComponent::InvalidateBoundingVolume()
|
||||
inline void GraphicsComponent::InvalidateBoundingVolume() const
|
||||
{
|
||||
m_boundingVolumeUpdated = false;
|
||||
}
|
||||
@@ -192,9 +167,9 @@ namespace Ndk
|
||||
|
||||
inline void GraphicsComponent::InvalidateTransformMatrix()
|
||||
{
|
||||
m_boundingVolumeUpdated = false;
|
||||
m_transformMatrixUpdated = false;
|
||||
|
||||
InvalidateBoundingVolume();
|
||||
InvalidateRenderables();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user