Graphics: WIP (almost working)

This commit is contained in:
Jérôme Leclercq
2020-10-30 23:08:48 +01:00
parent 73e86407b3
commit 89609570f4
28 changed files with 1036 additions and 2262 deletions

View File

@@ -17,24 +17,22 @@ namespace Nz
friend class MaterialPipeline;
public:
BasicMaterial(Material* material);
BasicMaterial(Material& material);
inline const TextureRef& GetAlphaMap() const;
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
float GetAlphaThreshold() const;
Color GetDiffuseColor() const;
inline const TextureRef& GetDiffuseMap() const;
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
inline bool HasAlphaMap() const;
inline bool HasAlphaThreshold() const;
inline bool HasDiffuseColor() const;
inline bool HasDiffuseMap() const;
inline bool SetAlphaMap(const String& textureName);
inline void SetAlphaMap(TextureRef alphaMap);
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
void SetAlphaThreshold(float alphaThreshold);
void SetDiffuseColor(const Color& diffuse);
inline bool SetDiffuseMap(const String& textureName);
inline void SetDiffuseMap(TextureRef diffuseMap);
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
static const std::shared_ptr<MaterialSettings>& GetSettings();
@@ -54,14 +52,13 @@ namespace Nz
static bool Initialize();
static void Uninitialize();
MaterialRef m_material;
Material& m_material;
std::size_t m_uniformBlockIndex;
TextureIndexes m_textureIndexes;
UniformOffsets m_uniformOffsets;
static std::shared_ptr<MaterialSettings> s_materialSettings;
static std::size_t s_uniformBlockIndex;
static RenderPipelineLayoutRef s_renderPipelineLayout;
static TextureIndexes s_textureIndexes;
static UniformOffsets s_uniformOffsets;
};

View File

@@ -9,16 +9,16 @@
namespace Nz
{
inline const TextureRef& BasicMaterial::GetAlphaMap() const
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.alpha);
return m_material.GetTexture(m_textureIndexes.alpha);
}
inline const TextureRef& BasicMaterial::GetDiffuseMap() const
inline const std::shared_ptr<Texture>& BasicMaterial::GetDiffuseMap() const
{
NazaraAssert(HasDiffuseMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.diffuse);
return m_material.GetTexture(m_textureIndexes.diffuse);
}
inline bool BasicMaterial::HasAlphaMap() const
@@ -41,50 +41,16 @@ namespace Nz
return m_textureIndexes.diffuse != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::SetAlphaMap(const String& textureName)
{
TextureRef texture = TextureLibrary::Query(textureName);
if (!texture)
{
texture = TextureManager::Get(textureName);
if (!texture)
{
NazaraError("Failed to get alpha map \"" + textureName + "\"");
return false;
}
}
SetAlphaMap(std::move(texture));
return true;
}
inline void BasicMaterial::SetAlphaMap(TextureRef alphaMap)
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
m_material->SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
}
inline bool BasicMaterial::SetDiffuseMap(const String& textureName)
{
TextureRef texture = TextureLibrary::Query(textureName);
if (!texture)
{
texture = TextureManager::Get(textureName);
if (!texture)
{
NazaraError("Failed to get diffuse map \"" + textureName + "\"");
return false;
}
}
SetDiffuseMap(std::move(texture));
return true;
}
inline void BasicMaterial::SetDiffuseMap(TextureRef diffuseMap)
inline void BasicMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
{
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
m_material->SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
}
}

View File

@@ -26,7 +26,7 @@ namespace Nz
struct Config;
Graphics(Config config);
~Graphics() = default;
~Graphics();
inline RenderDevice& GetRenderDevice();

View File

@@ -23,38 +23,20 @@
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Utility/UniformBuffer.hpp>
#include <array>
#include <string>
#include <vector>
namespace Nz
{
struct NAZARA_GRAPHICS_API MaterialParams : ResourceParameters
{
bool loadAlphaMap = true;
bool loadDiffuseMap = true;
bool loadEmissiveMap = true;
bool loadHeightMap = true;
bool loadNormalMap = true;
bool loadSpecularMap = true;
std::string shaderName = "Basic";
bool IsValid() const;
};
class NAZARA_GRAPHICS_API Material : public RefCounted, public Resource
{
public:
Material(std::shared_ptr<const MaterialSettings> settings);
inline Material(const Material& material);
inline ~Material();
void Apply(const MaterialPipeline::Instance& instance) const;
void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams());
inline void Configure(const MaterialPipeline* pipeline);
inline void Configure(std::shared_ptr<MaterialPipeline> pipeline);
inline void Configure(const MaterialPipelineInfo& pipelineInfo);
inline bool Configure(const String& pipelineName);
inline void EnableAlphaTest(bool alphaTest);
inline void EnableBlending(bool blending);
@@ -71,25 +53,23 @@ namespace Nz
inline void EnableVertexColor(bool vertexColor);
inline void EnsurePipelineUpdate() const;
inline RendererComparison GetDepthFunc() const;
inline RendererComparison GetDepthCompareFunc() const;
inline BlendFunc GetDstBlend() const;
inline FaceSide GetFaceCulling() const;
inline FaceFilling GetFaceFilling() const;
inline float GetLineWidth() const;
inline const MaterialPipeline* GetPipeline() const;
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
inline const MaterialPipelineInfo& GetPipelineInfo() const;
inline float GetPointSize() const;
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
inline const std::shared_ptr<Shader>& GetShader() const;
inline const std::shared_ptr<ShaderStage>& GetShader(ShaderStageType shaderStage) const;
inline BlendFunc GetSrcBlend() const;
inline UniformBuffer* GetSharedUniformBuffer(std::size_t bufferIndex) const;
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(std::size_t textureIndex) const;
inline UniformBufferRef& GetUniformBuffer(std::size_t bufferIndex);
inline const UniformBufferRef& GetUniformBuffer(std::size_t bufferIndex) const;
inline bool HasDepthMaterial() const;
inline bool HasTexture(std::size_t textureIndex) const;
inline bool HasVertexColor() const;
@@ -106,21 +86,17 @@ namespace Nz
inline bool IsShadowCastingEnabled() const;
inline bool IsShadowReceiveEnabled() const;
void SaveToParameters(ParameterList* matData);
inline void SetDepthFunc(RendererComparison depthFunc);
inline void SetDepthCompareFunc(RendererComparison depthFunc);
inline void SetDstBlend(BlendFunc func);
inline void SetFaceCulling(FaceSide faceSide);
inline void SetFaceFilling(FaceFilling filling);
inline void SetLineWidth(float lineWidth);
inline void SetPointSize(float pointSize);
inline void SetShader(std::shared_ptr<Shader> shader);
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBuffer* uniformBuffer);
inline void SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader);
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer);
inline void SetSrcBlend(BlendFunc func);
inline void SetTexture(std::size_t textureIndex, Texture* texture);
inline void SetTextureSampler(std::size_t textureIndex, const TextureSampler& sampler);
inline Material& operator=(const Material& material);
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
inline void SetTextureSampler(std::size_t textureIndex, std::shared_ptr<TextureSampler> sampler);
// Signals:
NazaraSignal(OnMaterialRelease, const Material* /*material*/);
@@ -138,7 +114,7 @@ namespace Nz
std::shared_ptr<const MaterialSettings> m_settings;
std::vector<MaterialTexture> m_textures;
std::vector<UniformBufferRef> m_uniformBuffers;
mutable const MaterialPipeline* m_pipeline;
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
MaterialPipelineInfo m_pipelineInfo;
mutable bool m_pipelineUpdated;
bool m_shadowCastingEnabled;

View File

@@ -9,18 +9,6 @@
namespace Nz
{
/*!
* \brief Constructs a Material object by assignation
*
* \param material Material to copy into this
*/
inline Material::Material(const Material& material) :
RefCounted(),
Resource(material)
{
operator=(material);
}
/*!
* \brief Destructs the object and calls OnMaterialRelease
*
@@ -40,11 +28,11 @@ namespace Nz
*
* \see Configure
*/
inline void Material::Configure(const MaterialPipeline* pipeline)
inline void Material::Configure(std::shared_ptr<MaterialPipeline> pipeline)
{
NazaraAssert(pipeline, "Invalid material pipeline");
m_pipeline = pipeline;
m_pipeline = std::move(pipeline);
m_pipelineInfo = m_pipeline->GetInfo();
m_pipelineUpdated = true;
}
@@ -65,28 +53,6 @@ namespace Nz
InvalidatePipeline();
}
/*!
* \brief Reset material pipeline state
*
* Sets the material pipeline using a name to lookup in the MaterialPipelineLibrary
*
* \return True if the material pipeline was found in the library
*
* \see Configure
*/
inline bool Material::Configure(const String& pipelineName)
{
MaterialPipelineRef pipeline = MaterialPipelineLibrary::Query(pipelineName);
if (!pipeline)
{
NazaraError("Failed to get pipeline \"" + pipelineName + "\"");
return false;
}
Configure(std::move(pipeline));
return true;
}
/*!
* \brief Enable/Disable alpha test for this material
*
@@ -377,23 +343,11 @@ namespace Nz
* \see EnableDepthTest
* \see SetAmbientColor
*/
inline RendererComparison Material::GetDepthFunc() const
inline RendererComparison Material::GetDepthCompareFunc() const
{
return m_pipelineInfo.depthCompare;
}
/*!
* \brief Gets the depth material
*
* \return Constant reference to the depth material
*
* \see EnableShadowCasting
*/
inline const MaterialRef& Material::GetDepthMaterial() const
{
return m_depthMaterial;
}
/*!
* \brief Gets the dst in blend
*
@@ -440,7 +394,7 @@ namespace Nz
* \brief Gets the render states
* \return Constant reference to the render states
*/
inline const MaterialPipeline* Material::GetPipeline() const
inline const std::shared_ptr<MaterialPipeline>& Material::GetPipeline() const
{
EnsurePipelineUpdate();
@@ -465,18 +419,6 @@ namespace Nz
return m_pipelineInfo.pointSize;
}
/*!
* \brief Gets the reflection mode of the material
*
* \return Current reflection mode
*
* \see SetReflectionMode
*/
inline ReflectionMode Material::GetReflectionMode() const
{
return m_reflectionMode;
}
inline const std::shared_ptr<const MaterialSettings>& Material::GetSettings() const
{
return m_settings;
@@ -486,9 +428,9 @@ namespace Nz
* \brief Gets the über-shader used by this material
* \return Constant pointer to the über-shader used
*/
inline const UberShader* Material::GetShader() const
inline const std::shared_ptr<ShaderStage>& Material::GetShader(ShaderStageType shaderStage) const
{
return m_pipelineInfo.uberShader;
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)];
}
/*!
@@ -500,19 +442,13 @@ namespace Nz
return m_pipelineInfo.srcBlend;
}
inline const TextureRef& Material::GetTexture(std::size_t textureIndex) const
inline const std::shared_ptr<Texture>& Material::GetTexture(std::size_t textureIndex) const
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
return m_textures[textureIndex].texture;
}
inline TextureSampler& Material::GetTextureSampler(std::size_t textureIndex)
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
return m_textures[textureIndex].sampler;
}
inline const TextureSampler& Material::GetTextureSampler(std::size_t textureIndex) const
inline const std::shared_ptr<TextureSampler>& Material::GetTextureSampler(std::size_t textureIndex) const
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
return m_textures[textureIndex].sampler;
@@ -530,15 +466,9 @@ namespace Nz
return m_uniformBuffers[bufferIndex];
}
inline bool Material::HasDepthMaterial() const
{
return m_depthMaterial.IsValid();
}
inline bool Material::HasTexture(std::size_t textureIndex) const
{
Texture* texture = GetTexture(textureIndex);
return texture && texture->IsValid();
return GetTexture(textureIndex) != nullptr;
}
/*!
@@ -667,24 +597,13 @@ namespace Nz
*
* \remark Invalidates the pipeline
*/
inline void Material::SetDepthFunc(RendererComparison depthFunc)
inline void Material::SetDepthCompareFunc(RendererComparison depthFunc)
{
m_pipelineInfo.depthFunc = depthFunc;
m_pipelineInfo.depthCompare = depthFunc;
InvalidatePipeline();
}
/*!
* \brief Sets the depth material
* \return true If successful
*
* \param depthMaterial Material for depth
*/
inline void Material::SetDepthMaterial(MaterialRef depthMaterial)
{
m_depthMaterial = std::move(depthMaterial);
}
/*!
* \brief Sets the dst in blend
*
@@ -763,34 +682,6 @@ namespace Nz
InvalidatePipeline();
}
/*!
* \brief Changes reflection mode of the material
*
* When reflections are enabled, the material will render reflections from the object environment according to the reflection mode.
* This function does change the reflection mode used by the material.
*
* Skyboxes reflections are the cheapest but are static and thus can't reflect other objects.
* Probes reflections are cheap, depending on probes reflection mode, but require regular probe finding from objects using it.
* Real-time reflections are expensive but provide the most accurate reflection map (and can reflect other objects around).
*
* \param reflectionMode The new reflection mode this material should use
*
* \remark May invalidates the pipeline
*
* \see EnableReflectionMapping
* \see IsReflectionMappingEnabled
* \see SetReflectionSize
*/
inline void Material::SetReflectionMode(ReflectionMode reflectionMode)
{
if (m_reflectionMode != reflectionMode)
{
OnMaterialReflectionModeChange(this, reflectionMode);
m_reflectionMode = reflectionMode;
}
}
/*!
* \brief Sets the shader with a constant reference to a ubershader
*
@@ -800,52 +691,29 @@ namespace Nz
*
* \see GetShader
*/
inline void Material::SetShader(UberShaderConstRef uberShader)
inline void Material::SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader)
{
m_pipelineInfo.uberShader = std::move(uberShader);
m_pipelineInfo.shaders[UnderlyingCast(shaderStage)] = std::move(shader);
InvalidatePipeline();
}
/*!
* \brief Sets the shader by name
* \return true If successful
*
* \param uberShaderName Named shader
*/
inline bool Material::SetShader(const String& uberShaderName)
{
UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName);
if (!uberShader)
return false;
SetShader(std::move(uberShader));
return true;
}
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBuffer* uniformBuffer)
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer)
{
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid shared uniform buffer index");
m_uniformBuffers[bufferIndex] = uniformBuffer;
m_uniformBuffers[bufferIndex] = std::move(uniformBuffer);
}
inline void Material::SetTexture(std::size_t textureIndex, Texture* texture)
inline void Material::SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture)
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
m_textures[textureIndex].texture = texture;
if (texture)
m_pipelineInfo.textures |= UInt64(1) << UInt64(textureIndex);
else
m_pipelineInfo.textures &= ~(UInt64(1) << UInt64(textureIndex));
InvalidatePipeline();
m_textures[textureIndex].texture = std::move(texture);
}
inline void Material::SetTextureSampler(std::size_t textureIndex, const TextureSampler& sampler)
inline void Material::SetTextureSampler(std::size_t textureIndex, std::shared_ptr<TextureSampler> sampler)
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
m_textures[textureIndex].sampler = sampler;
m_textures[textureIndex].sampler = std::move(sampler);
}
/*!
@@ -864,93 +732,6 @@ namespace Nz
InvalidatePipeline();
}
/*!
* \brief Sets the current material with the content of the other one
* \return A reference to this
*
* \param material The other Material
*/
inline Material& Material::operator=(const Material& material)
{
Resource::operator=(material);
m_settings = material.m_settings;
m_textures = material.m_textures;
m_depthMaterial = material.m_depthMaterial;
m_pipeline = material.m_pipeline;
m_pipelineInfo = material.m_pipelineInfo;
m_pipelineUpdated = material.m_pipelineUpdated;
m_shadowCastingEnabled = material.m_shadowCastingEnabled;
m_reflectionSize = material.m_reflectionSize;
m_pipelineInfo.settings = m_settings;
for (std::size_t i = 0; i < m_uniformBuffers.size(); ++i)
{
const UniformBuffer* sourceBuffer = material.GetUniformBuffer(i);
UniformBuffer* targetBuffer = m_uniformBuffers[i] = UniformBuffer::New(sourceBuffer->GetEndOffset() - sourceBuffer->GetStartOffset(), DataStorage_Hardware, BufferUsage_Dynamic);
if (!targetBuffer->CopyContent(sourceBuffer))
NazaraError("Failed to copy uniform buffer content");
}
SetReflectionMode(material.GetReflectionMode());
return *this;
}
/*!
* \brief Gets the default material
*
* \return Reference to the default material
*
* \remark This material should NOT be modified as it would affect all objects using it
*/
inline MaterialRef Material::GetDefault()
{
return s_defaultMaterial;
}
inline int Material::GetTextureUnit(TextureMap textureMap)
{
return s_textureUnits[textureMap];
}
/*!
* \brief Loads the material from file
* \return true if loading is successful
*
* \param filePath Path to the file
* \param params Parameters for the material
*/
inline MaterialRef Material::LoadFromFile(const String& filePath, const MaterialParams& params)
{
return MaterialLoader::LoadFromFile(filePath, params);
}
/*!
* \brief Loads the material from memory
* \return true if loading is successful
*
* \param data Raw memory
* \param size Size of the memory
* \param params Parameters for the material
*/
inline MaterialRef Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params)
{
return MaterialLoader::LoadFromMemory(data, size, params);
}
/*!
* \brief Loads the material from stream
* \return true if loading is successful
*
* \param stream Stream to the material
* \param params Parameters for the material
*/
inline MaterialRef Material::LoadFromStream(Stream& stream, const MaterialParams& params)
{
return MaterialLoader::LoadFromStream(stream, params);
}
inline void Material::InvalidatePipeline()
{
m_pipelineUpdated = false;
@@ -958,24 +739,9 @@ namespace Nz
inline void Material::UpdatePipeline() const
{
m_pipeline = MaterialPipeline::GetPipeline(m_pipelineInfo);
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
m_pipelineUpdated = true;
}
/*!
* \brief Creates a new material from the arguments
* \return A reference to the newly created material
*
* \param args Arguments for the material
*/
template<typename... Args>
MaterialRef Material::New(Args&&... args)
{
std::unique_ptr<Material> object(new Material(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -17,7 +17,7 @@
namespace Nz
{
class Shader;
class ShaderStage;
struct MaterialPipelineInfo : RenderStates
{
@@ -26,11 +26,9 @@ namespace Nz
bool hasVertexColor = false;
bool reflectionMapping = false;
bool shadowReceive = true;
Nz::UInt64 textures = 0;
std::shared_ptr<RenderPipelineLayout> pipelineLayout;
std::shared_ptr<const MaterialSettings> settings;
std::shared_ptr<Shader> shader;
std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount> shaders;
};
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);
@@ -39,46 +37,33 @@ namespace Nz
class NAZARA_GRAPHICS_API MaterialPipeline
{
public:
struct Instance;
friend class Graphics;
struct Token {};
public:
inline MaterialPipeline(const MaterialPipelineInfo& pipelineInfo, Token);
MaterialPipeline(const MaterialPipeline&) = delete;
MaterialPipeline(MaterialPipeline&&) = delete;
~MaterialPipeline() = default;
inline const Instance& Apply(UInt32 flags = ShaderFlags_None) const;
MaterialPipeline& operator=(const MaterialPipeline&) = delete;
MaterialPipeline& operator=(MaterialPipeline&&) = delete;
inline const MaterialPipelineInfo& GetInfo() const;
inline const Instance& GetInstance(UInt32 flags = ShaderFlags_None) const;
const std::shared_ptr<RenderPipeline>& GetRenderPipeline(const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers) const;
static MaterialPipelineRef GetPipeline(const MaterialPipelineInfo& pipelineInfo);
struct Instance
{
RenderPipeline renderPipeline;
//Shader::LayoutBindings bindings;
//UberShaderInstance* uberInstance = nullptr;
};
static const std::shared_ptr<MaterialPipeline>& Get(const MaterialPipelineInfo& pipelineInfo);
private:
inline MaterialPipeline(const MaterialPipelineInfo& pipelineInfo);
void GenerateRenderPipeline(UInt32 flags) const;
static bool Initialize();
template<typename... Args> static MaterialPipelineRef New(Args&&... args);
static void Uninitialize();
mutable std::vector<std::shared_ptr<RenderPipeline>> m_renderPipelines;
MaterialPipelineInfo m_pipelineInfo;
mutable std::array<Instance, ShaderFlags_Max + 1> m_instances;
using PipelineCache = std::unordered_map<MaterialPipelineInfo, MaterialPipelineRef>;
using PipelineCache = std::unordered_map<MaterialPipelineInfo, std::shared_ptr<MaterialPipeline>>;
static PipelineCache s_pipelineCache;
static MaterialPipelineLibrary::LibraryMap s_library;
};
}

View File

@@ -3,32 +3,16 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/UberShaderInstance.hpp>
#include <functional>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo) :
inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo, Token) :
m_pipelineInfo(pipelineInfo)
{
}
/*!
* \brief Enable pipeline states for rendering
*
* \param flags Shader flags
*/
inline const MaterialPipeline::Instance& MaterialPipeline::Apply(UInt32 flags) const
{
const Instance& instance = GetInstance(flags);
instance.uberInstance->Activate();
Renderer::SetRenderStates(m_pipelineInfo);
return instance;
}
/*!
* \brief Retrieve a MaterialPipelineInfo object describing this pipeline
*
@@ -39,22 +23,6 @@ namespace Nz
return m_pipelineInfo;
}
/*!
* \brief Retrieve (and generate if required) a pipeline instance using shader flags without applying it
*
* \param flags Shader flags
*
* \return Pipeline instance
*/
inline const MaterialPipeline::Instance& MaterialPipeline::GetInstance(UInt32 flags) const
{
const Instance& instance = m_instances[flags];
if (!instance.uberInstance)
GenerateRenderPipeline(flags);
return instance;
}
bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs)
{
if (!operator==(static_cast<const RenderStates&>(lhs), static_cast<const RenderStates&>(rhs)))
@@ -68,9 +36,13 @@ namespace Nz
NazaraPipelineBoolMember(reflectionMapping);
NazaraPipelineBoolMember(shadowReceive);
NazaraPipelineMember(pipelineLayout);
NazaraPipelineMember(settings);
NazaraPipelineMember(shader);
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
{
if (lhs.shaders[i] != rhs.shaders[i])
return false;
}
#undef NazaraPipelineMember
#undef NazaraPipelineBoolMember
@@ -82,20 +54,6 @@ namespace Nz
{
return !operator==(lhs, rhs);
}
/*!
* \brief Creates a new MaterialPipeline from the arguments
* \return A reference to the newly created material pipeline
*
* \param args Arguments for the material pipeline
*/
template<typename... Args>
MaterialPipelineRef MaterialPipeline::New(Args&&... args)
{
std::unique_ptr<MaterialPipeline> object(new MaterialPipeline(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}
namespace std
@@ -121,9 +79,10 @@ namespace std
NazaraPipelineBoolMember(reflectionMapping);
NazaraPipelineBoolMember(shadowReceive);
NazaraPipelineMember(pipelineLayout.get()); //< Hash pointer
NazaraPipelineMember(settings.get()); //< Hash pointer
NazaraPipelineMember(shader.get());
for (const auto& shader : pipelineInfo.shaders)
Nz::HashCombine(seed, shader.get());
#undef NazaraPipelineMember
#undef NazaraPipelineBoolMember

View File

@@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/ShaderStage.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <array>
#include <limits>
@@ -21,6 +22,7 @@ namespace Nz
class MaterialSettings
{
public:
using DefaultShaders = std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount>;
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBinding_Max + 1>;
struct SharedUniformBlock;
@@ -28,11 +30,13 @@ namespace Nz
struct UniformBlock;
inline MaterialSettings();
inline MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBinding);
inline MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBinding, DefaultShaders defaultShaders);
MaterialSettings(const MaterialSettings&) = default;
MaterialSettings(MaterialSettings&&) = delete;
~MaterialSettings() = default;
inline const std::shared_ptr<ShaderStage>& GetDefaultShader(ShaderStageType stage) const;
inline const DefaultShaders& GetDefaultShaders() const;
inline std::size_t GetPredefinedBindingIndex(PredefinedShaderBinding binding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
@@ -83,6 +87,7 @@ namespace Nz
std::vector<SharedUniformBlock> m_sharedUniformBlocks;
std::vector<Texture> m_textures;
std::vector<UniformBlock> m_uniformBlocks;
DefaultShaders m_defaultShaders;
PredefinedBinding m_predefinedBinding;
};
}

View File

@@ -10,14 +10,15 @@
namespace Nz
{
inline MaterialSettings::MaterialSettings() :
MaterialSettings({}, {}, {}, { InvalidIndex })
MaterialSettings({}, {}, {}, { InvalidIndex }, {})
{
}
inline MaterialSettings::MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBindings) :
inline MaterialSettings::MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBindings, DefaultShaders defaultShaders) :
m_sharedUniformBlocks(std::move(sharedUniformBlocks)),
m_textures(std::move(textures)),
m_uniformBlocks(std::move(uniformBlocks)),
m_defaultShaders(std::move(defaultShaders)),
m_predefinedBinding(predefinedBindings)
{
RenderPipelineLayoutInfo info;
@@ -27,7 +28,7 @@ namespace Nz
for (const Texture& textureInfo : m_textures)
{
info.bindings.push_back({
textureInfo.bindingPoint,
//textureInfo.bindingPoint,
ShaderBindingType::Texture,
ShaderStageType_All,
bindingIndex++
@@ -37,7 +38,7 @@ namespace Nz
for (const UniformBlock& ubo : m_uniformBlocks)
{
info.bindings.push_back({
ubo.bindingPoint,
//ubo.bindingPoint,
ShaderBindingType::UniformBuffer,
ShaderStageType_All,
bindingIndex++
@@ -47,7 +48,7 @@ namespace Nz
for (const SharedUniformBlock& ubo : m_sharedUniformBlocks)
{
info.bindings.push_back({
ubo.bindingPoint,
//ubo.bindingPoint,
ShaderBindingType::UniformBuffer,
ShaderStageType_All,
bindingIndex++
@@ -57,9 +58,19 @@ namespace Nz
m_pipelineLayout = Graphics::Instance()->GetRenderDevice().InstantiateRenderPipelineLayout(std::move(info));
}
inline const std::shared_ptr<ShaderStage>& MaterialSettings::GetDefaultShader(ShaderStageType stage) const
{
return m_defaultShaders[UnderlyingCast(stage)];
}
inline auto MaterialSettings::GetDefaultShaders() const -> const DefaultShaders&
{
return m_defaultShaders;
}
inline std::size_t MaterialSettings::GetPredefinedBindingIndex(PredefinedShaderBinding binding) const
{
return m_predefinedBinding[static_cast<std::size_t>(binding)];
return m_predefinedBinding[UnderlyingCast(binding)];
}
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const

View File

@@ -17,21 +17,21 @@ namespace Nz
friend class MaterialPipeline;
public:
PhongLightingMaterial(Material* material);
PhongLightingMaterial(Material& material);
inline const TextureRef& GetAlphaMap() const;
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
float GetAlphaThreshold() const;
Color GetAmbientColor() const;
Color GetDiffuseColor() const;
inline const TextureRef& GetDiffuseMap() const;
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
inline TextureSampler& GetDiffuseSampler();
inline const TextureSampler& GetDiffuseSampler() const;
inline const TextureRef& GetEmissiveMap() const;
inline const TextureRef& GetHeightMap() const;
inline const TextureRef& GetNormalMap() const;
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
inline const std::shared_ptr<Texture>& GetHeightMap() const;
inline const std::shared_ptr<Texture>& GetNormalMap() const;
float GetShininess() const;
Color GetSpecularColor() const;
inline const TextureRef& GetSpecularMap() const;
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
inline TextureSampler& GetSpecularSampler();
inline const TextureSampler& GetSpecularSampler() const;
@@ -47,24 +47,18 @@ namespace Nz
inline bool HasSpecularColor() const;
inline bool HasSpecularMap() const;
inline bool SetAlphaMap(const String& textureName);
inline void SetAlphaMap(TextureRef alphaMap);
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
void SetAlphaThreshold(float alphaThreshold);
void SetAmbientColor(const Color& ambient);
void SetDiffuseColor(const Color& diffuse);
inline bool SetDiffuseMap(const String& textureName);
inline void SetDiffuseMap(TextureRef diffuseMap);
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
inline void SetDiffuseSampler(const TextureSampler& sampler);
inline bool SetEmissiveMap(const String& textureName);
inline void SetEmissiveMap(TextureRef textureName);
inline bool SetHeightMap(const String& textureName);
inline void SetHeightMap(TextureRef textureName);
inline bool SetNormalMap(const String& textureName);
inline void SetNormalMap(TextureRef textureName);
inline void SetEmissiveMap(std::shared_ptr<Texture> textureName);
inline void SetHeightMap(std::shared_ptr<Texture> textureName);
inline void SetNormalMap(std::shared_ptr<Texture> textureName);
void SetShininess(float shininess);
void SetSpecularColor(const Color& specular);
inline bool SetSpecularMap(const String& textureName);
inline void SetSpecularMap(TextureRef specularMap);
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
inline void SetSpecularSampler(const TextureSampler& sampler);
static const std::shared_ptr<MaterialSettings>& GetSettings();
@@ -92,14 +86,13 @@ namespace Nz
static bool Initialize();
static void Uninitialize();
MaterialRef m_material;
Material& m_material;
std::size_t m_phongUniformIndex;
TextureIndexes m_textureIndexes;
PhongUniformOffsets m_phongUniformOffsets;
static std::shared_ptr<MaterialSettings> s_materialSettings;
static std::size_t s_phongUniformBlockIndex;
static RenderPipelineLayoutRef s_renderPipelineLayout;
static TextureIndexes s_textureIndexes;
static PhongUniformOffsets s_phongUniformOffsets;
};

View File

@@ -9,40 +9,40 @@
namespace Nz
{
inline const TextureRef& PhongLightingMaterial::GetAlphaMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetAlphaMap() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.alpha);
return m_material.GetTexture(m_textureIndexes.alpha);
}
inline const TextureRef& PhongLightingMaterial::GetDiffuseMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetDiffuseMap() const
{
NazaraAssert(HasDiffuseMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.diffuse);
return m_material.GetTexture(m_textureIndexes.diffuse);
}
inline const TextureRef& PhongLightingMaterial::GetEmissiveMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetEmissiveMap() const
{
NazaraAssert(HasEmissiveMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.emissive);
return m_material.GetTexture(m_textureIndexes.emissive);
}
inline const TextureRef& PhongLightingMaterial::GetHeightMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetHeightMap() const
{
NazaraAssert(HasHeightMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.height);
return m_material.GetTexture(m_textureIndexes.height);
}
inline const TextureRef& PhongLightingMaterial::GetNormalMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetNormalMap() const
{
NazaraAssert(HasNormalMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.normal);
return m_material.GetTexture(m_textureIndexes.normal);
}
inline const TextureRef& PhongLightingMaterial::GetSpecularMap() const
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetSpecularMap() const
{
NazaraAssert(HasSpecularMap(), "Material has no alpha map slot");
return m_material->GetTexture(m_textureIndexes.specular);
return m_material.GetTexture(m_textureIndexes.specular);
}
inline bool PhongLightingMaterial::HasAlphaMap() const
@@ -100,56 +100,22 @@ namespace Nz
return m_textureIndexes.specular != MaterialSettings::InvalidIndex;
}
inline void PhongLightingMaterial::SetAlphaMap(TextureRef alphaMap)
inline void PhongLightingMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
m_material->SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
}
inline bool PhongLightingMaterial::SetDiffuseMap(const String& textureName)
{
TextureRef texture = TextureLibrary::Query(textureName);
if (!texture)
{
texture = TextureManager::Get(textureName);
if (!texture)
{
NazaraError("Failed to get diffuse map \"" + textureName + "\"");
return false;
}
}
SetDiffuseMap(std::move(texture));
return true;
}
inline void PhongLightingMaterial::SetDiffuseMap(TextureRef diffuseMap)
inline void PhongLightingMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
{
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
m_material->SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
}
inline bool PhongLightingMaterial::SetNormalMap(const String& textureName)
{
TextureRef texture = TextureLibrary::Query(textureName);
if (!texture)
{
texture = TextureManager::Get(textureName);
if (!texture)
{
NazaraError("Failed to get normal map \"" + textureName + "\"");
return false;
}
}
SetNormalMap(std::move(texture));
return true;
}
inline void PhongLightingMaterial::SetNormalMap(TextureRef normalMap)
inline void PhongLightingMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
m_material->SetTexture(m_textureIndexes.normal, std::move(normalMap));
m_material.SetTexture(m_textureIndexes.normal, std::move(normalMap));
}
}

View File

@@ -41,7 +41,7 @@ namespace Nz
std::size_t totalSize;
std::size_t worldMatrixOffset;
static PredefinedInstanceData GetOffset();
static PredefinedInstanceData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock();
};
@@ -58,7 +58,7 @@ namespace Nz
std::size_t viewMatrixOffset;
std::size_t viewProjMatrixOffset;
static PredefinedViewerData GetOffset();
static PredefinedViewerData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock();
};
}