Graphics: Use memory pools for render elements

This commit is contained in:
SirLynix 2022-08-30 19:27:52 +02:00
parent 7949c57f16
commit 017a6c7af3
43 changed files with 528 additions and 133 deletions

View File

@ -688,6 +688,8 @@ int main()
std::exit(__LINE__); std::exit(__LINE__);
} }
Nz::ElementRendererRegistry elementRegistry;
Nz::FrameGraph graph; Nz::FrameGraph graph;
colorTexture = graph.AddAttachment({ colorTexture = graph.AddAttachment({
@ -793,16 +795,26 @@ int main()
{ {
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
std::vector<std::unique_ptr<Nz::RenderElement>> elements; Nz::InstancedRenderable::ElementData elementData;
spaceshipModel.BuildElement(forwardPassIndex, modelInstance1, nullptr, elements, env.renderRect); elementData.scissorBox = &env.renderRect;
spaceshipModel.BuildElement(forwardPassIndex, modelInstance2, nullptr, elements, env.renderRect); elementData.skeletonInstance = nullptr;
planeModel.BuildElement(forwardPassIndex, planeInstance, nullptr, elements, env.renderRect);
std::vector<Nz::RenderElementOwner> elements;
elementData.worldInstance = &modelInstance1;
spaceshipModel.BuildElement(elementRegistry, elementData, forwardPassIndex, elements);
elementData.worldInstance = &modelInstance2;
spaceshipModel.BuildElement(elementRegistry, elementData, forwardPassIndex, elements);
elementData.worldInstance = &planeInstance;
planeModel.BuildElement(elementRegistry, elementData, forwardPassIndex, elements);
std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers; std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers;
std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size()); std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size());
elementPointers.reserve(elements.size()); elementPointers.reserve(elements.size());
for (const auto& element : elements) for (const auto& elementOwner : elements)
elementPointers.emplace_back(element.get()); elementPointers.emplace_back(elementOwner.GetElement());
submeshRenderer.Prepare(viewerInstance, *submeshRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data()); submeshRenderer.Prepare(viewerInstance, *submeshRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data());
submeshRenderer.PrepareEnd(*currentFrame, *spriteRendererData); submeshRenderer.PrepareEnd(*currentFrame, *spriteRendererData);
@ -859,15 +871,20 @@ int main()
builder.DrawIndexed(Nz::SafeCast<Nz::UInt32>(cubeMeshGfx->GetIndexCount(0))); builder.DrawIndexed(Nz::SafeCast<Nz::UInt32>(cubeMeshGfx->GetIndexCount(0)));
std::vector<std::unique_ptr<Nz::RenderElement>> elements; Nz::InstancedRenderable::ElementData elementData;
flareSprite.BuildElement(forwardPassIndex, flareInstance, nullptr, elements, env.renderRect); elementData.scissorBox = &env.renderRect;
elementData.skeletonInstance = nullptr;
elementData.worldInstance = &flareInstance;
std::vector<Nz::RenderElementOwner> elements;
flareSprite.BuildElement(elementRegistry, elementData, forwardPassIndex, elements);
std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers; std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers;
std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size()); std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size());
elementPointers.reserve(elements.size()); elementPointers.reserve(elements.size());
for (const auto& element : elements) for (const auto& element : elements)
elementPointers.emplace_back(element.get()); elementPointers.emplace_back(element.GetElement());
spritechainRenderer.Prepare(viewerInstance, *spriteRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data()); spritechainRenderer.Prepare(viewerInstance, *spriteRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data());
spritechainRenderer.Render(viewerInstance, *spriteRendererData, builder, elementPointers.size(), elementPointers.data()); spritechainRenderer.Render(viewerInstance, *spriteRendererData, builder, elementPointers.size(), elementPointers.data());
@ -888,15 +905,20 @@ int main()
{ {
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
std::vector<std::unique_ptr<Nz::RenderElement>> elements; Nz::InstancedRenderable::ElementData elementData;
flareSprite.BuildElement(forwardPassIndex, flareInstance, nullptr, elements, env.renderRect); elementData.scissorBox = &env.renderRect;
elementData.skeletonInstance = nullptr;
elementData.worldInstance = &flareInstance;
std::vector<Nz::RenderElementOwner> elements;
flareSprite.BuildElement(elementRegistry, elementData, forwardPassIndex, elements);
std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers; std::vector<Nz::Pointer<const Nz::RenderElement>> elementPointers;
std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size()); std::vector<Nz::ElementRenderer::RenderStates> renderStates(elements.size());
elementPointers.reserve(elements.size()); elementPointers.reserve(elements.size());
for (const auto& element : elements) for (const auto& element : elements)
elementPointers.emplace_back(element.get()); elementPointers.emplace_back(element.GetElement());
spritechainRenderer.Prepare(viewerInstance, *spriteRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data()); spritechainRenderer.Prepare(viewerInstance, *spriteRendererData, *currentFrame, elementPointers.size(), elementPointers.data(), renderStates.data());
spritechainRenderer.PrepareEnd(*currentFrame, *spriteRendererData); spritechainRenderer.PrepareEnd(*currentFrame, *spriteRendererData);

View File

@ -98,7 +98,8 @@ int main()
Nz::Recti scissorBox(Nz::Vector2i(window.GetSize())); Nz::Recti scissorBox(Nz::Vector2i(window.GetSize()));
Nz::ForwardFramePipeline framePipeline; Nz::ElementRendererRegistry elementRegistry;
Nz::ForwardFramePipeline framePipeline(elementRegistry);
std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0); std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0);
std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance); std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance);
std::size_t worldInstanceIndex2 = framePipeline.RegisterWorldInstance(modelInstance2); std::size_t worldInstanceIndex2 = framePipeline.RegisterWorldInstance(modelInstance2);

View File

@ -91,7 +91,8 @@ int main()
Nz::Recti scissorBox(Nz::Vector2i(window.GetSize())); Nz::Recti scissorBox(Nz::Vector2i(window.GetSize()));
Nz::ForwardFramePipeline framePipeline; Nz::ElementRendererRegistry elementRegistry;
Nz::ForwardFramePipeline framePipeline(elementRegistry);
std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0); std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0);
std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance); std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance);
framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox); framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox);

View File

@ -40,6 +40,7 @@
#include <Nazara/Graphics/DepthPipelinePass.hpp> #include <Nazara/Graphics/DepthPipelinePass.hpp>
#include <Nazara/Graphics/DirectionalLight.hpp> #include <Nazara/Graphics/DirectionalLight.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Enums.hpp> #include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/ForwardFramePipeline.hpp> #include <Nazara/Graphics/ForwardFramePipeline.hpp>
#include <Nazara/Graphics/ForwardPipelinePass.hpp> #include <Nazara/Graphics/ForwardPipelinePass.hpp>
@ -65,6 +66,8 @@
#include <Nazara/Graphics/PointLight.hpp> #include <Nazara/Graphics/PointLight.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp> #include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Graphics/RenderElement.hpp> #include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Graphics/RenderQueue.hpp> #include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp> #include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp> #include <Nazara/Graphics/RenderSpriteChain.hpp>

View File

@ -13,6 +13,7 @@
#include <Nazara/Graphics/FramePipelinePass.hpp> #include <Nazara/Graphics/FramePipelinePass.hpp>
#include <Nazara/Graphics/MaterialPass.hpp> #include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/RenderElement.hpp> #include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/RenderQueue.hpp> #include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp> #include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
@ -20,6 +21,7 @@
namespace Nz namespace Nz
{ {
class AbstractViewer; class AbstractViewer;
class ElementRendererRegistry;
class FrameGraph; class FrameGraph;
class FramePipeline; class FramePipeline;
class Material; class Material;
@ -27,7 +29,7 @@ namespace Nz
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
{ {
public: public:
DepthPipelinePass(FramePipeline& owner, AbstractViewer* viewer); DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
DepthPipelinePass(const DepthPipelinePass&) = delete; DepthPipelinePass(const DepthPipelinePass&) = delete;
DepthPipelinePass(DepthPipelinePass&&) = delete; DepthPipelinePass(DepthPipelinePass&&) = delete;
~DepthPipelinePass(); ~DepthPipelinePass();
@ -57,12 +59,13 @@ namespace Nz
std::size_t m_depthPassIndex; std::size_t m_depthPassIndex;
std::size_t m_lastVisibilityHash; std::size_t m_lastVisibilityHash;
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData; std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<std::unique_ptr<RenderElement>> m_renderElements;
std::vector<ElementRenderer::RenderStates> m_renderStates; std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses; std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
RenderQueue<RenderElement*> m_renderQueue; RenderQueue<const RenderElement*> m_renderQueue;
RenderQueueRegistry m_renderQueueRegistry; RenderQueueRegistry m_renderQueueRegistry;
AbstractViewer* m_viewer; AbstractViewer* m_viewer;
ElementRendererRegistry& m_elementRegistry;
FramePipeline& m_pipeline; FramePipeline& m_pipeline;
bool m_rebuildCommandBuffer; bool m_rebuildCommandBuffer;
bool m_rebuildElements; bool m_rebuildElements;

View File

@ -11,6 +11,7 @@
#include <Nazara/Core/Algorithm.hpp> #include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Graphics/Config.hpp> #include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp> #include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Renderer/RenderBufferView.hpp> #include <Nazara/Renderer/RenderBufferView.hpp>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -32,6 +33,8 @@ namespace Nz
ElementRenderer() = default; ElementRenderer() = default;
virtual ~ElementRenderer(); virtual ~ElementRenderer();
virtual RenderElementPoolBase& GetPool() = 0;
virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0; virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0;
virtual void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates); virtual void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates);
virtual void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData); virtual void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData);
@ -41,7 +44,6 @@ namespace Nz
struct RenderStates struct RenderStates
{ {
RenderBufferView lightData; RenderBufferView lightData;
RenderBufferView skeletalData;
}; };
}; };

View File

@ -0,0 +1,51 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_ELEMENTRENDERERREGISTRY_HPP
#define NAZARA_GRAPHICS_ELEMENTRENDERERREGISTRY_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Graphics/RenderQueue.hpp>
#include <memory>
namespace Nz
{
class ElementRenderer;
class NAZARA_GRAPHICS_API ElementRendererRegistry
{
public:
ElementRendererRegistry();
ElementRendererRegistry(const ElementRendererRegistry&) = delete;
ElementRendererRegistry(ElementRendererRegistry&&) = delete;
~ElementRendererRegistry() = default;
template<typename T, typename... Args> RenderElementOwner AllocateElement(Args&&... args);
template<typename F> void ForEachElementRenderer(F&& callback);
inline ElementRenderer& GetElementRenderer(std::size_t elementIndex);
inline std::size_t GetElementRendererCount() const;
template<typename F> void ProcessRenderQueue(const RenderQueue<const RenderElement*>& renderQueue, F&& callback);
template<typename T> void RegisterElementRenderer(std::unique_ptr<ElementRenderer> renderer);
inline void RegisterElementRenderer(std::size_t elementIndex, std::unique_ptr<ElementRenderer> renderer);
ElementRendererRegistry& operator=(const ElementRendererRegistry&) = delete;
ElementRendererRegistry& operator=(ElementRendererRegistry&&) = delete;
private:
std::vector<std::unique_ptr<ElementRenderer>> m_elementRenderers;
};
}
#include <Nazara/Graphics/ElementRendererRegistry.inl>
#endif // NAZARA_GRAPHICS_ELEMENTRENDERERREGISTRY_HPP

View File

@ -0,0 +1,84 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Utils/Algorithm.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
template<typename T, typename ...Args>
RenderElementOwner ElementRendererRegistry::AllocateElement(Args&&... args)
{
ElementRenderer& elementRenderer = GetElementRenderer(SafeCast<std::size_t>(T::ElementType));
RenderElementPool<T>& pool = SafeCast<RenderElementPool<T>&>(elementRenderer.GetPool());
return pool.Allocate(std::forward<Args>(args)...);
}
inline ElementRenderer& ElementRendererRegistry::GetElementRenderer(std::size_t elementIndex)
{
assert(elementIndex < m_elementRenderers.size());
return *m_elementRenderers[elementIndex];
}
inline std::size_t ElementRendererRegistry::GetElementRendererCount() const
{
return m_elementRenderers.size();
}
template<typename F>
void ElementRendererRegistry::ForEachElementRenderer(F&& callback)
{
for (std::size_t i = 0; i < m_elementRenderers.size(); ++i)
{
if (m_elementRenderers[i])
callback(i, *m_elementRenderers[i]);
}
}
template<typename F>
void ElementRendererRegistry::ProcessRenderQueue(const RenderQueue<const RenderElement*>& renderQueue, F&& callback)
{
if (renderQueue.empty())
return;
auto it = renderQueue.begin();
auto itEnd = renderQueue.end();
while (it != itEnd)
{
const RenderElement* element = *it;
UInt8 elementType = element->GetElementType();
const Pointer<const RenderElement>* first = it;
++it;
while (it != itEnd && (*it)->GetElementType() == elementType)
++it;
std::size_t count = it - first;
if (elementType >= m_elementRenderers.size() || !m_elementRenderers[elementType])
continue;
callback(elementType, first, count);
}
}
template<typename T>
inline void ElementRendererRegistry::RegisterElementRenderer(std::unique_ptr<ElementRenderer> renderer)
{
return RegisterElementRenderer(SafeCast<std::size_t>(T::ElementType), std::move(renderer));
}
inline void ElementRendererRegistry::RegisterElementRenderer(std::size_t elementIndex, std::unique_ptr<ElementRenderer> renderer)
{
if (elementIndex >= m_elementRenderers.size())
m_elementRenderers.resize(elementIndex + 1);
assert(!m_elementRenderers[elementIndex]);
m_elementRenderers[elementIndex] = std::move(renderer);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -37,7 +37,7 @@ namespace Nz
class NAZARA_GRAPHICS_API ForwardFramePipeline : public FramePipeline class NAZARA_GRAPHICS_API ForwardFramePipeline : public FramePipeline
{ {
public: public:
ForwardFramePipeline(); ForwardFramePipeline(ElementRendererRegistry& elementRegistry);
ForwardFramePipeline(const ForwardFramePipeline&) = delete; ForwardFramePipeline(const ForwardFramePipeline&) = delete;
ForwardFramePipeline(ForwardFramePipeline&&) = delete; ForwardFramePipeline(ForwardFramePipeline&&) = delete;
~ForwardFramePipeline(); ~ForwardFramePipeline();
@ -137,6 +137,7 @@ namespace Nz
Bitset<UInt64> m_removedSkeletonInstances; Bitset<UInt64> m_removedSkeletonInstances;
Bitset<UInt64> m_removedViewerInstances; Bitset<UInt64> m_removedViewerInstances;
Bitset<UInt64> m_removedWorldInstances; Bitset<UInt64> m_removedWorldInstances;
ElementRendererRegistry& m_elementRegistry;
MemoryPool<RenderableData> m_renderablePool; MemoryPool<RenderableData> m_renderablePool;
MemoryPool<LightData> m_lightPool; MemoryPool<LightData> m_lightPool;
MemoryPool<SkeletonInstancePtr> m_skeletonInstances; MemoryPool<SkeletonInstancePtr> m_skeletonInstances;

View File

@ -14,6 +14,7 @@
#include <Nazara/Graphics/Light.hpp> #include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/MaterialPass.hpp> #include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/RenderElement.hpp> #include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/RenderQueue.hpp> #include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp> #include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Math/Frustum.hpp> #include <Nazara/Math/Frustum.hpp>
@ -22,6 +23,7 @@
namespace Nz namespace Nz
{ {
class AbstractViewer; class AbstractViewer;
class ElementRendererRegistry;
class FrameGraph; class FrameGraph;
class FramePipeline; class FramePipeline;
class Light; class Light;
@ -30,7 +32,7 @@ namespace Nz
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass
{ {
public: public:
ForwardPipelinePass(FramePipeline& owner, AbstractViewer* viewer); ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
ForwardPipelinePass(const ForwardPipelinePass&) = delete; ForwardPipelinePass(const ForwardPipelinePass&) = delete;
ForwardPipelinePass(ForwardPipelinePass&&) = delete; ForwardPipelinePass(ForwardPipelinePass&&) = delete;
~ForwardPipelinePass(); ~ForwardPipelinePass();
@ -82,16 +84,17 @@ namespace Nz
std::size_t m_lastVisibilityHash; std::size_t m_lastVisibilityHash;
std::shared_ptr<LightUboPool> m_lightUboPool; std::shared_ptr<LightUboPool> m_lightUboPool;
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData; std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<std::unique_ptr<RenderElement>> m_renderElements;
std::vector<ElementRenderer::RenderStates> m_renderStates; std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses; std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
std::unordered_map<const RenderElement*, RenderBufferView> m_lightPerRenderElement; std::unordered_map<const RenderElement*, RenderBufferView> m_lightPerRenderElement;
std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights; std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights;
std::vector<LightDataUbo> m_lightDataBuffers; std::vector<LightDataUbo> m_lightDataBuffers;
std::vector<const Light*> m_renderableLights; std::vector<const Light*> m_renderableLights;
RenderQueue<RenderElement*> m_renderQueue; RenderQueue<const RenderElement*> m_renderQueue;
RenderQueueRegistry m_renderQueueRegistry; RenderQueueRegistry m_renderQueueRegistry;
AbstractViewer* m_viewer; AbstractViewer* m_viewer;
ElementRendererRegistry& m_elementRegistry;
FramePipeline& m_pipeline; FramePipeline& m_pipeline;
bool m_rebuildCommandBuffer; bool m_rebuildCommandBuffer;
bool m_rebuildElements; bool m_rebuildElements;

View File

@ -10,7 +10,6 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp> #include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/RenderElement.hpp> #include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/SkeletonInstance.hpp> #include <Nazara/Graphics/SkeletonInstance.hpp>
#include <Nazara/Graphics/WorldInstance.hpp> #include <Nazara/Graphics/WorldInstance.hpp>
#include <Nazara/Renderer/DebugDrawer.hpp> #include <Nazara/Renderer/DebugDrawer.hpp>
@ -20,7 +19,6 @@
namespace Nz namespace Nz
{ {
class AbstractViewer; class AbstractViewer;
class ElementRenderer;
class InstancedRenderable; class InstancedRenderable;
class Light; class Light;
class MaterialPass; class MaterialPass;
@ -34,18 +32,12 @@ namespace Nz
FramePipeline(FramePipeline&&) noexcept = default; FramePipeline(FramePipeline&&) noexcept = default;
virtual ~FramePipeline(); virtual ~FramePipeline();
template<typename F> void ForEachElementRenderer(F&& callback);
inline DebugDrawer& GetDebugDrawer(); inline DebugDrawer& GetDebugDrawer();
inline ElementRenderer& GetElementRenderer(std::size_t elementIndex);
inline std::size_t GetElementRendererCount() const;
virtual void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) = 0; virtual void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) = 0;
virtual void InvalidateViewer(std::size_t viewerIndex) = 0; virtual void InvalidateViewer(std::size_t viewerIndex) = 0;
virtual void InvalidateWorldInstance(std::size_t worldInstance) = 0; virtual void InvalidateWorldInstance(std::size_t worldInstance) = 0;
template<typename F> void ProcessRenderQueue(const RenderQueue<RenderElement*>& renderQueue, F&& callback);
virtual std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) = 0; virtual std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) = 0;
virtual void RegisterMaterialPass(MaterialPass* materialPass) = 0; virtual void RegisterMaterialPass(MaterialPass* materialPass) = 0;
virtual std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) = 0; virtual std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) = 0;
@ -75,7 +67,6 @@ namespace Nz
static constexpr std::size_t NoSkeletonInstance = std::numeric_limits<std::size_t>::max(); static constexpr std::size_t NoSkeletonInstance = std::numeric_limits<std::size_t>::max();
private: private:
std::vector<std::unique_ptr<ElementRenderer>> m_elementRenderers;
DebugDrawer m_debugDrawer; DebugDrawer m_debugDrawer;
}; };
} }

View File

@ -12,54 +12,6 @@ namespace Nz
{ {
return m_debugDrawer; return m_debugDrawer;
} }
inline ElementRenderer& FramePipeline::GetElementRenderer(std::size_t elementIndex)
{
assert(elementIndex < m_elementRenderers.size());
return *m_elementRenderers[elementIndex];
}
inline std::size_t FramePipeline::GetElementRendererCount() const
{
return m_elementRenderers.size();
}
template<typename F>
void FramePipeline::ForEachElementRenderer(F&& callback)
{
for (std::size_t i = 0; i < m_elementRenderers.size(); ++i)
{
if (m_elementRenderers[i])
callback(i, *m_elementRenderers[i]);
}
}
template<typename F>
void FramePipeline::ProcessRenderQueue(const RenderQueue<RenderElement*>& renderQueue, F&& callback)
{
if (renderQueue.empty())
return;
auto it = renderQueue.begin();
auto itEnd = renderQueue.end();
while (it != itEnd)
{
const RenderElement* element = *it;
UInt8 elementType = element->GetElementType();
const Pointer<RenderElement>* first = it;
++it;
while (it != itEnd && (*it)->GetElementType() == elementType)
++it;
std::size_t count = it - first;
if (elementType >= m_elementRenderers.size() || !m_elementRenderers[elementType])
continue;
callback(elementType, first, count);
}
}
} }
#include <Nazara/Graphics/DebugOff.hpp> #include <Nazara/Graphics/DebugOff.hpp>

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp> #include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Math/Box.hpp> #include <Nazara/Math/Box.hpp>
#include <Nazara/Utils/Signal.hpp> #include <Nazara/Utils/Signal.hpp>
#include <memory> #include <memory>
@ -16,6 +17,7 @@
namespace Nz namespace Nz
{ {
class CommandBufferBuilder; class CommandBufferBuilder;
class ElementRendererRegistry;
class Material; class Material;
class RenderElement; class RenderElement;
class SkeletonInstance; class SkeletonInstance;
@ -24,12 +26,14 @@ namespace Nz
class NAZARA_GRAPHICS_API InstancedRenderable class NAZARA_GRAPHICS_API InstancedRenderable
{ {
public: public:
struct ElementData;
inline InstancedRenderable(); inline InstancedRenderable();
InstancedRenderable(const InstancedRenderable&) = delete; InstancedRenderable(const InstancedRenderable&) = delete;
InstancedRenderable(InstancedRenderable&&) noexcept = default; InstancedRenderable(InstancedRenderable&&) noexcept = default;
~InstancedRenderable(); ~InstancedRenderable();
virtual void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const = 0; virtual void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const = 0;
inline const Boxf& GetAABB() const; inline const Boxf& GetAABB() const;
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0; virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
@ -45,6 +49,13 @@ namespace Nz
NazaraSignal(OnElementInvalidated, InstancedRenderable* /*instancedRenderable*/); NazaraSignal(OnElementInvalidated, InstancedRenderable* /*instancedRenderable*/);
NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<Material>& /*newMaterial*/); NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<Material>& /*newMaterial*/);
struct ElementData
{
const Recti* scissorBox;
const SkeletonInstance* skeletonInstance;
const WorldInstance* worldInstance;
};
protected: protected:
inline void UpdateAABB(Boxf aabb); inline void UpdateAABB(Boxf aabb);

View File

@ -30,7 +30,7 @@ namespace Nz
inline void AddSection(float size, float textureCoord); inline void AddSection(float size, float textureCoord);
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const override; void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const override;
inline void Clear(); inline void Clear();

View File

@ -28,7 +28,7 @@ namespace Nz
Model(Model&&) noexcept = default; Model(Model&&) noexcept = default;
~Model() = default; ~Model() = default;
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const override; void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const override;
const std::shared_ptr<RenderBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const; const std::shared_ptr<RenderBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
std::size_t GetIndexCount(std::size_t subMeshIndex) const; std::size_t GetIndexCount(std::size_t subMeshIndex) const;

View File

@ -0,0 +1,45 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERELEMENTOWNER_HPP
#define NAZARA_GRAPHICS_RENDERELEMENTOWNER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
namespace Nz
{
class RenderElement;
class RenderElementPoolBase;
class NAZARA_GRAPHICS_API RenderElementOwner
{
public:
inline RenderElementOwner(RenderElementPoolBase* pool, std::size_t poolIndex, RenderElement* element);
RenderElementOwner(const RenderElementOwner&) = delete;
RenderElementOwner(RenderElementOwner&&) noexcept = default;
~RenderElementOwner();
inline RenderElement* GetElement();
inline const RenderElement* GetElement() const;
inline RenderElement* operator->();
inline const RenderElement* operator->() const;
RenderElementOwner& operator=(const RenderElementOwner&) = delete;
RenderElementOwner& operator=(RenderElementOwner&&) noexcept = default;
private:
std::size_t m_poolIndex;
MovablePtr<RenderElement> m_element;
MovablePtr<RenderElementPoolBase> m_pool;
};
}
#include <Nazara/Graphics/RenderElementOwner.inl>
#endif // NAZARA_GRAPHICS_RENDERELEMENTOWNER_HPP

View File

@ -0,0 +1,39 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline RenderElementOwner::RenderElementOwner(RenderElementPoolBase* pool, std::size_t poolIndex, RenderElement* element) :
m_poolIndex(poolIndex),
m_element(element),
m_pool(pool)
{
}
inline RenderElement* RenderElementOwner::GetElement()
{
return m_element;
}
inline const RenderElement* RenderElementOwner::GetElement() const
{
return m_element;
}
inline RenderElement* RenderElementOwner::operator->()
{
// FIXME: Element pointer could also be retrieved from memory pool using poolIndex at the cost of a division
return m_element;
}
inline const RenderElement* RenderElementOwner::operator->() const
{
return m_element;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,60 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERELEMENTPOOL_HPP
#define NAZARA_GRAPHICS_RENDERELEMENTPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
namespace Nz
{
class RenderElementOwner;
class NAZARA_GRAPHICS_API RenderElementPoolBase
{
public:
RenderElementPoolBase() = default;
RenderElementPoolBase(const RenderElementPoolBase&) = delete;
RenderElementPoolBase(RenderElementPoolBase&&) = delete;
virtual ~RenderElementPoolBase();
virtual void Clear() = 0;
virtual void Free(std::size_t index) = 0;
RenderElementPoolBase& operator=(const RenderElementPoolBase&) = delete;
RenderElementPoolBase& operator=(RenderElementPoolBase&&) = delete;
};
template<typename T>
class RenderElementPool final : public RenderElementPoolBase
{
public:
RenderElementPool();
RenderElementPool(const RenderElementPool&) = delete;
RenderElementPool(RenderElementPool&&) = delete;
~RenderElementPool() = default;
template<typename... Args> RenderElementOwner Allocate(Args&&... args);
void Clear() override;
void Free(std::size_t index) override;
RenderElementPool& operator=(const RenderElementPool&) = delete;
RenderElementPool& operator=(RenderElementPool&&) = delete;
private:
MemoryPool<T> m_pool;
};
}
#include <Nazara/Graphics/RenderElementPool.inl>
#endif // NAZARA_GRAPHICS_RENDERELEMENTPOOL_HPP

View File

@ -0,0 +1,39 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
template<typename T>
template<typename... Args>
RenderElementOwner RenderElementPool<T>::Allocate(Args&&... args)
{
std::size_t poolIndex;
T* element = m_pool.Allocate(poolIndex, std::forward<Args>(args)...);
return RenderElementOwner(this, poolIndex, element);
}
template<typename T>
RenderElementPool<T>::RenderElementPool() :
m_pool(4096) //< TODO: Allow to adjust pool count
{
}
template<typename T>
void RenderElementPool<T>::Clear()
{
m_pool.Clear();
}
template<typename T>
void RenderElementPool<T>::Free(std::size_t index)
{
m_pool.Free(index);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -39,6 +39,8 @@ namespace Nz
inline void Register(RenderQueueRegistry& registry) const override; inline void Register(RenderQueueRegistry& registry) const override;
static constexpr BasicRenderElement ElementType = BasicRenderElement::SpriteChain;
private: private:
std::shared_ptr<MaterialPass> m_materialPass; std::shared_ptr<MaterialPass> m_materialPass;
std::shared_ptr<RenderPipeline> m_renderPipeline; std::shared_ptr<RenderPipeline> m_renderPipeline;

View File

@ -41,6 +41,8 @@ namespace Nz
inline void Register(RenderQueueRegistry& registry) const override; inline void Register(RenderQueueRegistry& registry) const override;
static constexpr BasicRenderElement ElementType = BasicRenderElement::Submesh;
private: private:
std::shared_ptr<RenderBuffer> m_indexBuffer; std::shared_ptr<RenderBuffer> m_indexBuffer;
std::shared_ptr<RenderBuffer> m_vertexBuffer; std::shared_ptr<RenderBuffer> m_vertexBuffer;

View File

@ -27,7 +27,7 @@ namespace Nz
SlicedSprite(SlicedSprite&&) noexcept = default; SlicedSprite(SlicedSprite&&) noexcept = default;
~SlicedSprite() = default; ~SlicedSprite() = default;
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const override; void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const override;
inline const Color& GetColor() const; inline const Color& GetColor() const;
inline const Corner& GetBottomRightCorner() const; inline const Corner& GetBottomRightCorner() const;

View File

@ -25,7 +25,7 @@ namespace Nz
Sprite(Sprite&&) noexcept = default; Sprite(Sprite&&) noexcept = default;
~Sprite() = default; ~Sprite() = default;
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const override; void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const override;
inline const Color& GetColor() const; inline const Color& GetColor() const;
inline const Color& GetCornerColor(RectCorner corner) const; inline const Color& GetCornerColor(RectCorner corner) const;

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Math/Rect.hpp> #include <Nazara/Math/Rect.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp> #include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Renderer/UploadPool.hpp> #include <Nazara/Renderer/UploadPool.hpp>
@ -21,7 +22,6 @@ namespace Nz
class MaterialPass; class MaterialPass;
class RenderDevice; class RenderDevice;
class RenderPipeline; class RenderPipeline;
class RenderSpriteChain;
class ShaderBinding; class ShaderBinding;
class Texture; class Texture;
class VertexDeclaration; class VertexDeclaration;
@ -57,6 +57,8 @@ namespace Nz
SpriteChainRenderer(RenderDevice& device, std::size_t maxVertexBufferSize = 32 * 1024); SpriteChainRenderer(RenderDevice& device, std::size_t maxVertexBufferSize = 32 * 1024);
~SpriteChainRenderer() = default; ~SpriteChainRenderer() = default;
RenderElementPool<RenderSpriteChain>& GetPool() override;
std::unique_ptr<ElementRendererData> InstanciateData() override; std::unique_ptr<ElementRendererData> InstanciateData() override;
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override; void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override;
void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData) override; void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData) override;
@ -103,6 +105,7 @@ namespace Nz
std::size_t m_maxVertexCount; std::size_t m_maxVertexCount;
std::vector<BufferCopy> m_pendingCopies; std::vector<BufferCopy> m_pendingCopies;
std::vector<ShaderBinding::Binding> m_bindingCache; std::vector<ShaderBinding::Binding> m_bindingCache;
RenderElementPool<RenderSpriteChain> m_spriteChainPool;
PendingData m_pendingData; PendingData m_pendingData;
RenderDevice& m_device; RenderDevice& m_device;
}; };

View File

@ -9,21 +9,23 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/RenderSubmesh.hpp>
#include <Nazara/Math/Rect.hpp> #include <Nazara/Math/Rect.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp> #include <Nazara/Renderer/ShaderBinding.hpp>
namespace Nz namespace Nz
{ {
class RenderPipeline; class RenderPipeline;
class RenderSubmesh;
class ShaderBinding; class ShaderBinding;
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer class NAZARA_GRAPHICS_API SubmeshRenderer final : public ElementRenderer
{ {
public: public:
SubmeshRenderer() = default; SubmeshRenderer() = default;
~SubmeshRenderer() = default; ~SubmeshRenderer() = default;
RenderElementPool<RenderSubmesh>& GetPool() override;
std::unique_ptr<ElementRendererData> InstanciateData() override; std::unique_ptr<ElementRendererData> InstanciateData() override;
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override; void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override;
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, std::size_t elementCount, const Pointer<const RenderElement>* elements) override; void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, std::size_t elementCount, const Pointer<const RenderElement>* elements) override;
@ -31,6 +33,7 @@ namespace Nz
private: private:
std::vector<ShaderBinding::Binding> m_bindingCache; std::vector<ShaderBinding::Binding> m_bindingCache;
RenderElementPool<RenderSubmesh> m_submeshPool;
}; };
struct SubmeshRendererData : public ElementRendererData struct SubmeshRendererData : public ElementRendererData

View File

@ -8,6 +8,7 @@
#define NAZARA_GRAPHICS_SYSTEMS_RENDERSYSTEM_HPP #define NAZARA_GRAPHICS_SYSTEMS_RENDERSYSTEM_HPP
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Graphics.hpp> #include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp> #include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Graphics/Components/LightComponent.hpp> #include <Nazara/Graphics/Components/LightComponent.hpp>
@ -132,6 +133,7 @@ namespace Nz
std::unordered_set<LightEntity*> m_newlyHiddenLightEntities; std::unordered_set<LightEntity*> m_newlyHiddenLightEntities;
std::unordered_set<LightEntity*> m_newlyVisibleLightEntities; std::unordered_set<LightEntity*> m_newlyVisibleLightEntities;
std::vector<std::unique_ptr<RenderWindow>> m_renderWindows; std::vector<std::unique_ptr<RenderWindow>> m_renderWindows;
ElementRendererRegistry m_elementRegistry;
MemoryPool<CameraEntity> m_cameraEntityPool; MemoryPool<CameraEntity> m_cameraEntityPool;
MemoryPool<GraphicsEntity> m_graphicsEntityPool; MemoryPool<GraphicsEntity> m_graphicsEntityPool;
MemoryPool<LightEntity> m_lightEntityPool; MemoryPool<LightEntity> m_lightEntityPool;

View File

@ -28,7 +28,7 @@ namespace Nz
TextSprite(TextSprite&&) noexcept = default; TextSprite(TextSprite&&) noexcept = default;
~TextSprite() = default; ~TextSprite() = default;
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const override; void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const override;
inline void Clear(); inline void Clear();

View File

@ -5,6 +5,7 @@
#include <Nazara/Graphics/DepthPipelinePass.hpp> #include <Nazara/Graphics/DepthPipelinePass.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp> #include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/FrameGraph.hpp> #include <Nazara/Graphics/FrameGraph.hpp>
#include <Nazara/Graphics/FramePipeline.hpp> #include <Nazara/Graphics/FramePipeline.hpp>
#include <Nazara/Graphics/Graphics.hpp> #include <Nazara/Graphics/Graphics.hpp>
@ -15,9 +16,10 @@
namespace Nz namespace Nz
{ {
DepthPipelinePass::DepthPipelinePass(FramePipeline& owner, AbstractViewer* viewer) : DepthPipelinePass::DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer) :
m_lastVisibilityHash(0), m_lastVisibilityHash(0),
m_viewer(viewer), m_viewer(viewer),
m_elementRegistry(elementRegistry),
m_pipeline(owner), m_pipeline(owner),
m_rebuildCommandBuffer(false), m_rebuildCommandBuffer(false),
m_rebuildElements(false) m_rebuildElements(false)
@ -39,7 +41,15 @@ namespace Nz
m_renderElements.clear(); m_renderElements.clear();
for (const auto& renderableData : visibleRenderables) for (const auto& renderableData : visibleRenderables)
renderableData.instancedRenderable->BuildElement(m_depthPassIndex, *renderableData.worldInstance, renderableData.skeletonInstance, m_renderElements, renderableData.scissorBox); {
InstancedRenderable::ElementData elementData{
&renderableData.scissorBox,
renderableData.skeletonInstance,
renderableData.worldInstance
};
renderableData.instancedRenderable->BuildElement(m_elementRegistry, elementData, m_depthPassIndex, m_renderElements);
}
m_renderQueueRegistry.Clear(); m_renderQueueRegistry.Clear();
m_renderQueue.Clear(); m_renderQueue.Clear();
@ -47,7 +57,7 @@ namespace Nz
for (const auto& renderElement : m_renderElements) for (const auto& renderElement : m_renderElements)
{ {
renderElement->Register(m_renderQueueRegistry); renderElement->Register(m_renderQueueRegistry);
m_renderQueue.Insert(renderElement.get()); m_renderQueue.Insert(renderElement.GetElement());
} }
m_renderQueueRegistry.Finalize(); m_renderQueueRegistry.Finalize();
@ -64,7 +74,7 @@ namespace Nz
if (m_rebuildElements) if (m_rebuildElements)
{ {
m_pipeline.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer) m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
{ {
if (elementType >= m_elementRendererData.size() || !m_elementRendererData[elementType]) if (elementType >= m_elementRendererData.size() || !m_elementRendererData[elementType])
{ {
@ -79,9 +89,9 @@ namespace Nz
const auto& viewerInstance = m_viewer->GetViewerInstance(); const auto& viewerInstance = m_viewer->GetViewerInstance();
m_pipeline.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount) m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
ElementRenderer& elementRenderer = m_pipeline.GetElementRenderer(elementType); ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
m_renderStates.clear(); m_renderStates.clear();
m_renderStates.resize(elementCount); m_renderStates.resize(elementCount);
@ -89,7 +99,7 @@ namespace Nz
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, m_renderStates.data()); elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, m_renderStates.data());
}); });
m_pipeline.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer) m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
{ {
elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]); elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]);
}); });
@ -146,9 +156,9 @@ namespace Nz
const auto& viewerInstance = m_viewer->GetViewerInstance(); const auto& viewerInstance = m_viewer->GetViewerInstance();
m_pipeline.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount) m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
ElementRenderer& elementRenderer = m_pipeline.GetElementRenderer(elementType); ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
elementRenderer.Render(viewerInstance, *m_elementRendererData[elementType], builder, elementCount, elements); elementRenderer.Render(viewerInstance, *m_elementRendererData[elementType], builder, elementCount, elements);
}); });

View File

@ -0,0 +1,21 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/RenderSubmesh.hpp>
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
#include <Nazara/Graphics/SubmeshRenderer.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
ElementRendererRegistry::ElementRendererRegistry()
{
RegisterElementRenderer<RenderSpriteChain>(std::make_unique<SpriteChainRenderer>(*Graphics::Instance()->GetRenderDevice()));
RegisterElementRenderer<RenderSubmesh>(std::make_unique<SubmeshRenderer>());
}
}

View File

@ -26,7 +26,8 @@
namespace Nz namespace Nz
{ {
ForwardFramePipeline::ForwardFramePipeline() : ForwardFramePipeline::ForwardFramePipeline(ElementRendererRegistry& elementRegistry) :
m_elementRegistry(elementRegistry),
m_renderablePool(4096), m_renderablePool(4096),
m_lightPool(64), m_lightPool(64),
m_skeletonInstances(1024), m_skeletonInstances(1024),
@ -182,8 +183,8 @@ namespace Nz
auto& viewerData = *m_viewerPool.Allocate(viewerIndex); auto& viewerData = *m_viewerPool.Allocate(viewerIndex);
viewerData.renderOrder = renderOrder; viewerData.renderOrder = renderOrder;
viewerData.debugDrawPass = std::make_unique<DebugDrawPipelinePass>(*this, viewerInstance); viewerData.debugDrawPass = std::make_unique<DebugDrawPipelinePass>(*this, viewerInstance);
viewerData.depthPrepass = std::make_unique<DepthPipelinePass>(*this, viewerInstance); viewerData.depthPrepass = std::make_unique<DepthPipelinePass>(*this, m_elementRegistry, viewerInstance);
viewerData.forwardPass = std::make_unique<ForwardPipelinePass>(*this, viewerInstance); viewerData.forwardPass = std::make_unique<ForwardPipelinePass>(*this, m_elementRegistry, viewerInstance);
viewerData.viewer = viewerInstance; viewerData.viewer = viewerInstance;
m_invalidatedViewerInstances.UnboundedSet(viewerIndex); m_invalidatedViewerInstances.UnboundedSet(viewerIndex);

View File

@ -4,6 +4,7 @@
#include <Nazara/Graphics/ForwardPipelinePass.hpp> #include <Nazara/Graphics/ForwardPipelinePass.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp> #include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/FrameGraph.hpp> #include <Nazara/Graphics/FrameGraph.hpp>
#include <Nazara/Graphics/FramePipeline.hpp> #include <Nazara/Graphics/FramePipeline.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp> #include <Nazara/Graphics/InstancedRenderable.hpp>
@ -16,9 +17,10 @@
namespace Nz namespace Nz
{ {
ForwardPipelinePass::ForwardPipelinePass(FramePipeline& owner, AbstractViewer* viewer) : ForwardPipelinePass::ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer) :
m_lastVisibilityHash(0), m_lastVisibilityHash(0),
m_viewer(viewer), m_viewer(viewer),
m_elementRegistry(elementRegistry),
m_pipeline(owner), m_pipeline(owner),
m_rebuildCommandBuffer(false), m_rebuildCommandBuffer(false),
m_rebuildElements(false) m_rebuildElements(false)
@ -147,11 +149,17 @@ namespace Nz
else else
lightUboView = it->second; lightUboView = it->second;
InstancedRenderable::ElementData elementData{
&renderableData.scissorBox,
renderableData.skeletonInstance,
renderableData.worldInstance
};
std::size_t previousCount = m_renderElements.size(); std::size_t previousCount = m_renderElements.size();
renderableData.instancedRenderable->BuildElement(m_forwardPassIndex, *renderableData.worldInstance, renderableData.skeletonInstance, m_renderElements, renderableData.scissorBox); renderableData.instancedRenderable->BuildElement(m_elementRegistry, elementData, m_forwardPassIndex, m_renderElements);
for (std::size_t i = previousCount; i < m_renderElements.size(); ++i) for (std::size_t i = previousCount; i < m_renderElements.size(); ++i)
{ {
const RenderElement* element = m_renderElements[i].get(); const RenderElement* element = m_renderElements[i].GetElement();
m_lightPerRenderElement.emplace(element, lightUboView); m_lightPerRenderElement.emplace(element, lightUboView);
} }
} }
@ -159,7 +167,7 @@ namespace Nz
for (const auto& renderElement : m_renderElements) for (const auto& renderElement : m_renderElements)
{ {
renderElement->Register(m_renderQueueRegistry); renderElement->Register(m_renderQueueRegistry);
m_renderQueue.Insert(renderElement.get()); m_renderQueue.Insert(renderElement.GetElement());
} }
m_renderQueueRegistry.Finalize(); m_renderQueueRegistry.Finalize();
@ -193,15 +201,13 @@ namespace Nz
if (m_rebuildElements) if (m_rebuildElements)
{ {
m_pipeline.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer) m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
{ {
if (elementType >= m_elementRendererData.size() || !m_elementRendererData[elementType]) if (elementType >= m_elementRendererData.size())
{ m_elementRendererData.resize(elementType + 1);
if (elementType >= m_elementRendererData.size())
m_elementRendererData.resize(elementType + 1);
if (!m_elementRendererData[elementType])
m_elementRendererData[elementType] = elementRenderer.InstanciateData(); m_elementRendererData[elementType] = elementRenderer.InstanciateData();
}
elementRenderer.Reset(*m_elementRendererData[elementType], renderFrame); elementRenderer.Reset(*m_elementRendererData[elementType], renderFrame);
}); });
@ -209,9 +215,9 @@ namespace Nz
const auto& viewerInstance = m_viewer->GetViewerInstance(); const auto& viewerInstance = m_viewer->GetViewerInstance();
auto& lightPerRenderElement = m_lightPerRenderElement; auto& lightPerRenderElement = m_lightPerRenderElement;
m_pipeline.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount) m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
ElementRenderer& elementRenderer = m_pipeline.GetElementRenderer(elementType); ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
m_renderStates.clear(); m_renderStates.clear();
@ -228,7 +234,7 @@ namespace Nz
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, m_renderStates.data()); elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, m_renderStates.data());
}); });
m_pipeline.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer) m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
{ {
elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]); elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]);
}); });
@ -291,9 +297,9 @@ namespace Nz
const auto& viewerInstance = m_viewer->GetViewerInstance(); const auto& viewerInstance = m_viewer->GetViewerInstance();
m_pipeline.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount) m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
ElementRenderer& elementRenderer = m_pipeline.GetElementRenderer(elementType); ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
elementRenderer.Render(viewerInstance, *m_elementRendererData[elementType], builder, elementCount, elements); elementRenderer.Render(viewerInstance, *m_elementRendererData[elementType], builder, elementCount, elements);
}); });

View File

@ -3,20 +3,14 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/FramePipeline.hpp> #include <Nazara/Graphics/FramePipeline.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/Graphics.hpp> #include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
#include <Nazara/Graphics/SubmeshRenderer.hpp>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
namespace Nz namespace Nz
{ {
FramePipeline::FramePipeline() : FramePipeline::FramePipeline() :
m_elementRenderers(BasicRenderElementCount),
m_debugDrawer(*Graphics::Instance()->GetRenderDevice()) m_debugDrawer(*Graphics::Instance()->GetRenderDevice())
{ {
m_elementRenderers[UnderlyingCast(BasicRenderElement::SpriteChain)] = std::make_unique<SpriteChainRenderer>(*Graphics::Instance()->GetRenderDevice());
m_elementRenderers[UnderlyingCast(BasicRenderElement::Submesh)] = std::make_unique<SubmeshRenderer>();
} }
FramePipeline::~FramePipeline() = default; FramePipeline::~FramePipeline() = default;

View File

@ -4,6 +4,7 @@
#include <Nazara/Graphics/LinearSlicedSprite.hpp> #include <Nazara/Graphics/LinearSlicedSprite.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp> #include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp> #include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
@ -22,7 +23,7 @@ namespace Nz
UpdateVertices(); UpdateVertices();
} }
void LinearSlicedSprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const void LinearSlicedSprite::BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const
{ {
const auto& materialPass = m_material->GetPass(passIndex); const auto& materialPass = m_material->GetPass(passIndex);
if (!materialPass) if (!materialPass)
@ -42,7 +43,7 @@ namespace Nz
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)]; const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data(), scissorBox)); elements.emplace_back(registry.AllocateElement<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, *elementData.worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data(), *elementData.scissorBox));
} }
const std::shared_ptr<Material>& LinearSlicedSprite::GetMaterial(std::size_t i) const const std::shared_ptr<Material>& LinearSlicedSprite::GetMaterial(std::size_t i) const

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/Model.hpp> #include <Nazara/Graphics/Model.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/GraphicalMesh.hpp> #include <Nazara/Graphics/GraphicalMesh.hpp>
#include <Nazara/Graphics/Graphics.hpp> #include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
@ -37,7 +38,7 @@ namespace Nz
UpdateAABB(aabb); UpdateAABB(aabb);
} }
void Model::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const void Model::BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const
{ {
for (std::size_t i = 0; i < m_submeshes.size(); ++i) for (std::size_t i = 0; i < m_submeshes.size(); ++i)
{ {
@ -54,7 +55,7 @@ namespace Nz
std::size_t indexCount = m_graphicalMesh->GetIndexCount(i); std::size_t indexCount = m_graphicalMesh->GetIndexCount(i);
IndexType indexType = m_graphicalMesh->GetIndexType(i); IndexType indexType = m_graphicalMesh->GetIndexType(i);
elements.emplace_back(std::make_unique<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, skeletonInstance, indexCount, indexType, indexBuffer, vertexBuffer, scissorBox)); elements.emplace_back(registry.AllocateElement<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, *elementData.worldInstance, elementData.skeletonInstance, indexCount, indexType, indexBuffer, vertexBuffer, *elementData.scissorBox));
} }
} }

View File

@ -0,0 +1,16 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
RenderElementOwner::~RenderElementOwner()
{
if (m_pool)
m_pool->Free(m_poolIndex);
}
}

View File

@ -0,0 +1,11 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
RenderElementPoolBase::~RenderElementPoolBase() = default;
}

View File

@ -4,6 +4,7 @@
#include <Nazara/Graphics/SlicedSprite.hpp> #include <Nazara/Graphics/SlicedSprite.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp> #include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp> #include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/Debug.hpp> #include <Nazara/Graphics/Debug.hpp>
@ -19,7 +20,7 @@ namespace Nz
UpdateVertices(); UpdateVertices();
} }
void SlicedSprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const void SlicedSprite::BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const
{ {
const auto& materialPass = m_material->GetPass(passIndex); const auto& materialPass = m_material->GetPass(passIndex);
if (!materialPass) if (!materialPass)
@ -39,7 +40,7 @@ namespace Nz
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)]; const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data(), scissorBox)); elements.emplace_back(registry.AllocateElement<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, *elementData.worldInstance, vertexDeclaration, whiteTexture, m_spriteCount, m_vertices.data(), *elementData.scissorBox));
} }
const std::shared_ptr<Material>& SlicedSprite::GetMaterial(std::size_t i) const const std::shared_ptr<Material>& SlicedSprite::GetMaterial(std::size_t i) const

View File

@ -4,6 +4,7 @@
#include <Nazara/Graphics/Sprite.hpp> #include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp> #include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp> #include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/WorldInstance.hpp> #include <Nazara/Graphics/WorldInstance.hpp>
@ -23,7 +24,7 @@ namespace Nz
UpdateVertices(); UpdateVertices();
} }
void Sprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const void Sprite::BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const
{ {
const auto& materialPass = m_material->GetPass(passIndex); const auto& materialPass = m_material->GetPass(passIndex);
if (!materialPass) if (!materialPass)
@ -43,7 +44,7 @@ namespace Nz
const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)]; const auto& whiteTexture = Graphics::Instance()->GetDefaultTextures().whiteTextures[UnderlyingCast(ImageType::E2D)];
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, whiteTexture, 1, m_vertices.data(), scissorBox)); elements.emplace_back(registry.AllocateElement<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, *elementData.worldInstance, vertexDeclaration, whiteTexture, 1, m_vertices.data(), *elementData.scissorBox));
} }
const std::shared_ptr<Material>& Sprite::GetMaterial(std::size_t i) const const std::shared_ptr<Material>& Sprite::GetMaterial(std::size_t i) const

View File

@ -45,6 +45,11 @@ namespace Nz
m_indexBuffer = m_device.InstantiateBuffer(BufferType::Index, indexCount * sizeof(UInt16), BufferUsage::DeviceLocal | BufferUsage::Write, indices.data()); m_indexBuffer = m_device.InstantiateBuffer(BufferType::Index, indexCount * sizeof(UInt16), BufferUsage::DeviceLocal | BufferUsage::Write, indices.data());
} }
RenderElementPool<RenderSpriteChain>& SpriteChainRenderer::GetPool()
{
return m_spriteChainPool;
}
std::unique_ptr<ElementRendererData> SpriteChainRenderer::InstanciateData() std::unique_ptr<ElementRendererData> SpriteChainRenderer::InstanciateData()
{ {
return std::make_unique<SpriteChainRendererData>(); return std::make_unique<SpriteChainRendererData>();

View File

@ -13,6 +13,11 @@
namespace Nz namespace Nz
{ {
RenderElementPool<RenderSubmesh>& SubmeshRenderer::GetPool()
{
return m_submeshPool;
}
std::unique_ptr<ElementRendererData> SubmeshRenderer::InstanciateData() std::unique_ptr<ElementRendererData> SubmeshRenderer::InstanciateData()
{ {
return std::make_unique<SubmeshRendererData>(); return std::make_unique<SubmeshRendererData>();

View File

@ -37,7 +37,7 @@ namespace Nz
m_sharedSkeletonDestroyConnection = registry.on_destroy<SharedSkeletonComponent>().connect<&RenderSystem::OnSharedSkeletonDestroy>(this); m_sharedSkeletonDestroyConnection = registry.on_destroy<SharedSkeletonComponent>().connect<&RenderSystem::OnSharedSkeletonDestroy>(this);
m_skeletonDestroyConnection = registry.on_destroy<SkeletonComponent>().connect<&RenderSystem::OnSkeletonDestroy>(this); m_skeletonDestroyConnection = registry.on_destroy<SkeletonComponent>().connect<&RenderSystem::OnSkeletonDestroy>(this);
m_pipeline = std::make_unique<ForwardFramePipeline>(); m_pipeline = std::make_unique<ForwardFramePipeline>(m_elementRegistry);
} }
RenderSystem::~RenderSystem() RenderSystem::~RenderSystem()
@ -45,6 +45,7 @@ namespace Nz
m_cameraConstructObserver.disconnect(); m_cameraConstructObserver.disconnect();
m_graphicsConstructObserver.disconnect(); m_graphicsConstructObserver.disconnect();
m_lightConstructObserver.disconnect(); m_lightConstructObserver.disconnect();
m_pipeline.reset();
} }
void RenderSystem::Update(float /*elapsedTime*/) void RenderSystem::Update(float /*elapsedTime*/)

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/TextSprite.hpp> #include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp> #include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/WorldInstance.hpp> #include <Nazara/Graphics/WorldInstance.hpp>
@ -18,7 +19,7 @@ namespace Nz
{ {
} }
void TextSprite::BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::vector<std::unique_ptr<RenderElement>>& elements, const Recti& scissorBox) const void TextSprite::BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const
{ {
const auto& materialPass = m_material->GetPass(passIndex); const auto& materialPass = m_material->GetPass(passIndex);
if (!materialPass) if (!materialPass)
@ -42,7 +43,7 @@ namespace Nz
RenderIndices& indices = pair.second; RenderIndices& indices = pair.second;
if (indices.count > 0) if (indices.count > 0)
elements.emplace_back(std::make_unique<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4], scissorBox)); elements.emplace_back(registry.AllocateElement<RenderSpriteChain>(GetRenderLayer(), materialPass, renderPipeline, *elementData.worldInstance, vertexDeclaration, key.texture->shared_from_this(), indices.count, &m_vertices[indices.first * 4], *elementData.scissorBox));
} }
} }

View File

@ -3,9 +3,9 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/Components/NodeComponent.hpp> #include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Components/SharedSkeletonComponent.hpp> #include <Nazara/Utility/Components/SharedSkeletonComponent.hpp>
#include <Nazara/Utility/Components/SkeletonComponent.hpp> #include <Nazara/Utility/Components/SkeletonComponent.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Debug.hpp> #include <Nazara/Utility/Debug.hpp>
namespace Nz namespace Nz