Graphics: Add MaterialPassRegistry
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -18,7 +19,7 @@ namespace Nz
|
||||
class CommandBufferBuilder;
|
||||
class RenderElement;
|
||||
|
||||
class ElementRenderer
|
||||
class NAZARA_GRAPHICS_API ElementRenderer
|
||||
{
|
||||
public:
|
||||
ElementRenderer() = default;
|
||||
|
||||
@@ -73,6 +73,8 @@ namespace Nz
|
||||
ShaderBindingPtr blitShaderBinding;
|
||||
};
|
||||
|
||||
std::size_t m_depthPassIndex;
|
||||
std::size_t m_forwardPassIndex;
|
||||
std::unordered_map<AbstractViewer*, ViewerData> m_viewers;
|
||||
std::unordered_map<MaterialPass*, MaterialData> m_materials;
|
||||
std::unordered_map<WorldInstancePtr, std::unordered_map<const InstancedRenderable*, RenderableData>> m_renderables;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
@@ -36,6 +37,8 @@ namespace Nz
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& GetBlitPipelineLayout() const;
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetFullscreenVertexBuffer() const;
|
||||
inline const std::shared_ptr<VertexDeclaration>& GetFullscreenVertexDeclaration() const;
|
||||
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
||||
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
||||
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& GetReferencePipelineLayout() const;
|
||||
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
||||
@@ -58,6 +61,7 @@ namespace Nz
|
||||
private:
|
||||
void BuildBlitPipeline();
|
||||
void BuildFullscreenVertexBuffer();
|
||||
void RegisterMaterialPasses();
|
||||
void SelectDepthStencilFormats();
|
||||
|
||||
std::optional<RenderPassCache> m_renderPassCache;
|
||||
@@ -68,6 +72,7 @@ namespace Nz
|
||||
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
||||
std::shared_ptr<RenderPipelineLayout> m_referencePipelineLayout;
|
||||
std::shared_ptr<VertexDeclaration> m_fullscreenVertexDeclaration;
|
||||
MaterialPassRegistry m_materialPassRegistry;
|
||||
PixelFormat m_preferredDepthStencilFormat;
|
||||
|
||||
static Graphics* s_instance;
|
||||
|
||||
@@ -27,6 +27,16 @@ namespace Nz
|
||||
return m_fullscreenVertexDeclaration;
|
||||
}
|
||||
|
||||
inline MaterialPassRegistry& Graphics::GetMaterialPassRegistry()
|
||||
{
|
||||
return m_materialPassRegistry;
|
||||
}
|
||||
|
||||
inline const MaterialPassRegistry& Graphics::GetMaterialPassRegistry() const
|
||||
{
|
||||
return m_materialPassRegistry;
|
||||
}
|
||||
|
||||
inline PixelFormat Graphics::GetPreferredDepthStencilFormat() const
|
||||
{
|
||||
return m_preferredDepthStencilFormat;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Nz
|
||||
InstancedRenderable(InstancedRenderable&&) noexcept = default;
|
||||
~InstancedRenderable();
|
||||
|
||||
virtual void BuildElement(const std::string& pass, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const = 0;
|
||||
virtual void BuildElement(std::size_t passIndex, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const = 0;
|
||||
|
||||
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
|
||||
virtual std::size_t GetMaterialCount() const = 0;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define NAZARA_MATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
|
||||
namespace Nz
|
||||
@@ -18,16 +19,18 @@ namespace Nz
|
||||
Material();
|
||||
~Material() = default;
|
||||
|
||||
void AddPass(std::string name, std::shared_ptr<MaterialPass> pass);
|
||||
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(const std::string& name) const;
|
||||
inline MaterialPass* GetPass(std::size_t passIndex) const;
|
||||
|
||||
bool HasPass(const std::string& name) const;
|
||||
inline bool HasPass(std::size_t passIndex) const;
|
||||
|
||||
void RemovePass(const std::string& name);
|
||||
inline void RemovePass(std::size_t passIndex);
|
||||
inline void RemovePass(const std::string& passName);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<MaterialPass>> m_passes;
|
||||
std::vector<std::shared_ptr<MaterialPass>> m_passes;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,45 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline MaterialPass* Material::GetPass(const std::string& name) const
|
||||
inline void Material::AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass)
|
||||
{
|
||||
auto it = m_passes.find(name);
|
||||
if (it == m_passes.end())
|
||||
if (passIndex >= m_passes.size())
|
||||
m_passes.resize(passIndex + 1);
|
||||
|
||||
m_passes[passIndex] = std::move(pass);
|
||||
}
|
||||
|
||||
inline void Material::AddPass(std::string passName, std::shared_ptr<MaterialPass> pass)
|
||||
{
|
||||
auto& registry = Graphics::Instance()->GetMaterialPassRegistry();
|
||||
return AddPass(registry.GetPassIndex(passName), std::move(pass));
|
||||
}
|
||||
|
||||
inline MaterialPass* Material::GetPass(std::size_t passIndex) const
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
return nullptr;
|
||||
|
||||
return it->second.get();
|
||||
return m_passes[passIndex].get();
|
||||
}
|
||||
|
||||
inline bool Material::HasPass(std::size_t passIndex) const
|
||||
{
|
||||
return GetPass(passIndex) != nullptr;
|
||||
}
|
||||
|
||||
inline void Material::RemovePass(std::size_t passIndex)
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
return;
|
||||
|
||||
m_passes[passIndex].reset();
|
||||
}
|
||||
|
||||
inline void Material::RemovePass(const std::string& passName)
|
||||
{
|
||||
auto& registry = Graphics::Instance()->GetMaterialPassRegistry();
|
||||
return RemovePass(registry.GetPassIndex(passName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace Nz
|
||||
UInt64 m_enabledOptions;
|
||||
mutable MaterialPipelineInfo m_pipelineInfo;
|
||||
ShaderBindingPtr m_shaderBinding;
|
||||
bool m_forceCommandBufferRegeneration;
|
||||
mutable bool m_pipelineUpdated;
|
||||
bool m_shaderBindingUpdated;
|
||||
};
|
||||
|
||||
@@ -621,13 +621,17 @@ namespace Nz
|
||||
|
||||
inline void MaterialPass::InvalidatePipeline()
|
||||
{
|
||||
m_forceCommandBufferRegeneration = true;
|
||||
m_pipelineUpdated = false;
|
||||
|
||||
OnMaterialInvalidated(this);
|
||||
}
|
||||
|
||||
inline void MaterialPass::InvalidateShaderBinding()
|
||||
{
|
||||
m_forceCommandBufferRegeneration = true;
|
||||
m_shaderBindingUpdated = false;
|
||||
|
||||
OnMaterialInvalidated(this);
|
||||
}
|
||||
|
||||
|
||||
38
include/Nazara/Graphics/MaterialPassRegistry.hpp
Normal file
38
include/Nazara/Graphics/MaterialPassRegistry.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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_MATERIAL_PASS_REGISTRY_HPP
|
||||
#define NAZARA_MATERIAL_PASS_REGISTRY_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPassRegistry
|
||||
{
|
||||
public:
|
||||
MaterialPassRegistry() = default;
|
||||
MaterialPassRegistry(const MaterialPassRegistry&) = default;
|
||||
MaterialPassRegistry(MaterialPassRegistry&&) = default;
|
||||
~MaterialPassRegistry() = default;
|
||||
|
||||
inline std::size_t GetPassIndex(const std::string& passName) const;
|
||||
|
||||
inline std::size_t RegisterPass(std::string passName);
|
||||
|
||||
MaterialPassRegistry& operator=(const MaterialPassRegistry&) = default;
|
||||
MaterialPassRegistry& operator=(MaterialPassRegistry&&) = default;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::size_t> m_passIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/MaterialPassRegistry.inl>
|
||||
|
||||
#endif
|
||||
32
include/Nazara/Graphics/MaterialPassRegistry.inl
Normal file
32
include/Nazara/Graphics/MaterialPassRegistry.inl
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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/MaterialPassRegistry.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
std::size_t MaterialPassRegistry::GetPassIndex(const std::string& passName) const
|
||||
{
|
||||
auto it = m_passIndex.find(passName);
|
||||
if (it == m_passIndex.end())
|
||||
throw std::runtime_error("pass " + passName + " must be registered before being used");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline std::size_t MaterialPassRegistry::RegisterPass(std::string passName)
|
||||
{
|
||||
if (m_passIndex.find(passName) != m_passIndex.end())
|
||||
throw std::runtime_error("pass " + passName + " is already registered");
|
||||
|
||||
std::size_t passIndex = m_passIndex.size();
|
||||
m_passIndex.emplace(std::move(passName), passIndex);
|
||||
|
||||
return passIndex;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -28,7 +28,7 @@ namespace Nz
|
||||
Model(Model&&) noexcept = default;
|
||||
~Model() = default;
|
||||
|
||||
void BuildElement(const std::string& pass, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const override;
|
||||
void BuildElement(std::size_t passIndex, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const override;
|
||||
|
||||
const std::shared_ptr<AbstractBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
||||
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace Nz
|
||||
|
||||
inline UInt64 RenderSubmesh::ComputeSortingScore(const RenderQueueRegistry& registry) const
|
||||
{
|
||||
UInt64 elementType = GetElementType();
|
||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||
UInt64 elementType = GetElementType();
|
||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace Nz
|
||||
// - VertexBuffer (8bits)
|
||||
// - ?? (24bits) - Depth?
|
||||
|
||||
return (elementType & 0xF) << 60 |
|
||||
(layerIndex & 0xFF) << 52 |
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(elementType & 0xF) << 52 |
|
||||
(pipelineIndex & 0xFFFF) << 36 |
|
||||
(vertexBufferIndex & 0xFF) << 24;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class SubmeshRenderer : public ElementRenderer
|
||||
class NAZARA_GRAPHICS_API SubmeshRenderer : public ElementRenderer
|
||||
{
|
||||
public:
|
||||
SubmeshRenderer() = default;
|
||||
|
||||
Reference in New Issue
Block a user