Proof of concept

This commit is contained in:
Jérôme Leclercq
2021-10-20 23:50:23 +02:00
parent 58485cfa79
commit e84ec8e4ac
25 changed files with 366 additions and 139 deletions

View File

@@ -19,6 +19,7 @@ namespace Nz
class CommandBufferBuilder;
class RenderElement;
class RenderFrame;
class ViewerInstance;
struct ElementRendererData;
class NAZARA_GRAPHICS_API ElementRenderer
@@ -28,8 +29,8 @@ namespace Nz
virtual ~ElementRenderer();
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 Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
virtual void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) = 0;
virtual void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
};

View File

@@ -22,7 +22,7 @@ namespace Nz
inline void AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass);
inline void AddPass(std::string passName, std::shared_ptr<MaterialPass> pass);
inline MaterialPass* GetPass(std::size_t passIndex) const;
inline const std::shared_ptr<MaterialPass>& GetPass(std::size_t passIndex) const;
inline bool HasPass(std::size_t passIndex) const;

View File

@@ -21,17 +21,23 @@ namespace Nz
return AddPass(registry.GetPassIndex(passName), std::move(pass));
}
inline MaterialPass* Material::GetPass(std::size_t passIndex) const
inline const std::shared_ptr<MaterialPass>& Material::GetPass(std::size_t passIndex) const
{
if (passIndex >= m_passes.size())
return nullptr;
{
static std::shared_ptr<MaterialPass> dummy;
return dummy;
}
return m_passes[passIndex].get();
return m_passes[passIndex];
}
inline bool Material::HasPass(std::size_t passIndex) const
{
return GetPass(passIndex) != nullptr;
if (passIndex >= m_passes.size())
return false;
return m_passes[passIndex] != nullptr;
}
inline void Material::RemovePass(std::size_t passIndex)

View File

@@ -52,6 +52,8 @@ namespace Nz
inline void EnsurePipelineUpdate() const;
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
inline RendererComparison GetDepthCompareFunc() const;
inline BlendEquation GetBlendAlphaModeEquation() const;
inline BlendEquation GetBlendColorModeEquation() const;

View File

@@ -39,6 +39,7 @@ namespace Nz
inline const Builder& GetBuilderData() const;
inline const std::vector<Option>& GetOptions() const;
inline std::size_t GetOptionIndex(const std::string_view& name) const;
inline std::size_t GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
@@ -60,6 +61,8 @@ namespace Nz
struct Builder
{
inline Builder();
std::vector<std::shared_ptr<UberShader>> shaders;
std::vector<Option> options;
std::vector<Texture> textures;

View File

@@ -73,6 +73,11 @@ namespace Nz
return InvalidIndex;
}
inline std::size_t MaterialSettings::GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const
{
return m_data.predefinedBindings[UnderlyingCast(shaderBinding)];
}
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
{
return m_pipelineLayout;
@@ -190,6 +195,11 @@ namespace Nz
});
}
}
inline MaterialSettings::Builder::Builder()
{
predefinedBindings.fill(InvalidIndex);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -25,7 +25,7 @@ namespace Nz
class RenderSpriteChain : public RenderElement
{
public:
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData);
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData);
~RenderSpriteChain() = default;
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
@@ -36,7 +36,6 @@ namespace Nz
inline const void* GetSpriteData() const;
inline const Texture* GetTextureOverlay() const;
inline const VertexDeclaration* GetVertexDeclaration() const;
inline const ViewerInstance& GetViewerInstance() const;
inline const WorldInstance& GetWorldInstance() const;
inline void Register(RenderQueueRegistry& registry) const override;
@@ -48,7 +47,6 @@ namespace Nz
std::shared_ptr<Texture> m_textureOverlay;
std::size_t m_spriteCount;
const void* m_spriteData;
const ViewerInstance& m_viewerInstance;
const WorldInstance& m_worldInstance;
int m_renderLayer;
};

View File

@@ -8,7 +8,7 @@
namespace Nz
{
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const ViewerInstance& viewerInstance, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData) :
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData) :
RenderElement(BasicRenderElement::SpriteChain),
m_materialPass(std::move(materialPass)),
m_renderPipeline(std::move(renderPipeline)),
@@ -16,7 +16,6 @@ namespace Nz
m_textureOverlay(std::move(textureOverlay)),
m_spriteCount(spriteCount),
m_spriteData(spriteData),
m_viewerInstance(viewerInstance),
m_worldInstance(worldInstance),
m_renderLayer(renderLayer)
{
@@ -96,11 +95,6 @@ namespace Nz
return m_vertexDeclaration.get();
}
inline const ViewerInstance& RenderSpriteChain::GetViewerInstance() const
{
return m_viewerInstance;
}
inline const WorldInstance& RenderSpriteChain::GetWorldInstance() const
{
return m_worldInstance;

View File

@@ -17,33 +17,33 @@
namespace Nz
{
class AbstractBuffer;
class MaterialPass;
class RenderPipeline;
class ShaderBinding;
class RenderSubmesh : public RenderElement
{
public:
inline RenderSubmesh(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer, const WorldInstance& worldInstance, const ShaderBinding& materialBinding, const MaterialPassFlags& matFlags);
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer);
~RenderSubmesh() = default;
inline UInt64 ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const override;
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
inline const AbstractBuffer* GetIndexBuffer() const;
inline std::size_t GetIndexCount() const;
inline const MaterialPass& GetMaterialPass() const;
inline const RenderPipeline* GetRenderPipeline() const;
inline const ShaderBinding& GetInstanceBinding() const;
inline const ShaderBinding& GetMaterialBinding() const;
inline const AbstractBuffer* GetVertexBuffer() const;
inline const WorldInstance& GetWorldInstance() const;
inline void Register(RenderQueueRegistry& registry) const override;
private:
std::shared_ptr<AbstractBuffer> m_indexBuffer;
std::shared_ptr<AbstractBuffer> m_vertexBuffer;
std::shared_ptr<MaterialPass> m_materialPass;
std::shared_ptr<RenderPipeline> m_renderPipeline;
std::size_t m_indexCount;
MaterialPassFlags m_matFlags;
const ShaderBinding& m_materialBinding;
const WorldInstance& m_worldInstance;
int m_renderLayer;
};

View File

@@ -4,31 +4,31 @@
#include <Nazara/Graphics/RenderSubmesh.hpp>
#include <Nazara/Graphics/Algorithm.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<RenderPipeline> renderPipeline, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer, const WorldInstance& worldInstance, const ShaderBinding& materialBinding, const MaterialPassFlags& matFlags) :
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr<AbstractBuffer> indexBuffer, std::shared_ptr<AbstractBuffer> vertexBuffer) :
RenderElement(BasicRenderElement::Submesh),
m_indexBuffer(std::move(indexBuffer)),
m_vertexBuffer(std::move(vertexBuffer)),
m_materialPass(std::move(materialPass)),
m_renderPipeline(std::move(renderPipeline)),
m_indexCount(indexCount),
m_matFlags(matFlags),
m_materialBinding(materialBinding),
m_worldInstance(worldInstance),
m_renderLayer(renderLayer)
{
}
inline UInt64 RenderSubmesh::ComputeSortingScore(const Nz::Frustumf& frustum, const RenderQueueRegistry& registry) const
inline UInt64 RenderSubmesh::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
{
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
UInt64 elementType = GetElementType();
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
if (m_matFlags.Test(MaterialPassFlag::Transparent))
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::Transparent))
{
UInt64 matFlags = 1;
@@ -74,26 +74,26 @@ namespace Nz
return m_indexCount;
}
inline const MaterialPass& RenderSubmesh::GetMaterialPass() const
{
return *m_materialPass;
}
inline const RenderPipeline* RenderSubmesh::GetRenderPipeline() const
{
return m_renderPipeline.get();
}
inline const ShaderBinding& RenderSubmesh::GetInstanceBinding() const
{
return m_worldInstance.GetShaderBinding();
}
inline const ShaderBinding& RenderSubmesh::GetMaterialBinding() const
{
return m_materialBinding;
}
inline const AbstractBuffer* RenderSubmesh::GetVertexBuffer() const
{
return m_vertexBuffer.get();
}
inline const WorldInstance& RenderSubmesh::GetWorldInstance() const
{
return m_worldInstance;
}
inline void RenderSubmesh::Register(RenderQueueRegistry& registry) const
{
registry.RegisterLayer(m_renderLayer);

View File

@@ -30,8 +30,8 @@ namespace Nz
~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 Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
private:
@@ -52,6 +52,7 @@ namespace Nz
std::size_t m_maxVertexBufferSize;
std::size_t m_maxVertexCount;
std::vector<BufferCopy> m_pendingCopies;
std::vector<ShaderBinding::Binding> m_bindingCache;
RenderDevice& m_device;
};

View File

@@ -13,6 +13,10 @@
namespace Nz
{
class AbstractBuffer;
class RenderPipeline;
class ShaderBinding;
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer
{
public:
@@ -20,10 +24,27 @@ namespace Nz
~SubmeshRenderer() = default;
std::unique_ptr<ElementRendererData> InstanciateData();
void Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount);
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount) override;
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
private:
ShaderBindingPtr m_renderDataBinding;
std::vector<ShaderBinding::Binding> m_bindingCache;
};
struct SubmeshRendererData : public ElementRendererData
{
struct DrawCall
{
const AbstractBuffer* indexBuffer;
const AbstractBuffer* vertexBuffer;
const RenderPipeline* renderPipeline;
const ShaderBinding* shaderBinding;
std::size_t indexCount;
};
std::vector<DrawCall> drawCalls;
std::vector<ShaderBindingPtr> shaderBindings;
};
}

View File

@@ -33,8 +33,8 @@ namespace Nz
inline const Matrix4f& GetProjectionMatrix() const;
inline const Matrix4f& GetViewMatrix() const;
inline const Matrix4f& GetViewProjMatrix() const;
inline std::shared_ptr<AbstractBuffer>& GetInstanceBuffer();
inline const std::shared_ptr<AbstractBuffer>& GetInstanceBuffer() const;
inline std::shared_ptr<AbstractBuffer>& GetViewerBuffer();
inline const std::shared_ptr<AbstractBuffer>& GetViewerBuffer() const;
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);

View File

@@ -38,12 +38,12 @@ namespace Nz
return m_viewProjMatrix;
}
inline std::shared_ptr<AbstractBuffer>& ViewerInstance::GetInstanceBuffer()
inline std::shared_ptr<AbstractBuffer>& ViewerInstance::GetViewerBuffer()
{
return m_viewerDataBuffer;
}
inline const std::shared_ptr<AbstractBuffer>& ViewerInstance::GetInstanceBuffer() const
inline const std::shared_ptr<AbstractBuffer>& ViewerInstance::GetViewerBuffer() const
{
return m_viewerDataBuffer;
}