Graphics/FramePipeline: Replace maps with memory pools and indices

This commit is contained in:
Jérôme Leclercq
2022-02-21 20:47:11 +01:00
parent a1b6f51398
commit 20a86312ff
14 changed files with 598 additions and 354 deletions

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Graphics/WorldInstance.hpp>
#include <Nazara/Math/Rect.hpp>
#include <entt/entt.hpp>
#include <memory>
#include <vector>
@@ -20,6 +21,7 @@ namespace Nz
{
public:
struct Renderable;
static constexpr std::size_t MaxRenderableCount = 8;
inline GraphicsComponent(bool initialyVisible = true);
GraphicsComponent(const GraphicsComponent&) = default;
@@ -32,7 +34,8 @@ namespace Nz
inline void DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable);
inline const std::vector<Renderable>& GetRenderables() const;
inline const Renderable& GetRenderableEntry(std::size_t renderableIndex) const;
inline const std::array<Renderable, MaxRenderableCount>& GetRenderables() const;
inline const Recti& GetScissorBox() const;
inline const WorldInstancePtr& GetWorldInstance() const;
@@ -47,8 +50,9 @@ namespace Nz
GraphicsComponent& operator=(const GraphicsComponent&) = default;
GraphicsComponent& operator=(GraphicsComponent&&) = default;
NazaraSignal(OnRenderableAttached, GraphicsComponent* /*graphicsComponent*/, const Renderable& /*renderable*/);
NazaraSignal(OnRenderableDetach, GraphicsComponent* /*graphicsComponent*/, const Renderable& /*renderable*/);
NazaraSignal(OnRenderableAttached, GraphicsComponent* /*graphicsComponent*/, std::size_t /*renderableIndex*/);
NazaraSignal(OnRenderableDetach, GraphicsComponent* /*graphicsComponent*/, std::size_t /*renderableIndex*/);
NazaraSignal(OnScissorBoxUpdate, GraphicsComponent* /*graphicsComponent*/, const Recti& /*newScissorBox*/);
NazaraSignal(OnVisibilityUpdate, GraphicsComponent* /*graphicsComponent*/, bool /*newVisibilityState*/);
struct Renderable
@@ -58,7 +62,7 @@ namespace Nz
};
private:
std::vector<Renderable> m_renderables;
std::array<Renderable, MaxRenderableCount> m_renderables;
Recti m_scissorBox;
WorldInstancePtr m_worldInstance;
bool m_isVisible;

View File

@@ -16,19 +16,31 @@ namespace Nz
inline void GraphicsComponent::AttachRenderable(std::shared_ptr<InstancedRenderable> renderable, UInt32 renderMask)
{
auto& entry = m_renderables.emplace_back();
entry.renderable = std::move(renderable);
entry.renderMask = renderMask;
for (std::size_t i = 0; i < m_renderables.size(); ++i)
{
auto& entry = m_renderables[i];
if (entry.renderable)
continue;
OnRenderableAttached(this, m_renderables.back());
entry.renderable = std::move(renderable);
entry.renderMask = renderMask;
OnRenderableAttached(this, i);
break;
}
}
inline void GraphicsComponent::Clear()
{
for (const auto& renderable : m_renderables)
OnRenderableDetach(this, renderable);
for (std::size_t i = 0; i < m_renderables.size(); ++i)
{
auto& entry = m_renderables[i];
if (entry.renderable)
continue;
m_renderables.clear();
OnRenderableDetach(this, i);
entry.renderable.reset();
}
}
inline void GraphicsComponent::DetachRenderable(const std::shared_ptr<InstancedRenderable>& renderable)
@@ -36,13 +48,19 @@ namespace Nz
auto it = std::find_if(m_renderables.begin(), m_renderables.end(), [&](const auto& renderableEntry) { return renderableEntry.renderable == renderable; });
if (it != m_renderables.end())
{
OnRenderableDetach(this, *it);
OnRenderableDetach(this, std::distance(m_renderables.begin(), it));
m_renderables.erase(it);
it->renderable.reset();
}
}
inline auto GraphicsComponent::GetRenderables() const -> const std::vector<Renderable>&
inline auto GraphicsComponent::GetRenderableEntry(std::size_t renderableIndex) const -> const Renderable&
{
assert(renderableIndex < m_renderables.size());
return m_renderables[renderableIndex];
}
inline auto GraphicsComponent::GetRenderables() const -> const std::array<Renderable, MaxRenderableCount>&
{
return m_renderables;
}

View File

@@ -11,6 +11,7 @@
#include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/WorldInstance.hpp>
#include <entt/entt.hpp>
#include <array>
#include <memory>
#include <vector>
@@ -20,6 +21,7 @@ namespace Nz
{
public:
struct LightEntry;
static constexpr std::size_t MaxLightCount = 8;
inline LightComponent(bool initialyVisible = true);
LightComponent(const LightComponent&) = default;
@@ -32,7 +34,8 @@ namespace Nz
inline void DetachLight(const std::shared_ptr<Light>& renderable);
inline const std::vector<LightEntry>& GetLights() const;
inline const LightEntry& GetLightEntry(std::size_t lightIndex) const;
inline const std::array<LightEntry, MaxLightCount>& GetLights() const;
inline void Hide();
@@ -43,8 +46,8 @@ namespace Nz
LightComponent& operator=(const LightComponent&) = default;
LightComponent& operator=(LightComponent&&) = default;
NazaraSignal(OnLightAttached, LightComponent* /*graphicsComponent*/, const LightEntry& /*lightEntry*/);
NazaraSignal(OnLightDetach, LightComponent* /*graphicsComponent*/, const LightEntry& /*lightEntry*/);
NazaraSignal(OnLightAttached, LightComponent* /*graphicsComponent*/, std::size_t /*lightIndex*/);
NazaraSignal(OnLightDetach, LightComponent* /*graphicsComponent*/, std::size_t /*lightIndex*/);
NazaraSignal(OnVisibilityUpdate, LightComponent* /*graphicsComponent*/, bool /*newVisibilityState*/);
struct LightEntry
@@ -54,7 +57,7 @@ namespace Nz
};
private:
std::vector<LightEntry> m_lightEntries;
std::array<LightEntry, MaxLightCount> m_lightEntries;
bool m_isVisible;
};
}

View File

@@ -14,19 +14,31 @@ namespace Nz
inline void LightComponent::AttachLight(std::shared_ptr<Light> light, UInt32 renderMask)
{
auto& entry = m_lightEntries.emplace_back();
entry.light = std::move(light);
entry.renderMask = renderMask;
for (std::size_t i = 0; i < m_lightEntries.size(); ++i)
{
auto& entry = m_lightEntries[i];
if (entry.light)
continue;
OnLightAttached(this, m_lightEntries.back());
entry.light = std::move(light);
entry.renderMask = renderMask;
OnLightAttached(this, i);
break;
}
}
inline void LightComponent::Clear()
{
for (const auto& lightEntry : m_lightEntries)
OnLightDetach(this, lightEntry);
for (std::size_t i = 0; i < m_lightEntries.size(); ++i)
{
auto& entry = m_lightEntries[i];
if (entry.light)
continue;
m_lightEntries.clear();
OnLightDetach(this, i);
entry.light.reset();
}
}
inline void LightComponent::DetachLight(const std::shared_ptr<Light>& light)
@@ -34,13 +46,19 @@ namespace Nz
auto it = std::find_if(m_lightEntries.begin(), m_lightEntries.end(), [&](const auto& lightEntry) { return lightEntry.light == light; });
if (it != m_lightEntries.end())
{
OnLightDetach(this, *it);
OnLightDetach(this, std::distance(m_lightEntries.begin(), it));
m_lightEntries.erase(it);
it->light.reset();
}
}
inline auto LightComponent::GetLights() const -> const std::vector<LightEntry>&
inline auto LightComponent::GetLightEntry(std::size_t lightIndex) const -> const LightEntry&
{
assert(lightIndex < m_lightEntries.size());
return m_lightEntries[lightIndex];
}
inline auto LightComponent::GetLights() const -> const std::array<LightEntry, MaxLightCount>&
{
return m_lightEntries;
}