Graphics: Add SpriteChainRenderer
This commit is contained in:
@@ -18,6 +18,8 @@ namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class RenderElement;
|
||||
class RenderFrame;
|
||||
struct ElementRendererData;
|
||||
|
||||
class NAZARA_GRAPHICS_API ElementRenderer
|
||||
{
|
||||
@@ -25,7 +27,16 @@ namespace Nz
|
||||
ElementRenderer() = default;
|
||||
virtual ~ElementRenderer();
|
||||
|
||||
virtual void Render(CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) = 0;
|
||||
virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0;
|
||||
virtual void Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
||||
virtual void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) = 0;
|
||||
virtual void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||
};
|
||||
|
||||
struct NAZARA_GRAPHICS_API ElementRendererData
|
||||
{
|
||||
ElementRendererData() = default;
|
||||
virtual ~ElementRendererData();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,20 @@
|
||||
#ifndef NAZARA_ENUMS_GRAPHICS_HPP
|
||||
#define NAZARA_ENUMS_GRAPHICS_HPP
|
||||
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
enum class BasicRenderElement
|
||||
{
|
||||
Submesh = 0,
|
||||
SpriteChain = 0,
|
||||
Submesh = 1,
|
||||
|
||||
Max = Submesh
|
||||
};
|
||||
|
||||
constexpr std::size_t BasicRenderElementCount = UnderlyingCast(BasicRenderElement::Max) + 1;
|
||||
|
||||
enum class CullTest
|
||||
{
|
||||
Box,
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API ForwardFramePipeline : public FramePipeline
|
||||
{
|
||||
public:
|
||||
@@ -51,7 +53,7 @@ namespace Nz
|
||||
BakedFrameGraph BuildFrameGraph();
|
||||
|
||||
void RegisterMaterialPass(MaterialPass* material);
|
||||
void ProcessRenderQueue(CommandBufferBuilder& builder, const RenderQueue<RenderElement*>& renderQueue);
|
||||
template<typename F> void ProcessRenderQueue(const RenderQueue<RenderElement*>& renderQueue, F&& callback);
|
||||
void UnregisterMaterialPass(MaterialPass* material);
|
||||
|
||||
struct MaterialData
|
||||
@@ -79,6 +81,7 @@ namespace Nz
|
||||
std::size_t visibilityHash = 0;
|
||||
std::vector<std::unique_ptr<RenderElement>> depthPrepassRenderElements;
|
||||
std::vector<std::unique_ptr<RenderElement>> forwardRenderElements;
|
||||
std::vector<std::unique_ptr<ElementRendererData>> elementRendererData;
|
||||
RenderQueueRegistry depthPrepassRegistry;
|
||||
RenderQueueRegistry forwardRegistry;
|
||||
RenderQueue<RenderElement*> depthPrepassRenderQueue;
|
||||
@@ -100,6 +103,7 @@ namespace Nz
|
||||
std::vector<std::unique_ptr<ElementRenderer>> m_elementRenderers;
|
||||
std::vector<VisibleRenderable> m_visibleRenderables;
|
||||
BakedFrameGraph m_bakedFrameGraph;
|
||||
RenderFrame* m_currentRenderFrame;
|
||||
bool m_rebuildFrameGraph;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Nz
|
||||
{
|
||||
class AbstractBuffer;
|
||||
class RenderPipeline;
|
||||
class VertexDeclaration;
|
||||
|
||||
class RenderQueueRegistry
|
||||
{
|
||||
@@ -26,15 +27,18 @@ namespace Nz
|
||||
inline std::size_t FetchLayerIndex(int renderLayer) const;
|
||||
inline std::size_t FetchPipelineIndex(const RenderPipeline* pipeline) const;
|
||||
inline std::size_t FetchVertexBuffer(const AbstractBuffer* vertexBuffer) const;
|
||||
inline std::size_t FetchVertexDeclaration(const VertexDeclaration* vertexDeclaration) const;
|
||||
|
||||
inline void RegisterLayer(int renderLayer);
|
||||
inline void RegisterPipeline(const RenderPipeline* pipeline);
|
||||
inline void RegisterVertexBuffer(const AbstractBuffer* vertexBuffer);
|
||||
inline void RegisterVertexDeclaration(const VertexDeclaration* vertexDeclaration);
|
||||
|
||||
private:
|
||||
robin_hood::unordered_map<int, std::size_t> m_renderLayerRegistry;
|
||||
robin_hood::unordered_map<const RenderPipeline*, std::size_t> m_pipelineRegistry;
|
||||
robin_hood::unordered_map<const AbstractBuffer*, std::size_t> m_vertexBufferRegistry;
|
||||
robin_hood::unordered_map<const VertexDeclaration*, std::size_t> m_vertexDeclarationRegistry;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,14 @@ namespace Nz
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline std::size_t RenderQueueRegistry::FetchVertexDeclaration(const VertexDeclaration* vertexDeclaration) const
|
||||
{
|
||||
auto it = m_vertexDeclarationRegistry.find(vertexDeclaration);
|
||||
assert(it != m_vertexDeclarationRegistry.end());
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline void RenderQueueRegistry::RegisterLayer(int renderLayer)
|
||||
{
|
||||
m_renderLayerRegistry.try_emplace(renderLayer, m_renderLayerRegistry.size());
|
||||
@@ -52,6 +60,11 @@ namespace Nz
|
||||
{
|
||||
m_vertexBufferRegistry.try_emplace(vertexBuffer, m_vertexBufferRegistry.size());
|
||||
}
|
||||
|
||||
inline void RenderQueueRegistry::RegisterVertexDeclaration(const VertexDeclaration* vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclarationRegistry.try_emplace(vertexDeclaration, m_vertexDeclarationRegistry.size());
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
53
include/Nazara/Graphics/RenderSpriteChain.hpp
Normal file
53
include/Nazara/Graphics/RenderSpriteChain.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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_RENDERSUBMESH_HPP
|
||||
#define NAZARA_RENDERSUBMESH_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractBuffer;
|
||||
class RenderPipeline;
|
||||
class ShaderBinding;
|
||||
class VertexDeclaration;
|
||||
|
||||
class RenderSpriteChain : public RenderElement
|
||||
{
|
||||
public:
|
||||
inline RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding);
|
||||
~RenderSpriteChain() = default;
|
||||
|
||||
inline UInt64 ComputeSortingScore(const RenderQueueRegistry& registry) const override;
|
||||
|
||||
inline const ShaderBinding& GetInstanceBinding() const;
|
||||
inline const ShaderBinding& GetMaterialBinding() const;
|
||||
inline const RenderPipeline* GetRenderPipeline() const;
|
||||
inline std::size_t GetSpriteCount() const;
|
||||
inline const void* GetSpriteData() const;
|
||||
inline const VertexDeclaration* GetVertexDeclaration() const;
|
||||
|
||||
inline void Register(RenderQueueRegistry& registry) const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
|
||||
std::size_t m_spriteCount;
|
||||
const void* m_spriteData;
|
||||
const ShaderBinding& m_instanceBinding;
|
||||
const ShaderBinding& m_materialBinding;
|
||||
int m_renderLayer;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/RenderSpriteChain.inl>
|
||||
|
||||
#endif
|
||||
80
include/Nazara/Graphics/RenderSpriteChain.inl
Normal file
80
include/Nazara/Graphics/RenderSpriteChain.inl
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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/RenderSpriteChain.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::size_t spriteCount, const void* spriteData, const ShaderBinding& materialBinding, const ShaderBinding& instanceBinding) :
|
||||
RenderElement(BasicRenderElement::SpriteChain),
|
||||
m_renderPipeline(std::move(renderPipeline)),
|
||||
m_vertexDeclaration(std::move(vertexDeclaration)),
|
||||
m_spriteCount(spriteCount),
|
||||
m_spriteData(spriteData),
|
||||
m_instanceBinding(instanceBinding),
|
||||
m_materialBinding(materialBinding),
|
||||
m_renderLayer(renderLayer)
|
||||
{
|
||||
}
|
||||
|
||||
inline UInt64 RenderSpriteChain::ComputeSortingScore(const RenderQueueRegistry& registry) const
|
||||
{
|
||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||
UInt64 elementType = GetElementType();
|
||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
||||
|
||||
// RQ index:
|
||||
// - Layer (8bits)
|
||||
// - Element type (4bits)
|
||||
// - Pipeline (16bits)
|
||||
// - VertexDeclaration (8bits)
|
||||
// - ?? (24bits) - Depth?
|
||||
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(elementType & 0xF) << 52 |
|
||||
(pipelineIndex & 0xFFFF) << 36 |
|
||||
(vertexDeclarationIndex & 0xFF) << 24;
|
||||
}
|
||||
|
||||
inline const ShaderBinding& RenderSpriteChain::GetInstanceBinding() const
|
||||
{
|
||||
return m_instanceBinding;
|
||||
}
|
||||
|
||||
inline const ShaderBinding& RenderSpriteChain::GetMaterialBinding() const
|
||||
{
|
||||
return m_materialBinding;
|
||||
}
|
||||
|
||||
inline const RenderPipeline* RenderSpriteChain::GetRenderPipeline() const
|
||||
{
|
||||
return m_renderPipeline.get();
|
||||
}
|
||||
|
||||
inline std::size_t RenderSpriteChain::GetSpriteCount() const
|
||||
{
|
||||
return m_spriteCount;
|
||||
}
|
||||
|
||||
inline const void* RenderSpriteChain::GetSpriteData() const
|
||||
{
|
||||
return m_spriteData;
|
||||
}
|
||||
|
||||
inline const VertexDeclaration* RenderSpriteChain::GetVertexDeclaration() const
|
||||
{
|
||||
return m_vertexDeclaration.get();
|
||||
}
|
||||
|
||||
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
|
||||
{
|
||||
registry.RegisterLayer(m_renderLayer);
|
||||
registry.RegisterPipeline(m_renderPipeline.get());
|
||||
registry.RegisterVertexDeclaration(m_vertexDeclaration.get());
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -27,8 +27,8 @@ namespace Nz
|
||||
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
|
||||
|
||||
// RQ index:
|
||||
// - Element type (4bits)
|
||||
// - Layer (8bits)
|
||||
// - Element type (4bits)
|
||||
// - Pipeline (16bits)
|
||||
// - VertexBuffer (8bits)
|
||||
// - ?? (24bits) - Depth?
|
||||
|
||||
46
include/Nazara/Graphics/Sprite.hpp
Normal file
46
include/Nazara/Graphics/Sprite.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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_SPRITE_HPP
|
||||
#define NAZARA_SPRITE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Renderer/RenderPipeline.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/VertexStruct.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API Sprite : public InstancedRenderable
|
||||
{
|
||||
public:
|
||||
Sprite(std::shared_ptr<Material> material);
|
||||
Sprite(const Sprite&) = delete;
|
||||
Sprite(Sprite&&) noexcept = default;
|
||||
~Sprite() = default;
|
||||
|
||||
void BuildElement(std::size_t passIndex, const WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const override;
|
||||
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t i) const;
|
||||
std::size_t GetMaterialCount() const;
|
||||
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
|
||||
Sprite& operator=(const Sprite&) = delete;
|
||||
Sprite& operator=(Sprite&&) noexcept = default;
|
||||
|
||||
private:
|
||||
std::array<VertexStruct_XYZ_Color_UV, 4> m_vertices;
|
||||
std::shared_ptr<Material> m_material;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/Sprite.inl>
|
||||
|
||||
#endif
|
||||
17
include/Nazara/Graphics/Sprite.inl
Normal file
17
include/Nazara/Graphics/Sprite.inl
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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/Sprite.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void Sprite::SetMaterial(std::shared_ptr<Material> material)
|
||||
{
|
||||
m_material = std::move(material);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
68
include/Nazara/Graphics/SpriteChainRenderer.hpp
Normal file
68
include/Nazara/Graphics/SpriteChainRenderer.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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_SPRITECHAINRENDERER_HPP
|
||||
#define NAZARA_SPRITECHAINRENDERER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractBuffer;
|
||||
class RenderDevice;
|
||||
class RenderPipeline;
|
||||
class RenderSpriteChain;
|
||||
class ShaderBinding;
|
||||
|
||||
class NAZARA_GRAPHICS_API SpriteChainRenderer : public ElementRenderer
|
||||
{
|
||||
public:
|
||||
SpriteChainRenderer(RenderDevice& device, std::size_t maxVertexBufferSize = 32 * 1024);
|
||||
~SpriteChainRenderer() = default;
|
||||
|
||||
std::unique_ptr<ElementRendererData> InstanciateData();
|
||||
void Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
|
||||
void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
||||
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||
|
||||
private:
|
||||
std::shared_ptr<AbstractBuffer> m_indexBuffer;
|
||||
std::size_t m_maxVertexBufferSize;
|
||||
std::size_t m_maxVertexCount;
|
||||
RenderDevice& m_device;
|
||||
};
|
||||
|
||||
struct SpriteChainRendererData : public ElementRendererData
|
||||
{
|
||||
struct DrawCall
|
||||
{
|
||||
const AbstractBuffer* vertexBuffer;
|
||||
const RenderPipeline* renderPipeline;
|
||||
const ShaderBinding* instanceBinding;
|
||||
const ShaderBinding* materialBinding;
|
||||
std::size_t firstIndex;
|
||||
std::size_t quadCount;
|
||||
};
|
||||
|
||||
struct DrawCallIndices
|
||||
{
|
||||
std::size_t start;
|
||||
std::size_t count;
|
||||
};
|
||||
|
||||
std::unordered_map<const RenderSpriteChain*, DrawCallIndices> drawCallPerElement;
|
||||
std::vector<DrawCall> drawCalls;
|
||||
std::vector<std::shared_ptr<AbstractBuffer>> vertexBuffers;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/SpriteChainRenderer.inl>
|
||||
|
||||
#endif
|
||||
12
include/Nazara/Graphics/SpriteChainRenderer.inl
Normal file
12
include/Nazara/Graphics/SpriteChainRenderer.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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/SpriteChainRenderer.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -18,7 +18,8 @@ namespace Nz
|
||||
SubmeshRenderer() = default;
|
||||
~SubmeshRenderer() = default;
|
||||
|
||||
void Render(CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
||||
std::unique_ptr<ElementRendererData> InstanciateData();
|
||||
void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user