Refactor material system (#382)
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Nz
|
||||
inline bool EndsWith(const std::string_view& str, const std::string_view& s)
|
||||
{
|
||||
//FIXME: Replace with proper C++20 value once it's available
|
||||
#if __cplusplus > 201703L
|
||||
#if NAZARA_CPP_VER > 201703L
|
||||
// C++20
|
||||
return str.ends_with(s);
|
||||
#else
|
||||
@@ -53,7 +53,7 @@ namespace Nz
|
||||
inline bool StartsWith(const std::string_view& str, const std::string_view& s)
|
||||
{
|
||||
//FIXME: Replace with proper C++20 value once it's available
|
||||
#if __cplusplus > 201703L
|
||||
#if NAZARA_CPP_VER > 201703L
|
||||
// C++20
|
||||
return str.starts_with(s);
|
||||
#else
|
||||
|
||||
@@ -32,11 +32,9 @@
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/Algorithm.hpp>
|
||||
#include <Nazara/Graphics/BakedFrameGraph.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
#include <Nazara/Graphics/Camera.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/DebugDrawPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/DepthMaterial.hpp>
|
||||
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/DirectionalLight.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
@@ -56,15 +54,16 @@
|
||||
#include <Nazara/Graphics/Light.hpp>
|
||||
#include <Nazara/Graphics/LinearSlicedSprite.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
|
||||
#include <Nazara/Graphics/PhysicallyBasedMaterial.hpp>
|
||||
#include <Nazara/Graphics/PointLight.hpp>
|
||||
#include <Nazara/Graphics/PredefinedMaterials.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/RenderBufferPool.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderElementOwner.hpp>
|
||||
#include <Nazara/Graphics/RenderElementPool.hpp>
|
||||
@@ -72,6 +71,7 @@
|
||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||
#include <Nazara/Graphics/RenderSpriteChain.hpp>
|
||||
#include <Nazara/Graphics/RenderSubmesh.hpp>
|
||||
#include <Nazara/Graphics/ShaderReflection.hpp>
|
||||
#include <Nazara/Graphics/SkeletonInstance.hpp>
|
||||
#include <Nazara/Graphics/SlicedSprite.hpp>
|
||||
#include <Nazara/Graphics/SpotLight.hpp>
|
||||
@@ -80,6 +80,7 @@
|
||||
#include <Nazara/Graphics/SubmeshRenderer.hpp>
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Graphics/UberShader.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
// 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_BASICMATERIAL_HPP
|
||||
#define NAZARA_GRAPHICS_BASICMATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
|
||||
namespace nzsl
|
||||
{
|
||||
class FieldOffsets;
|
||||
}
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API BasicMaterial
|
||||
{
|
||||
friend class MaterialPipeline;
|
||||
|
||||
public:
|
||||
struct BasicUniformOffsets;
|
||||
|
||||
BasicMaterial(MaterialPass& material);
|
||||
~BasicMaterial() = default;
|
||||
|
||||
inline void EnableAlphaTest(bool alphaTest);
|
||||
|
||||
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
||||
inline const TextureSamplerInfo& GetAlphaSampler() const;
|
||||
float GetAlphaTestThreshold() const;
|
||||
Color GetBaseColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetBaseColorMap() const;
|
||||
inline const TextureSamplerInfo& GetBaseColorSampler() const;
|
||||
|
||||
inline bool IsAlphaTestEnabled() const;
|
||||
|
||||
inline bool HasAlphaMap() const;
|
||||
inline bool HasAlphaTest() const;
|
||||
inline bool HasAlphaTestThreshold() const;
|
||||
inline bool HasBaseColor() const;
|
||||
inline bool HasBaseColorMap() const;
|
||||
|
||||
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
||||
inline void SetAlphaSampler(TextureSamplerInfo alphaSampler);
|
||||
void SetAlphaTestThreshold(float alphaThreshold);
|
||||
void SetBaseColor(const Color& baseColor);
|
||||
inline void SetBaseColorMap(std::shared_ptr<Texture> baseColorMap);
|
||||
inline void SetBaseColorSampler(TextureSamplerInfo baseColorSampler);
|
||||
|
||||
static inline const BasicUniformOffsets& GetOffsets();
|
||||
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||
|
||||
struct BasicUniformOffsets
|
||||
{
|
||||
std::size_t alphaThreshold;
|
||||
std::size_t baseColor;
|
||||
std::size_t totalSize;
|
||||
};
|
||||
|
||||
protected:
|
||||
struct NoInit {};
|
||||
|
||||
inline BasicMaterial(MaterialPass& material, NoInit);
|
||||
|
||||
struct BasicOptionIndexes
|
||||
{
|
||||
std::size_t alphaTest;
|
||||
std::size_t hasAlphaMap;
|
||||
std::size_t hasBaseColorMap;
|
||||
};
|
||||
|
||||
struct BasicTextureIndexes
|
||||
{
|
||||
std::size_t alpha;
|
||||
std::size_t baseColor;
|
||||
};
|
||||
|
||||
struct BasicBuildOptions
|
||||
{
|
||||
// Common
|
||||
std::vector<UInt8> defaultValues;
|
||||
std::size_t* uniformBlockIndex = nullptr;
|
||||
std::vector<std::shared_ptr<UberShader>> shaders;
|
||||
|
||||
// Basic
|
||||
BasicUniformOffsets basicOffsets;
|
||||
BasicOptionIndexes* basicOptionIndexes = nullptr;
|
||||
BasicTextureIndexes* basicTextureIndexes = nullptr;
|
||||
};
|
||||
|
||||
inline MaterialPass& GetMaterial();
|
||||
inline const MaterialPass& GetMaterial() const;
|
||||
|
||||
static MaterialSettings::Builder Build(BasicBuildOptions& options);
|
||||
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
|
||||
static std::pair<BasicUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
|
||||
|
||||
std::size_t m_uniformBlockIndex;
|
||||
BasicOptionIndexes m_basicOptionIndexes;
|
||||
BasicTextureIndexes m_basicTextureIndexes;
|
||||
BasicUniformOffsets m_basicUniformOffsets;
|
||||
|
||||
static std::shared_ptr<MaterialSettings> s_basicMaterialSettings;
|
||||
static std::size_t s_uniformBlockIndex;
|
||||
static BasicOptionIndexes s_basicOptionIndexes;
|
||||
static BasicTextureIndexes s_basicTextureIndexes;
|
||||
static BasicUniformOffsets s_basicUniformOffsets;
|
||||
|
||||
private:
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
MaterialPass& m_material;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/BasicMaterial.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_BASICMATERIAL_HPP
|
||||
@@ -1,149 +0,0 @@
|
||||
// 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/BasicMaterial.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline BasicMaterial::BasicMaterial(MaterialPass& material, NoInit) :
|
||||
m_material(material)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable alpha test for this material
|
||||
*
|
||||
* When enabled, all objects using this material will be rendered using alpha testing,
|
||||
* rejecting pixels if their alpha component is under a defined threshold.
|
||||
* This allows some kind of transparency with a much cheaper cost as it doesn't prevent any optimization (as deferred rendering or batching).
|
||||
*
|
||||
* \param alphaTest Defines if this material will use alpha testing
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsAlphaTestEnabled
|
||||
* \see SetAlphaThreshold
|
||||
*/
|
||||
inline void BasicMaterial::EnableAlphaTest(bool alphaTest)
|
||||
{
|
||||
NazaraAssert(HasAlphaTest(), "Material has no alpha test option");
|
||||
m_material.SetOptionValue(m_basicOptionIndexes.alphaTest, alphaTest);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTexture(m_basicTextureIndexes.alpha);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& BasicMaterial::GetAlphaSampler() const
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTextureSampler(m_basicTextureIndexes.alpha);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& BasicMaterial::GetBaseColorMap() const
|
||||
{
|
||||
NazaraAssert(HasBaseColorMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTexture(m_basicTextureIndexes.baseColor);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& BasicMaterial::GetBaseColorSampler() const
|
||||
{
|
||||
NazaraAssert(HasBaseColorMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTextureSampler(m_basicTextureIndexes.baseColor);
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::IsAlphaTestEnabled() const
|
||||
{
|
||||
NazaraAssert(HasAlphaTest(), "Material has no alpha test option");
|
||||
const auto& optionOpt = m_material.GetOptionValue(m_basicOptionIndexes.alphaTest);
|
||||
if (std::holds_alternative<nzsl::Ast::NoValue>(optionOpt))
|
||||
return false;
|
||||
|
||||
return std::get<bool>(optionOpt);
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::HasAlphaMap() const
|
||||
{
|
||||
return m_basicTextureIndexes.alpha != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::HasAlphaTest() const
|
||||
{
|
||||
return m_basicOptionIndexes.alphaTest != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::HasAlphaTestThreshold() const
|
||||
{
|
||||
return m_basicUniformOffsets.alphaThreshold != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::HasBaseColor() const
|
||||
{
|
||||
return m_basicUniformOffsets.baseColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool BasicMaterial::HasBaseColorMap() const
|
||||
{
|
||||
return m_basicTextureIndexes.baseColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
||||
bool hasAlphaMap = (alphaMap != nullptr);
|
||||
m_material.SetTexture(m_basicTextureIndexes.alpha, std::move(alphaMap));
|
||||
|
||||
if (m_basicOptionIndexes.hasBaseColorMap != MaterialSettings::InvalidIndex)
|
||||
m_material.SetOptionValue(m_basicOptionIndexes.hasAlphaMap, hasAlphaMap);
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetAlphaSampler(TextureSamplerInfo alphaSampler)
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
||||
m_material.SetTextureSampler(m_basicTextureIndexes.alpha, std::move(alphaSampler));
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetBaseColorMap(std::shared_ptr<Texture> baseColorMap)
|
||||
{
|
||||
NazaraAssert(HasBaseColorMap(), "Material has no diffuse map slot");
|
||||
bool hasBaseColorMap = (baseColorMap != nullptr);
|
||||
m_material.SetTexture(m_basicTextureIndexes.baseColor, std::move(baseColorMap));
|
||||
|
||||
if (m_basicOptionIndexes.hasBaseColorMap != MaterialSettings::InvalidIndex)
|
||||
m_material.SetOptionValue(m_basicOptionIndexes.hasBaseColorMap, hasBaseColorMap);
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetBaseColorSampler(TextureSamplerInfo diffuseSampler)
|
||||
{
|
||||
NazaraAssert(HasBaseColorMap(), "Material has no diffuse map slot");
|
||||
m_material.SetTextureSampler(m_basicTextureIndexes.baseColor, std::move(diffuseSampler));
|
||||
}
|
||||
|
||||
inline MaterialPass& BasicMaterial::GetMaterial()
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
inline const MaterialPass& BasicMaterial::GetMaterial() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<MaterialSettings>& BasicMaterial::GetSettings()
|
||||
{
|
||||
return s_basicMaterialSettings;
|
||||
}
|
||||
|
||||
inline auto BasicMaterial::GetOffsets() -> const BasicUniformOffsets&
|
||||
{
|
||||
return s_basicUniformOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -1,38 +0,0 @@
|
||||
// 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_DEPTHMATERIAL_HPP
|
||||
#define NAZARA_GRAPHICS_DEPTHMATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API DepthMaterial : public BasicMaterial
|
||||
{
|
||||
friend class MaterialPipeline;
|
||||
|
||||
public:
|
||||
using BasicMaterial::BasicMaterial;
|
||||
~DepthMaterial() = default;
|
||||
|
||||
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||
|
||||
protected:
|
||||
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
|
||||
|
||||
private:
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
static std::shared_ptr<MaterialSettings> s_depthMaterialSettings;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DepthMaterial.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_DEPTHMATERIAL_HPP
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderElementOwner.hpp>
|
||||
@@ -24,7 +25,6 @@ namespace Nz
|
||||
class ElementRendererRegistry;
|
||||
class FrameGraph;
|
||||
class FramePipeline;
|
||||
class Material;
|
||||
|
||||
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
|
||||
{
|
||||
@@ -32,17 +32,17 @@ namespace Nz
|
||||
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
|
||||
DepthPipelinePass(const DepthPipelinePass&) = delete;
|
||||
DepthPipelinePass(DepthPipelinePass&&) = delete;
|
||||
~DepthPipelinePass();
|
||||
~DepthPipelinePass() = default;
|
||||
|
||||
inline void InvalidateCommandBuffers();
|
||||
inline void InvalidateElements();
|
||||
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
|
||||
|
||||
void RegisterMaterial(const Material& material);
|
||||
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex);
|
||||
|
||||
void UnregisterMaterial(const Material& material);
|
||||
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
|
||||
DepthPipelinePass& operator=(const DepthPipelinePass&) = delete;
|
||||
DepthPipelinePass& operator=(DepthPipelinePass&&) = delete;
|
||||
@@ -52,8 +52,8 @@ namespace Nz
|
||||
{
|
||||
std::size_t usedCount = 1;
|
||||
|
||||
NazaraSlot(MaterialPass, OnMaterialPassPipelineInvalidated, onMaterialPipelineInvalidated);
|
||||
NazaraSlot(MaterialPass, OnMaterialPassShaderBindingInvalidated, onMaterialShaderBindingInvalidated);
|
||||
NazaraSlot(MaterialInstance, OnMaterialInstancePipelineInvalidated, onMaterialInstancePipelineInvalidated);
|
||||
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
|
||||
};
|
||||
|
||||
std::size_t m_depthPassIndex;
|
||||
@@ -61,7 +61,7 @@ namespace Nz
|
||||
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
std::vector<RenderElementOwner> m_renderElements;
|
||||
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
|
||||
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
|
||||
RenderQueue<const RenderElement*> m_renderQueue;
|
||||
RenderQueueRegistry m_renderQueueRegistry;
|
||||
AbstractViewer* m_viewer;
|
||||
|
||||
@@ -41,6 +41,27 @@ namespace Nz
|
||||
Volume
|
||||
};
|
||||
|
||||
enum class MaterialPropertyType
|
||||
{
|
||||
Bool,
|
||||
Bool2,
|
||||
Bool3,
|
||||
Bool4,
|
||||
Color,
|
||||
Float,
|
||||
Float2,
|
||||
Float3,
|
||||
Float4,
|
||||
Int,
|
||||
Int2,
|
||||
Int3,
|
||||
Int4,
|
||||
UInt,
|
||||
UInt2,
|
||||
UInt3,
|
||||
UInt4
|
||||
};
|
||||
|
||||
enum class MaterialLightingType
|
||||
{
|
||||
None,
|
||||
@@ -69,7 +90,7 @@ namespace Nz
|
||||
Perspective
|
||||
};
|
||||
|
||||
enum class PredefinedShaderBinding
|
||||
enum class EngineShaderBinding
|
||||
{
|
||||
InstanceDataUbo,
|
||||
LightDataUbo,
|
||||
@@ -80,7 +101,7 @@ namespace Nz
|
||||
Max = ViewerDataUbo
|
||||
};
|
||||
|
||||
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(PredefinedShaderBinding::Max) + 1;
|
||||
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(EngineShaderBinding::Max) + 1;
|
||||
}
|
||||
|
||||
#endif // NAZARA_GRAPHICS_ENUMS_HPP
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderQueue.hpp>
|
||||
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <Nazara/Utils/MemoryPool.hpp>
|
||||
#include <memory>
|
||||
@@ -42,12 +43,7 @@ namespace Nz
|
||||
ForwardFramePipeline(ForwardFramePipeline&&) = delete;
|
||||
~ForwardFramePipeline();
|
||||
|
||||
void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) override;
|
||||
void InvalidateViewer(std::size_t viewerIndex) override;
|
||||
void InvalidateWorldInstance(std::size_t renderableIndex) override;
|
||||
|
||||
std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) override;
|
||||
void RegisterMaterialPass(MaterialPass* materialPass) override;
|
||||
std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) override;
|
||||
std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) override;
|
||||
std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) override;
|
||||
@@ -56,7 +52,6 @@ namespace Nz
|
||||
void Render(RenderFrame& renderFrame) override;
|
||||
|
||||
void UnregisterLight(std::size_t lightIndex) override;
|
||||
void UnregisterMaterialPass(MaterialPass* material) override;
|
||||
void UnregisterRenderable(std::size_t renderableIndex) override;
|
||||
void UnregisterSkeleton(std::size_t skeletonIndex) override;
|
||||
void UnregisterViewer(std::size_t viewerIndex) override;
|
||||
@@ -73,6 +68,9 @@ namespace Nz
|
||||
private:
|
||||
BakedFrameGraph BuildFrameGraph();
|
||||
|
||||
void RegisterMaterialInstance(MaterialInstance* materialPass);
|
||||
void UnregisterMaterialInstance(MaterialInstance* material);
|
||||
|
||||
struct ViewerData;
|
||||
|
||||
struct LightData
|
||||
@@ -83,11 +81,11 @@ namespace Nz
|
||||
NazaraSlot(Light, OnLightDataInvalided, onLightInvalidated);
|
||||
};
|
||||
|
||||
struct MaterialPassData
|
||||
struct MaterialInstanceData
|
||||
{
|
||||
std::size_t usedCount = 0;
|
||||
|
||||
NazaraSlot(MaterialPass, OnMaterialPassInvalidated, onMaterialPassInvalided);
|
||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||
};
|
||||
|
||||
struct RenderableData
|
||||
@@ -109,6 +107,13 @@ namespace Nz
|
||||
ShaderBindingPtr blitShaderBinding;
|
||||
};
|
||||
|
||||
struct SkeletonInstanceData
|
||||
{
|
||||
SkeletonInstancePtr skeleton;
|
||||
|
||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||
};
|
||||
|
||||
struct ViewerData
|
||||
{
|
||||
std::size_t forwardColorAttachment;
|
||||
@@ -122,27 +127,33 @@ namespace Nz
|
||||
RenderQueueRegistry forwardRegistry;
|
||||
RenderQueue<RenderElement*> forwardRenderQueue;
|
||||
ShaderBindingPtr blitShaderBinding;
|
||||
|
||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||
};
|
||||
|
||||
struct WorldInstanceData
|
||||
{
|
||||
WorldInstancePtr worldInstance;
|
||||
|
||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||
};
|
||||
|
||||
std::unordered_map<MaterialPass*, MaterialPassData> m_activeMaterialPasses;
|
||||
std::unordered_map<const RenderTarget*, RenderTargetData> m_renderTargets;
|
||||
std::unordered_set<MaterialPass*> m_invalidatedMaterialPasses;
|
||||
std::unordered_map<MaterialInstance*, MaterialInstanceData> m_materialInstances;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
std::vector<FramePipelinePass::VisibleRenderable> m_visibleRenderables;
|
||||
std::vector<const Light*> m_visibleLights;
|
||||
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
||||
BakedFrameGraph m_bakedFrameGraph;
|
||||
Bitset<UInt64> m_invalidatedSkeletonInstances;
|
||||
Bitset<UInt64> m_invalidatedViewerInstances;
|
||||
Bitset<UInt64> m_invalidatedWorldInstances;
|
||||
Bitset<UInt64> m_removedSkeletonInstances;
|
||||
Bitset<UInt64> m_removedViewerInstances;
|
||||
Bitset<UInt64> m_removedWorldInstances;
|
||||
ElementRendererRegistry& m_elementRegistry;
|
||||
MemoryPool<RenderableData> m_renderablePool;
|
||||
MemoryPool<LightData> m_lightPool;
|
||||
MemoryPool<SkeletonInstancePtr> m_skeletonInstances;
|
||||
MemoryPool<SkeletonInstanceData> m_skeletonInstances;
|
||||
MemoryPool<ViewerData> m_viewerPool;
|
||||
MemoryPool<WorldInstancePtr> m_worldInstances;
|
||||
MemoryPool<WorldInstanceData> m_worldInstances;
|
||||
RenderFrame* m_currentRenderFrame;
|
||||
bool m_rebuildFrameGraph;
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <Nazara/Graphics/Light.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderElementOwner.hpp>
|
||||
@@ -27,7 +28,6 @@ namespace Nz
|
||||
class FrameGraph;
|
||||
class FramePipeline;
|
||||
class Light;
|
||||
class Material;
|
||||
|
||||
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass
|
||||
{
|
||||
@@ -35,17 +35,17 @@ namespace Nz
|
||||
ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
|
||||
ForwardPipelinePass(const ForwardPipelinePass&) = delete;
|
||||
ForwardPipelinePass(ForwardPipelinePass&&) = delete;
|
||||
~ForwardPipelinePass();
|
||||
~ForwardPipelinePass() = default;
|
||||
|
||||
inline void InvalidateCommandBuffers();
|
||||
inline void InvalidateElements();
|
||||
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<const Light*>& visibleLights, std::size_t visibilityHash);
|
||||
|
||||
void RegisterMaterial(const Material& material);
|
||||
void RegisterMaterialInstance(const MaterialInstance& material);
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
|
||||
|
||||
void UnregisterMaterial(const Material& material);
|
||||
void UnregisterMaterialInstance(const MaterialInstance& material);
|
||||
|
||||
ForwardPipelinePass& operator=(const ForwardPipelinePass&) = delete;
|
||||
ForwardPipelinePass& operator=(ForwardPipelinePass&&) = delete;
|
||||
@@ -57,8 +57,8 @@ namespace Nz
|
||||
{
|
||||
std::size_t usedCount = 1;
|
||||
|
||||
NazaraSlot(MaterialPass, OnMaterialPassPipelineInvalidated, onMaterialPipelineInvalidated);
|
||||
NazaraSlot(MaterialPass, OnMaterialPassShaderBindingInvalidated, onMaterialShaderBindingInvalidated);
|
||||
NazaraSlot(MaterialInstance, OnMaterialInstancePipelineInvalidated, onMaterialInstancePipelineInvalidated);
|
||||
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
|
||||
};
|
||||
|
||||
using LightKey = std::array<const Light*, MaxLightCountPerDraw>;
|
||||
@@ -86,7 +86,7 @@ namespace Nz
|
||||
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
std::vector<RenderElementOwner> m_renderElements;
|
||||
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
|
||||
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
|
||||
std::unordered_map<const RenderElement*, RenderBufferView> m_lightPerRenderElement;
|
||||
std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights;
|
||||
std::vector<LightDataUbo> m_lightDataBuffers;
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Nz
|
||||
class AbstractViewer;
|
||||
class InstancedRenderable;
|
||||
class Light;
|
||||
class MaterialPass;
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API FramePipeline
|
||||
@@ -34,12 +33,7 @@ namespace Nz
|
||||
|
||||
inline DebugDrawer& GetDebugDrawer();
|
||||
|
||||
virtual void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) = 0;
|
||||
virtual void InvalidateViewer(std::size_t viewerIndex) = 0;
|
||||
virtual void InvalidateWorldInstance(std::size_t worldInstance) = 0;
|
||||
|
||||
virtual std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) = 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 RegisterSkeleton(SkeletonInstancePtr skeletonInstance) = 0;
|
||||
virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) = 0;
|
||||
@@ -48,7 +42,6 @@ namespace Nz
|
||||
virtual void Render(RenderFrame& renderFrame) = 0;
|
||||
|
||||
virtual void UnregisterLight(std::size_t lightIndex) = 0;
|
||||
virtual void UnregisterMaterialPass(MaterialPass* materialPass) = 0;
|
||||
virtual void UnregisterRenderable(std::size_t renderableIndex) = 0;
|
||||
virtual void UnregisterSkeleton(std::size_t skeletonIndex) = 0;
|
||||
virtual void UnregisterViewer(std::size_t viewerIndex) = 0;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
@@ -43,8 +44,10 @@ namespace Nz
|
||||
inline const DefaultTextures& GetDefaultTextures() const;
|
||||
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
||||
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
||||
MaterialLoader& GetMaterialLoader();
|
||||
const MaterialLoader& GetMaterialLoader() const;
|
||||
inline MaterialInstanceLoader& GetMaterialInstanceLoader();
|
||||
inline const MaterialInstanceLoader& GetMaterialInstanceLoader() const;
|
||||
inline MaterialLoader& GetMaterialLoader();
|
||||
inline const MaterialLoader& GetMaterialLoader() const;
|
||||
inline PixelFormat GetPreferredDepthStencilFormat() const;
|
||||
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
||||
inline const RenderPassCache& GetRenderPassCache() const;
|
||||
@@ -59,8 +62,13 @@ namespace Nz
|
||||
|
||||
struct DefaultMaterials
|
||||
{
|
||||
std::shared_ptr<Material> depthMaterial;
|
||||
std::shared_ptr<Material> noDepthMaterial;
|
||||
std::shared_ptr<Material> basicMaterial;
|
||||
std::shared_ptr<Material> phongMaterial;
|
||||
std::shared_ptr<Material> pbrMaterial;
|
||||
|
||||
std::shared_ptr<MaterialInstance> basicDefault;
|
||||
std::shared_ptr<MaterialInstance> basicNoDepth;
|
||||
std::shared_ptr<MaterialInstance> basicTransparent;
|
||||
};
|
||||
|
||||
struct DefaultTextures
|
||||
@@ -86,6 +94,7 @@ namespace Nz
|
||||
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
||||
DefaultMaterials m_defaultMaterials;
|
||||
DefaultTextures m_defaultTextures;
|
||||
MaterialInstanceLoader m_materialInstanceLoader;
|
||||
MaterialLoader m_materialLoader;
|
||||
MaterialPassRegistry m_materialPassRegistry;
|
||||
PixelFormat m_preferredDepthStencilFormat;
|
||||
|
||||
@@ -37,6 +37,16 @@ namespace Nz
|
||||
return m_materialPassRegistry;
|
||||
}
|
||||
|
||||
inline MaterialInstanceLoader& Graphics::GetMaterialInstanceLoader()
|
||||
{
|
||||
return m_materialInstanceLoader;
|
||||
}
|
||||
|
||||
inline const MaterialInstanceLoader& Graphics::GetMaterialInstanceLoader() const
|
||||
{
|
||||
return m_materialInstanceLoader;
|
||||
}
|
||||
|
||||
inline MaterialLoader& Graphics::GetMaterialLoader()
|
||||
{
|
||||
return m_materialLoader;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class ElementRendererRegistry;
|
||||
class Material;
|
||||
class MaterialInstance;
|
||||
class RenderElement;
|
||||
class SkeletonInstance;
|
||||
class WorldInstance;
|
||||
@@ -36,7 +36,7 @@ namespace Nz
|
||||
virtual void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const = 0;
|
||||
|
||||
inline const Boxf& GetAABB() const;
|
||||
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
|
||||
virtual const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i) const = 0;
|
||||
virtual std::size_t GetMaterialCount() const = 0;
|
||||
inline int GetRenderLayer() const;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Nz
|
||||
|
||||
NazaraSignal(OnAABBUpdate, InstancedRenderable* /*instancedRenderable*/, const Boxf& /*aabb*/);
|
||||
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<MaterialInstance>& /*newMaterial*/);
|
||||
|
||||
struct ElementData
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Nz
|
||||
enum class Orientation;
|
||||
struct Section;
|
||||
|
||||
LinearSlicedSprite(std::shared_ptr<Material> material, Orientation orientation);
|
||||
LinearSlicedSprite(std::shared_ptr<MaterialInstance> material, Orientation orientation);
|
||||
LinearSlicedSprite(const LinearSlicedSprite&) = delete;
|
||||
LinearSlicedSprite(LinearSlicedSprite&&) noexcept = default;
|
||||
~LinearSlicedSprite() = default;
|
||||
@@ -35,7 +35,7 @@ namespace Nz
|
||||
inline void Clear();
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
|
||||
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
|
||||
std::size_t GetMaterialCount() const override;
|
||||
inline Orientation GetOrientation() const;
|
||||
inline const Section& GetSection(std::size_t sectionIndex) const;
|
||||
@@ -46,7 +46,7 @@ namespace Nz
|
||||
inline void RemoveSection(std::size_t sectionIndex);
|
||||
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetSection(std::size_t sectionIndex, float size, float textureCoord);
|
||||
inline void SetSectionSize(std::size_t sectionIndex, float size);
|
||||
inline void SetSectionTextureCoord(std::size_t sectionIndex, float textureCoord);
|
||||
@@ -76,7 +76,7 @@ namespace Nz
|
||||
|
||||
std::array<Section, MaxSection> m_sections;
|
||||
std::array<VertexStruct_XYZ_Color_UV, 4 * MaxSection> m_vertices;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::size_t m_sectionCount;
|
||||
std::size_t m_spriteCount;
|
||||
Color m_color;
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Nz
|
||||
UpdateVertices();
|
||||
}
|
||||
|
||||
inline void LinearSlicedSprite::SetMaterial(std::shared_ptr<Material> material)
|
||||
inline void LinearSlicedSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
assert(material);
|
||||
|
||||
|
||||
@@ -14,50 +14,91 @@
|
||||
#include <Nazara/Core/ResourceSaver.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
#include <Nazara/Graphics/RenderBufferPool.hpp>
|
||||
#include <Nazara/Graphics/ShaderReflection.hpp>
|
||||
#include <NZSL/Ast/Module.hpp>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct NAZARA_GRAPHICS_API MaterialParams : ResourceParameters
|
||||
{
|
||||
MaterialLightingType lightingType = MaterialLightingType::None;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class Material;
|
||||
class MaterialPass;
|
||||
class MaterialInstance;
|
||||
class RenderPipelineLayout;
|
||||
|
||||
using MaterialLibrary = ObjectLibrary<Material>;
|
||||
using MaterialLoader = ResourceLoader<Material, MaterialParams>;
|
||||
using MaterialManager = ResourceManager<Material, MaterialParams>;
|
||||
using MaterialSaver = ResourceSaver<Material, MaterialParams>;
|
||||
|
||||
class NAZARA_GRAPHICS_API Material : public Resource
|
||||
class NAZARA_GRAPHICS_API Material : public Resource, public std::enable_shared_from_this<Material>
|
||||
{
|
||||
public:
|
||||
Material() = default;
|
||||
struct TextureData;
|
||||
struct UniformBlockData;
|
||||
|
||||
Material(MaterialSettings settings, const std::string& referenceModuleName);
|
||||
Material(MaterialSettings settings, const nzsl::Ast::ModulePtr& referenceModule);
|
||||
~Material() = default;
|
||||
|
||||
inline void AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass);
|
||||
void AddPass(std::string passName, std::shared_ptr<MaterialPass> pass);
|
||||
std::shared_ptr<MaterialInstance> CreateInstance() const;
|
||||
|
||||
const std::shared_ptr<MaterialPass>& FindPass(const std::string& passName) const;
|
||||
std::shared_ptr<MaterialInstance> GetDefaultInstance() const;
|
||||
|
||||
template<typename F> void ForEachPass(F&& callback);
|
||||
inline std::size_t FindTextureByTag(const std::string& tag) const;
|
||||
inline std::size_t FindUniformBlockByTag(const std::string& tag) const;
|
||||
|
||||
inline const std::shared_ptr<MaterialPass>& GetPass(std::size_t passIndex) const;
|
||||
|
||||
inline bool HasPass(std::size_t passIndex) const;
|
||||
|
||||
inline void RemovePass(std::size_t passIndex);
|
||||
void RemovePass(const std::string& passName);
|
||||
inline UInt32 GetEngineBindingIndex(EngineShaderBinding shaderBinding) const;
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
||||
inline const MaterialSettings& GetSettings() const;
|
||||
inline const TextureData& GetTextureData(std::size_t textureIndex) const;
|
||||
inline std::size_t GetTextureCount() const;
|
||||
inline const UniformBlockData& GetUniformBlockData(std::size_t uniformBlockIndex) const;
|
||||
inline std::size_t GetUniformBlockCount() const;
|
||||
|
||||
static std::shared_ptr<Material> Build(const ParameterList& materialData);
|
||||
static std::shared_ptr<Material> LoadFromFile(const std::filesystem::path& filePath, const MaterialParams& params = MaterialParams());
|
||||
static std::shared_ptr<Material> LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams());
|
||||
static std::shared_ptr<Material> LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams());
|
||||
|
||||
static inline ImageType ToImageType(nzsl::ImageType imageType);
|
||||
|
||||
static constexpr UInt32 InvalidBindingIndex = std::numeric_limits<UInt32>::max();
|
||||
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct TextureData
|
||||
{
|
||||
UInt32 bindingSet;
|
||||
UInt32 bindingIndex;
|
||||
ImageType imageType;
|
||||
};
|
||||
|
||||
struct UniformBlockData
|
||||
{
|
||||
UInt32 bindingSet;
|
||||
UInt32 bindingIndex;
|
||||
std::size_t structIndex;
|
||||
std::unique_ptr<RenderBufferPool> bufferPool;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<MaterialPass>> m_passes;
|
||||
std::array<UInt32, PredefinedShaderBindingCount> m_engineShaderBindings;
|
||||
std::shared_ptr<RenderPipelineLayout> m_renderPipelineLayout;
|
||||
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> m_optionValues;
|
||||
std::unordered_map<std::string /*tag*/, std::size_t> m_textureByTag;
|
||||
std::unordered_map<std::string /*tag*/, std::size_t> m_uniformBlockByTag;
|
||||
std::vector<TextureData> m_textures;
|
||||
std::vector<UniformBlockData> m_uniformBlocks;
|
||||
mutable std::weak_ptr<MaterialInstance> m_defaultInstance;
|
||||
MaterialSettings m_settings;
|
||||
ShaderReflection m_reflection;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,49 +7,75 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void Material::AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass)
|
||||
inline std::size_t Material::FindTextureByTag(const std::string& tag) const
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
m_passes.resize(passIndex + 1);
|
||||
auto it = m_textureByTag.find(tag);
|
||||
if (it == m_textureByTag.end())
|
||||
return InvalidIndex;
|
||||
|
||||
m_passes[passIndex] = std::move(pass);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Material::ForEachPass(F&& callback)
|
||||
inline std::size_t Material::FindUniformBlockByTag(const std::string& tag) const
|
||||
{
|
||||
for (std::size_t i = 0; i < m_passes.size(); ++i)
|
||||
{
|
||||
if (m_passes[i])
|
||||
callback(i, m_passes[i]);
|
||||
}
|
||||
auto it = m_uniformBlockByTag.find(tag);
|
||||
if (it == m_uniformBlockByTag.end())
|
||||
return InvalidIndex;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<MaterialPass>& Material::GetPass(std::size_t passIndex) const
|
||||
inline UInt32 Material::GetEngineBindingIndex(EngineShaderBinding shaderBinding) const
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
return m_engineShaderBindings[UnderlyingCast(shaderBinding)];
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& Material::GetRenderPipelineLayout() const
|
||||
{
|
||||
return m_renderPipelineLayout;
|
||||
}
|
||||
|
||||
inline const MaterialSettings& Material::GetSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
inline auto Material::GetTextureData(std::size_t textureIndex) const -> const TextureData&
|
||||
{
|
||||
assert(textureIndex < m_textures.size());
|
||||
return m_textures[textureIndex];
|
||||
}
|
||||
|
||||
inline std::size_t Material::GetTextureCount() const
|
||||
{
|
||||
return m_textures.size();
|
||||
}
|
||||
|
||||
inline auto Material::GetUniformBlockData(std::size_t uniformBlockIndex) const -> const UniformBlockData&
|
||||
{
|
||||
assert(uniformBlockIndex < m_uniformBlocks.size());
|
||||
return m_uniformBlocks[uniformBlockIndex];
|
||||
}
|
||||
|
||||
inline std::size_t Material::GetUniformBlockCount() const
|
||||
{
|
||||
return m_uniformBlocks.size();
|
||||
}
|
||||
|
||||
inline ImageType Material::ToImageType(nzsl::ImageType imageType)
|
||||
{
|
||||
switch (imageType)
|
||||
{
|
||||
static std::shared_ptr<MaterialPass> dummy;
|
||||
return dummy;
|
||||
case nzsl::ImageType::E1D: return ImageType::E1D;
|
||||
case nzsl::ImageType::E1D_Array: return ImageType::E1D_Array;
|
||||
case nzsl::ImageType::E2D: return ImageType::E2D;
|
||||
case nzsl::ImageType::E2D_Array: return ImageType::E2D_Array;
|
||||
case nzsl::ImageType::E3D: return ImageType::E3D;
|
||||
case nzsl::ImageType::Cubemap: return ImageType::Cubemap;
|
||||
}
|
||||
|
||||
return m_passes[passIndex];
|
||||
}
|
||||
|
||||
inline bool Material::HasPass(std::size_t passIndex) const
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
return false;
|
||||
|
||||
return m_passes[passIndex] != nullptr;
|
||||
}
|
||||
|
||||
inline void Material::RemovePass(std::size_t passIndex)
|
||||
{
|
||||
if (passIndex >= m_passes.size())
|
||||
return;
|
||||
|
||||
m_passes[passIndex].reset();
|
||||
NazaraError("invalid image type 0x" + NumberToString(UnderlyingCast(imageType), 16));
|
||||
return ImageType::E2D;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
165
include/Nazara/Graphics/MaterialInstance.hpp
Normal file
165
include/Nazara/Graphics/MaterialInstance.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
// 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_MATERIALINSTANCE_HPP
|
||||
#define NAZARA_GRAPHICS_MATERIALINSTANCE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Renderer/RenderBufferView.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <Nazara/Utils/FunctionRef.hpp>
|
||||
#include <NZSL/Ast/ConstantValue.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct NAZARA_GRAPHICS_API MaterialInstanceParams : ResourceParameters
|
||||
{
|
||||
MaterialLightingType lightingType = MaterialLightingType::None;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class Material;
|
||||
class MaterialInstance;
|
||||
class MaterialPipeline;
|
||||
class Texture;
|
||||
|
||||
using MaterialInstanceLibrary = ObjectLibrary<MaterialInstance>;
|
||||
using MaterialInstanceLoader = ResourceLoader<MaterialInstance, MaterialInstanceParams>;
|
||||
using MaterialInstanceManager = ResourceManager<MaterialInstance, MaterialInstanceParams>;
|
||||
using MaterialInstanceSaver = ResourceSaver<MaterialInstance, MaterialInstanceParams>;
|
||||
|
||||
class NAZARA_GRAPHICS_API MaterialInstance : public TransferInterface
|
||||
{
|
||||
struct CopyToken {};
|
||||
|
||||
public:
|
||||
MaterialInstance(std::shared_ptr<const Material> parent);
|
||||
MaterialInstance(const MaterialInstance&) = delete;
|
||||
MaterialInstance(const MaterialInstance& material, CopyToken);
|
||||
MaterialInstance(MaterialInstance&&) = delete;
|
||||
~MaterialInstance();
|
||||
|
||||
inline std::shared_ptr<MaterialInstance> Clone() const;
|
||||
|
||||
void DisablePass(std::string_view passName);
|
||||
inline void DisablePass(std::size_t passIndex);
|
||||
void EnablePass(std::string_view passName, bool enable = true);
|
||||
inline void EnablePass(std::size_t passIndex, bool enable = true);
|
||||
|
||||
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
|
||||
|
||||
inline std::size_t FindTextureProperty(std::string_view propertyName) const;
|
||||
inline std::size_t FindValueProperty(std::string_view propertyName) const;
|
||||
|
||||
inline const std::shared_ptr<const Material>& GetParentMaterial() const;
|
||||
inline MaterialPassFlags GetPassFlags(std::size_t passIndex) const;
|
||||
const std::shared_ptr<MaterialPipeline>& GetPipeline(std::size_t passIndex) const;
|
||||
|
||||
inline const std::shared_ptr<Texture>* GetTextureProperty(std::string_view propertyName) const;
|
||||
inline const std::shared_ptr<Texture>& GetTextureProperty(std::size_t textureIndex) const;
|
||||
inline const std::shared_ptr<Texture>& GetTexturePropertyOverride(std::size_t textureIndex) const;
|
||||
|
||||
inline const TextureSamplerInfo* GetTextureSamplerProperty(std::string_view propertyName) const;
|
||||
inline const TextureSamplerInfo& GetTextureSamplerProperty(std::size_t textureIndex) const;
|
||||
|
||||
inline const MaterialSettings::Value* GetValueProperty(std::string_view propertyName) const;
|
||||
inline const MaterialSettings::Value& GetValueProperty(std::size_t valueIndex) const;
|
||||
inline const MaterialSettings::Value& GetValuePropertyOverride(std::size_t valueIndex) const;
|
||||
|
||||
bool HasPass(std::string_view passName) const;
|
||||
inline bool HasPass(std::size_t passIndex) const;
|
||||
|
||||
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
|
||||
|
||||
inline void SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture);
|
||||
inline void SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo);
|
||||
void SetTextureProperty(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||
void SetTextureProperty(std::size_t textureIndex, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo);
|
||||
|
||||
inline void SetTextureSamplerProperty(std::string_view propertyName, const TextureSamplerInfo& samplerInfo);
|
||||
void SetTextureSamplerProperty(std::size_t textureIndex, const TextureSamplerInfo& samplerInfo);
|
||||
|
||||
inline void SetValueProperty(std::string_view propertyName, const MaterialSettings::Value& value);
|
||||
void SetValueProperty(std::size_t valueIndex, const MaterialSettings::Value& value);
|
||||
|
||||
void UpdateOptionValue(UInt32 optionHash, const nzsl::Ast::ConstantSingleValue& value);
|
||||
void UpdatePassFlags(std::string_view passName, MaterialPassFlags materialFlags);
|
||||
inline void UpdatePassFlags(std::size_t passName, MaterialPassFlags materialFlags);
|
||||
void UpdatePassStates(std::string_view passName, FunctionRef<bool(RenderStates&)> stateUpdater);
|
||||
template<typename F> void UpdatePassStates(std::size_t passIndex, F&& stateUpdater);
|
||||
void UpdateTextureBinding(std::size_t textureBinding, std::shared_ptr<Texture> texture, std::shared_ptr<TextureSampler> textureSampler);
|
||||
void UpdateUniformBufferData(std::size_t uniformBufferIndex, std::size_t offset, std::size_t size, const void* data);
|
||||
|
||||
MaterialInstance& operator=(const MaterialInstance&) = delete;
|
||||
MaterialInstance& operator=(MaterialInstance&&) = delete;
|
||||
|
||||
static constexpr std::size_t InvalidPropertyIndex = MaterialSettings::InvalidPropertyIndex;
|
||||
|
||||
NazaraSignal(OnMaterialInstancePipelineInvalidated, const MaterialInstance* /*matInstance*/, std::size_t /*passIndex*/);
|
||||
NazaraSignal(OnMaterialInstanceShaderBindingInvalidated, const MaterialInstance* /*matInstance*/);
|
||||
|
||||
private:
|
||||
inline void InvalidatePassPipeline(std::size_t passIndex);
|
||||
inline void InvalidateShaderBinding();
|
||||
|
||||
struct PassShader
|
||||
{
|
||||
std::shared_ptr<UberShader> shader;
|
||||
|
||||
NazaraSlot(UberShader, OnShaderUpdated, onShaderUpdated);
|
||||
};
|
||||
|
||||
struct PassData
|
||||
{
|
||||
mutable MaterialPipelineInfo pipelineInfo;
|
||||
mutable std::shared_ptr<MaterialPipeline> pipeline;
|
||||
std::vector<PassShader> shaders;
|
||||
MaterialPassFlags flags;
|
||||
bool enabled = false;
|
||||
};
|
||||
|
||||
struct TextureBinding
|
||||
{
|
||||
std::shared_ptr<Texture> texture;
|
||||
std::shared_ptr<TextureSampler> sampler;
|
||||
};
|
||||
|
||||
struct TextureProperty
|
||||
{
|
||||
std::shared_ptr<Texture> texture;
|
||||
TextureSamplerInfo samplerInfo;
|
||||
};
|
||||
|
||||
struct UniformBuffer
|
||||
{
|
||||
std::size_t bufferIndex;
|
||||
std::vector<UInt8> values;
|
||||
RenderBufferView bufferView;
|
||||
bool dataInvalidated = true;
|
||||
};
|
||||
|
||||
std::shared_ptr<const Material> m_parent;
|
||||
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> m_optionValuesOverride;
|
||||
std::vector<MaterialSettings::Value> m_valueOverride;
|
||||
std::vector<PassData> m_passes;
|
||||
std::vector<TextureBinding> m_textureBinding;
|
||||
std::vector<TextureProperty> m_textureOverride;
|
||||
std::vector<UniformBuffer> m_uniformBuffers;
|
||||
const MaterialSettings& m_materialSettings;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/MaterialInstance.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_MATERIALINSTANCE_HPP
|
||||
216
include/Nazara/Graphics/MaterialInstance.inl
Normal file
216
include/Nazara/Graphics/MaterialInstance.inl
Normal file
@@ -0,0 +1,216 @@
|
||||
// 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/MaterialInstance.hpp>
|
||||
#include <type_traits>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::shared_ptr<MaterialInstance> MaterialInstance::Clone() const
|
||||
{
|
||||
return std::make_shared<MaterialInstance>(*this, CopyToken{});
|
||||
}
|
||||
|
||||
inline void MaterialInstance::DisablePass(std::size_t passIndex)
|
||||
{
|
||||
EnablePass(passIndex, false);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::EnablePass(std::size_t passIndex, bool enable)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
if (m_passes[passIndex].enabled != enable)
|
||||
{
|
||||
m_passes[passIndex].enabled = enable;
|
||||
InvalidatePassPipeline(passIndex);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::size_t MaterialInstance::FindTextureProperty(std::string_view propertyName) const
|
||||
{
|
||||
return m_materialSettings.FindTextureProperty(propertyName);
|
||||
}
|
||||
|
||||
inline std::size_t MaterialInstance::FindValueProperty(std::string_view propertyName) const
|
||||
{
|
||||
return m_materialSettings.FindValueProperty(propertyName);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<const Material>& MaterialInstance::GetParentMaterial() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
inline MaterialPassFlags MaterialInstance::GetPassFlags(std::size_t passIndex) const
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
return m_passes[passIndex].flags;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>* MaterialInstance::GetTextureProperty(std::string_view propertyName) const
|
||||
{
|
||||
std::size_t propertyIndex = FindTextureProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no texture property named " + std::string(propertyName));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &GetTextureProperty(propertyIndex);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& MaterialInstance::GetTextureProperty(std::size_t textureIndex) const
|
||||
{
|
||||
if (const std::shared_ptr<Texture>& textureOverride = GetTexturePropertyOverride(textureIndex))
|
||||
return textureOverride;
|
||||
else
|
||||
return m_materialSettings.GetTextureProperty(textureIndex).defaultTexture;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& MaterialInstance::GetTexturePropertyOverride(std::size_t textureIndex) const
|
||||
{
|
||||
assert(textureIndex < m_textureOverride.size());
|
||||
return m_textureOverride[textureIndex].texture;
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo* MaterialInstance::GetTextureSamplerProperty(std::string_view propertyName) const
|
||||
{
|
||||
std::size_t propertyIndex = FindTextureProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no texture property named " + std::string(propertyName));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &GetTextureSamplerProperty(propertyIndex);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& MaterialInstance::GetTextureSamplerProperty(std::size_t textureIndex) const
|
||||
{
|
||||
assert(textureIndex < m_textureOverride.size());
|
||||
return m_textureOverride[textureIndex].samplerInfo;
|
||||
}
|
||||
|
||||
inline const MaterialSettings::Value* MaterialInstance::GetValueProperty(std::string_view propertyName) const
|
||||
{
|
||||
std::size_t propertyIndex = FindValueProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no value property named " + std::string(propertyName));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &GetValueProperty(propertyIndex);
|
||||
}
|
||||
|
||||
inline const MaterialSettings::Value& MaterialInstance::GetValueProperty(std::size_t valueIndex) const
|
||||
{
|
||||
if (const MaterialSettings::Value& valueOverride = GetValuePropertyOverride(valueIndex); !std::holds_alternative<MaterialPropertyNoValue>(valueOverride))
|
||||
return valueOverride;
|
||||
else
|
||||
return m_materialSettings.GetValueProperty(valueIndex).defaultValue;
|
||||
}
|
||||
|
||||
inline const MaterialSettings::Value& MaterialInstance::GetValuePropertyOverride(std::size_t valueIndex) const
|
||||
{
|
||||
assert(valueIndex < m_valueOverride.size());
|
||||
return m_valueOverride[valueIndex];
|
||||
}
|
||||
|
||||
inline bool MaterialInstance::HasPass(std::size_t passIndex) const
|
||||
{
|
||||
return passIndex < m_passes.size() && m_passes[passIndex].enabled;
|
||||
}
|
||||
|
||||
inline void MaterialInstance::SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture)
|
||||
{
|
||||
std::size_t propertyIndex = FindTextureProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no texture property named " + std::string(propertyName));
|
||||
return;
|
||||
}
|
||||
|
||||
return SetTextureProperty(propertyIndex, std::move(texture));
|
||||
}
|
||||
|
||||
inline void MaterialInstance::SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo)
|
||||
{
|
||||
std::size_t propertyIndex = FindTextureProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no texture property named " + std::string(propertyName));
|
||||
return;
|
||||
}
|
||||
|
||||
return SetTextureProperty(propertyIndex, std::move(texture), samplerInfo);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::SetTextureSamplerProperty(std::string_view propertyName, const TextureSamplerInfo& samplerInfo)
|
||||
{
|
||||
std::size_t propertyIndex = FindTextureProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no texture property named " + std::string(propertyName));
|
||||
return;
|
||||
}
|
||||
|
||||
return SetTextureSamplerProperty(propertyIndex, samplerInfo);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::SetValueProperty(std::string_view propertyName, const MaterialSettings::Value& value)
|
||||
{
|
||||
std::size_t propertyIndex = FindValueProperty(propertyName);
|
||||
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
|
||||
{
|
||||
NazaraError("material has no value property named " + std::string(propertyName));
|
||||
return;
|
||||
}
|
||||
|
||||
return SetValueProperty(propertyIndex, value);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::UpdatePassFlags(std::size_t passIndex, MaterialPassFlags materialFlags)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
if (m_passes[passIndex].flags != materialFlags)
|
||||
{
|
||||
m_passes[passIndex].flags = materialFlags;
|
||||
InvalidatePassPipeline(passIndex);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void MaterialInstance::UpdatePassStates(std::size_t passIndex, F&& stateUpdater)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
using Ret = std::invoke_result_t<F, RenderStates&>;
|
||||
if constexpr (std::is_same_v<Ret, bool>)
|
||||
{
|
||||
if (!stateUpdater(static_cast<RenderStates&>(m_passes[passIndex].pipelineInfo)))
|
||||
return;
|
||||
}
|
||||
else if constexpr (std::is_void_v<Ret>)
|
||||
stateUpdater(static_cast<RenderStates&>(m_passes[passIndex].pipelineInfo));
|
||||
else
|
||||
static_assert(AlwaysFalse<Ret>(), "callback must either return a bool or nothing");
|
||||
|
||||
InvalidatePassPipeline(passIndex);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::InvalidatePassPipeline(std::size_t passIndex)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
m_passes[passIndex].pipeline.reset();
|
||||
OnMaterialInstancePipelineInvalidated(this, passIndex);
|
||||
}
|
||||
|
||||
inline void MaterialInstance::InvalidateShaderBinding()
|
||||
{
|
||||
OnMaterialInstanceShaderBindingInvalidated(this);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -10,10 +10,6 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceManager.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
@@ -24,145 +20,19 @@
|
||||
#include <Nazara/Utils/Signal.hpp>
|
||||
#include <NZSL/Ast/ConstantValue.hpp>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API MaterialPass
|
||||
struct MaterialPass
|
||||
{
|
||||
public:
|
||||
MaterialPass(std::shared_ptr<const MaterialSettings> settings);
|
||||
MaterialPass(const MaterialPass&) = delete;
|
||||
MaterialPass(MaterialPass&&) = delete;
|
||||
inline ~MaterialPass();
|
||||
|
||||
inline void Configure(std::shared_ptr<MaterialPipeline> pipeline);
|
||||
inline void Configure(const MaterialPipelineInfo& pipelineInfo);
|
||||
|
||||
inline void EnableBlending(bool blending);
|
||||
inline void EnableColorWrite(bool colorWrite);
|
||||
inline void EnableDepthBuffer(bool depthBuffer);
|
||||
inline void EnableDepthClamp(bool depthClamp);
|
||||
inline void EnableDepthWrite(bool depthWrite);
|
||||
inline void EnableFaceCulling(bool faceCulling);
|
||||
inline void EnableFlag(MaterialPassFlag flag, bool enable = true);
|
||||
inline void EnableScissorTest(bool scissorTest);
|
||||
inline void EnableStencilTest(bool stencilTest);
|
||||
|
||||
inline void EnsurePipelineUpdate() const;
|
||||
|
||||
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
|
||||
|
||||
inline RendererComparison GetDepthCompareFunc() const;
|
||||
inline BlendEquation GetBlendAlphaModeEquation() const;
|
||||
inline BlendEquation GetBlendColorModeEquation() const;
|
||||
inline BlendFunc GetBlendDstAlphaFunc() const;
|
||||
inline BlendFunc GetBlendDstColorFunc() const;
|
||||
inline BlendFunc GetBlendSrcAlphaFunc() const;
|
||||
inline BlendFunc GetBlendSrcColorFunc() const;
|
||||
inline FaceSide GetFaceCulling() const;
|
||||
inline FaceFilling GetFaceFilling() const;
|
||||
inline MaterialPassFlags GetFlags() const;
|
||||
inline float GetLineWidth() const;
|
||||
inline const nzsl::Ast::ConstantSingleValue& GetOptionValue(std::size_t optionIndex) const;
|
||||
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
|
||||
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
||||
inline float GetPointSize() const;
|
||||
inline PrimitiveMode GetPrimitiveMode() const;
|
||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
||||
inline const std::shared_ptr<UberShader>& GetShader(nzsl::ShaderStageType shaderStage) const;
|
||||
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
|
||||
inline const std::shared_ptr<RenderBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
|
||||
inline const std::vector<UInt8>& GetUniformBufferConstData(std::size_t bufferIndex) const;
|
||||
inline std::vector<UInt8>& GetUniformBufferData(std::size_t bufferIndex);
|
||||
|
||||
inline bool HasTexture(std::size_t textureIndex) const;
|
||||
|
||||
inline bool IsBlendingEnabled() const;
|
||||
inline bool IsColorWriteEnabled() const;
|
||||
inline bool IsDepthBufferEnabled() const;
|
||||
inline bool IsDepthClampEnabled() const;
|
||||
inline bool IsDepthWriteEnabled() const;
|
||||
inline bool IsFaceCullingEnabled() const;
|
||||
inline bool IsFlagEnabled(MaterialPassFlag flag) const;
|
||||
inline bool IsScissorTestEnabled() const;
|
||||
inline bool IsStencilTestEnabled() const;
|
||||
|
||||
inline void SetDepthCompareFunc(RendererComparison depthFunc);
|
||||
inline void SetBlendEquation(BlendEquation colorMode, BlendEquation alphaMode);
|
||||
inline void SetBlendFunc(BlendFunc srcColor, BlendFunc dstColor, BlendFunc srcAlpha, BlendFunc dstAlpha);
|
||||
inline void SetFaceCulling(FaceSide faceSide);
|
||||
inline void SetFaceFilling(FaceFilling filling);
|
||||
inline void SetLineWidth(float lineWidth);
|
||||
inline void SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantSingleValue value);
|
||||
inline void SetPointSize(float pointSize);
|
||||
inline void SetPrimitiveMode(PrimitiveMode mode);
|
||||
inline void SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer);
|
||||
inline void SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer, UInt64 offset, UInt64 size);
|
||||
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||
inline void SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo);
|
||||
|
||||
void Update(RenderFrame& renderFrame, CommandBufferBuilder& builder);
|
||||
|
||||
MaterialPass& operator=(const MaterialPass&) = delete;
|
||||
MaterialPass& operator=(MaterialPass&&) = delete;
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnMaterialPassInvalidated, const MaterialPass* /*materialPass*/);
|
||||
NazaraSignal(OnMaterialPassPipelineInvalidated, const MaterialPass* /*materialPass*/);
|
||||
NazaraSignal(OnMaterialPassShaderBindingInvalidated, const MaterialPass* /*materialPass*/);
|
||||
NazaraSignal(OnMaterialPassRelease, const MaterialPass* /*materialPass*/);
|
||||
|
||||
private:
|
||||
inline void InvalidatePipeline();
|
||||
inline void InvalidateShaderBinding();
|
||||
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
||||
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
|
||||
void UpdatePipeline() const;
|
||||
|
||||
struct MaterialTexture
|
||||
{
|
||||
mutable std::shared_ptr<TextureSampler> sampler;
|
||||
std::shared_ptr<Texture> texture;
|
||||
TextureSamplerInfo samplerInfo;
|
||||
};
|
||||
|
||||
struct ShaderEntry
|
||||
{
|
||||
NazaraSlot(UberShader, OnShaderUpdated, onShaderUpdated);
|
||||
};
|
||||
|
||||
struct ShaderUniformBuffer
|
||||
{
|
||||
std::shared_ptr<RenderBuffer> buffer; //< kept for ownership
|
||||
RenderBufferView bufferView;
|
||||
};
|
||||
|
||||
struct UniformBuffer
|
||||
{
|
||||
std::shared_ptr<RenderBuffer> buffer;
|
||||
std::vector<UInt8> data;
|
||||
bool dataInvalidated = true;
|
||||
};
|
||||
|
||||
std::array<nzsl::Ast::ConstantSingleValue, 64> m_optionValues;
|
||||
std::shared_ptr<const MaterialSettings> m_settings;
|
||||
std::vector<MaterialTexture> m_textures;
|
||||
std::vector<ShaderEntry> m_shaders;
|
||||
std::vector<ShaderUniformBuffer> m_sharedUniformBuffers;
|
||||
std::vector<UniformBuffer> m_uniformBuffers;
|
||||
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
||||
mutable MaterialPipelineInfo m_pipelineInfo;
|
||||
MaterialPassFlags m_flags;
|
||||
mutable bool m_pipelineUpdated;
|
||||
MaterialPassFlags flags;
|
||||
RenderStates states;
|
||||
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> options;
|
||||
std::vector<std::shared_ptr<UberShader>> shaders;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/MaterialPass.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_MATERIALPASS_HPP
|
||||
|
||||
@@ -1,683 +0,0 @@
|
||||
// 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/MaterialPass.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \brief Destructs the object and calls OnMaterialRelease
|
||||
*
|
||||
* \see OnMaterialRelease
|
||||
*/
|
||||
inline MaterialPass::~MaterialPass()
|
||||
{
|
||||
OnMaterialPassRelease(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reset material pipeline state
|
||||
*
|
||||
* Sets the material pipeline
|
||||
*
|
||||
* \remark pipeline must be valid
|
||||
*
|
||||
* \see Configure
|
||||
*/
|
||||
inline void MaterialPass::Configure(std::shared_ptr<MaterialPipeline> pipeline)
|
||||
{
|
||||
NazaraAssert(pipeline, "Invalid material pipeline");
|
||||
|
||||
m_pipeline = std::move(pipeline);
|
||||
m_pipelineInfo = m_pipeline->GetInfo();
|
||||
m_pipelineUpdated = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reset material pipeline state
|
||||
*
|
||||
* Sets the material pipeline using pipeline info
|
||||
*
|
||||
* \remark pipeline must be valid
|
||||
*
|
||||
* \see Configure
|
||||
*/
|
||||
inline void MaterialPass::Configure(const MaterialPipelineInfo& pipelineInfo)
|
||||
{
|
||||
m_pipelineInfo = pipelineInfo;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable blending for this material
|
||||
*
|
||||
* When enabled, all objects using this material will be rendered using blending, obeying the dstBlend and srcBlend parameters
|
||||
* This is useful with translucent objects, but will reduces performance as it prevents some optimizations (as deferred rendering)
|
||||
*
|
||||
* \param blending Defines if this material will use blending
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsBlendingEnabled
|
||||
* \see SetDstBlend
|
||||
* \see SetSrcBlend
|
||||
*/
|
||||
inline void MaterialPass::EnableBlending(bool blending)
|
||||
{
|
||||
m_pipelineInfo.blending = blending;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable color writing for this material
|
||||
*
|
||||
* \param colorWrite Defines if this material will use color writing
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsColorWritingEnabled
|
||||
*/
|
||||
inline void MaterialPass::EnableColorWrite(bool colorWrite)
|
||||
{
|
||||
m_pipelineInfo.colorWrite = colorWrite;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable depth buffer for this material
|
||||
*
|
||||
* When enabled, all objects using this material will be rendered using a depth buffer, if the RenderTarget has one.
|
||||
* This will enable Depth Test, preventing further fragments to render on top of closer ones.
|
||||
*
|
||||
* This parameter is required for depth writing.
|
||||
*
|
||||
* In order to enable depth writing without enabling depth test, set the depth comparison function to RendererComparison::Never
|
||||
*
|
||||
* \param depthBuffer Defines if this material will use depth buffer
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see EnableDepthWrite
|
||||
* \see IsDepthBufferEnabled
|
||||
* \see SetDepthFunc
|
||||
*/
|
||||
inline void MaterialPass::EnableDepthBuffer(bool depthBuffer)
|
||||
{
|
||||
m_pipelineInfo.depthBuffer = depthBuffer;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable depth clamp for this material
|
||||
*
|
||||
* When enabled, all fragments generated by this material will be clamped to znear or zfar
|
||||
* instead of being clipped out when outside this range.
|
||||
*
|
||||
* This can be useful to prevent clipping near or far primitives.
|
||||
*
|
||||
* \param depthClamp Defines if this material will use depth clamping
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
* \remark Depth clamping requires RenderDeviceFeatures::depthClamping to be true
|
||||
*
|
||||
* \see IsDepthClampEnabled
|
||||
*/
|
||||
inline void MaterialPass::EnableDepthClamp(bool depthClamp)
|
||||
{
|
||||
m_pipelineInfo.depthClamp = depthClamp;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable depth writing for this material
|
||||
*
|
||||
* When enabled, and if depth buffer is enabled and present, all fragments generated with this material will write
|
||||
* to the depth buffer if they pass depth test.
|
||||
*
|
||||
* This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but
|
||||
* not depth writing (which could make other translucent fragments to fail depth test)
|
||||
*
|
||||
* \param depthBuffer Defines if this material will use depth write
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see EnableDepthBuffer
|
||||
* \see IsDepthWriteEnabled
|
||||
*/
|
||||
inline void MaterialPass::EnableDepthWrite(bool depthWrite)
|
||||
{
|
||||
m_pipelineInfo.depthWrite = depthWrite;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable face culling for this material
|
||||
*
|
||||
* When enabled, the material prevents front and/or back faces from rendering.
|
||||
* This is commonly used as an optimization to prevent processing of hidden faces by the rendering device.
|
||||
*
|
||||
* Use SetFaceCulling to control which side will be eliminated.
|
||||
*
|
||||
* \param faceCulling Defines if this material will use face culling
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsFaceCullingEnabled
|
||||
* \see SetFaceCulling
|
||||
*/
|
||||
inline void MaterialPass::EnableFaceCulling(bool faceCulling)
|
||||
{
|
||||
m_pipelineInfo.faceCulling = faceCulling;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void MaterialPass::EnableFlag(MaterialPassFlag flag, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
m_flags |= flag;
|
||||
else
|
||||
m_flags &= ~flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable scissor test for this material
|
||||
*
|
||||
* When enabled, the material prevents fragments out of the scissor box to be rendered.
|
||||
* This can be useful with GUI, where widgets must not be rendered outside of their parent rendering area.
|
||||
*
|
||||
* \param scissorTest Defines if this material will use scissor test
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsScissorTestEnabled
|
||||
*/
|
||||
inline void MaterialPass::EnableScissorTest(bool scissorTest)
|
||||
{
|
||||
m_pipelineInfo.scissorTest = scissorTest;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable/Disable stencil test for this material
|
||||
*
|
||||
* When enabled, all fragments must pass the stencil test to be rendered.
|
||||
*
|
||||
* \param scissorTest Defines if this material will use stencil test
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see IsStencilTestEnabled
|
||||
*/
|
||||
inline void MaterialPass::EnableStencilTest(bool stencilTest)
|
||||
{
|
||||
m_pipelineInfo.stencilTest = stencilTest;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Ensures the pipeline gets updated
|
||||
*
|
||||
* When the pipeline gets invalidated, it's not updated until required (per example by calling GetPipeline).
|
||||
* Using this function forces the pipeline update, making GetPipeline thread-safe as long as the pipeline does not get invalidated.
|
||||
*
|
||||
* \see GetPipeline
|
||||
*/
|
||||
inline void MaterialPass::EnsurePipelineUpdate() const
|
||||
{
|
||||
if (!m_pipelineUpdated)
|
||||
UpdatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the function to compare depth
|
||||
*
|
||||
* \return Function comparing the depth of two materials
|
||||
*
|
||||
* \see EnableDepthTest
|
||||
* \see SetAmbientColor
|
||||
*/
|
||||
inline RendererComparison MaterialPass::GetDepthCompareFunc() const
|
||||
{
|
||||
return m_pipelineInfo.depthCompare;
|
||||
}
|
||||
|
||||
inline BlendEquation MaterialPass::GetBlendAlphaModeEquation() const
|
||||
{
|
||||
return m_pipelineInfo.blend.modeAlpha;
|
||||
}
|
||||
|
||||
inline BlendEquation MaterialPass::GetBlendColorModeEquation() const
|
||||
{
|
||||
return m_pipelineInfo.blend.modeColor;
|
||||
}
|
||||
|
||||
inline BlendFunc MaterialPass::GetBlendDstAlphaFunc() const
|
||||
{
|
||||
return m_pipelineInfo.blend.dstAlpha;
|
||||
}
|
||||
|
||||
inline BlendFunc MaterialPass::GetBlendDstColorFunc() const
|
||||
{
|
||||
return m_pipelineInfo.blend.dstColor;
|
||||
}
|
||||
|
||||
inline BlendFunc MaterialPass::GetBlendSrcAlphaFunc() const
|
||||
{
|
||||
return m_pipelineInfo.blend.srcAlpha;
|
||||
}
|
||||
|
||||
inline BlendFunc MaterialPass::GetBlendSrcColorFunc() const
|
||||
{
|
||||
return m_pipelineInfo.blend.srcColor;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the face culling
|
||||
*
|
||||
* \return Current face culling side
|
||||
*
|
||||
* \see SetFaceCulling
|
||||
*/
|
||||
inline FaceSide MaterialPass::GetFaceCulling() const
|
||||
{
|
||||
return m_pipelineInfo.cullingSide;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the face filling
|
||||
* \return Current face filling
|
||||
*/
|
||||
inline FaceFilling MaterialPass::GetFaceFilling() const
|
||||
{
|
||||
return m_pipelineInfo.faceFilling;
|
||||
}
|
||||
|
||||
inline MaterialPassFlags MaterialPass::GetFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the line width of this material
|
||||
* \return Line width
|
||||
*/
|
||||
inline float MaterialPass::GetLineWidth() const
|
||||
{
|
||||
return m_pipelineInfo.lineWidth;
|
||||
}
|
||||
|
||||
inline const nzsl::Ast::ConstantSingleValue& MaterialPass::GetOptionValue(std::size_t optionIndex) const
|
||||
{
|
||||
assert(optionIndex < m_optionValues.size());
|
||||
return m_optionValues[optionIndex];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the render states
|
||||
* \return Constant reference to the render states
|
||||
*/
|
||||
inline const std::shared_ptr<MaterialPipeline>& MaterialPass::GetPipeline() const
|
||||
{
|
||||
EnsurePipelineUpdate();
|
||||
|
||||
return m_pipeline;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the pipeline informations
|
||||
* \return Constant reference to the pipeline info
|
||||
*/
|
||||
inline const MaterialPipelineInfo& MaterialPass::GetPipelineInfo() const
|
||||
{
|
||||
return m_pipelineInfo;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the point size of this material
|
||||
* \return Point size
|
||||
*/
|
||||
inline float MaterialPass::GetPointSize() const
|
||||
{
|
||||
return m_pipelineInfo.pointSize;
|
||||
}
|
||||
|
||||
inline PrimitiveMode MaterialPass::GetPrimitiveMode() const
|
||||
{
|
||||
return m_pipelineInfo.primitiveMode;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<const MaterialSettings>& MaterialPass::GetSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the über-shader used by this material
|
||||
* \return Constant pointer to the über-shader used
|
||||
*/
|
||||
inline const std::shared_ptr<UberShader>& MaterialPass::GetShader(nzsl::ShaderStageType shaderStage) const
|
||||
{
|
||||
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
return m_textures[textureIndex].texture;
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& MaterialPass::GetTextureSampler(std::size_t textureIndex) const
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
return m_textures[textureIndex].samplerInfo;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<RenderBuffer>& MaterialPass::GetUniformBuffer(std::size_t bufferIndex) const
|
||||
{
|
||||
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
|
||||
return m_uniformBuffers[bufferIndex].buffer;
|
||||
}
|
||||
|
||||
inline const std::vector<UInt8>& MaterialPass::GetUniformBufferConstData(std::size_t bufferIndex) const
|
||||
{
|
||||
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
|
||||
return m_uniformBuffers[bufferIndex].data;
|
||||
}
|
||||
|
||||
inline std::vector<UInt8>& MaterialPass::GetUniformBufferData(std::size_t bufferIndex)
|
||||
{
|
||||
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
|
||||
UniformBuffer& uboEntry = m_uniformBuffers[bufferIndex];
|
||||
InvalidateUniformData(bufferIndex);
|
||||
|
||||
return uboEntry.data;
|
||||
}
|
||||
|
||||
inline bool MaterialPass::HasTexture(std::size_t textureIndex) const
|
||||
{
|
||||
return GetTexture(textureIndex) != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has blending enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsBlendingEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.blending;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has color write enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsColorWriteEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.colorWrite;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has depth buffer enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsDepthBufferEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.depthBuffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has depth clamping enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsDepthClampEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.depthClamp;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has depth writing enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsDepthWriteEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.depthWrite;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has face culling enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsFaceCullingEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.faceCulling;
|
||||
}
|
||||
|
||||
inline bool MaterialPass::IsFlagEnabled(MaterialPassFlag flag) const
|
||||
{
|
||||
return m_flags.Test(flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has scissor test enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsScissorTestEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.scissorTest;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether this material has stencil test enabled
|
||||
* \return true If it is the case
|
||||
*/
|
||||
inline bool MaterialPass::IsStencilTestEnabled() const
|
||||
{
|
||||
return m_pipelineInfo.stencilTest;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the depth functor
|
||||
*
|
||||
* \param depthFunc
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*/
|
||||
inline void MaterialPass::SetDepthCompareFunc(RendererComparison depthFunc)
|
||||
{
|
||||
m_pipelineInfo.depthCompare = depthFunc;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetBlendEquation(BlendEquation colorMode, BlendEquation alphaMode)
|
||||
{
|
||||
m_pipelineInfo.blend.modeAlpha = alphaMode;
|
||||
m_pipelineInfo.blend.modeColor = colorMode;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetBlendFunc(BlendFunc srcColor, BlendFunc dstColor, BlendFunc srcAlpha, BlendFunc dstAlpha)
|
||||
{
|
||||
m_pipelineInfo.blend.dstAlpha = dstAlpha;
|
||||
m_pipelineInfo.blend.dstColor = dstColor;
|
||||
m_pipelineInfo.blend.srcAlpha = srcAlpha;
|
||||
m_pipelineInfo.blend.srcColor = srcColor;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the face culling
|
||||
*
|
||||
* \param faceSide Face to cull
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*/
|
||||
inline void MaterialPass::SetFaceCulling(FaceSide faceSide)
|
||||
{
|
||||
m_pipelineInfo.cullingSide = faceSide;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the face filling
|
||||
*
|
||||
* \param filling Face to fill
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*/
|
||||
inline void MaterialPass::SetFaceFilling(FaceFilling filling)
|
||||
{
|
||||
m_pipelineInfo.faceFilling = filling;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the line width for this material
|
||||
*
|
||||
* This parameter is used when rendering lines, to define the width (in pixels) the line will take on the framebuffer
|
||||
*
|
||||
* \param lineWidth Width of the line
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see GetLineWidth
|
||||
*/
|
||||
inline void MaterialPass::SetLineWidth(float lineWidth)
|
||||
{
|
||||
m_pipelineInfo.lineWidth = lineWidth;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantSingleValue value)
|
||||
{
|
||||
assert(optionIndex < m_optionValues.size());
|
||||
if (m_optionValues[optionIndex] != value)
|
||||
{
|
||||
m_optionValues[optionIndex] = std::move(value);
|
||||
InvalidatePipeline();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the point size for this material
|
||||
*
|
||||
* This parameter is used when rendering points, to define the size (in pixels) the point will take on the framebuffer
|
||||
*
|
||||
* \param pointSize Size of the point
|
||||
*
|
||||
* \remark Invalidates the pipeline
|
||||
*
|
||||
* \see GetPointSize
|
||||
*/
|
||||
inline void MaterialPass::SetPointSize(float pointSize)
|
||||
{
|
||||
m_pipelineInfo.pointSize = pointSize;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
|
||||
inline void MaterialPass::SetPrimitiveMode(PrimitiveMode mode)
|
||||
{
|
||||
m_pipelineInfo.primitiveMode = mode;
|
||||
|
||||
InvalidatePipeline();
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer)
|
||||
{
|
||||
if (uniformBuffer)
|
||||
{
|
||||
UInt64 size = uniformBuffer->GetSize();
|
||||
return SetSharedUniformBuffer(sharedUboIndex, std::move(uniformBuffer), 0, size);
|
||||
}
|
||||
else
|
||||
return SetSharedUniformBuffer(sharedUboIndex, std::move(uniformBuffer), 0, 0);
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer, UInt64 offset, UInt64 size)
|
||||
{
|
||||
NazaraAssert(sharedUboIndex < m_sharedUniformBuffers.size(), "Invalid shared uniform buffer index");
|
||||
|
||||
RenderBufferView bufferView(uniformBuffer.get(), offset, size);
|
||||
|
||||
if (m_sharedUniformBuffers[sharedUboIndex].bufferView != bufferView)
|
||||
{
|
||||
m_sharedUniformBuffers[sharedUboIndex].bufferView = bufferView;
|
||||
m_sharedUniformBuffers[sharedUboIndex].buffer = std::move(uniformBuffer);
|
||||
|
||||
InvalidateShaderBinding();
|
||||
}
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture)
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
if (m_textures[textureIndex].texture != texture)
|
||||
{
|
||||
m_textures[textureIndex].texture = std::move(texture);
|
||||
|
||||
InvalidateShaderBinding();
|
||||
}
|
||||
}
|
||||
|
||||
inline void MaterialPass::SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo)
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
if (m_textures[textureIndex].samplerInfo != samplerInfo)
|
||||
{
|
||||
m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
|
||||
|
||||
InvalidateTextureSampler(textureIndex);
|
||||
}
|
||||
}
|
||||
|
||||
inline void MaterialPass::InvalidatePipeline()
|
||||
{
|
||||
m_pipelineUpdated = false;
|
||||
|
||||
OnMaterialPassPipelineInvalidated(this);
|
||||
}
|
||||
|
||||
inline void MaterialPass::InvalidateShaderBinding()
|
||||
{
|
||||
OnMaterialPassShaderBindingInvalidated(this);
|
||||
}
|
||||
|
||||
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
|
||||
{
|
||||
assert(textureIndex < m_textures.size());
|
||||
m_textures[textureIndex].sampler.reset();
|
||||
|
||||
InvalidateShaderBinding();
|
||||
}
|
||||
|
||||
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
|
||||
{
|
||||
assert(uniformBufferIndex < m_uniformBuffers.size());
|
||||
UniformBuffer& uboEntry = m_uniformBuffers[uniformBufferIndex];
|
||||
uboEntry.dataInvalidated = true;
|
||||
|
||||
OnMaterialPassInvalidated(this);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -8,6 +8,8 @@
|
||||
#define NAZARA_GRAPHICS_MATERIALPASSREGISTRY_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Utils/Algorithm.hpp>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -21,7 +23,7 @@ namespace Nz
|
||||
MaterialPassRegistry(MaterialPassRegistry&&) = default;
|
||||
~MaterialPassRegistry() = default;
|
||||
|
||||
inline std::size_t GetPassIndex(const std::string& passName) const;
|
||||
inline std::size_t GetPassIndex(std::string_view passName) const;
|
||||
|
||||
inline std::size_t RegisterPass(std::string passName);
|
||||
|
||||
@@ -29,7 +31,8 @@ namespace Nz
|
||||
MaterialPassRegistry& operator=(MaterialPassRegistry&&) = default;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::size_t> m_passIndex;
|
||||
std::list<std::string> m_passNames; //< in order to allow std::string_view as a key in C++17 (keep std::string stable as well because of SSO)
|
||||
std::unordered_map<std::string_view, std::size_t> m_passIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
std::size_t MaterialPassRegistry::GetPassIndex(const std::string& passName) const
|
||||
std::size_t MaterialPassRegistry::GetPassIndex(std::string_view 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");
|
||||
throw std::runtime_error("pass " + std::string(passName) + " must be registered before being used");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
@@ -22,8 +22,10 @@ namespace Nz
|
||||
if (m_passIndex.find(passName) != m_passIndex.end())
|
||||
throw std::runtime_error("pass " + passName + " is already registered");
|
||||
|
||||
m_passNames.push_back(std::move(passName));
|
||||
|
||||
std::size_t passIndex = m_passIndex.size();
|
||||
m_passIndex.emplace(std::move(passName), passIndex);
|
||||
m_passIndex.emplace(m_passNames.back(), passIndex);
|
||||
|
||||
return passIndex;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
#include <Nazara/Graphics/UberShader.hpp>
|
||||
#include <Nazara/Renderer/RenderPipeline.hpp>
|
||||
#include <NZSL/Ast/ConstantValue.hpp>
|
||||
#include <array>
|
||||
@@ -33,10 +33,9 @@ namespace Nz
|
||||
std::shared_ptr<UberShader> uberShader;
|
||||
};
|
||||
|
||||
std::array<Option, 32> optionValues;
|
||||
std::size_t optionCount = 0;
|
||||
std::vector<Shader> shaders;
|
||||
std::shared_ptr<const MaterialSettings> settings;
|
||||
std::shared_ptr<RenderPipelineLayout> pipelineLayout;
|
||||
std::vector<Option> optionValues; //< TODO: FixedVector
|
||||
std::vector<Shader> shaders; //< TODO: FixedVector
|
||||
};
|
||||
|
||||
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);
|
||||
|
||||
@@ -40,16 +40,13 @@ namespace Nz
|
||||
|
||||
#define NazaraPipelineMember(field) if (lhs.field != rhs.field) return false
|
||||
|
||||
NazaraPipelineMember(settings);
|
||||
NazaraPipelineMember(optionCount);
|
||||
|
||||
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
|
||||
{
|
||||
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < lhs.optionCount; ++i)
|
||||
for (std::size_t i = 0; i < lhs.optionValues.size(); ++i)
|
||||
{
|
||||
if (lhs.optionValues[i].hash != rhs.optionValues[i].hash)
|
||||
return false;
|
||||
@@ -86,9 +83,7 @@ namespace std
|
||||
#define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.member)
|
||||
#define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
|
||||
|
||||
NazaraPipelineMember(settings.get()); //< Hash pointer
|
||||
|
||||
for (std::size_t i = 0; i < pipelineInfo.optionCount; ++i)
|
||||
for (std::size_t i = 0; i < pipelineInfo.optionValues.size(); ++i)
|
||||
{
|
||||
Nz::HashCombine(seed, pipelineInfo.optionValues[i].hash);
|
||||
Nz::HashCombine(seed, pipelineInfo.optionValues[i].value);
|
||||
|
||||
@@ -8,110 +8,100 @@
|
||||
#define NAZARA_GRAPHICS_MATERIALSETTINGS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/UberShader.hpp>
|
||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||
#include <Nazara/Renderer/ShaderModule.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <array>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Math/Vector4.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Utils/TypeList.hpp>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialSettings
|
||||
template<typename T> struct TypeToMaterialPropertyType;
|
||||
|
||||
template<typename T> constexpr MaterialPropertyType TypeToMaterialPropertyType_v = TypeToMaterialPropertyType<T>::PropertyType;
|
||||
|
||||
template<MaterialPropertyType P> struct MaterialPropertyTypeInfo;
|
||||
|
||||
struct MaterialPropertyNoValue {};
|
||||
|
||||
using MaterialPropertyTypeList = TypeList<
|
||||
MaterialPropertyNoValue,
|
||||
Color,
|
||||
bool, Vector2<bool>, Vector3<bool>, Vector4<bool>,
|
||||
float, Vector2<float>, Vector3<float>, Vector4<float>,
|
||||
Int32, Vector2<Int32>, Vector3<Int32>, Vector4<Int32>,
|
||||
UInt32, Vector2<UInt32>, Vector3<UInt32>, Vector4<UInt32>
|
||||
>;
|
||||
|
||||
class NAZARA_GRAPHICS_API MaterialSettings
|
||||
{
|
||||
public:
|
||||
struct Builder;
|
||||
struct Option;
|
||||
struct SharedUniformBlock;
|
||||
struct Texture;
|
||||
struct UniformBlock;
|
||||
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
|
||||
struct TextureProperty;
|
||||
struct ValueProperty;
|
||||
|
||||
inline MaterialSettings();
|
||||
inline MaterialSettings(Builder builder);
|
||||
MaterialSettings(const MaterialSettings&) = default;
|
||||
MaterialSettings(MaterialSettings&&) = delete;
|
||||
using Value = TypeListInstantiate<MaterialPropertyTypeList, std::variant>;
|
||||
|
||||
MaterialSettings() = default;
|
||||
MaterialSettings(const MaterialSettings&) = delete;
|
||||
MaterialSettings(MaterialSettings&&) noexcept = default;
|
||||
~MaterialSettings() = default;
|
||||
|
||||
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(nzsl::ShaderStageType stage) const;
|
||||
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
|
||||
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
|
||||
inline std::size_t GetSharedUniformBlockIndex(const std::string_view& name) const;
|
||||
inline std::size_t GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
|
||||
inline const std::vector<Texture>& GetTextures() const;
|
||||
inline std::size_t GetTextureIndex(const std::string_view& name) const;
|
||||
inline const std::vector<UniformBlock>& GetUniformBlocks() const;
|
||||
inline std::size_t GetUniformBlockIndex(const std::string_view& name) const;
|
||||
inline std::size_t GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
|
||||
void AddPass(std::string_view passName, MaterialPass materialPass);
|
||||
inline void AddPass(std::size_t passIndex, MaterialPass materialPass);
|
||||
inline void AddPropertyHandler(std::unique_ptr<PropertyHandler> propertyHandler);
|
||||
inline void AddTextureProperty(std::string propertyName, ImageType propertyType);
|
||||
inline void AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture);
|
||||
inline void AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture, const TextureSamplerInfo& defaultSamplerInfo);
|
||||
inline void AddValueProperty(std::string propertyName, MaterialPropertyType propertyType, Value defaultValue);
|
||||
template<typename T> void AddValueProperty(std::string propertyName);
|
||||
template<typename T, typename U> void AddValueProperty(std::string propertyName, U&& defaultValue);
|
||||
|
||||
inline std::size_t FindTextureProperty(std::string_view propertyName) const;
|
||||
inline std::size_t FindValueProperty(std::string_view propertyName) const;
|
||||
|
||||
const MaterialPass* GetPass(std::string_view passName) const;
|
||||
inline const MaterialPass* GetPass(std::size_t passIndex) const;
|
||||
inline const std::vector<std::optional<MaterialPass>>& GetPasses() const;
|
||||
inline const std::vector<std::unique_ptr<PropertyHandler>>& GetPropertyHandlers() const;
|
||||
inline const TextureProperty& GetTextureProperty(std::size_t texturePropertyIndex) const;
|
||||
inline std::size_t GetTexturePropertyCount() const;
|
||||
inline const ValueProperty& GetValueProperty(std::size_t valuePropertyIndex) const;
|
||||
inline std::size_t GetValuePropertyCount() const;
|
||||
|
||||
MaterialSettings& operator=(const MaterialSettings&) = delete;
|
||||
MaterialSettings& operator=(MaterialSettings&&) = delete;
|
||||
MaterialSettings& operator=(MaterialSettings&&) = default;
|
||||
|
||||
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
static inline void BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName);
|
||||
|
||||
struct Builder
|
||||
struct TextureProperty
|
||||
{
|
||||
inline Builder();
|
||||
|
||||
std::vector<std::shared_ptr<UberShader>> shaders;
|
||||
std::vector<Option> options;
|
||||
std::vector<Texture> textures;
|
||||
std::vector<UniformBlock> uniformBlocks;
|
||||
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
||||
PredefinedBinding predefinedBindings;
|
||||
};
|
||||
|
||||
struct Option
|
||||
{
|
||||
std::string name;
|
||||
UInt32 hash;
|
||||
};
|
||||
|
||||
struct UniformVariable
|
||||
{
|
||||
std::string name;
|
||||
std::size_t offset;
|
||||
};
|
||||
|
||||
struct SharedUniformBlock
|
||||
{
|
||||
UInt32 bindingIndex;
|
||||
std::string name;
|
||||
std::vector<UniformVariable> uniforms;
|
||||
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
|
||||
};
|
||||
|
||||
struct Texture
|
||||
{
|
||||
UInt32 bindingIndex;
|
||||
std::shared_ptr<Texture> defaultTexture;
|
||||
std::string name;
|
||||
ImageType type;
|
||||
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
|
||||
TextureSamplerInfo defaultSamplerInfo;
|
||||
};
|
||||
|
||||
struct UniformBlock
|
||||
struct ValueProperty
|
||||
{
|
||||
UInt32 bindingIndex;
|
||||
Value defaultValue;
|
||||
std::string name;
|
||||
std::size_t blockSize;
|
||||
std::vector<UniformVariable> uniforms;
|
||||
std::vector<UInt8> defaultValues;
|
||||
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
|
||||
MaterialPropertyType type;
|
||||
};
|
||||
|
||||
static constexpr std::size_t InvalidPropertyIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
private:
|
||||
std::shared_ptr<RenderPipelineLayout> m_pipelineLayout;
|
||||
Builder m_data;
|
||||
std::vector<std::unique_ptr<PropertyHandler>> m_propertyHandlers;
|
||||
std::vector<std::optional<MaterialPass>> m_materialPasses;
|
||||
std::vector<TextureProperty> m_textureProperties;
|
||||
std::vector<ValueProperty> m_valueProperties;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,186 +3,327 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Utils/Algorithm.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline MaterialSettings::MaterialSettings() :
|
||||
MaterialSettings(Builder{})
|
||||
template<typename T> class Vector2;
|
||||
template<typename T> class Vector3;
|
||||
template<typename T> class Vector4;
|
||||
|
||||
template<typename T>
|
||||
struct TypeToMaterialPropertyType
|
||||
{
|
||||
static_assert(AlwaysFalse<T>(), "T is not a valid type for material property");
|
||||
};
|
||||
|
||||
template<> struct TypeToMaterialPropertyType<bool> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector2<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool2; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector3<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool3; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector4<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool4; };
|
||||
|
||||
template<> struct TypeToMaterialPropertyType<Color> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Color; };
|
||||
|
||||
template<> struct TypeToMaterialPropertyType<float> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector2<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float2; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector3<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float3; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector4<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float4; };
|
||||
|
||||
template<> struct TypeToMaterialPropertyType<Int32> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector2<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int2; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector3<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int3; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector4<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int4; };
|
||||
|
||||
template<> struct TypeToMaterialPropertyType<UInt32> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector2<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt2; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector3<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt3; };
|
||||
template<> struct TypeToMaterialPropertyType<Vector4<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt4; };
|
||||
|
||||
template<MaterialPropertyType P>
|
||||
struct MaterialPropertyTypeInfo
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct MaterialPropertyTypeInfoPrimitive
|
||||
{
|
||||
using Type = T;
|
||||
using BufferType = T;
|
||||
using OptionType = T;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return value; }
|
||||
static Type DecodeFromOption(OptionType value) { return value; }
|
||||
static BufferType EncodeToBuffer(Type value) { return value; }
|
||||
static OptionType EncodeToOption(Type value) { return value; }
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct MaterialPropertyTypeInfoVector;
|
||||
|
||||
template<typename T>
|
||||
struct MaterialPropertyTypeInfoVector<T, 2>
|
||||
{
|
||||
using Type = Vector2<T>;
|
||||
using BufferType = nzsl::Vector2<T>;
|
||||
using OptionType = nzsl::Vector2<T>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y() }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y }; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct MaterialPropertyTypeInfoVector<T, 3>
|
||||
{
|
||||
using Type = Vector3<T>;
|
||||
using BufferType = nzsl::Vector3<T>;
|
||||
using OptionType = nzsl::Vector3<T>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z() }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z }; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct MaterialPropertyTypeInfoVector<T, 4>
|
||||
{
|
||||
using Type = Vector4<T>;
|
||||
using BufferType = nzsl::Vector4<T>;
|
||||
using OptionType = nzsl::Vector4<T>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z(), value.w() }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z, value.w }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z, value.w }; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool>
|
||||
{
|
||||
using Type = bool;
|
||||
using BufferType = UInt32;
|
||||
using OptionType = bool;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return value != 0; }
|
||||
static Type DecodeFromOption(OptionType value) { return value; }
|
||||
static BufferType EncodeToBuffer(Type value) { return value; }
|
||||
static OptionType EncodeToOption(Type value) { return value; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool2>
|
||||
{
|
||||
using Type = Vector2<bool>;
|
||||
using BufferType = nzsl::Vector2u32;
|
||||
using OptionType = nzsl::Vector2<bool>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0 }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y }; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool3>
|
||||
{
|
||||
using Type = Vector3<bool>;
|
||||
using BufferType = nzsl::Vector3u32;
|
||||
using OptionType = nzsl::Vector3<bool>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0, value.z() != 0 }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z }; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool4>
|
||||
{
|
||||
using Type = Vector4<bool>;
|
||||
using BufferType = nzsl::Vector4u32;
|
||||
using OptionType = nzsl::Vector4<bool>;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0, value.z() != 0, value.w() != 0}; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z, value.w }; }
|
||||
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z, value.w }; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct MaterialPropertyTypeInfo<MaterialPropertyType::Color>
|
||||
{
|
||||
using Type = Color;
|
||||
using BufferType = nzsl::Vector4f32;
|
||||
using OptionType = nzsl::Vector4f32;
|
||||
|
||||
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z(), value.w() }; }
|
||||
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
|
||||
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.r, value.g, value.b, value.a }; }
|
||||
static OptionType EncodeToOption(Type value) { return BufferType{ value.r, value.g, value.b, value.a }; }
|
||||
};
|
||||
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float> : MaterialPropertyTypeInfoPrimitive<float> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float2> : MaterialPropertyTypeInfoVector<float, 2> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float3> : MaterialPropertyTypeInfoVector<float, 3> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float4> : MaterialPropertyTypeInfoVector<float, 4> {};
|
||||
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int> : MaterialPropertyTypeInfoPrimitive<Int32> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int2> : MaterialPropertyTypeInfoVector<Int32, 2> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int3> : MaterialPropertyTypeInfoVector<Int32, 3> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int4> : MaterialPropertyTypeInfoVector<Int32, 4> {};
|
||||
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt> : MaterialPropertyTypeInfoPrimitive<UInt32> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt2> : MaterialPropertyTypeInfoVector<UInt32, 2> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt3> : MaterialPropertyTypeInfoVector<UInt32, 3> {};
|
||||
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt4> : MaterialPropertyTypeInfoVector<UInt32, 4> {};
|
||||
|
||||
|
||||
inline void MaterialSettings::AddPass(std::size_t passIndex, MaterialPass materialPass)
|
||||
{
|
||||
if (passIndex >= m_materialPasses.size())
|
||||
m_materialPasses.resize(passIndex + 1);
|
||||
|
||||
m_materialPasses[passIndex] = std::move(materialPass);
|
||||
}
|
||||
|
||||
inline MaterialSettings::MaterialSettings(Builder data) :
|
||||
m_data(std::move(data))
|
||||
inline void MaterialSettings::AddPropertyHandler(std::unique_ptr<PropertyHandler> propertyHandler)
|
||||
{
|
||||
RenderPipelineLayoutInfo info;
|
||||
|
||||
for (const Texture& textureInfo : m_data.textures)
|
||||
{
|
||||
info.bindings.push_back({
|
||||
0,
|
||||
textureInfo.bindingIndex,
|
||||
ShaderBindingType::Texture,
|
||||
textureInfo.shaderStages
|
||||
});
|
||||
}
|
||||
|
||||
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
||||
{
|
||||
info.bindings.push_back({
|
||||
0,
|
||||
ubo.bindingIndex,
|
||||
ShaderBindingType::UniformBuffer,
|
||||
ubo.shaderStages
|
||||
});
|
||||
}
|
||||
|
||||
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
||||
{
|
||||
info.bindings.push_back({
|
||||
0,
|
||||
ubo.bindingIndex,
|
||||
ShaderBindingType::UniformBuffer,
|
||||
ubo.shaderStages
|
||||
});
|
||||
}
|
||||
|
||||
m_pipelineLayout = Graphics::Instance()->GetRenderDevice()->InstantiateRenderPipelineLayout(std::move(info));
|
||||
m_propertyHandlers.emplace_back(std::move(propertyHandler));
|
||||
}
|
||||
|
||||
inline auto MaterialSettings::GetBuilderData() const -> const Builder&
|
||||
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType)
|
||||
{
|
||||
return m_data;
|
||||
auto& textureProperty = m_textureProperties.emplace_back();
|
||||
textureProperty.name = std::move(propertyName);
|
||||
textureProperty.type = propertyType;
|
||||
}
|
||||
|
||||
inline auto MaterialSettings::GetOptions() const -> const std::vector<Option>&
|
||||
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture)
|
||||
{
|
||||
return m_data.options;
|
||||
if (defaultTexture && defaultTexture->GetType() != propertyType)
|
||||
throw std::runtime_error("default texture type doesn't match property image type");
|
||||
|
||||
auto& textureProperty = m_textureProperties.emplace_back();
|
||||
textureProperty.name = std::move(propertyName);
|
||||
textureProperty.type = propertyType;
|
||||
textureProperty.defaultTexture = std::move(defaultTexture);
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetOptionIndex(const std::string_view& name) const
|
||||
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture, const TextureSamplerInfo& defaultSamplerInfo)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_data.options.size(); ++i)
|
||||
if (defaultTexture && defaultTexture->GetType() != propertyType)
|
||||
throw std::runtime_error("default texture type doesn't match property image type");
|
||||
|
||||
auto& textureProperty = m_textureProperties.emplace_back();
|
||||
textureProperty.name = std::move(propertyName);
|
||||
textureProperty.type = propertyType;
|
||||
textureProperty.defaultTexture = std::move(defaultTexture);
|
||||
textureProperty.defaultSamplerInfo = defaultSamplerInfo;
|
||||
}
|
||||
|
||||
inline void MaterialSettings::AddValueProperty(std::string propertyName, MaterialPropertyType propertyType, Value defaultValue)
|
||||
{
|
||||
std::visit([&](auto&& arg)
|
||||
{
|
||||
if (m_data.options[i].name == name)
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
|
||||
if constexpr (!std::is_same_v<T, MaterialPropertyNoValue>)
|
||||
{
|
||||
constexpr MaterialPropertyType valueType = TypeToMaterialPropertyType_v<T>;
|
||||
if (propertyType != valueType)
|
||||
throw std::runtime_error("default value type doesn't match property type");
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("value properties must have a default value");
|
||||
}, defaultValue);
|
||||
|
||||
auto& valueProperty = m_valueProperties.emplace_back();
|
||||
valueProperty.name = std::move(propertyName);
|
||||
valueProperty.type = propertyType;
|
||||
valueProperty.defaultValue = std::move(defaultValue);
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::FindTextureProperty(std::string_view propertyName) const
|
||||
{
|
||||
for (std::size_t i = 0; i < m_textureProperties.size(); ++i)
|
||||
{
|
||||
if (m_textureProperties[i].name == propertyName)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
return InvalidPropertyIndex;
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const
|
||||
inline std::size_t MaterialSettings::FindValueProperty(std::string_view propertyName) const
|
||||
{
|
||||
return m_data.predefinedBindings[UnderlyingCast(shaderBinding)];
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
||||
{
|
||||
return m_pipelineLayout;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(nzsl::ShaderStageType stage) const
|
||||
{
|
||||
return m_data.shaders[UnderlyingCast(stage)];
|
||||
}
|
||||
|
||||
inline const std::vector<std::shared_ptr<UberShader>>& MaterialSettings::GetShaders() const
|
||||
{
|
||||
return m_data.shaders;
|
||||
}
|
||||
|
||||
inline auto MaterialSettings::GetSharedUniformBlocks() const -> const std::vector<SharedUniformBlock>&
|
||||
{
|
||||
return m_data.sharedUniformBlocks;
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetSharedUniformBlockIndex(const std::string_view& name) const
|
||||
{
|
||||
for (std::size_t i = 0; i < m_data.sharedUniformBlocks.size(); ++i)
|
||||
for (std::size_t i = 0; i < m_valueProperties.size(); ++i)
|
||||
{
|
||||
if (m_data.sharedUniformBlocks[i].name == name)
|
||||
if (m_valueProperties[i].name == propertyName)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
return InvalidPropertyIndex;
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
||||
inline const MaterialPass* MaterialSettings::GetPass(std::size_t passIndex) const
|
||||
{
|
||||
assert(uniformBlockIndex < m_data.sharedUniformBlocks.size());
|
||||
if (passIndex > m_materialPasses.size() || !m_materialPasses[passIndex].has_value())
|
||||
return nullptr;
|
||||
|
||||
const std::vector<UniformVariable>& variables = m_data.sharedUniformBlocks[uniformBlockIndex].uniforms;
|
||||
for (std::size_t i = 0; i < variables.size(); ++i)
|
||||
{
|
||||
if (variables[i].name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
return &m_materialPasses[passIndex].value();
|
||||
}
|
||||
|
||||
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
|
||||
inline const std::vector<std::optional<MaterialPass>>& MaterialSettings::GetPasses() const
|
||||
{
|
||||
return m_data.textures;
|
||||
return m_materialPasses;
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetTextureIndex(const std::string_view& name) const
|
||||
inline const std::vector<std::unique_ptr<PropertyHandler>>& MaterialSettings::GetPropertyHandlers() const
|
||||
{
|
||||
for (std::size_t i = 0; i < m_data.textures.size(); ++i)
|
||||
{
|
||||
if (m_data.textures[i].name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
return m_propertyHandlers;
|
||||
}
|
||||
|
||||
inline auto MaterialSettings::GetUniformBlocks() const -> const std::vector<UniformBlock>&
|
||||
inline auto MaterialSettings::GetTextureProperty(std::size_t texturePropertyIndex) const -> const TextureProperty&
|
||||
{
|
||||
return m_data.uniformBlocks;
|
||||
assert(texturePropertyIndex < m_textureProperties.size());
|
||||
return m_textureProperties[texturePropertyIndex];
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetUniformBlockIndex(const std::string_view& name) const
|
||||
inline std::size_t MaterialSettings::GetTexturePropertyCount() const
|
||||
{
|
||||
for (std::size_t i = 0; i < m_data.uniformBlocks.size(); ++i)
|
||||
{
|
||||
if (m_data.uniformBlocks[i].name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
return m_textureProperties.size();
|
||||
}
|
||||
|
||||
inline std::size_t MaterialSettings::GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
||||
inline auto MaterialSettings::GetValueProperty(std::size_t valuePropertyIndex) const -> const ValueProperty&
|
||||
{
|
||||
assert(uniformBlockIndex < m_data.uniformBlocks.size());
|
||||
|
||||
const std::vector<UniformVariable>& variables = m_data.uniformBlocks[uniformBlockIndex].uniforms;
|
||||
for (std::size_t i = 0; i < variables.size(); ++i)
|
||||
{
|
||||
if (variables[i].name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidIndex;
|
||||
assert(valuePropertyIndex < m_valueProperties.size());
|
||||
return m_valueProperties[valuePropertyIndex];
|
||||
}
|
||||
|
||||
inline void MaterialSettings::BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName)
|
||||
inline std::size_t MaterialSettings::GetValuePropertyCount() const
|
||||
{
|
||||
UInt32 optionHash = CRC32(shaderOptionName);
|
||||
|
||||
options.push_back({
|
||||
std::move(optionName),
|
||||
optionHash
|
||||
});
|
||||
return m_valueProperties.size();
|
||||
}
|
||||
|
||||
inline MaterialSettings::Builder::Builder()
|
||||
template<typename T>
|
||||
void MaterialSettings::AddValueProperty(std::string propertyName)
|
||||
{
|
||||
predefinedBindings.fill(InvalidIndex);
|
||||
return AddValueProperty(std::move(propertyName), TypeToMaterialPropertyType_v<T>);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
void MaterialSettings::AddValueProperty(std::string propertyName, U&& defaultValue)
|
||||
{
|
||||
constexpr std::size_t TypeIndex = TypeListFind<MaterialPropertyTypeList, T>;
|
||||
|
||||
auto& valueProperty = m_valueProperties.emplace_back();
|
||||
valueProperty.name = std::move(propertyName);
|
||||
valueProperty.type = TypeToMaterialPropertyType_v<T>;
|
||||
valueProperty.defaultValue.emplace<TypeIndex>(std::forward<U>(defaultValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@ namespace Nz
|
||||
|
||||
const std::shared_ptr<RenderBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
|
||||
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t subMeshIndex) const override;
|
||||
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t subMeshIndex) const override;
|
||||
std::size_t GetMaterialCount() const override;
|
||||
inline std::size_t GetSubMeshCount() const;
|
||||
const std::vector<RenderPipelineInfo::VertexBufferData>& GetVertexBufferData(std::size_t subMeshIndex) const;
|
||||
const std::shared_ptr<RenderBuffer>& GetVertexBuffer(std::size_t subMeshIndex) const;
|
||||
|
||||
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialInstance> material);
|
||||
|
||||
Model& operator=(const Model&) = delete;
|
||||
Model& operator=(Model&&) noexcept = default;
|
||||
@@ -46,7 +46,7 @@ namespace Nz
|
||||
private:
|
||||
struct SubMeshData
|
||||
{
|
||||
std::shared_ptr<Material> material;
|
||||
std::shared_ptr<MaterialInstance> material;
|
||||
std::vector<RenderPipelineInfo::VertexBufferData> vertexBufferData;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace Nz
|
||||
return m_submeshes.size();
|
||||
}
|
||||
|
||||
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material)
|
||||
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
assert(subMeshIndex < m_submeshes.size());
|
||||
assert(material);
|
||||
|
||||
if (m_submeshes[subMeshIndex].material != material)
|
||||
{
|
||||
OnMaterialInvalidated(this, 0, material);
|
||||
OnMaterialInvalidated(this, subMeshIndex, material);
|
||||
m_submeshes[subMeshIndex].material = std::move(material);
|
||||
|
||||
OnElementInvalidated(this);
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
// 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_PHONGLIGHTINGMATERIAL_HPP
|
||||
#define NAZARA_GRAPHICS_PHONGLIGHTINGMATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API PhongLightingMaterial : public BasicMaterial
|
||||
{
|
||||
friend class MaterialPipeline;
|
||||
|
||||
public:
|
||||
PhongLightingMaterial(MaterialPass& material);
|
||||
|
||||
Color GetAmbientColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
|
||||
inline const TextureSamplerInfo& GetEmissiveSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetHeightMap() const;
|
||||
inline const TextureSamplerInfo& GetHeightSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetNormalMap() const;
|
||||
inline const TextureSamplerInfo& GetNormalSampler() const;
|
||||
float GetShininess() const;
|
||||
Color GetSpecularColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
|
||||
inline const TextureSamplerInfo& GetSpecularSampler() const;
|
||||
|
||||
inline bool HasAmbientColor() const;
|
||||
inline bool HasEmissiveMap() const;
|
||||
inline bool HasHeightMap() const;
|
||||
inline bool HasNormalMap() const;
|
||||
inline bool HasShininess() const;
|
||||
inline bool HasSpecularColor() const;
|
||||
inline bool HasSpecularMap() const;
|
||||
|
||||
void SetAmbientColor(const Color& ambient);
|
||||
inline void SetEmissiveMap(std::shared_ptr<Texture> emissiveMap);
|
||||
inline void SetEmissiveSampler(TextureSamplerInfo emissiveSampler);
|
||||
inline void SetHeightMap(std::shared_ptr<Texture> heightMap);
|
||||
inline void SetHeightSampler(TextureSamplerInfo heightSampler);
|
||||
inline void SetNormalMap(std::shared_ptr<Texture> normalMap);
|
||||
inline void SetNormalSampler(TextureSamplerInfo normalSampler);
|
||||
void SetShininess(float shininess);
|
||||
void SetSpecularColor(const Color& specular);
|
||||
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
|
||||
inline void SetSpecularSampler(TextureSamplerInfo specularSampler);
|
||||
|
||||
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||
|
||||
protected:
|
||||
struct PhongOptionIndexes
|
||||
{
|
||||
std::size_t hasEmissiveMap;
|
||||
std::size_t hasHeightMap;
|
||||
std::size_t hasNormalMap;
|
||||
std::size_t hasSpecularMap;
|
||||
};
|
||||
|
||||
struct PhongUniformOffsets
|
||||
{
|
||||
std::size_t ambientColor;
|
||||
std::size_t shininess;
|
||||
std::size_t totalSize;
|
||||
std::size_t specularColor;
|
||||
};
|
||||
|
||||
struct PhongTextureIndexes
|
||||
{
|
||||
std::size_t emissive;
|
||||
std::size_t height;
|
||||
std::size_t normal;
|
||||
std::size_t specular;
|
||||
};
|
||||
|
||||
struct PhongBuildOptions : BasicBuildOptions
|
||||
{
|
||||
PhongUniformOffsets phongOffsets;
|
||||
PhongOptionIndexes* phongOptionIndexes = nullptr;
|
||||
PhongTextureIndexes* phongTextureIndexes = nullptr;
|
||||
};
|
||||
|
||||
PhongOptionIndexes m_phongOptionIndexes;
|
||||
PhongTextureIndexes m_phongTextureIndexes;
|
||||
PhongUniformOffsets m_phongUniformOffsets;
|
||||
|
||||
static MaterialSettings::Builder Build(PhongBuildOptions& options);
|
||||
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
|
||||
static std::pair<PhongUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
|
||||
|
||||
private:
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
static std::shared_ptr<MaterialSettings> s_phongMaterialSettings;
|
||||
static std::size_t s_phongUniformBlockIndex;
|
||||
static PhongOptionIndexes s_phongOptionIndexes;
|
||||
static PhongTextureIndexes s_phongTextureIndexes;
|
||||
static PhongUniformOffsets s_phongUniformOffsets;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PhongLightingMaterial.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PHONGLIGHTINGMATERIAL_HPP
|
||||
@@ -1,160 +0,0 @@
|
||||
// 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/PhongLightingMaterial.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetEmissiveMap() const
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
return GetMaterial().GetTexture(m_phongTextureIndexes.emissive);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhongLightingMaterial::GetEmissiveSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no emissive map slot");
|
||||
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.emissive);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetHeightMap() const
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no height map slot");
|
||||
return GetMaterial().GetTexture(m_phongTextureIndexes.height);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhongLightingMaterial::GetHeightSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no height map slot");
|
||||
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.height);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetNormalMap() const
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
return GetMaterial().GetTexture(m_phongTextureIndexes.normal);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhongLightingMaterial::GetNormalSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no normal map slot");
|
||||
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.normal);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetSpecularMap() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
return GetMaterial().GetTexture(m_phongTextureIndexes.specular);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhongLightingMaterial::GetSpecularSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.specular);
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasAmbientColor() const
|
||||
{
|
||||
return m_phongUniformOffsets.ambientColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasEmissiveMap() const
|
||||
{
|
||||
return m_phongTextureIndexes.emissive != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasHeightMap() const
|
||||
{
|
||||
return m_phongTextureIndexes.height != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasNormalMap() const
|
||||
{
|
||||
return m_phongTextureIndexes.normal != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasShininess() const
|
||||
{
|
||||
return m_phongUniformOffsets.shininess != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasSpecularColor() const
|
||||
{
|
||||
return m_phongUniformOffsets.specularColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhongLightingMaterial::HasSpecularMap() const
|
||||
{
|
||||
return m_phongTextureIndexes.specular != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetEmissiveMap(std::shared_ptr<Texture> emissiveMap)
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
bool hasEmissiveMap = (emissiveMap != nullptr);
|
||||
GetMaterial().SetTexture(m_phongTextureIndexes.emissive, std::move(emissiveMap));
|
||||
|
||||
if (m_phongOptionIndexes.hasEmissiveMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasEmissiveMap, hasEmissiveMap);
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetEmissiveSampler(TextureSamplerInfo emissiveSampler)
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
GetMaterial().SetTextureSampler(m_phongTextureIndexes.emissive, std::move(emissiveSampler));
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetHeightMap(std::shared_ptr<Texture> heightMap)
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no specular map slot");
|
||||
bool hasHeightMap = (heightMap != nullptr);
|
||||
GetMaterial().SetTexture(m_phongTextureIndexes.height, std::move(heightMap));
|
||||
|
||||
if (m_phongOptionIndexes.hasHeightMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasHeightMap, hasHeightMap);
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetHeightSampler(TextureSamplerInfo heightSampler)
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no height map slot");
|
||||
GetMaterial().SetTextureSampler(m_phongTextureIndexes.height, std::move(heightSampler));
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
bool hasNormalMap = (normalMap != nullptr);
|
||||
GetMaterial().SetTexture(m_phongTextureIndexes.normal, std::move(normalMap));
|
||||
|
||||
if (m_phongOptionIndexes.hasNormalMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasNormalMap, hasNormalMap);
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetNormalSampler(TextureSamplerInfo normalSampler)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
GetMaterial().SetTextureSampler(m_phongTextureIndexes.normal, std::move(normalSampler));
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetSpecularMap(std::shared_ptr<Texture> specularMap)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no specular map slot");
|
||||
bool hasSpecularMap = (specularMap != nullptr);
|
||||
GetMaterial().SetTexture(m_phongTextureIndexes.specular, std::move(specularMap));
|
||||
|
||||
if (m_phongOptionIndexes.hasSpecularMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasSpecularMap, hasSpecularMap);
|
||||
}
|
||||
|
||||
inline void PhongLightingMaterial::SetSpecularSampler(TextureSamplerInfo specularSampler)
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
GetMaterial().SetTextureSampler(m_phongTextureIndexes.specular, std::move(specularSampler));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -1,125 +0,0 @@
|
||||
// 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_PHYSICALLYBASEDMATERIAL_HPP
|
||||
#define NAZARA_GRAPHICS_PHYSICALLYBASEDMATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API PhysicallyBasedMaterial : public BasicMaterial
|
||||
{
|
||||
friend class MaterialPipeline;
|
||||
|
||||
public:
|
||||
PhysicallyBasedMaterial(MaterialPass& material);
|
||||
|
||||
Color GetAmbientColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
|
||||
inline const TextureSamplerInfo& GetEmissiveSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetHeightMap() const;
|
||||
inline const TextureSamplerInfo& GetHeightSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetMetallicMap() const;
|
||||
inline const TextureSamplerInfo& GetMetallicSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetNormalMap() const;
|
||||
inline const TextureSamplerInfo& GetNormalSampler() const;
|
||||
inline const std::shared_ptr<Texture>& GetRoughnessMap() const;
|
||||
inline const TextureSamplerInfo& GetRoughnessSampler() const;
|
||||
float GetShininess() const;
|
||||
Color GetSpecularColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
|
||||
inline const TextureSamplerInfo& GetSpecularSampler() const;
|
||||
|
||||
inline bool HasAmbientColor() const;
|
||||
inline bool HasEmissiveMap() const;
|
||||
inline bool HasHeightMap() const;
|
||||
inline bool HasMetallicMap() const;
|
||||
inline bool HasNormalMap() const;
|
||||
inline bool HasRoughnessMap() const;
|
||||
inline bool HasShininess() const;
|
||||
inline bool HasSpecularColor() const;
|
||||
inline bool HasSpecularMap() const;
|
||||
|
||||
void SetAmbientColor(const Color& ambient);
|
||||
inline void SetEmissiveMap(std::shared_ptr<Texture> emissiveMap);
|
||||
inline void SetEmissiveSampler(TextureSamplerInfo emissiveSampler);
|
||||
inline void SetHeightMap(std::shared_ptr<Texture> heightMap);
|
||||
inline void SetHeightSampler(TextureSamplerInfo heightSampler);
|
||||
inline void SetMetallicMap(std::shared_ptr<Texture> metallicMap);
|
||||
inline void SetMetallicSampler(TextureSamplerInfo metallicSampler);
|
||||
inline void SetNormalMap(std::shared_ptr<Texture> normalMap);
|
||||
inline void SetNormalSampler(TextureSamplerInfo normalSampler);
|
||||
inline void SetRoughnessMap(std::shared_ptr<Texture> roughnessMap);
|
||||
inline void SetRoughnessSampler(TextureSamplerInfo roughnessSampler);
|
||||
void SetShininess(float shininess);
|
||||
void SetSpecularColor(const Color& specular);
|
||||
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
|
||||
inline void SetSpecularSampler(TextureSamplerInfo specularSampler);
|
||||
|
||||
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||
|
||||
protected:
|
||||
struct PbrOptionIndexes
|
||||
{
|
||||
std::size_t hasEmissiveMap;
|
||||
std::size_t hasHeightMap;
|
||||
std::size_t hasMetallicMap;
|
||||
std::size_t hasNormalMap;
|
||||
std::size_t hasRoughnessMap;
|
||||
std::size_t hasSpecularMap;
|
||||
};
|
||||
|
||||
struct PbrUniformOffsets
|
||||
{
|
||||
std::size_t ambientColor;
|
||||
std::size_t shininess;
|
||||
std::size_t totalSize;
|
||||
std::size_t specularColor;
|
||||
};
|
||||
|
||||
struct PbrTextureIndexes
|
||||
{
|
||||
std::size_t emissive;
|
||||
std::size_t height;
|
||||
std::size_t metallic;
|
||||
std::size_t roughness;
|
||||
std::size_t normal;
|
||||
std::size_t specular;
|
||||
};
|
||||
|
||||
struct PbrBuildOptions : BasicBuildOptions
|
||||
{
|
||||
PbrUniformOffsets pbrOffsets;
|
||||
PbrOptionIndexes* pbrOptionIndexes = nullptr;
|
||||
PbrTextureIndexes* pbrTextureIndexes = nullptr;
|
||||
};
|
||||
|
||||
PbrOptionIndexes m_pbrOptionIndexes;
|
||||
PbrTextureIndexes m_pbrTextureIndexes;
|
||||
PbrUniformOffsets m_pbrUniformOffsets;
|
||||
|
||||
static MaterialSettings::Builder Build(PbrBuildOptions& options);
|
||||
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
|
||||
static std::pair<PbrUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
|
||||
|
||||
private:
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
static std::shared_ptr<MaterialSettings> s_pbrMaterialSettings;
|
||||
static std::size_t s_pbrUniformBlockIndex;
|
||||
static PbrOptionIndexes s_pbrOptionIndexes;
|
||||
static PbrTextureIndexes s_pbrTextureIndexes;
|
||||
static PbrUniformOffsets s_pbrUniformOffsets;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PhysicallyBasedMaterial.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PHYSICALLYBASEDMATERIAL_HPP
|
||||
@@ -1,226 +0,0 @@
|
||||
// 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/PhysicallyBasedMaterial.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetEmissiveMap() const
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.emissive);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetEmissiveSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no emissive map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.emissive);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetHeightMap() const
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no height map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.height);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetHeightSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no height map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.height);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetMetallicMap() const
|
||||
{
|
||||
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.metallic);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetMetallicSampler() const
|
||||
{
|
||||
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.metallic);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetNormalMap() const
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.normal);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetNormalSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no normal map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.normal);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetRoughnessMap() const
|
||||
{
|
||||
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.roughness);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetRoughnessSampler() const
|
||||
{
|
||||
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.roughness);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetSpecularMap() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
return GetMaterial().GetTexture(m_pbrTextureIndexes.specular);
|
||||
}
|
||||
|
||||
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetSpecularSampler() const
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.specular);
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasAmbientColor() const
|
||||
{
|
||||
return m_pbrUniformOffsets.ambientColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasEmissiveMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.emissive != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasHeightMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.height != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasMetallicMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.metallic != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasNormalMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.normal != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasRoughnessMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.roughness != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasShininess() const
|
||||
{
|
||||
return m_pbrUniformOffsets.shininess != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasSpecularColor() const
|
||||
{
|
||||
return m_pbrUniformOffsets.specularColor != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline bool PhysicallyBasedMaterial::HasSpecularMap() const
|
||||
{
|
||||
return m_pbrTextureIndexes.specular != MaterialSettings::InvalidIndex;
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetEmissiveMap(std::shared_ptr<Texture> emissiveMap)
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
bool hasEmissiveMap = (emissiveMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.emissive, std::move(emissiveMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasEmissiveMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasEmissiveMap, hasEmissiveMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetEmissiveSampler(TextureSamplerInfo emissiveSampler)
|
||||
{
|
||||
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.emissive, std::move(emissiveSampler));
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetHeightMap(std::shared_ptr<Texture> heightMap)
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no specular map slot");
|
||||
bool hasHeightMap = (heightMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.height, std::move(heightMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasHeightMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasHeightMap, hasHeightMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetHeightSampler(TextureSamplerInfo heightSampler)
|
||||
{
|
||||
NazaraAssert(HasHeightMap(), "Material has no height map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.height, std::move(heightSampler));
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetMetallicMap(std::shared_ptr<Texture> metallicMap)
|
||||
{
|
||||
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
|
||||
bool hasMetallicMap = (metallicMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.metallic, std::move(metallicMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasMetallicMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasMetallicMap, hasMetallicMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetMetallicSampler(TextureSamplerInfo metallicSampler)
|
||||
{
|
||||
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.metallic, std::move(metallicSampler));
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
bool hasNormalMap = (normalMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.normal, std::move(normalMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasNormalMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasNormalMap, hasNormalMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetNormalSampler(TextureSamplerInfo normalSampler)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.normal, std::move(normalSampler));
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetRoughnessMap(std::shared_ptr<Texture> roughnessMap)
|
||||
{
|
||||
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
|
||||
bool hasRoughnessMap = (roughnessMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.roughness, std::move(roughnessMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasRoughnessMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasRoughnessMap, hasRoughnessMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetRoughnessSampler(TextureSamplerInfo metallicSampler)
|
||||
{
|
||||
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.roughness, std::move(metallicSampler));
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetSpecularMap(std::shared_ptr<Texture> specularMap)
|
||||
{
|
||||
NazaraAssert(HasNormalMap(), "Material has no specular map slot");
|
||||
bool hasSpecularMap = (specularMap != nullptr);
|
||||
GetMaterial().SetTexture(m_pbrTextureIndexes.specular, std::move(specularMap));
|
||||
|
||||
if (m_pbrOptionIndexes.hasSpecularMap != MaterialSettings::InvalidIndex)
|
||||
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasSpecularMap, hasSpecularMap);
|
||||
}
|
||||
|
||||
inline void PhysicallyBasedMaterial::SetSpecularSampler(TextureSamplerInfo specularSampler)
|
||||
{
|
||||
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
|
||||
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.specular, std::move(specularSampler));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
31
include/Nazara/Graphics/PredefinedMaterials.hpp
Normal file
31
include/Nazara/Graphics/PredefinedMaterials.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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_PREDEFINEDMATERIALS_HPP
|
||||
#define NAZARA_GRAPHICS_PREDEFINEDMATERIALS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialSettings;
|
||||
|
||||
class NAZARA_GRAPHICS_API PredefinedMaterials
|
||||
{
|
||||
public:
|
||||
PredefinedMaterials() = delete;
|
||||
~PredefinedMaterials() = delete;
|
||||
|
||||
static void AddBasicSettings(MaterialSettings& settings);
|
||||
static void AddPbrSettings(MaterialSettings& settings);
|
||||
static void AddPhongSettings(MaterialSettings& settings);
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PredefinedMaterials.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PREDEFINEDMATERIALS_HPP
|
||||
@@ -2,15 +2,11 @@
|
||||
// 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/DepthMaterial.hpp>
|
||||
#include <Nazara/Graphics/PredefinedMaterials.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const std::shared_ptr<MaterialSettings>& DepthMaterial::GetSettings()
|
||||
{
|
||||
return s_depthMaterialSettings;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -35,7 +35,6 @@ namespace Nz
|
||||
static constexpr std::size_t MaxLightCount = 3;
|
||||
|
||||
static PredefinedLightData GetOffsets();
|
||||
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
|
||||
};
|
||||
|
||||
struct NAZARA_GRAPHICS_API PredefinedInstanceData
|
||||
@@ -45,7 +44,6 @@ namespace Nz
|
||||
std::size_t worldMatrixOffset;
|
||||
|
||||
static PredefinedInstanceData GetOffsets();
|
||||
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
|
||||
};
|
||||
|
||||
struct NAZARA_GRAPHICS_API PredefinedSkeletalData
|
||||
@@ -56,7 +54,6 @@ namespace Nz
|
||||
static constexpr std::size_t MaxMatricesCount = 256;
|
||||
|
||||
static PredefinedSkeletalData GetOffsets();
|
||||
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
|
||||
};
|
||||
|
||||
struct NAZARA_GRAPHICS_API PredefinedViewerData
|
||||
@@ -73,7 +70,6 @@ namespace Nz
|
||||
std::size_t viewProjMatrixOffset;
|
||||
|
||||
static PredefinedViewerData GetOffsets();
|
||||
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP
|
||||
#define NAZARA_GRAPHICS_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API OptionValuePropertyHandler : public PropertyHandler
|
||||
{
|
||||
public:
|
||||
inline OptionValuePropertyHandler(std::string propertyName, std::string optionName);
|
||||
OptionValuePropertyHandler(const OptionValuePropertyHandler&) = default;
|
||||
OptionValuePropertyHandler(OptionValuePropertyHandler&&) = delete;
|
||||
~OptionValuePropertyHandler() = default;
|
||||
|
||||
bool NeedsUpdateOnValueUpdate(std::size_t updatedPropertyIndex) const override;
|
||||
|
||||
void Setup(const Material& material, const ShaderReflection& reflection) override;
|
||||
|
||||
void Update(MaterialInstance& materialInstance) const override;
|
||||
|
||||
OptionValuePropertyHandler& operator=(const OptionValuePropertyHandler&) = delete;
|
||||
OptionValuePropertyHandler& operator=(OptionValuePropertyHandler&&) = delete;
|
||||
|
||||
private:
|
||||
std::size_t m_propertyIndex;
|
||||
std::string m_propertyName;
|
||||
std::string m_optionName;
|
||||
UInt32 m_optionHash;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PropertyHandler/OptionValuePropertyHandler.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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/PropertyHandler/OptionValuePropertyHandler.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline OptionValuePropertyHandler::OptionValuePropertyHandler(std::string propertyName, std::string optionName) :
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_optionName(std::move(optionName))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
54
include/Nazara/Graphics/PropertyHandler/PropertyHandler.hpp
Normal file
54
include/Nazara/Graphics/PropertyHandler/PropertyHandler.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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_PROPERTYHANDLER_PROPERTYHANDLER_HPP
|
||||
#define NAZARA_GRAPHICS_PROPERTYHANDLER_PROPERTYHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <NZSL/Enums.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class Material;
|
||||
class MaterialInstance;
|
||||
class ShaderReflection;
|
||||
|
||||
class NAZARA_GRAPHICS_API PropertyHandler
|
||||
{
|
||||
public:
|
||||
PropertyHandler() = default;
|
||||
PropertyHandler(const PropertyHandler&) = delete;
|
||||
PropertyHandler(PropertyHandler&&) = delete;
|
||||
virtual ~PropertyHandler();
|
||||
|
||||
virtual bool NeedsUpdateOnTextureUpdate(std::size_t updatedTexturePropertyIndex) const;
|
||||
virtual bool NeedsUpdateOnValueUpdate(std::size_t updatedValuePropertyIndex) const;
|
||||
|
||||
virtual void Setup(const Material& material, const ShaderReflection& reflection) = 0;
|
||||
|
||||
virtual void Update(MaterialInstance& materialInstance) const = 0;
|
||||
|
||||
PropertyHandler& operator=(const PropertyHandler&) = delete;
|
||||
PropertyHandler& operator=(PropertyHandler&&) = delete;
|
||||
|
||||
struct SamplerData
|
||||
{
|
||||
std::size_t textureIndex;
|
||||
};
|
||||
|
||||
struct UniformValue
|
||||
{
|
||||
std::size_t uniformBufferIndex;
|
||||
std::size_t offset;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_PROPERTYHANDLER_HPP
|
||||
13
include/Nazara/Graphics/PropertyHandler/PropertyHandler.inl
Normal file
13
include/Nazara/Graphics/PropertyHandler/PropertyHandler.inl
Normal file
@@ -0,0 +1,13 @@
|
||||
// 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/PropertyHandler/PropertyHandler.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP
|
||||
#define NAZARA_GRAPHICS_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API TexturePropertyHandler : public PropertyHandler
|
||||
{
|
||||
public:
|
||||
inline TexturePropertyHandler(std::string propertyName);
|
||||
inline TexturePropertyHandler(std::string propertyName, std::string optionName);
|
||||
inline TexturePropertyHandler(std::string propertyName, std::string samplerTag, std::string optionName);
|
||||
TexturePropertyHandler(const TexturePropertyHandler&) = delete;
|
||||
TexturePropertyHandler(TexturePropertyHandler&&) = delete;
|
||||
~TexturePropertyHandler() = default;
|
||||
|
||||
bool NeedsUpdateOnTextureUpdate(std::size_t updatedPropertyIndex) const override;
|
||||
|
||||
void Setup(const Material& material, const ShaderReflection& reflection) override;
|
||||
|
||||
void Update(MaterialInstance& materialInstance) const override;
|
||||
|
||||
TexturePropertyHandler& operator=(const TexturePropertyHandler&) = delete;
|
||||
TexturePropertyHandler& operator=(TexturePropertyHandler&&) = delete;
|
||||
|
||||
private:
|
||||
std::size_t m_propertyIndex;
|
||||
std::size_t m_textureIndex;
|
||||
std::string m_optionName;
|
||||
std::string m_propertyName;
|
||||
std::string m_samplerTag;
|
||||
UInt32 m_optionHash;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PropertyHandler/TexturePropertyHandler.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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/PropertyHandler/TexturePropertyHandler.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName) :
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_samplerTag(m_propertyName)
|
||||
{
|
||||
}
|
||||
|
||||
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName, std::string optionName) :
|
||||
m_optionName(std::move(optionName)),
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_samplerTag(m_propertyName)
|
||||
{
|
||||
}
|
||||
|
||||
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName, std::string samplerTag, std::string optionName) :
|
||||
m_optionName(std::move(optionName)),
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_samplerTag(std::move(samplerTag))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP
|
||||
#define NAZARA_GRAPHICS_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API UniformValuePropertyHandler : public PropertyHandler
|
||||
{
|
||||
public:
|
||||
inline UniformValuePropertyHandler(std::string propertyName, std::string blockTag = "Settings");
|
||||
inline UniformValuePropertyHandler(std::string propertyName, std::string memberTag, std::string blockTag = "Settings");
|
||||
UniformValuePropertyHandler(const UniformValuePropertyHandler&) = delete;
|
||||
UniformValuePropertyHandler(UniformValuePropertyHandler&&) = delete;
|
||||
~UniformValuePropertyHandler() = default;
|
||||
|
||||
bool NeedsUpdateOnValueUpdate(std::size_t updatedPropertyIndex) const override;
|
||||
|
||||
void Setup(const Material& material, const ShaderReflection& reflection) override;
|
||||
|
||||
void Update(MaterialInstance& materialInstance) const override;
|
||||
|
||||
UniformValuePropertyHandler& operator=(const UniformValuePropertyHandler&) = delete;
|
||||
UniformValuePropertyHandler& operator=(UniformValuePropertyHandler&&) = delete;
|
||||
|
||||
private:
|
||||
std::size_t m_propertyIndex;
|
||||
std::size_t m_offset;
|
||||
std::size_t m_size;
|
||||
std::size_t m_uniformBlockIndex;
|
||||
std::string m_blockTag;
|
||||
std::string m_propertyName;
|
||||
std::string m_memberTag;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PropertyHandler/UniformValuePropertyHandler.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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/PropertyHandler/UniformValuePropertyHandler.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline UniformValuePropertyHandler::UniformValuePropertyHandler(std::string propertyName, std::string blockTag) :
|
||||
m_blockTag(std::move(blockTag)),
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_memberTag(m_propertyName)
|
||||
{
|
||||
}
|
||||
|
||||
inline UniformValuePropertyHandler::UniformValuePropertyHandler(std::string propertyName, std::string memberTag, std::string blockTag) :
|
||||
m_blockTag(std::move(blockTag)),
|
||||
m_propertyName(std::move(propertyName)),
|
||||
m_memberTag(std::move(memberTag))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
54
include/Nazara/Graphics/RenderBufferPool.hpp
Normal file
54
include/Nazara/Graphics/RenderBufferPool.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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_RENDERBUFFERPOOL_HPP
|
||||
#define NAZARA_GRAPHICS_RENDERBUFFERPOOL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderBufferView.hpp>
|
||||
#include <Nazara/Utils/Bitset.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderBuffer;
|
||||
class RenderDevice;
|
||||
|
||||
class NAZARA_GRAPHICS_API RenderBufferPool
|
||||
{
|
||||
public:
|
||||
RenderBufferPool(std::shared_ptr<RenderDevice> renderDevice, BufferType bufferType, std::size_t bufferSize, std::size_t bufferPerBlock = 2048);
|
||||
RenderBufferPool(const RenderBufferPool&) = delete;
|
||||
RenderBufferPool(RenderBufferPool&&) = delete;
|
||||
~RenderBufferPool() = default;
|
||||
|
||||
RenderBufferView Allocate(std::size_t& index);
|
||||
|
||||
void Free(std::size_t index);
|
||||
|
||||
inline UInt64 GetBufferAlignedSize() const;
|
||||
inline UInt64 GetBufferPerBlock() const;
|
||||
inline UInt64 GetBufferSize() const;
|
||||
inline BufferType GetBufferType() const;
|
||||
|
||||
RenderBufferPool& operator=(const RenderBufferPool&) = delete;
|
||||
RenderBufferPool& operator=(RenderBufferPool&&) = delete;
|
||||
|
||||
private:
|
||||
UInt64 m_bufferAlignedSize;
|
||||
UInt64 m_bufferPerBlock;
|
||||
UInt64 m_bufferSize;
|
||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
std::vector<std::shared_ptr<RenderBuffer>> m_bufferBlocks;
|
||||
Bitset<UInt64> m_availableEntries;
|
||||
BufferType m_bufferType;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/RenderBufferPool.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_RENDERBUFFERPOOL_HPP
|
||||
31
include/Nazara/Graphics/RenderBufferPool.inl
Normal file
31
include/Nazara/Graphics/RenderBufferPool.inl
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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/RenderBufferPool.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline UInt64 Nz::RenderBufferPool::GetBufferAlignedSize() const
|
||||
{
|
||||
return m_bufferAlignedSize;
|
||||
}
|
||||
|
||||
inline UInt64 RenderBufferPool::GetBufferPerBlock() const
|
||||
{
|
||||
return m_bufferPerBlock;
|
||||
}
|
||||
|
||||
inline UInt64 RenderBufferPool::GetBufferSize() const
|
||||
{
|
||||
return m_bufferSize;
|
||||
}
|
||||
|
||||
inline BufferType RenderBufferPool::GetBufferType() const
|
||||
{
|
||||
return m_bufferType;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPass;
|
||||
class MaterialInstance;
|
||||
class RenderPipeline;
|
||||
class Skeleton;
|
||||
class VertexDeclaration;
|
||||
@@ -27,7 +27,7 @@ namespace Nz
|
||||
inline void Clear();
|
||||
|
||||
inline std::size_t FetchLayerIndex(int renderLayer) const;
|
||||
inline std::size_t FetchMaterialPassIndex(const MaterialPass* materialPass) const;
|
||||
inline std::size_t FetchMaterialInstanceIndex(const MaterialInstance* materialInstance) const;
|
||||
inline std::size_t FetchPipelineIndex(const RenderPipeline* pipeline) const;
|
||||
inline std::size_t FetchSkeletonIndex(const Skeleton* skeleton) const;
|
||||
inline std::size_t FetchVertexBuffer(const RenderBuffer* vertexBuffer) const;
|
||||
@@ -36,7 +36,7 @@ namespace Nz
|
||||
inline void Finalize();
|
||||
|
||||
inline void RegisterLayer(int renderLayer);
|
||||
inline void RegisterMaterialPass(const MaterialPass* materialPass);
|
||||
inline void RegisterMaterialInstance(const MaterialInstance* materialInstance);
|
||||
inline void RegisterPipeline(const RenderPipeline* pipeline);
|
||||
inline void RegisterSkeleton(const Skeleton* skeleton);
|
||||
inline void RegisterVertexBuffer(const RenderBuffer* vertexBuffer);
|
||||
@@ -45,7 +45,7 @@ namespace Nz
|
||||
private:
|
||||
std::set<int> m_renderLayers;
|
||||
robin_hood::unordered_map<int, std::size_t> m_renderLayerRegistry;
|
||||
robin_hood::unordered_map<const MaterialPass*, std::size_t> m_materialPassRegistry;
|
||||
robin_hood::unordered_map<const MaterialInstance*, std::size_t> m_materialPassRegistry;
|
||||
robin_hood::unordered_map<const RenderPipeline*, std::size_t> m_pipelineRegistry;
|
||||
robin_hood::unordered_map<const RenderBuffer*, std::size_t> m_vertexBufferRegistry;
|
||||
robin_hood::unordered_map<const Skeleton*, std::size_t> m_skeletonRegistry;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Nz
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline std::size_t RenderQueueRegistry::FetchMaterialPassIndex(const MaterialPass* materialPass) const
|
||||
inline std::size_t RenderQueueRegistry::FetchMaterialInstanceIndex(const MaterialInstance* materialPass) const
|
||||
{
|
||||
auto it = m_materialPassRegistry.find(materialPass);
|
||||
assert(it != m_materialPassRegistry.end());
|
||||
@@ -78,9 +78,9 @@ namespace Nz
|
||||
m_renderLayers.insert(renderLayer);
|
||||
}
|
||||
|
||||
inline void RenderQueueRegistry::RegisterMaterialPass(const MaterialPass* materialPass)
|
||||
inline void RenderQueueRegistry::RegisterMaterialInstance(const MaterialInstance* materialInstance)
|
||||
{
|
||||
m_materialPassRegistry.try_emplace(materialPass, m_materialPassRegistry.size());
|
||||
m_materialPassRegistry.try_emplace(materialInstance, m_materialPassRegistry.size());
|
||||
}
|
||||
|
||||
inline void RenderQueueRegistry::RegisterPipeline(const RenderPipeline* pipeline)
|
||||
|
||||
@@ -16,19 +16,19 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPass;
|
||||
class MaterialInstance;
|
||||
class VertexDeclaration;
|
||||
class ViewerInstance;
|
||||
|
||||
class RenderSpriteChain : public RenderElement
|
||||
{
|
||||
public:
|
||||
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, const Recti& scissorBox);
|
||||
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, 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, const Recti& scissorBox);
|
||||
~RenderSpriteChain() = default;
|
||||
|
||||
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||
|
||||
inline const MaterialPass& GetMaterialPass() const;
|
||||
inline const MaterialInstance& GetMaterialInstance() const;
|
||||
inline const RenderPipeline& GetRenderPipeline() const;
|
||||
inline const Recti& GetScissorBox() const;
|
||||
inline std::size_t GetSpriteCount() const;
|
||||
@@ -42,13 +42,14 @@ namespace Nz
|
||||
static constexpr BasicRenderElement ElementType = BasicRenderElement::SpriteChain;
|
||||
|
||||
private:
|
||||
std::shared_ptr<MaterialPass> m_materialPass;
|
||||
std::shared_ptr<MaterialInstance> m_materialInstance;
|
||||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
|
||||
std::shared_ptr<Texture> m_textureOverlay;
|
||||
std::size_t m_spriteCount;
|
||||
const void* m_spriteData;
|
||||
const WorldInstance& m_worldInstance;
|
||||
MaterialPassFlags m_materialFlags;
|
||||
Recti m_scissorBox;
|
||||
int m_renderLayer;
|
||||
};
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
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, const Recti& scissorBox) :
|
||||
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, 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, const Recti& scissorBox) :
|
||||
RenderElement(BasicRenderElement::SpriteChain),
|
||||
m_materialPass(std::move(materialPass)),
|
||||
m_materialInstance(std::move(materialInstance)),
|
||||
m_renderPipeline(std::move(renderPipeline)),
|
||||
m_vertexDeclaration(std::move(vertexDeclaration)),
|
||||
m_textureOverlay(std::move(textureOverlay)),
|
||||
m_spriteCount(spriteCount),
|
||||
m_spriteData(spriteData),
|
||||
m_worldInstance(worldInstance),
|
||||
m_materialFlags(materialFlags),
|
||||
m_scissorBox(scissorBox),
|
||||
m_renderLayer(renderLayer)
|
||||
{
|
||||
@@ -27,7 +28,7 @@ namespace Nz
|
||||
{
|
||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||
|
||||
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::SortByDistance))
|
||||
if (m_materialFlags.Test(MaterialPassFlag::SortByDistance))
|
||||
{
|
||||
UInt64 matFlags = 1;
|
||||
|
||||
@@ -48,7 +49,7 @@ namespace Nz
|
||||
else
|
||||
{
|
||||
UInt64 elementType = GetElementType();
|
||||
UInt64 materialPassIndex = registry.FetchMaterialPassIndex(m_materialPass.get());
|
||||
UInt64 materialInstanceIndex = registry.FetchMaterialInstanceIndex(m_materialInstance.get());
|
||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
|
||||
|
||||
@@ -63,18 +64,18 @@ namespace Nz
|
||||
// - VertexDeclaration (8bits)
|
||||
// - ?? (8bits) - Depth?
|
||||
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
(elementType & 0xF) << 51 |
|
||||
(pipelineIndex & 0xFFFF) << 35 |
|
||||
(materialPassIndex & 0xFFFF) << 23 |
|
||||
(vertexDeclarationIndex & 0xFF) << 7;
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
(elementType & 0xF) << 51 |
|
||||
(pipelineIndex & 0xFFFF) << 35 |
|
||||
(materialInstanceIndex & 0xFFFF) << 23 |
|
||||
(vertexDeclarationIndex & 0xFF) << 7;
|
||||
}
|
||||
}
|
||||
|
||||
inline const MaterialPass& RenderSpriteChain::GetMaterialPass() const
|
||||
inline const MaterialInstance& RenderSpriteChain::GetMaterialInstance() const
|
||||
{
|
||||
return *m_materialPass;
|
||||
return *m_materialInstance;
|
||||
}
|
||||
|
||||
inline const RenderPipeline& RenderSpriteChain::GetRenderPipeline() const
|
||||
@@ -115,7 +116,7 @@ namespace Nz
|
||||
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
|
||||
{
|
||||
registry.RegisterLayer(m_renderLayer);
|
||||
registry.RegisterMaterialPass(m_materialPass.get());
|
||||
registry.RegisterMaterialInstance(m_materialInstance.get());
|
||||
registry.RegisterPipeline(m_renderPipeline.get());
|
||||
registry.RegisterVertexDeclaration(m_vertexDeclaration.get());
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPass;
|
||||
class MaterialInstance;
|
||||
class RenderPipeline;
|
||||
class ShaderBinding;
|
||||
|
||||
class RenderSubmesh : public RenderElement
|
||||
{
|
||||
public:
|
||||
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox);
|
||||
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox);
|
||||
~RenderSubmesh() = default;
|
||||
|
||||
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
|
||||
@@ -32,7 +32,7 @@ namespace Nz
|
||||
inline const RenderBuffer* GetIndexBuffer() const;
|
||||
inline std::size_t GetIndexCount() const;
|
||||
inline IndexType GetIndexType() const;
|
||||
inline const MaterialPass& GetMaterialPass() const;
|
||||
inline const MaterialInstance& GetMaterialInstance() const;
|
||||
inline const RenderPipeline* GetRenderPipeline() const;
|
||||
inline const Recti& GetScissorBox() const;
|
||||
inline const SkeletonInstance* GetSkeletonInstance() const;
|
||||
@@ -46,12 +46,13 @@ namespace Nz
|
||||
private:
|
||||
std::shared_ptr<RenderBuffer> m_indexBuffer;
|
||||
std::shared_ptr<RenderBuffer> m_vertexBuffer;
|
||||
std::shared_ptr<MaterialPass> m_materialPass;
|
||||
std::shared_ptr<MaterialInstance> m_materialInstance;
|
||||
std::shared_ptr<RenderPipeline> m_renderPipeline;
|
||||
std::size_t m_indexCount;
|
||||
const SkeletonInstance* m_skeletonInstance;
|
||||
const WorldInstance& m_worldInstance;
|
||||
IndexType m_indexType;
|
||||
MaterialPassFlags m_materialFlags;
|
||||
Recti m_scissorBox;
|
||||
int m_renderLayer;
|
||||
};
|
||||
|
||||
@@ -9,16 +9,17 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox) :
|
||||
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox) :
|
||||
RenderElement(BasicRenderElement::Submesh),
|
||||
m_indexBuffer(std::move(indexBuffer)),
|
||||
m_vertexBuffer(std::move(vertexBuffer)),
|
||||
m_materialPass(std::move(materialPass)),
|
||||
m_materialInstance(std::move(materialInstance)),
|
||||
m_renderPipeline(std::move(renderPipeline)),
|
||||
m_indexCount(indexCount),
|
||||
m_skeletonInstance(skeletonInstance),
|
||||
m_worldInstance(worldInstance),
|
||||
m_indexType(indexType),
|
||||
m_materialFlags(materialFlags),
|
||||
m_scissorBox(scissorBox),
|
||||
m_renderLayer(renderLayer)
|
||||
{
|
||||
@@ -27,8 +28,8 @@ namespace Nz
|
||||
inline UInt64 RenderSubmesh::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
|
||||
{
|
||||
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
|
||||
|
||||
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::SortByDistance))
|
||||
|
||||
if (m_materialFlags.Test(MaterialPassFlag::SortByDistance))
|
||||
{
|
||||
UInt64 matFlags = 1;
|
||||
|
||||
@@ -48,7 +49,7 @@ namespace Nz
|
||||
else
|
||||
{
|
||||
UInt64 elementType = GetElementType();
|
||||
UInt64 materialPassIndex = registry.FetchMaterialPassIndex(m_materialPass.get());
|
||||
UInt64 materialInstanceIndex = registry.FetchMaterialInstanceIndex(m_materialInstance.get());
|
||||
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
|
||||
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
|
||||
|
||||
@@ -67,12 +68,12 @@ namespace Nz
|
||||
// - VertexBuffer (8bits)
|
||||
// - Skeleton (8bits)
|
||||
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
(elementType & 0xF) << 51 |
|
||||
(pipelineIndex & 0xFFFF) << 35 |
|
||||
(materialPassIndex & 0xFFFF) << 23 |
|
||||
(vertexBufferIndex & 0xFF) << 7 |
|
||||
return (layerIndex & 0xFF) << 60 |
|
||||
(matFlags) << 52 |
|
||||
(elementType & 0xF) << 51 |
|
||||
(pipelineIndex & 0xFFFF) << 35 |
|
||||
(materialInstanceIndex & 0xFFFF) << 23 |
|
||||
(vertexBufferIndex & 0xFF) << 7 |
|
||||
(skeletonIndex & 0xFF);
|
||||
}
|
||||
}
|
||||
@@ -92,9 +93,9 @@ namespace Nz
|
||||
return m_indexType;
|
||||
}
|
||||
|
||||
inline const MaterialPass& RenderSubmesh::GetMaterialPass() const
|
||||
inline const MaterialInstance& RenderSubmesh::GetMaterialInstance() const
|
||||
{
|
||||
return *m_materialPass;
|
||||
return *m_materialInstance;
|
||||
}
|
||||
|
||||
inline const RenderPipeline* RenderSubmesh::GetRenderPipeline() const
|
||||
@@ -125,7 +126,7 @@ namespace Nz
|
||||
inline void RenderSubmesh::Register(RenderQueueRegistry& registry) const
|
||||
{
|
||||
registry.RegisterLayer(m_renderLayer);
|
||||
registry.RegisterMaterialPass(m_materialPass.get());
|
||||
registry.RegisterMaterialInstance(m_materialInstance.get());
|
||||
registry.RegisterPipeline(m_renderPipeline.get());
|
||||
registry.RegisterVertexBuffer(m_vertexBuffer.get());
|
||||
if (m_skeletonInstance)
|
||||
|
||||
108
include/Nazara/Graphics/ShaderReflection.hpp
Normal file
108
include/Nazara/Graphics/ShaderReflection.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// 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_SHADERREFLECTION_HPP
|
||||
#define NAZARA_GRAPHICS_SHADERREFLECTION_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||
#include <NZSL/Ast/Module.hpp>
|
||||
#include <NZSL/Ast/RecursiveVisitor.hpp>
|
||||
#include <NZSL/Math/FieldOffsets.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API ShaderReflection : nzsl::Ast::RecursiveVisitor
|
||||
{
|
||||
public:
|
||||
struct ExternalBlockData;
|
||||
struct OptionData;
|
||||
struct StructData;
|
||||
|
||||
ShaderReflection() = default;
|
||||
ShaderReflection(const ShaderReflection&) = delete;
|
||||
ShaderReflection(ShaderReflection&&) = delete;
|
||||
~ShaderReflection() = default;
|
||||
|
||||
inline const RenderPipelineLayoutInfo& GetPipelineLayoutInfo() const;
|
||||
inline const ExternalBlockData* GetExternalBlockByTag(const std::string& tag) const;
|
||||
inline const OptionData* GetOptionByName(const std::string& optionName) const;
|
||||
inline const StructData* GetStructByIndex(std::size_t structIndex) const;
|
||||
|
||||
void Reflect(nzsl::Ast::Module& module);
|
||||
|
||||
ShaderReflection& operator=(const ShaderReflection&) = delete;
|
||||
ShaderReflection& operator=(ShaderReflection&&) = delete;
|
||||
|
||||
struct ExternalData
|
||||
{
|
||||
UInt32 bindingSet;
|
||||
UInt32 bindingIndex;
|
||||
};
|
||||
|
||||
struct ExternalStorageBlock : ExternalData
|
||||
{
|
||||
std::size_t structIndex;
|
||||
};
|
||||
|
||||
struct ExternalTexture : ExternalData
|
||||
{
|
||||
nzsl::ImageType imageType;
|
||||
nzsl::Ast::PrimitiveType sampledType;
|
||||
};
|
||||
|
||||
struct ExternalUniformBlock : ExternalData
|
||||
{
|
||||
std::size_t structIndex;
|
||||
};
|
||||
|
||||
struct ExternalBlockData
|
||||
{
|
||||
std::unordered_map<std::string /*tag*/, ExternalStorageBlock> storageBlocks;
|
||||
std::unordered_map<std::string /*tag*/, ExternalTexture> samplers;
|
||||
std::unordered_map<std::string /*tag*/, ExternalUniformBlock> uniformBlocks;
|
||||
};
|
||||
|
||||
struct OptionData
|
||||
{
|
||||
nzsl::Ast::ExpressionType type;
|
||||
UInt32 hash;
|
||||
};
|
||||
|
||||
struct StructMemberData
|
||||
{
|
||||
std::size_t offset;
|
||||
std::size_t size;
|
||||
nzsl::Ast::ExpressionType type;
|
||||
};
|
||||
|
||||
struct StructData
|
||||
{
|
||||
StructData(nzsl::StructLayout layout) : fieldOffsets(layout) {}
|
||||
|
||||
std::unordered_map<std::string /*tag*/, StructMemberData> members;
|
||||
nzsl::FieldOffsets fieldOffsets;
|
||||
};
|
||||
|
||||
private:
|
||||
void Visit(nzsl::Ast::ConditionalStatement& node) override;
|
||||
void Visit(nzsl::Ast::DeclareExternalStatement& node) override;
|
||||
void Visit(nzsl::Ast::DeclareOptionStatement& node) override;
|
||||
void Visit(nzsl::Ast::DeclareStructStatement& node) override;
|
||||
|
||||
std::unordered_map<std::string /*tag*/, ExternalBlockData> m_externalBlocks;
|
||||
std::unordered_map<std::string /*name*/, OptionData> m_options;
|
||||
std::unordered_map<std::size_t /*structIndex*/, StructData> m_structs;
|
||||
RenderPipelineLayoutInfo m_pipelineLayoutInfo;
|
||||
bool m_isConditional;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/ShaderReflection.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_SHADERREFLECTION_HPP
|
||||
43
include/Nazara/Graphics/ShaderReflection.inl
Normal file
43
include/Nazara/Graphics/ShaderReflection.inl
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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/ShaderReflection.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const RenderPipelineLayoutInfo& ShaderReflection::GetPipelineLayoutInfo() const
|
||||
{
|
||||
return m_pipelineLayoutInfo;
|
||||
}
|
||||
|
||||
inline auto ShaderReflection::GetExternalBlockByTag(const std::string& tag) const -> const ExternalBlockData*
|
||||
{
|
||||
auto it = m_externalBlocks.find(tag);
|
||||
if (it == m_externalBlocks.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
inline auto ShaderReflection::GetOptionByName(const std::string& optionName) const -> const OptionData*
|
||||
{
|
||||
auto it = m_options.find(optionName);
|
||||
if (it == m_options.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
inline auto ShaderReflection::GetStructByIndex(std::size_t structIndex) const -> const StructData*
|
||||
{
|
||||
auto it = m_structs.find(structIndex);
|
||||
if (it == m_structs.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <Nazara/Utility/Skeleton.hpp>
|
||||
@@ -23,7 +24,7 @@ namespace Nz
|
||||
|
||||
using SkeletonInstancePtr = std::shared_ptr<SkeletonInstance>;
|
||||
|
||||
class NAZARA_GRAPHICS_API SkeletonInstance
|
||||
class NAZARA_GRAPHICS_API SkeletonInstance : public TransferInterface
|
||||
{
|
||||
public:
|
||||
SkeletonInstance(std::shared_ptr<const Skeleton> skeleton);
|
||||
@@ -35,7 +36,7 @@ namespace Nz
|
||||
inline const std::shared_ptr<RenderBuffer>& GetSkeletalBuffer() const;
|
||||
inline const std::shared_ptr<const Skeleton>& GetSkeleton() const;
|
||||
|
||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
|
||||
|
||||
SkeletonInstance& operator=(const SkeletonInstance&) = delete;
|
||||
SkeletonInstance& operator=(SkeletonInstance&& skeletonInstance) noexcept;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Nz
|
||||
public:
|
||||
struct Corner;
|
||||
|
||||
SlicedSprite(std::shared_ptr<Material> material);
|
||||
SlicedSprite(std::shared_ptr<MaterialInstance> material);
|
||||
SlicedSprite(const SlicedSprite&) = delete;
|
||||
SlicedSprite(SlicedSprite&&) noexcept = default;
|
||||
~SlicedSprite() = default;
|
||||
@@ -31,7 +31,7 @@ namespace Nz
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
inline const Corner& GetBottomRightCorner() const;
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
|
||||
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
|
||||
std::size_t GetMaterialCount() const override;
|
||||
inline const Corner& GetTopLeftCorner() const;
|
||||
inline const Rectf& GetTextureCoords() const;
|
||||
@@ -41,7 +41,7 @@ namespace Nz
|
||||
inline void SetCorners(const Corner& topLeftCorner, const Corner& bottomRightCorner);
|
||||
inline void SetCornersSize(const Vector2f& topLeftSize, const Vector2f& bottomRightSize);
|
||||
inline void SetCornersTextureCoords(const Vector2f& topLeftTextureCoords, const Vector2f& bottomRightTextureCoords);
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetSize(const Vector2f& size);
|
||||
inline void SetTextureCoords(const Rectf& textureCoords);
|
||||
inline void SetTextureRect(const Rectf& textureRect);
|
||||
@@ -59,7 +59,7 @@ namespace Nz
|
||||
void UpdateVertices();
|
||||
|
||||
std::array<VertexStruct_XYZ_Color_UV, 4 * 9> m_vertices;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::size_t m_spriteCount;
|
||||
Color m_color;
|
||||
Corner m_topLeftCorner;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Nz
|
||||
UpdateVertices();
|
||||
}
|
||||
|
||||
inline void SlicedSprite::SetMaterial(std::shared_ptr<Material> material)
|
||||
inline void SlicedSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
assert(material);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nz
|
||||
class NAZARA_GRAPHICS_API Sprite : public InstancedRenderable
|
||||
{
|
||||
public:
|
||||
Sprite(std::shared_ptr<Material> material);
|
||||
Sprite(std::shared_ptr<MaterialInstance> material);
|
||||
Sprite(const Sprite&) = delete;
|
||||
Sprite(Sprite&&) noexcept = default;
|
||||
~Sprite() = default;
|
||||
@@ -29,7 +29,7 @@ namespace Nz
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
inline const Color& GetCornerColor(RectCorner corner) const;
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
|
||||
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
|
||||
std::size_t GetMaterialCount() const override;
|
||||
inline const Vector3f& GetOrigin() const;
|
||||
inline const Vector2f& GetSize() const;
|
||||
@@ -38,7 +38,7 @@ namespace Nz
|
||||
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetCornerColor(RectCorner corner, const Color& color);
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetOrigin(const Vector3f& origin);
|
||||
inline void SetSize(const Vector2f& size);
|
||||
inline void SetTextureCoords(const Rectf& textureCoords);
|
||||
@@ -52,7 +52,7 @@ namespace Nz
|
||||
|
||||
std::array<Color, RectCornerCount> m_cornerColor;
|
||||
std::array<VertexStruct_XYZ_Color_UV, 4> m_vertices;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
Color m_color;
|
||||
Rectf m_textureCoords;
|
||||
Vector2f m_size;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Nz
|
||||
UpdateVertices();
|
||||
}
|
||||
|
||||
inline void Sprite::SetMaterial(std::shared_ptr<Material> material)
|
||||
inline void Sprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
assert(material);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPass;
|
||||
class RenderDevice;
|
||||
class RenderPipeline;
|
||||
class ShaderBinding;
|
||||
@@ -85,7 +84,7 @@ namespace Nz
|
||||
UInt8* currentAllocationMemPtr = nullptr;
|
||||
const VertexDeclaration* currentVertexDeclaration = nullptr;
|
||||
RenderBuffer* currentVertexBuffer = nullptr;
|
||||
const MaterialPass* currentMaterialPass = nullptr;
|
||||
const MaterialInstance* currentMaterialInstance = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
const Texture* currentTextureOverlay = nullptr;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Nz
|
||||
class NAZARA_GRAPHICS_API TextSprite : public InstancedRenderable
|
||||
{
|
||||
public:
|
||||
TextSprite(std::shared_ptr<Material> material);
|
||||
TextSprite(std::shared_ptr<MaterialInstance> material = {});
|
||||
TextSprite(const TextSprite&) = delete;
|
||||
TextSprite(TextSprite&&) noexcept = default;
|
||||
~TextSprite() = default;
|
||||
@@ -32,10 +32,10 @@ namespace Nz
|
||||
|
||||
inline void Clear();
|
||||
|
||||
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
|
||||
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
|
||||
std::size_t GetMaterialCount() const override;
|
||||
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
|
||||
void Update(const AbstractTextDrawer& drawer, float scale = 1.f);
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Nz
|
||||
|
||||
std::unordered_map<const AbstractAtlas*, AtlasSlots> m_atlases;
|
||||
mutable std::unordered_map<RenderKey, RenderIndices, HashRenderKey> m_renderInfos;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::vector<RenderData> m_data;
|
||||
std::vector<VertexStruct_XYZ_Color_UV> m_vertices;
|
||||
Recti m_scissorBox;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Nz
|
||||
OnElementInvalidated(this);
|
||||
}
|
||||
|
||||
inline void TextSprite::SetMaterial(std::shared_ptr<Material> material)
|
||||
inline void TextSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
assert(material);
|
||||
|
||||
|
||||
38
include/Nazara/Graphics/TransferInterface.hpp
Normal file
38
include/Nazara/Graphics/TransferInterface.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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_TRANSFERINTERFACE_HPP
|
||||
#define NAZARA_GRAPHICS_TRANSFERINTERFACE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Utils/Signal.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API TransferInterface
|
||||
{
|
||||
public:
|
||||
TransferInterface() = default;
|
||||
TransferInterface(const TransferInterface&) = default;
|
||||
TransferInterface(TransferInterface&&) = default;
|
||||
virtual ~TransferInterface();
|
||||
|
||||
virtual void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) = 0;
|
||||
|
||||
TransferInterface& operator=(const TransferInterface&) = default;
|
||||
TransferInterface& operator=(TransferInterface&&) = default;
|
||||
|
||||
NazaraSignal(OnTransferRequired, TransferInterface* /*transfer*/);
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/TransferInterface.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_TRANSFERINTERFACE_HPP
|
||||
12
include/Nazara/Graphics/TransferInterface.inl
Normal file
12
include/Nazara/Graphics/TransferInterface.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// 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/TransferInterface.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <memory>
|
||||
@@ -20,7 +21,7 @@ namespace Nz
|
||||
class RenderBuffer;
|
||||
class UploadPool;
|
||||
|
||||
class NAZARA_GRAPHICS_API ViewerInstance
|
||||
class NAZARA_GRAPHICS_API ViewerInstance : public TransferInterface
|
||||
{
|
||||
public:
|
||||
ViewerInstance();
|
||||
@@ -39,7 +40,8 @@ namespace Nz
|
||||
inline std::shared_ptr<RenderBuffer>& GetViewerBuffer();
|
||||
inline const std::shared_ptr<RenderBuffer>& GetViewerBuffer() const;
|
||||
|
||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
|
||||
|
||||
inline void UpdateEyePosition(const Vector3f& eyePosition);
|
||||
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
|
||||
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix);
|
||||
@@ -54,6 +56,8 @@ namespace Nz
|
||||
ViewerInstance& operator=(ViewerInstance&&) noexcept = default;
|
||||
|
||||
private:
|
||||
inline void InvalidateData();
|
||||
|
||||
std::shared_ptr<RenderBuffer> m_viewerDataBuffer;
|
||||
Matrix4f m_invProjectionMatrix;
|
||||
Matrix4f m_invViewProjMatrix;
|
||||
|
||||
@@ -61,7 +61,8 @@ namespace Nz
|
||||
inline void ViewerInstance::UpdateEyePosition(const Vector3f& eyePosition)
|
||||
{
|
||||
m_eyePosition = eyePosition;
|
||||
m_dataInvalidated = true;
|
||||
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
|
||||
@@ -73,7 +74,7 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix)
|
||||
@@ -84,7 +85,7 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& viewMatrix)
|
||||
@@ -100,7 +101,7 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
|
||||
@@ -113,7 +114,7 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix, const Matrix4f& viewProjMatrix, const Matrix4f& invViewProjMatrix)
|
||||
@@ -126,14 +127,14 @@ namespace Nz
|
||||
m_viewProjMatrix = viewProjMatrix;
|
||||
m_invViewProjMatrix = invViewProjMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateTargetSize(const Vector2f& targetSize)
|
||||
{
|
||||
m_targetSize = targetSize;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix)
|
||||
@@ -145,7 +146,7 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
m_dataInvalidated = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
|
||||
@@ -156,7 +157,13 @@ namespace Nz
|
||||
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
|
||||
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
|
||||
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void ViewerInstance::InvalidateData()
|
||||
{
|
||||
m_dataInvalidated = true;
|
||||
OnTransferRequired(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/TransferInterface.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <memory>
|
||||
@@ -22,7 +23,7 @@ namespace Nz
|
||||
|
||||
using WorldInstancePtr = std::shared_ptr<WorldInstance>;
|
||||
|
||||
class NAZARA_GRAPHICS_API WorldInstance
|
||||
class NAZARA_GRAPHICS_API WorldInstance : public TransferInterface
|
||||
{
|
||||
public:
|
||||
WorldInstance();
|
||||
@@ -35,7 +36,8 @@ namespace Nz
|
||||
inline const Matrix4f& GetInvWorldMatrix() const;
|
||||
inline const Matrix4f& GetWorldMatrix() const;
|
||||
|
||||
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
|
||||
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
|
||||
|
||||
inline void UpdateWorldMatrix(const Matrix4f& worldMatrix);
|
||||
inline void UpdateWorldMatrix(const Matrix4f& worldMatrix, const Matrix4f& invWorldMatrix);
|
||||
|
||||
@@ -43,6 +45,8 @@ namespace Nz
|
||||
WorldInstance& operator=(WorldInstance&&) noexcept = default;
|
||||
|
||||
private:
|
||||
inline void InvalidateData();
|
||||
|
||||
std::shared_ptr<RenderBuffer> m_instanceDataBuffer;
|
||||
Matrix4f m_invWorldMatrix;
|
||||
Matrix4f m_worldMatrix;
|
||||
|
||||
@@ -34,14 +34,21 @@ namespace Nz
|
||||
if (!m_worldMatrix.GetInverseTransform(&m_invWorldMatrix))
|
||||
NazaraError("failed to inverse world matrix");
|
||||
|
||||
m_dataInvalided = true;
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
inline void WorldInstance::UpdateWorldMatrix(const Matrix4f& worldMatrix, const Matrix4f& invWorldMatrix)
|
||||
{
|
||||
m_worldMatrix = worldMatrix;
|
||||
m_invWorldMatrix = invWorldMatrix;
|
||||
|
||||
InvalidateData();
|
||||
}
|
||||
|
||||
void WorldInstance::InvalidateData()
|
||||
{
|
||||
m_dataInvalided = true;
|
||||
OnTransferRequired(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Nz
|
||||
class RenderPass;
|
||||
class Texture;
|
||||
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLFboFramebuffer : public OpenGLFramebuffer
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLFboFramebuffer final : public OpenGLFramebuffer
|
||||
{
|
||||
public:
|
||||
OpenGLFboFramebuffer(OpenGLDevice& device, const std::vector<std::shared_ptr<Texture>>& attachments);
|
||||
@@ -31,12 +31,15 @@ namespace Nz
|
||||
|
||||
std::size_t GetColorBufferCount() const override;
|
||||
|
||||
const Vector2ui& GetSize() const override;
|
||||
|
||||
OpenGLFboFramebuffer& operator=(const OpenGLFboFramebuffer&) = delete;
|
||||
OpenGLFboFramebuffer& operator=(OpenGLFboFramebuffer&&) = delete;
|
||||
|
||||
private:
|
||||
GL::Framebuffer m_framebuffer;
|
||||
std::size_t m_colorAttachmentCount;
|
||||
Vector2ui m_size;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define NAZARA_OPENGLRENDERER_OPENGLFRAMEBUFFER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Framebuffer.hpp>
|
||||
|
||||
@@ -26,6 +27,8 @@ namespace Nz
|
||||
|
||||
virtual std::size_t GetColorBufferCount() const = 0;
|
||||
|
||||
virtual const Vector2ui& GetSize() const = 0;
|
||||
|
||||
OpenGLFramebuffer& operator=(const OpenGLFramebuffer&) = delete;
|
||||
OpenGLFramebuffer& operator=(OpenGLFramebuffer&&) noexcept = default;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Nz
|
||||
{
|
||||
class RenderWindow;
|
||||
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow : public RenderWindowImpl
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow final : public RenderWindowImpl
|
||||
{
|
||||
public:
|
||||
OpenGLRenderWindow(RenderWindow& owner);
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Nz
|
||||
|
||||
std::size_t GetColorBufferCount() const override;
|
||||
|
||||
const Vector2ui& GetSize() const override;
|
||||
|
||||
OpenGLWindowFramebuffer& operator=(const OpenGLWindowFramebuffer&) = delete;
|
||||
OpenGLWindowFramebuffer& operator=(OpenGLWindowFramebuffer&&) = delete;
|
||||
|
||||
|
||||
@@ -111,10 +111,10 @@ namespace Nz::GL
|
||||
|
||||
inline void Context::ResetColorWriteMasks() const
|
||||
{
|
||||
if (!m_state.renderStates.colorWrite)
|
||||
if (m_state.renderStates.colorWriteMask != ColorComponentAll)
|
||||
{
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
m_state.renderStates.colorWrite = true;
|
||||
m_state.renderStates.colorWriteMask = ColorComponentAll;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf);
|
||||
typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||
|
||||
// Depth clamp (OpenGL 3.2)
|
||||
#define GL_DEPTH_CLAMP 0x864F
|
||||
|
||||
// Clip control (OpenGL 4.5)
|
||||
#define GL_LOWER_LEFT 0x8CA1
|
||||
#define GL_UPPER_LEFT 0x8CA2
|
||||
|
||||
@@ -24,6 +24,24 @@ namespace Nz
|
||||
Store
|
||||
};
|
||||
|
||||
enum class ColorComponent
|
||||
{
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
Alpha
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumAsFlags<ColorComponent>
|
||||
{
|
||||
static constexpr ColorComponent max = ColorComponent::Alpha;
|
||||
};
|
||||
|
||||
using ColorComponentMask = Flags<ColorComponent>;
|
||||
|
||||
constexpr ColorComponentMask ColorComponentAll = ColorComponent::Red | ColorComponent::Green | ColorComponent::Blue | ColorComponent::Alpha;
|
||||
|
||||
enum class FramebufferType
|
||||
{
|
||||
Texture,
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Nz
|
||||
|
||||
struct RenderDeviceLimits
|
||||
{
|
||||
UInt64 minStorageBufferOffsetAlignment;
|
||||
UInt64 minUniformBufferOffsetAlignment;
|
||||
UInt64 maxStorageBufferSize;
|
||||
UInt64 maxUniformBufferSize;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Nz
|
||||
|
||||
struct RenderStates
|
||||
{
|
||||
ColorComponentMask colorWriteMask = ColorComponentAll;
|
||||
FaceFilling faceFilling = FaceFilling::Fill;
|
||||
FaceSide cullingSide = FaceSide::Back;
|
||||
FrontFace frontFace = FrontFace::CounterClockwise;
|
||||
@@ -47,7 +48,6 @@ namespace Nz
|
||||
} stencilBack, stencilFront;
|
||||
|
||||
bool blending = false;
|
||||
bool colorWrite = true;
|
||||
bool depthBuffer = false;
|
||||
bool depthClamp = false;
|
||||
bool depthWrite = true;
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Nz
|
||||
#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false
|
||||
|
||||
NazaraRenderStateBoolMember(blending);
|
||||
NazaraRenderStateBoolMember(colorWrite);
|
||||
NazaraRenderStateBoolMember(depthBuffer);
|
||||
NazaraRenderStateBoolMember(depthClamp);
|
||||
NazaraRenderStateBoolMember(faceCulling);
|
||||
@@ -27,6 +26,7 @@ namespace Nz
|
||||
if (lhs.depthBuffer)
|
||||
NazaraRenderStateBoolMember(depthWrite);
|
||||
|
||||
NazaraRenderStateMember(colorWriteMask);
|
||||
NazaraRenderStateMember(faceFilling);
|
||||
|
||||
if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
|
||||
@@ -91,10 +91,10 @@ namespace std
|
||||
#define NazaraRenderStateBoolDep(dependency, member) parameterHash |= ((pipelineInfo.dependency && pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
|
||||
#define NazaraRenderStateEnum(member) Nz::HashCombine(seed, static_cast<Nz::UInt8>(pipelineInfo.member))
|
||||
#define NazaraRenderStateFloat(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.member / maxDiff) * maxDiff)
|
||||
#define NazaraRenderStateUInt8(member) Nz::HashCombine(seed, pipelineInfo.member)
|
||||
#define NazaraRenderStateUInt32(member) Nz::HashCombine(seed, pipelineInfo.member)
|
||||
|
||||
NazaraRenderStateBool(blending);
|
||||
NazaraRenderStateBool(colorWrite);
|
||||
NazaraRenderStateBool(depthBuffer);
|
||||
NazaraRenderStateBool(depthClamp);
|
||||
NazaraRenderStateBool(faceCulling);
|
||||
@@ -103,6 +103,7 @@ namespace std
|
||||
|
||||
NazaraRenderStateBoolDep(depthBuffer, depthWrite);
|
||||
|
||||
NazaraRenderStateUInt8(colorWriteMask);
|
||||
NazaraRenderStateEnum(faceFilling);
|
||||
|
||||
if (pipelineInfo.blending) //< we don't care about blending state if blending isn't enabled
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Nz
|
||||
|
||||
struct Binding
|
||||
{
|
||||
std::size_t bindingIndex;
|
||||
UInt32 bindingIndex;
|
||||
std::variant<StorageBufferBinding, TextureBinding, UniformBufferBinding> content;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractTextDrawer;
|
||||
class MaterialPass;
|
||||
|
||||
class NAZARA_WIDGETS_API ButtonWidget : public BaseWidget
|
||||
{
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class MaterialPass;
|
||||
|
||||
class NAZARA_WIDGETS_API CheckboxWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -34,20 +34,20 @@ namespace Nz
|
||||
DefaultWidgetTheme& operator=(DefaultWidgetTheme&&) = default;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Material> m_buttonMaterial;
|
||||
std::shared_ptr<Material> m_buttonHoveredMaterial;
|
||||
std::shared_ptr<Material> m_buttonPressedHoveredMaterial;
|
||||
std::shared_ptr<Material> m_buttonPressedMaterial;
|
||||
std::shared_ptr<Material> m_checkboxBackgroundMaterial;
|
||||
std::shared_ptr<Material> m_checkboxBackgroundHoveredMaterial;
|
||||
std::shared_ptr<Material> m_checkboxCheckMaterial;
|
||||
std::shared_ptr<Material> m_checkboxTristateMaterial;
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_scrollbarBackgroundHorizontalMaterial;
|
||||
std::shared_ptr<Material> m_scrollbarBackgroundVerticalMaterial;
|
||||
std::shared_ptr<Material> m_scrollbarButtonMaterial;
|
||||
std::shared_ptr<Material> m_scrollbarButtonHoveredMaterial;
|
||||
std::shared_ptr<Material> m_scrollbarButtonGrabbedMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_buttonMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_buttonHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_buttonPressedHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_buttonPressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_checkboxBackgroundMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_checkboxBackgroundHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_checkboxCheckMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_checkboxTristateMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_scrollbarBackgroundHorizontalMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_scrollbarBackgroundVerticalMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_scrollbarButtonMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_scrollbarButtonHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_scrollbarButtonGrabbedMaterial;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractTextDrawer;
|
||||
class MaterialPass;
|
||||
|
||||
class NAZARA_WIDGETS_API ImageButtonWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material);
|
||||
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, float cornerSize, float cornerTexCoords);
|
||||
ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial, std::shared_ptr<Material> pressedMaterial, float cornerSize, float cornerTexCoords);
|
||||
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material);
|
||||
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, float cornerSize, float cornerTexCoords);
|
||||
ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, std::shared_ptr<MaterialInstance> hoveredMaterial, std::shared_ptr<MaterialInstance> pressedMaterial, float cornerSize, float cornerTexCoords);
|
||||
ImageButtonWidget(const ImageButtonWidget&) = delete;
|
||||
ImageButtonWidget(ImageButtonWidget&&) = default;
|
||||
~ImageButtonWidget() = default;
|
||||
@@ -31,16 +30,16 @@ namespace Nz
|
||||
inline const Color& GetColor() const;
|
||||
inline float GetCornerSize() const;
|
||||
inline float GetCornerTexCoords() const;
|
||||
inline const std::shared_ptr<Material>& GetHoveredMaterial() const;
|
||||
inline const std::shared_ptr<Material>& GetMaterial() const;
|
||||
inline const std::shared_ptr<Material>& GetPressedMaterial() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetHoveredMaterial() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetMaterial() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetPressedMaterial() const;
|
||||
inline const Rectf& GetTextureCoords() const;
|
||||
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetCorner(float size, float texcoords);
|
||||
inline void SetHoveredMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetPressedMaterial(std::shared_ptr<Material> material);
|
||||
inline void SetHoveredMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetPressedMaterial(std::shared_ptr<MaterialInstance> material);
|
||||
inline void SetTextureCoords(const Rectf& coords);
|
||||
|
||||
ImageButtonWidget& operator=(const ImageButtonWidget&) = delete;
|
||||
@@ -61,9 +60,9 @@ namespace Nz
|
||||
void UpdatePreferredSize();
|
||||
|
||||
std::unique_ptr<ImageButtonWidgetStyle> m_style;
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<Material> m_pressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_pressedMaterial;
|
||||
Color m_color;
|
||||
Rectf m_textureCoords;
|
||||
float m_cornerSize;
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material) :
|
||||
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material) :
|
||||
ImageButtonWidget(parent, std::move(material), {}, {}, 0.f, 0.f)
|
||||
{
|
||||
}
|
||||
|
||||
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, float cornerSize, float cornerTexCoords) :
|
||||
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, float cornerSize, float cornerTexCoords) :
|
||||
ImageButtonWidget(parent, std::move(material), {}, {}, cornerSize, cornerTexCoords)
|
||||
{
|
||||
}
|
||||
@@ -32,17 +32,17 @@ namespace Nz
|
||||
return m_cornerTexCoords;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Material>& ImageButtonWidget::GetHoveredMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetHoveredMaterial() const
|
||||
{
|
||||
return m_hoveredMaterial;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Material>& ImageButtonWidget::GetMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetMaterial() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Material>& ImageButtonWidget::GetPressedMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetPressedMaterial() const
|
||||
{
|
||||
return m_pressedMaterial;
|
||||
}
|
||||
@@ -67,14 +67,14 @@ namespace Nz
|
||||
m_style->OnUpdate();
|
||||
}
|
||||
|
||||
inline void ImageButtonWidget::SetHoveredMaterial(std::shared_ptr<Material> material)
|
||||
inline void ImageButtonWidget::SetHoveredMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
m_hoveredMaterial = std::move(material);
|
||||
|
||||
m_style->OnUpdate();
|
||||
}
|
||||
|
||||
inline void ImageButtonWidget::SetMaterial(std::shared_ptr<Material> material)
|
||||
inline void ImageButtonWidget::SetMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
m_material = std::move(material);
|
||||
UpdatePreferredSize();
|
||||
@@ -82,7 +82,7 @@ namespace Nz
|
||||
m_style->OnUpdate();
|
||||
}
|
||||
|
||||
inline void ImageButtonWidget::SetPressedMaterial(std::shared_ptr<Material> material)
|
||||
inline void ImageButtonWidget::SetPressedMaterial(std::shared_ptr<MaterialInstance> material)
|
||||
{
|
||||
m_pressedMaterial = std::move(material);
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@ namespace Nz
|
||||
class NAZARA_WIDGETS_API ImageWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
ImageWidget(BaseWidget* parent, std::shared_ptr<Material> material);
|
||||
ImageWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material);
|
||||
ImageWidget(const ImageWidget&) = delete;
|
||||
ImageWidget(ImageWidget&&) = default;
|
||||
~ImageWidget() = default;
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
inline const std::shared_ptr<Material>& GetMaterial() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetMaterial() const;
|
||||
inline const Rectf& GetTextureCoords() const;
|
||||
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetMaterial(const std::shared_ptr<Material>& texture);
|
||||
inline void SetMaterial(const std::shared_ptr<MaterialInstance>& texture);
|
||||
inline void SetTextureCoords(const Rectf& coords);
|
||||
inline void SetTextureRect(const Rectf& rect);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Nz
|
||||
return m_sprite->GetColor();
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Material>& ImageWidget::GetMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& ImageWidget::GetMaterial() const
|
||||
{
|
||||
return m_sprite->GetMaterial();
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace Nz
|
||||
m_sprite->SetColor(color);
|
||||
}
|
||||
|
||||
inline void ImageWidget::SetMaterial(const std::shared_ptr<Material>& texture)
|
||||
inline void ImageWidget::SetMaterial(const std::shared_ptr<MaterialInstance>& texture)
|
||||
{
|
||||
m_sprite->SetMaterial(texture);
|
||||
UpdatePreferredSize();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractTextDrawer;
|
||||
class MaterialPass;
|
||||
|
||||
class NAZARA_WIDGETS_API ScrollbarButtonWidget : public BaseWidget
|
||||
{
|
||||
|
||||
@@ -40,10 +40,10 @@ namespace Nz
|
||||
|
||||
struct StyleConfig
|
||||
{
|
||||
std::shared_ptr<Material> hoveredMaterial;
|
||||
std::shared_ptr<Material> material;
|
||||
std::shared_ptr<Material> pressedMaterial;
|
||||
std::shared_ptr<Material> pressedHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> material;
|
||||
std::shared_ptr<MaterialInstance> pressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> pressedHoveredMaterial;
|
||||
float cornerSize;
|
||||
float cornerTexCoords;
|
||||
};
|
||||
@@ -52,10 +52,10 @@ namespace Nz
|
||||
virtual void UpdateMaterial(bool hovered, bool pressed);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<Material> m_pressedMaterial;
|
||||
std::shared_ptr<Material> m_pressedHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_pressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_pressedHoveredMaterial;
|
||||
std::shared_ptr<SlicedSprite> m_sprite;
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
entt::entity m_spriteEntity;
|
||||
@@ -87,10 +87,10 @@ namespace Nz
|
||||
|
||||
struct StyleConfig
|
||||
{
|
||||
std::shared_ptr<Material> backgroundMaterial;
|
||||
std::shared_ptr<Material> backgroundHoveredMaterial;
|
||||
std::shared_ptr<Material> checkMaterial;
|
||||
std::shared_ptr<Material> tristateMaterial;
|
||||
std::shared_ptr<MaterialInstance> backgroundMaterial;
|
||||
std::shared_ptr<MaterialInstance> backgroundHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> checkMaterial;
|
||||
std::shared_ptr<MaterialInstance> tristateMaterial;
|
||||
float backgroundCornerSize;
|
||||
float backgroundCornerTexCoords;
|
||||
};
|
||||
@@ -99,10 +99,10 @@ namespace Nz
|
||||
virtual void UpdateMaterial(bool hovered);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Material> m_checkMaterial;
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<Material> m_tristateMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_checkMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_tristateMaterial;
|
||||
std::shared_ptr<Sprite> m_checkSprite;
|
||||
std::shared_ptr<SlicedSprite> m_backgroundSprite;
|
||||
entt::entity m_backgroundEntity;
|
||||
@@ -135,7 +135,7 @@ namespace Nz
|
||||
|
||||
struct StyleConfig
|
||||
{
|
||||
std::shared_ptr<Material> hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> hoveredMaterial;
|
||||
float hoveredCornerSize;
|
||||
float hoveredCornerTexCoords;
|
||||
};
|
||||
@@ -154,7 +154,7 @@ namespace Nz
|
||||
class NAZARA_WIDGETS_API SimpleLabelWidgetStyle : public LabelWidgetStyle
|
||||
{
|
||||
public:
|
||||
SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial = {});
|
||||
SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<MaterialInstance> material, std::shared_ptr<MaterialInstance> hoveredMaterial = {});
|
||||
SimpleLabelWidgetStyle(const SimpleLabelWidgetStyle&) = delete;
|
||||
SimpleLabelWidgetStyle(SimpleLabelWidgetStyle&&) = default;
|
||||
~SimpleLabelWidgetStyle() = default;
|
||||
@@ -174,8 +174,8 @@ namespace Nz
|
||||
virtual void UpdateMaterial(bool hovered);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
entt::entity m_entity;
|
||||
};
|
||||
@@ -196,8 +196,8 @@ namespace Nz
|
||||
SimpleScrollAreaWidgetStyle& operator=(SimpleScrollAreaWidgetStyle&&) = default;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
entt::entity m_entity;
|
||||
};
|
||||
@@ -221,8 +221,8 @@ namespace Nz
|
||||
|
||||
struct StyleConfig
|
||||
{
|
||||
std::shared_ptr<Material> backgroundHorizontalMaterial;
|
||||
std::shared_ptr<Material> backgroundVerticalMaterial;
|
||||
std::shared_ptr<MaterialInstance> backgroundHorizontalMaterial;
|
||||
std::shared_ptr<MaterialInstance> backgroundVerticalMaterial;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -257,10 +257,10 @@ namespace Nz
|
||||
|
||||
struct StyleConfig
|
||||
{
|
||||
std::shared_ptr<Material> material;
|
||||
std::shared_ptr<Material> grabbedMaterial;
|
||||
std::shared_ptr<Material> grabbedHoveredMaterial;
|
||||
std::shared_ptr<Material> hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> material;
|
||||
std::shared_ptr<MaterialInstance> grabbedMaterial;
|
||||
std::shared_ptr<MaterialInstance> grabbedHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> hoveredMaterial;
|
||||
float cornerSize;
|
||||
float cornerTexCoords;
|
||||
};
|
||||
@@ -270,10 +270,10 @@ namespace Nz
|
||||
|
||||
private:
|
||||
StyleConfig m_config;
|
||||
std::shared_ptr<Material> m_hoveredMaterial;
|
||||
std::shared_ptr<Material> m_material;
|
||||
std::shared_ptr<Material> m_pressedMaterial;
|
||||
std::shared_ptr<Material> m_pressedHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_material;
|
||||
std::shared_ptr<MaterialInstance> m_pressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_pressedHoveredMaterial;
|
||||
std::shared_ptr<SlicedSprite> m_sprite;
|
||||
entt::entity m_entity;
|
||||
bool m_isHovered;
|
||||
|
||||
@@ -56,18 +56,18 @@ namespace Nz
|
||||
|
||||
struct Config
|
||||
{
|
||||
std::shared_ptr<Material> scrollbarButtonDownMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonDownHoveredMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonDownPressedMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonLeftMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonLeftHoveredMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonLeftPressedMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonRightMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonRightHoveredMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonRightPressedMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonUpMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonUpHoveredMaterial;
|
||||
std::shared_ptr<Material> scrollbarButtonUpPressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonDownMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonDownHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonDownPressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonLeftMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonLeftHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonLeftPressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonRightMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonRightHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonRightPressedMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonUpMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonUpHoveredMaterial;
|
||||
std::shared_ptr<MaterialInstance> scrollbarButtonUpPressedMaterial;
|
||||
float scrollbarButtonCornerSize;
|
||||
float scrollbarButtonCornerTexcoords;
|
||||
};
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
namespace Nz
|
||||
{
|
||||
class Material;
|
||||
class MaterialPass;
|
||||
|
||||
class NAZARA_WIDGETS_API Widgets : public ModuleBase<Widgets>
|
||||
{
|
||||
@@ -30,21 +29,16 @@ namespace Nz
|
||||
Widgets(Config config);
|
||||
~Widgets() = default;
|
||||
|
||||
inline const std::shared_ptr<Material>& GetOpaqueMaterial() const;
|
||||
inline const std::shared_ptr<MaterialPass>& GetOpaqueMaterialPass() const;
|
||||
|
||||
inline const std::shared_ptr<Material>& GetTransparentMaterial() const;
|
||||
inline const std::shared_ptr<MaterialPass>& GetTransparentMaterialPass() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetOpaqueMaterial() const;
|
||||
inline const std::shared_ptr<MaterialInstance>& GetTransparentMaterial() const;
|
||||
|
||||
struct Config {};
|
||||
|
||||
private:
|
||||
void CreateDefaultMaterials();
|
||||
|
||||
std::shared_ptr<Material> m_opaqueMaterial;
|
||||
std::shared_ptr<Material> m_transparentMaterial;
|
||||
std::shared_ptr<MaterialPass> m_opaqueMaterialPass;
|
||||
std::shared_ptr<MaterialPass> m_transparentMaterialPass;
|
||||
std::shared_ptr<MaterialInstance> m_opaqueMaterial;
|
||||
std::shared_ptr<MaterialInstance> m_transparentMaterial;
|
||||
|
||||
static Widgets* s_instance;
|
||||
};
|
||||
|
||||
@@ -7,25 +7,15 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const std::shared_ptr<Material>& Widgets::GetOpaqueMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& Widgets::GetOpaqueMaterial() const
|
||||
{
|
||||
return m_opaqueMaterial;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<MaterialPass>& Widgets::GetOpaqueMaterialPass() const
|
||||
{
|
||||
return m_opaqueMaterialPass;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Material>& Widgets::GetTransparentMaterial() const
|
||||
inline const std::shared_ptr<MaterialInstance>& Widgets::GetTransparentMaterial() const
|
||||
{
|
||||
return m_transparentMaterial;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<MaterialPass>& Widgets::GetTransparentMaterialPass() const
|
||||
{
|
||||
return m_transparentMaterialPass;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/DebugOff.hpp>
|
||||
|
||||
Reference in New Issue
Block a user