Graphics: WIP (almost working)
This commit is contained in:
parent
73e86407b3
commit
89609570f4
|
|
@ -29,8 +29,16 @@
|
||||||
#ifndef NAZARA_GLOBAL_GRAPHICS_HPP
|
#ifndef NAZARA_GLOBAL_GRAPHICS_HPP
|
||||||
#define NAZARA_GLOBAL_GRAPHICS_HPP
|
#define NAZARA_GLOBAL_GRAPHICS_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
|
#include <Nazara/Graphics/CullingList.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||||
|
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
|
||||||
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
|
#include <Nazara/Graphics/RenderQueue.hpp>
|
||||||
|
|
||||||
#endif // NAZARA_GLOBAL_GRAPHICS_HPP
|
#endif // NAZARA_GLOBAL_GRAPHICS_HPP
|
||||||
|
|
|
||||||
|
|
@ -17,24 +17,22 @@ namespace Nz
|
||||||
friend class MaterialPipeline;
|
friend class MaterialPipeline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BasicMaterial(Material* material);
|
BasicMaterial(Material& material);
|
||||||
|
|
||||||
inline const TextureRef& GetAlphaMap() const;
|
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
||||||
float GetAlphaThreshold() const;
|
float GetAlphaThreshold() const;
|
||||||
Color GetDiffuseColor() const;
|
Color GetDiffuseColor() const;
|
||||||
inline const TextureRef& GetDiffuseMap() const;
|
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
|
||||||
|
|
||||||
inline bool HasAlphaMap() const;
|
inline bool HasAlphaMap() const;
|
||||||
inline bool HasAlphaThreshold() const;
|
inline bool HasAlphaThreshold() const;
|
||||||
inline bool HasDiffuseColor() const;
|
inline bool HasDiffuseColor() const;
|
||||||
inline bool HasDiffuseMap() const;
|
inline bool HasDiffuseMap() const;
|
||||||
|
|
||||||
inline bool SetAlphaMap(const String& textureName);
|
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
||||||
inline void SetAlphaMap(TextureRef alphaMap);
|
|
||||||
void SetAlphaThreshold(float alphaThreshold);
|
void SetAlphaThreshold(float alphaThreshold);
|
||||||
void SetDiffuseColor(const Color& diffuse);
|
void SetDiffuseColor(const Color& diffuse);
|
||||||
inline bool SetDiffuseMap(const String& textureName);
|
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
|
||||||
inline void SetDiffuseMap(TextureRef diffuseMap);
|
|
||||||
|
|
||||||
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||||
|
|
||||||
|
|
@ -54,14 +52,13 @@ namespace Nz
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
||||||
MaterialRef m_material;
|
Material& m_material;
|
||||||
std::size_t m_uniformBlockIndex;
|
std::size_t m_uniformBlockIndex;
|
||||||
TextureIndexes m_textureIndexes;
|
TextureIndexes m_textureIndexes;
|
||||||
UniformOffsets m_uniformOffsets;
|
UniformOffsets m_uniformOffsets;
|
||||||
|
|
||||||
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
||||||
static std::size_t s_uniformBlockIndex;
|
static std::size_t s_uniformBlockIndex;
|
||||||
static RenderPipelineLayoutRef s_renderPipelineLayout;
|
|
||||||
static TextureIndexes s_textureIndexes;
|
static TextureIndexes s_textureIndexes;
|
||||||
static UniformOffsets s_uniformOffsets;
|
static UniformOffsets s_uniformOffsets;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,16 @@
|
||||||
|
|
||||||
namespace Nz
|
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");
|
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");
|
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
|
inline bool BasicMaterial::HasAlphaMap() const
|
||||||
|
|
@ -41,50 +41,16 @@ namespace Nz
|
||||||
return m_textureIndexes.diffuse != MaterialSettings::InvalidIndex;
|
return m_textureIndexes.diffuse != MaterialSettings::InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BasicMaterial::SetAlphaMap(const String& textureName)
|
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
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)
|
inline void BasicMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Nz
|
||||||
struct Config;
|
struct Config;
|
||||||
|
|
||||||
Graphics(Config config);
|
Graphics(Config config);
|
||||||
~Graphics() = default;
|
~Graphics();
|
||||||
|
|
||||||
inline RenderDevice& GetRenderDevice();
|
inline RenderDevice& GetRenderDevice();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,38 +23,20 @@
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||||
#include <Nazara/Utility/UniformBuffer.hpp>
|
#include <Nazara/Utility/UniformBuffer.hpp>
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
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
|
class NAZARA_GRAPHICS_API Material : public RefCounted, public Resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Material(std::shared_ptr<const MaterialSettings> settings);
|
Material(std::shared_ptr<const MaterialSettings> settings);
|
||||||
inline Material(const Material& material);
|
|
||||||
inline ~Material();
|
inline ~Material();
|
||||||
|
|
||||||
void Apply(const MaterialPipeline::Instance& instance) const;
|
inline void Configure(std::shared_ptr<MaterialPipeline> pipeline);
|
||||||
|
|
||||||
void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams());
|
|
||||||
|
|
||||||
inline void Configure(const MaterialPipeline* pipeline);
|
|
||||||
inline void Configure(const MaterialPipelineInfo& pipelineInfo);
|
inline void Configure(const MaterialPipelineInfo& pipelineInfo);
|
||||||
inline bool Configure(const String& pipelineName);
|
|
||||||
|
|
||||||
inline void EnableAlphaTest(bool alphaTest);
|
inline void EnableAlphaTest(bool alphaTest);
|
||||||
inline void EnableBlending(bool blending);
|
inline void EnableBlending(bool blending);
|
||||||
|
|
@ -71,25 +53,23 @@ namespace Nz
|
||||||
inline void EnableVertexColor(bool vertexColor);
|
inline void EnableVertexColor(bool vertexColor);
|
||||||
|
|
||||||
inline void EnsurePipelineUpdate() const;
|
inline void EnsurePipelineUpdate() const;
|
||||||
|
|
||||||
inline RendererComparison GetDepthFunc() const;
|
inline RendererComparison GetDepthCompareFunc() const;
|
||||||
inline BlendFunc GetDstBlend() const;
|
inline BlendFunc GetDstBlend() const;
|
||||||
inline FaceSide GetFaceCulling() const;
|
inline FaceSide GetFaceCulling() const;
|
||||||
inline FaceFilling GetFaceFilling() const;
|
inline FaceFilling GetFaceFilling() const;
|
||||||
inline float GetLineWidth() const;
|
inline float GetLineWidth() const;
|
||||||
inline const MaterialPipeline* GetPipeline() const;
|
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
|
||||||
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
||||||
inline float GetPointSize() const;
|
inline float GetPointSize() const;
|
||||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() 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 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<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||||
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(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 UniformBufferRef& GetUniformBuffer(std::size_t bufferIndex);
|
||||||
inline const UniformBufferRef& GetUniformBuffer(std::size_t bufferIndex) const;
|
inline const UniformBufferRef& GetUniformBuffer(std::size_t bufferIndex) const;
|
||||||
|
|
||||||
inline bool HasDepthMaterial() const;
|
|
||||||
inline bool HasTexture(std::size_t textureIndex) const;
|
inline bool HasTexture(std::size_t textureIndex) const;
|
||||||
inline bool HasVertexColor() const;
|
inline bool HasVertexColor() const;
|
||||||
|
|
||||||
|
|
@ -106,21 +86,17 @@ namespace Nz
|
||||||
inline bool IsShadowCastingEnabled() const;
|
inline bool IsShadowCastingEnabled() const;
|
||||||
inline bool IsShadowReceiveEnabled() const;
|
inline bool IsShadowReceiveEnabled() const;
|
||||||
|
|
||||||
void SaveToParameters(ParameterList* matData);
|
inline void SetDepthCompareFunc(RendererComparison depthFunc);
|
||||||
|
|
||||||
inline void SetDepthFunc(RendererComparison depthFunc);
|
|
||||||
inline void SetDstBlend(BlendFunc func);
|
inline void SetDstBlend(BlendFunc func);
|
||||||
inline void SetFaceCulling(FaceSide faceSide);
|
inline void SetFaceCulling(FaceSide faceSide);
|
||||||
inline void SetFaceFilling(FaceFilling filling);
|
inline void SetFaceFilling(FaceFilling filling);
|
||||||
inline void SetLineWidth(float lineWidth);
|
inline void SetLineWidth(float lineWidth);
|
||||||
inline void SetPointSize(float pointSize);
|
inline void SetPointSize(float pointSize);
|
||||||
inline void SetShader(std::shared_ptr<Shader> shader);
|
inline void SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader);
|
||||||
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBuffer* uniformBuffer);
|
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer);
|
||||||
inline void SetSrcBlend(BlendFunc func);
|
inline void SetSrcBlend(BlendFunc func);
|
||||||
inline void SetTexture(std::size_t textureIndex, Texture* texture);
|
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||||
inline void SetTextureSampler(std::size_t textureIndex, const TextureSampler& sampler);
|
inline void SetTextureSampler(std::size_t textureIndex, std::shared_ptr<TextureSampler> sampler);
|
||||||
|
|
||||||
inline Material& operator=(const Material& material);
|
|
||||||
|
|
||||||
// Signals:
|
// Signals:
|
||||||
NazaraSignal(OnMaterialRelease, const Material* /*material*/);
|
NazaraSignal(OnMaterialRelease, const Material* /*material*/);
|
||||||
|
|
@ -138,7 +114,7 @@ namespace Nz
|
||||||
std::shared_ptr<const MaterialSettings> m_settings;
|
std::shared_ptr<const MaterialSettings> m_settings;
|
||||||
std::vector<MaterialTexture> m_textures;
|
std::vector<MaterialTexture> m_textures;
|
||||||
std::vector<UniformBufferRef> m_uniformBuffers;
|
std::vector<UniformBufferRef> m_uniformBuffers;
|
||||||
mutable const MaterialPipeline* m_pipeline;
|
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
||||||
MaterialPipelineInfo m_pipelineInfo;
|
MaterialPipelineInfo m_pipelineInfo;
|
||||||
mutable bool m_pipelineUpdated;
|
mutable bool m_pipelineUpdated;
|
||||||
bool m_shadowCastingEnabled;
|
bool m_shadowCastingEnabled;
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,6 @@
|
||||||
|
|
||||||
namespace Nz
|
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
|
* \brief Destructs the object and calls OnMaterialRelease
|
||||||
*
|
*
|
||||||
|
|
@ -40,11 +28,11 @@ namespace Nz
|
||||||
*
|
*
|
||||||
* \see Configure
|
* \see Configure
|
||||||
*/
|
*/
|
||||||
inline void Material::Configure(const MaterialPipeline* pipeline)
|
inline void Material::Configure(std::shared_ptr<MaterialPipeline> pipeline)
|
||||||
{
|
{
|
||||||
NazaraAssert(pipeline, "Invalid material pipeline");
|
NazaraAssert(pipeline, "Invalid material pipeline");
|
||||||
|
|
||||||
m_pipeline = pipeline;
|
m_pipeline = std::move(pipeline);
|
||||||
m_pipelineInfo = m_pipeline->GetInfo();
|
m_pipelineInfo = m_pipeline->GetInfo();
|
||||||
m_pipelineUpdated = true;
|
m_pipelineUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
@ -65,28 +53,6 @@ namespace Nz
|
||||||
InvalidatePipeline();
|
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
|
* \brief Enable/Disable alpha test for this material
|
||||||
*
|
*
|
||||||
|
|
@ -377,23 +343,11 @@ namespace Nz
|
||||||
* \see EnableDepthTest
|
* \see EnableDepthTest
|
||||||
* \see SetAmbientColor
|
* \see SetAmbientColor
|
||||||
*/
|
*/
|
||||||
inline RendererComparison Material::GetDepthFunc() const
|
inline RendererComparison Material::GetDepthCompareFunc() const
|
||||||
{
|
{
|
||||||
return m_pipelineInfo.depthCompare;
|
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
|
* \brief Gets the dst in blend
|
||||||
*
|
*
|
||||||
|
|
@ -440,7 +394,7 @@ namespace Nz
|
||||||
* \brief Gets the render states
|
* \brief Gets the render states
|
||||||
* \return Constant reference to 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();
|
EnsurePipelineUpdate();
|
||||||
|
|
||||||
|
|
@ -465,18 +419,6 @@ namespace Nz
|
||||||
return m_pipelineInfo.pointSize;
|
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
|
inline const std::shared_ptr<const MaterialSettings>& Material::GetSettings() const
|
||||||
{
|
{
|
||||||
return m_settings;
|
return m_settings;
|
||||||
|
|
@ -486,9 +428,9 @@ namespace Nz
|
||||||
* \brief Gets the über-shader used by this material
|
* \brief Gets the über-shader used by this material
|
||||||
* \return Constant pointer to the über-shader used
|
* \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;
|
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");
|
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||||
return m_textures[textureIndex].texture;
|
return m_textures[textureIndex].texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TextureSampler& Material::GetTextureSampler(std::size_t textureIndex)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const TextureSampler& Material::GetTextureSampler(std::size_t textureIndex) const
|
|
||||||
{
|
{
|
||||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||||
return m_textures[textureIndex].sampler;
|
return m_textures[textureIndex].sampler;
|
||||||
|
|
@ -530,15 +466,9 @@ namespace Nz
|
||||||
return m_uniformBuffers[bufferIndex];
|
return m_uniformBuffers[bufferIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Material::HasDepthMaterial() const
|
|
||||||
{
|
|
||||||
return m_depthMaterial.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Material::HasTexture(std::size_t textureIndex) const
|
inline bool Material::HasTexture(std::size_t textureIndex) const
|
||||||
{
|
{
|
||||||
Texture* texture = GetTexture(textureIndex);
|
return GetTexture(textureIndex) != nullptr;
|
||||||
return texture && texture->IsValid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -667,24 +597,13 @@ namespace Nz
|
||||||
*
|
*
|
||||||
* \remark Invalidates the pipeline
|
* \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();
|
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
|
* \brief Sets the dst in blend
|
||||||
*
|
*
|
||||||
|
|
@ -763,34 +682,6 @@ namespace Nz
|
||||||
InvalidatePipeline();
|
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
|
* \brief Sets the shader with a constant reference to a ubershader
|
||||||
*
|
*
|
||||||
|
|
@ -800,52 +691,29 @@ namespace Nz
|
||||||
*
|
*
|
||||||
* \see GetShader
|
* \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();
|
InvalidatePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer)
|
||||||
* \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)
|
|
||||||
{
|
{
|
||||||
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid shared uniform buffer index");
|
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");
|
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||||
m_textures[textureIndex].texture = texture;
|
m_textures[textureIndex].texture = std::move(texture);
|
||||||
|
|
||||||
if (texture)
|
|
||||||
m_pipelineInfo.textures |= UInt64(1) << UInt64(textureIndex);
|
|
||||||
else
|
|
||||||
m_pipelineInfo.textures &= ~(UInt64(1) << UInt64(textureIndex));
|
|
||||||
|
|
||||||
InvalidatePipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
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();
|
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()
|
inline void Material::InvalidatePipeline()
|
||||||
{
|
{
|
||||||
m_pipelineUpdated = false;
|
m_pipelineUpdated = false;
|
||||||
|
|
@ -958,24 +739,9 @@ namespace Nz
|
||||||
|
|
||||||
inline void Material::UpdatePipeline() const
|
inline void Material::UpdatePipeline() const
|
||||||
{
|
{
|
||||||
m_pipeline = MaterialPipeline::GetPipeline(m_pipelineInfo);
|
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
||||||
m_pipelineUpdated = true;
|
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>
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class Shader;
|
class ShaderStage;
|
||||||
|
|
||||||
struct MaterialPipelineInfo : RenderStates
|
struct MaterialPipelineInfo : RenderStates
|
||||||
{
|
{
|
||||||
|
|
@ -26,11 +26,9 @@ namespace Nz
|
||||||
bool hasVertexColor = false;
|
bool hasVertexColor = false;
|
||||||
bool reflectionMapping = false;
|
bool reflectionMapping = false;
|
||||||
bool shadowReceive = true;
|
bool shadowReceive = true;
|
||||||
Nz::UInt64 textures = 0;
|
|
||||||
|
|
||||||
std::shared_ptr<RenderPipelineLayout> pipelineLayout;
|
|
||||||
std::shared_ptr<const MaterialSettings> settings;
|
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);
|
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);
|
||||||
|
|
@ -39,46 +37,33 @@ namespace Nz
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API MaterialPipeline
|
class NAZARA_GRAPHICS_API MaterialPipeline
|
||||||
{
|
{
|
||||||
public:
|
friend class Graphics;
|
||||||
struct Instance;
|
|
||||||
|
|
||||||
|
struct Token {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline MaterialPipeline(const MaterialPipelineInfo& pipelineInfo, Token);
|
||||||
MaterialPipeline(const MaterialPipeline&) = delete;
|
MaterialPipeline(const MaterialPipeline&) = delete;
|
||||||
MaterialPipeline(MaterialPipeline&&) = delete;
|
MaterialPipeline(MaterialPipeline&&) = delete;
|
||||||
~MaterialPipeline() = default;
|
~MaterialPipeline() = default;
|
||||||
|
|
||||||
inline const Instance& Apply(UInt32 flags = ShaderFlags_None) const;
|
|
||||||
|
|
||||||
MaterialPipeline& operator=(const MaterialPipeline&) = delete;
|
MaterialPipeline& operator=(const MaterialPipeline&) = delete;
|
||||||
MaterialPipeline& operator=(MaterialPipeline&&) = delete;
|
MaterialPipeline& operator=(MaterialPipeline&&) = delete;
|
||||||
|
|
||||||
inline const MaterialPipelineInfo& GetInfo() const;
|
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);
|
static const std::shared_ptr<MaterialPipeline>& Get(const MaterialPipelineInfo& pipelineInfo);
|
||||||
|
|
||||||
struct Instance
|
|
||||||
{
|
|
||||||
RenderPipeline renderPipeline;
|
|
||||||
//Shader::LayoutBindings bindings;
|
|
||||||
//UberShaderInstance* uberInstance = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline MaterialPipeline(const MaterialPipelineInfo& pipelineInfo);
|
|
||||||
|
|
||||||
void GenerateRenderPipeline(UInt32 flags) const;
|
|
||||||
|
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
template<typename... Args> static MaterialPipelineRef New(Args&&... args);
|
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
||||||
|
mutable std::vector<std::shared_ptr<RenderPipeline>> m_renderPipelines;
|
||||||
MaterialPipelineInfo m_pipelineInfo;
|
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 PipelineCache s_pipelineCache;
|
||||||
|
|
||||||
static MaterialPipelineLibrary::LibraryMap s_library;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,32 +3,16 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Renderer/UberShaderInstance.hpp>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo) :
|
inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo, Token) :
|
||||||
m_pipelineInfo(pipelineInfo)
|
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
|
* \brief Retrieve a MaterialPipelineInfo object describing this pipeline
|
||||||
*
|
*
|
||||||
|
|
@ -39,22 +23,6 @@ namespace Nz
|
||||||
return m_pipelineInfo;
|
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)
|
bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs)
|
||||||
{
|
{
|
||||||
if (!operator==(static_cast<const RenderStates&>(lhs), static_cast<const RenderStates&>(rhs)))
|
if (!operator==(static_cast<const RenderStates&>(lhs), static_cast<const RenderStates&>(rhs)))
|
||||||
|
|
@ -68,9 +36,13 @@ namespace Nz
|
||||||
NazaraPipelineBoolMember(reflectionMapping);
|
NazaraPipelineBoolMember(reflectionMapping);
|
||||||
NazaraPipelineBoolMember(shadowReceive);
|
NazaraPipelineBoolMember(shadowReceive);
|
||||||
|
|
||||||
NazaraPipelineMember(pipelineLayout);
|
|
||||||
NazaraPipelineMember(settings);
|
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 NazaraPipelineMember
|
||||||
#undef NazaraPipelineBoolMember
|
#undef NazaraPipelineBoolMember
|
||||||
|
|
@ -82,20 +54,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
return !operator==(lhs, rhs);
|
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
|
namespace std
|
||||||
|
|
@ -121,9 +79,10 @@ namespace std
|
||||||
NazaraPipelineBoolMember(reflectionMapping);
|
NazaraPipelineBoolMember(reflectionMapping);
|
||||||
NazaraPipelineBoolMember(shadowReceive);
|
NazaraPipelineBoolMember(shadowReceive);
|
||||||
|
|
||||||
NazaraPipelineMember(pipelineLayout.get()); //< Hash pointer
|
|
||||||
NazaraPipelineMember(settings.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 NazaraPipelineMember
|
||||||
#undef NazaraPipelineBoolMember
|
#undef NazaraPipelineBoolMember
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||||
|
#include <Nazara/Renderer/ShaderStage.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
@ -21,6 +22,7 @@ namespace Nz
|
||||||
class MaterialSettings
|
class MaterialSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using DefaultShaders = std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount>;
|
||||||
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBinding_Max + 1>;
|
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBinding_Max + 1>;
|
||||||
|
|
||||||
struct SharedUniformBlock;
|
struct SharedUniformBlock;
|
||||||
|
|
@ -28,11 +30,13 @@ namespace Nz
|
||||||
struct UniformBlock;
|
struct UniformBlock;
|
||||||
|
|
||||||
inline MaterialSettings();
|
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(const MaterialSettings&) = default;
|
||||||
MaterialSettings(MaterialSettings&&) = delete;
|
MaterialSettings(MaterialSettings&&) = delete;
|
||||||
~MaterialSettings() = default;
|
~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 std::size_t GetPredefinedBindingIndex(PredefinedShaderBinding binding) const;
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
||||||
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
|
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
|
||||||
|
|
@ -83,6 +87,7 @@ namespace Nz
|
||||||
std::vector<SharedUniformBlock> m_sharedUniformBlocks;
|
std::vector<SharedUniformBlock> m_sharedUniformBlocks;
|
||||||
std::vector<Texture> m_textures;
|
std::vector<Texture> m_textures;
|
||||||
std::vector<UniformBlock> m_uniformBlocks;
|
std::vector<UniformBlock> m_uniformBlocks;
|
||||||
|
DefaultShaders m_defaultShaders;
|
||||||
PredefinedBinding m_predefinedBinding;
|
PredefinedBinding m_predefinedBinding;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,15 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline MaterialSettings::MaterialSettings() :
|
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_sharedUniformBlocks(std::move(sharedUniformBlocks)),
|
||||||
m_textures(std::move(textures)),
|
m_textures(std::move(textures)),
|
||||||
m_uniformBlocks(std::move(uniformBlocks)),
|
m_uniformBlocks(std::move(uniformBlocks)),
|
||||||
|
m_defaultShaders(std::move(defaultShaders)),
|
||||||
m_predefinedBinding(predefinedBindings)
|
m_predefinedBinding(predefinedBindings)
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
RenderPipelineLayoutInfo info;
|
||||||
|
|
@ -27,7 +28,7 @@ namespace Nz
|
||||||
for (const Texture& textureInfo : m_textures)
|
for (const Texture& textureInfo : m_textures)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
textureInfo.bindingPoint,
|
//textureInfo.bindingPoint,
|
||||||
ShaderBindingType::Texture,
|
ShaderBindingType::Texture,
|
||||||
ShaderStageType_All,
|
ShaderStageType_All,
|
||||||
bindingIndex++
|
bindingIndex++
|
||||||
|
|
@ -37,7 +38,7 @@ namespace Nz
|
||||||
for (const UniformBlock& ubo : m_uniformBlocks)
|
for (const UniformBlock& ubo : m_uniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
ubo.bindingPoint,
|
//ubo.bindingPoint,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ShaderStageType_All,
|
ShaderStageType_All,
|
||||||
bindingIndex++
|
bindingIndex++
|
||||||
|
|
@ -47,7 +48,7 @@ namespace Nz
|
||||||
for (const SharedUniformBlock& ubo : m_sharedUniformBlocks)
|
for (const SharedUniformBlock& ubo : m_sharedUniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
ubo.bindingPoint,
|
//ubo.bindingPoint,
|
||||||
ShaderBindingType::UniformBuffer,
|
ShaderBindingType::UniformBuffer,
|
||||||
ShaderStageType_All,
|
ShaderStageType_All,
|
||||||
bindingIndex++
|
bindingIndex++
|
||||||
|
|
@ -57,9 +58,19 @@ namespace Nz
|
||||||
m_pipelineLayout = Graphics::Instance()->GetRenderDevice().InstantiateRenderPipelineLayout(std::move(info));
|
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
|
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
|
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
||||||
|
|
|
||||||
|
|
@ -17,21 +17,21 @@ namespace Nz
|
||||||
friend class MaterialPipeline;
|
friend class MaterialPipeline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PhongLightingMaterial(Material* material);
|
PhongLightingMaterial(Material& material);
|
||||||
|
|
||||||
inline const TextureRef& GetAlphaMap() const;
|
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
||||||
float GetAlphaThreshold() const;
|
float GetAlphaThreshold() const;
|
||||||
Color GetAmbientColor() const;
|
Color GetAmbientColor() const;
|
||||||
Color GetDiffuseColor() const;
|
Color GetDiffuseColor() const;
|
||||||
inline const TextureRef& GetDiffuseMap() const;
|
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
|
||||||
inline TextureSampler& GetDiffuseSampler();
|
inline TextureSampler& GetDiffuseSampler();
|
||||||
inline const TextureSampler& GetDiffuseSampler() const;
|
inline const TextureSampler& GetDiffuseSampler() const;
|
||||||
inline const TextureRef& GetEmissiveMap() const;
|
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
|
||||||
inline const TextureRef& GetHeightMap() const;
|
inline const std::shared_ptr<Texture>& GetHeightMap() const;
|
||||||
inline const TextureRef& GetNormalMap() const;
|
inline const std::shared_ptr<Texture>& GetNormalMap() const;
|
||||||
float GetShininess() const;
|
float GetShininess() const;
|
||||||
Color GetSpecularColor() const;
|
Color GetSpecularColor() const;
|
||||||
inline const TextureRef& GetSpecularMap() const;
|
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
|
||||||
inline TextureSampler& GetSpecularSampler();
|
inline TextureSampler& GetSpecularSampler();
|
||||||
inline const TextureSampler& GetSpecularSampler() const;
|
inline const TextureSampler& GetSpecularSampler() const;
|
||||||
|
|
||||||
|
|
@ -47,24 +47,18 @@ namespace Nz
|
||||||
inline bool HasSpecularColor() const;
|
inline bool HasSpecularColor() const;
|
||||||
inline bool HasSpecularMap() const;
|
inline bool HasSpecularMap() const;
|
||||||
|
|
||||||
inline bool SetAlphaMap(const String& textureName);
|
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
||||||
inline void SetAlphaMap(TextureRef alphaMap);
|
|
||||||
void SetAlphaThreshold(float alphaThreshold);
|
void SetAlphaThreshold(float alphaThreshold);
|
||||||
void SetAmbientColor(const Color& ambient);
|
void SetAmbientColor(const Color& ambient);
|
||||||
void SetDiffuseColor(const Color& diffuse);
|
void SetDiffuseColor(const Color& diffuse);
|
||||||
inline bool SetDiffuseMap(const String& textureName);
|
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
|
||||||
inline void SetDiffuseMap(TextureRef diffuseMap);
|
|
||||||
inline void SetDiffuseSampler(const TextureSampler& sampler);
|
inline void SetDiffuseSampler(const TextureSampler& sampler);
|
||||||
inline bool SetEmissiveMap(const String& textureName);
|
inline void SetEmissiveMap(std::shared_ptr<Texture> textureName);
|
||||||
inline void SetEmissiveMap(TextureRef textureName);
|
inline void SetHeightMap(std::shared_ptr<Texture> textureName);
|
||||||
inline bool SetHeightMap(const String& textureName);
|
inline void SetNormalMap(std::shared_ptr<Texture> textureName);
|
||||||
inline void SetHeightMap(TextureRef textureName);
|
|
||||||
inline bool SetNormalMap(const String& textureName);
|
|
||||||
inline void SetNormalMap(TextureRef textureName);
|
|
||||||
void SetShininess(float shininess);
|
void SetShininess(float shininess);
|
||||||
void SetSpecularColor(const Color& specular);
|
void SetSpecularColor(const Color& specular);
|
||||||
inline bool SetSpecularMap(const String& textureName);
|
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
|
||||||
inline void SetSpecularMap(TextureRef specularMap);
|
|
||||||
inline void SetSpecularSampler(const TextureSampler& sampler);
|
inline void SetSpecularSampler(const TextureSampler& sampler);
|
||||||
|
|
||||||
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||||
|
|
@ -92,14 +86,13 @@ namespace Nz
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
||||||
MaterialRef m_material;
|
Material& m_material;
|
||||||
std::size_t m_phongUniformIndex;
|
std::size_t m_phongUniformIndex;
|
||||||
TextureIndexes m_textureIndexes;
|
TextureIndexes m_textureIndexes;
|
||||||
PhongUniformOffsets m_phongUniformOffsets;
|
PhongUniformOffsets m_phongUniformOffsets;
|
||||||
|
|
||||||
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
||||||
static std::size_t s_phongUniformBlockIndex;
|
static std::size_t s_phongUniformBlockIndex;
|
||||||
static RenderPipelineLayoutRef s_renderPipelineLayout;
|
|
||||||
static TextureIndexes s_textureIndexes;
|
static TextureIndexes s_textureIndexes;
|
||||||
static PhongUniformOffsets s_phongUniformOffsets;
|
static PhongUniformOffsets s_phongUniformOffsets;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,40 +9,40 @@
|
||||||
|
|
||||||
namespace Nz
|
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");
|
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");
|
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");
|
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");
|
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");
|
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");
|
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
|
inline bool PhongLightingMaterial::HasAlphaMap() const
|
||||||
|
|
@ -100,56 +100,22 @@ namespace Nz
|
||||||
return m_textureIndexes.specular != MaterialSettings::InvalidIndex;
|
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");
|
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)
|
inline void PhongLightingMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
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)
|
inline void PhongLightingMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace Nz
|
||||||
std::size_t totalSize;
|
std::size_t totalSize;
|
||||||
std::size_t worldMatrixOffset;
|
std::size_t worldMatrixOffset;
|
||||||
|
|
||||||
static PredefinedInstanceData GetOffset();
|
static PredefinedInstanceData GetOffsets();
|
||||||
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ namespace Nz
|
||||||
std::size_t viewMatrixOffset;
|
std::size_t viewMatrixOffset;
|
||||||
std::size_t viewProjMatrixOffset;
|
std::size_t viewProjMatrixOffset;
|
||||||
|
|
||||||
static PredefinedViewerData GetOffset();
|
static PredefinedViewerData GetOffsets();
|
||||||
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
static MaterialSettings::SharedUniformBlock GetUniformBlock();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
struct Binding
|
struct Binding
|
||||||
{
|
{
|
||||||
std::string name; //< FIXME: wtf is this?
|
|
||||||
ShaderBindingType type;
|
ShaderBindingType type;
|
||||||
ShaderStageTypeFlags shaderStageFlags;
|
ShaderStageTypeFlags shaderStageFlags;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,8 @@ namespace Nz
|
||||||
Max = Vertex
|
Max = Vertex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr std::size_t ShaderStageTypeCount = static_cast<std::size_t>(ShaderStageType::Max) + 1;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct EnumAsFlags<ShaderStageType>
|
struct EnumAsFlags<ShaderStageType>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,361 @@
|
||||||
|
{
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"bindingIndex": 5,
|
||||||
|
"name": "viewerData",
|
||||||
|
"structIndex": 2,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 4,
|
||||||
|
"name": "instanceData",
|
||||||
|
"structIndex": 1,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 3,
|
||||||
|
"name": "settings",
|
||||||
|
"structIndex": 0,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{ac98a68f-0160-4189-af31-b8278e7c119c}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{db10f064-504d-4072-a49e-51a061b2efbe}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{c41cd67b-2f34-4ec4-acc6-2f7285e7c6e3}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{74d3ca95-ae1d-496d-88c1-ce6c7327012a}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{07a43c79-67e2-46b1-87d4-e00d2da22820}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{be3547ff-0bf3-4701-9c27-c21e9d1322c3}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
|
"out_index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"locationIndex": 0,
|
||||||
|
"name": "vertNormal",
|
||||||
|
"role": "Normal",
|
||||||
|
"roleIndex": 0,
|
||||||
|
"type": "Float3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locationIndex": 1,
|
||||||
|
"name": "vertUV",
|
||||||
|
"role": "TexCoord",
|
||||||
|
"roleIndex": 0,
|
||||||
|
"type": "Float2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "{c41cd67b-2f34-4ec4-acc6-2f7285e7c6e3}",
|
||||||
|
"model": {
|
||||||
|
"input": "vertNormal",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 103,
|
||||||
|
"y": 173
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_dot",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": "lightFactor"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 278,
|
||||||
|
"y": 212
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{74d3ca95-ae1d-496d-88c1-ce6c7327012a}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec3_constant",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"value": [
|
||||||
|
0,
|
||||||
|
-0.7070000171661377,
|
||||||
|
0.7070000171661377
|
||||||
|
],
|
||||||
|
"variable_name": "lightDir"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 115,
|
||||||
|
"y": 267
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"model": {
|
||||||
|
"name": "SampleTexture",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 299,
|
||||||
|
"y": 488
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{ac98a68f-0160-4189-af31-b8278e7c119c}",
|
||||||
|
"model": {
|
||||||
|
"name": "Texture",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"texture": "MaterialDiffuseMap",
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 103,
|
||||||
|
"y": 470
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{db10f064-504d-4072-a49e-51a061b2efbe}",
|
||||||
|
"model": {
|
||||||
|
"input": "vertUV",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 113,
|
||||||
|
"y": 579
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
|
"model": {
|
||||||
|
"name": "vecfloat_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 488,
|
||||||
|
"y": 376
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{be3547ff-0bf3-4701-9c27-c21e9d1322c3}",
|
||||||
|
"model": {
|
||||||
|
"name": "Output",
|
||||||
|
"output": "RenderTarget0",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 912,
|
||||||
|
"y": 489
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 707,
|
||||||
|
"y": 492
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
||||||
|
"model": {
|
||||||
|
"name": "cast_vec4",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"variable_name": "matDiffuse"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 521,
|
||||||
|
"y": 616
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{07a43c79-67e2-46b1-87d4-e00d2da22820}",
|
||||||
|
"model": {
|
||||||
|
"buffer": "settings",
|
||||||
|
"field": "DiffuseColor",
|
||||||
|
"name": "BufferField",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 309,
|
||||||
|
"y": 637
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"locationIndex": 0,
|
||||||
|
"name": "RenderTarget0",
|
||||||
|
"type": "Float4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"structs": [
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "AlphaThreshold",
|
||||||
|
"type": "Float"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DiffuseColor",
|
||||||
|
"type": "Float3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "BasicSettings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "worldMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invWorldMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "InstanceData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "projectionMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invProjectionMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "viewMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invViewMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "viewProjMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invViewProjMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "renderTargetSize",
|
||||||
|
"type": "Float2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invRenderTargetSize",
|
||||||
|
"type": "Float2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "eyePosition",
|
||||||
|
"type": "Float3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ViewerData"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"bindingIndex": 0,
|
||||||
|
"name": "MaterialAlphaMap",
|
||||||
|
"type": "Sampler2D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 1,
|
||||||
|
"name": "MaterialDiffuseMap",
|
||||||
|
"type": "Sampler2D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 2,
|
||||||
|
"name": "TextureOverlay",
|
||||||
|
"type": "Sampler2D"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "Fragment"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,392 @@
|
||||||
|
{
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"bindingIndex": 5,
|
||||||
|
"name": "viewerData",
|
||||||
|
"structIndex": 2,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 4,
|
||||||
|
"name": "instanceData",
|
||||||
|
"structIndex": 1,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bindingIndex": 3,
|
||||||
|
"name": "settings",
|
||||||
|
"structIndex": 0,
|
||||||
|
"type": "UniformBufferObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"in_id": "{1bb9712b-8bff-4398-9e4e-fba79a04df0e}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{a2fff9e2-af6e-4c7f-80ee-ca3492f3c5ab}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{62731a4b-f054-4f78-82da-08d2584e51ab}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{7ac65f09-7f55-4a6e-9380-1bee5213f079}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{62731a4b-f054-4f78-82da-08d2584e51ab}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{1bb9712b-8bff-4398-9e4e-fba79a04df0e}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{43ce1867-629f-442b-a672-540fa67f1446}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{33840c70-4e37-4127-bab0-23c4a4cb6d7f}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{7ac65f09-7f55-4a6e-9380-1bee5213f079}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{c3b906bc-d230-4026-a32e-34c00eaf4481}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{d8f4d14a-c67a-470f-87bf-8f60d9513c3b}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{d32dfb1d-c8a4-4315-a710-90d2a51f68e8}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{1bb9712b-8bff-4398-9e4e-fba79a04df0e}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{d8f4d14a-c67a-470f-87bf-8f60d9513c3b}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{63bb13f0-55e3-451b-860e-568b65e09b04}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{62731a4b-f054-4f78-82da-08d2584e51ab}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{0fc53363-dbce-4874-8de5-5ca05ae038b7}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{412684ce-0ec2-4db5-964c-10e5b68d43e8}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{d8f4d14a-c67a-470f-87bf-8f60d9513c3b}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{c6058af1-6913-4218-a9b9-11adb5cdffa0}",
|
||||||
|
"out_index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"locationIndex": 0,
|
||||||
|
"name": "inPos",
|
||||||
|
"role": "Position",
|
||||||
|
"roleIndex": 0,
|
||||||
|
"type": "Float3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locationIndex": 1,
|
||||||
|
"name": "inNormals",
|
||||||
|
"role": "Normal",
|
||||||
|
"roleIndex": 0,
|
||||||
|
"type": "Float3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locationIndex": 2,
|
||||||
|
"name": "inTexCoord",
|
||||||
|
"role": "TexCoord",
|
||||||
|
"roleIndex": 0,
|
||||||
|
"type": "Float2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "{43ce1867-629f-442b-a672-540fa67f1446}",
|
||||||
|
"model": {
|
||||||
|
"name": "Output",
|
||||||
|
"output": "vertUV",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 243,
|
||||||
|
"y": 292
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{412684ce-0ec2-4db5-964c-10e5b68d43e8}",
|
||||||
|
"model": {
|
||||||
|
"input": "inNormals",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 79,
|
||||||
|
"y": 184
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{0fc53363-dbce-4874-8de5-5ca05ae038b7}",
|
||||||
|
"model": {
|
||||||
|
"name": "Output",
|
||||||
|
"output": "vertNormal",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 240,
|
||||||
|
"y": 192
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{33840c70-4e37-4127-bab0-23c4a4cb6d7f}",
|
||||||
|
"model": {
|
||||||
|
"input": "inTexCoord",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 82,
|
||||||
|
"y": 287
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{d8f4d14a-c67a-470f-87bf-8f60d9513c3b}",
|
||||||
|
"model": {
|
||||||
|
"name": "mat4_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 248,
|
||||||
|
"y": 424
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{1bb9712b-8bff-4398-9e4e-fba79a04df0e}",
|
||||||
|
"model": {
|
||||||
|
"name": "mat4_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 463,
|
||||||
|
"y": 496
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{c3b906bc-d230-4026-a32e-34c00eaf4481}",
|
||||||
|
"model": {
|
||||||
|
"input": "inPos",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 54,
|
||||||
|
"y": 675
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{62731a4b-f054-4f78-82da-08d2584e51ab}",
|
||||||
|
"model": {
|
||||||
|
"name": "mat4vec_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 699,
|
||||||
|
"y": 512
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{7ac65f09-7f55-4a6e-9380-1bee5213f079}",
|
||||||
|
"model": {
|
||||||
|
"name": "cast_vec4",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 345,
|
||||||
|
"y": 668
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{63bb13f0-55e3-451b-860e-568b65e09b04}",
|
||||||
|
"model": {
|
||||||
|
"name": "PositionOutputValue",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 930,
|
||||||
|
"y": 524
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{d32dfb1d-c8a4-4315-a710-90d2a51f68e8}",
|
||||||
|
"model": {
|
||||||
|
"buffer": "viewerData",
|
||||||
|
"field": "projectionMatrix",
|
||||||
|
"name": "BufferField",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 374
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{c6058af1-6913-4218-a9b9-11adb5cdffa0}",
|
||||||
|
"model": {
|
||||||
|
"buffer": "viewerData",
|
||||||
|
"field": "viewMatrix",
|
||||||
|
"name": "BufferField",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 456
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{a2fff9e2-af6e-4c7f-80ee-ca3492f3c5ab}",
|
||||||
|
"model": {
|
||||||
|
"buffer": "instanceData",
|
||||||
|
"field": "worldMatrix",
|
||||||
|
"name": "BufferField",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 538
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"locationIndex": 0,
|
||||||
|
"name": "vertNormal",
|
||||||
|
"type": "Float3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locationIndex": 1,
|
||||||
|
"name": "vertUV",
|
||||||
|
"type": "Float2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"structs": [
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "AlphaThreshold",
|
||||||
|
"type": "Float"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DiffuseColor",
|
||||||
|
"type": "Float3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "BasicSettings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "worldMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invWorldMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "InstanceData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"name": "projectionMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invProjectionMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "viewMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invViewMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "viewProjMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invViewProjMatrix",
|
||||||
|
"type": "Mat4x4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "renderTargetSize",
|
||||||
|
"type": "Float2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invRenderTargetSize",
|
||||||
|
"type": "Float2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "eyePosition",
|
||||||
|
"type": "Float3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ViewerData"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures": [
|
||||||
|
],
|
||||||
|
"type": "Vertex"
|
||||||
|
}
|
||||||
|
|
@ -17,18 +17,20 @@ namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr std::size_t AlphaMapBinding = 0;
|
const UInt8 r_fragmentShader[] = {
|
||||||
constexpr std::size_t DiffuseMapBinding = 1;
|
#include <Nazara/Graphics/Resources/Shaders/basicmaterial.frag.shader.h>
|
||||||
constexpr std::size_t TextureOverlayBinding = 2;
|
};
|
||||||
|
|
||||||
|
const UInt8 r_vertexShader[] = {
|
||||||
|
#include <Nazara/Graphics/Resources/Shaders/basicmaterial.vert.shader.h>
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicMaterial::BasicMaterial(Material* material) :
|
BasicMaterial::BasicMaterial(Material& material) :
|
||||||
m_material(material)
|
m_material(material)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
// Most common case: don't fetch texture indexes as a little optimization
|
// Most common case: don't fetch texture indexes as a little optimization
|
||||||
const std::shared_ptr<const MaterialSettings>& materialSettings = material->GetSettings();
|
const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
|
||||||
if (materialSettings == s_materialSettings)
|
if (materialSettings == s_materialSettings)
|
||||||
{
|
{
|
||||||
m_textureIndexes = s_textureIndexes;
|
m_textureIndexes = s_textureIndexes;
|
||||||
|
|
@ -51,17 +53,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
||||||
return *AccessByOffset<const float>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
|
return AccessByOffset<const float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color BasicMaterial::GetDiffuseColor() const
|
Color BasicMaterial::GetDiffuseColor() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
||||||
|
|
||||||
const float* colorPtr = AccessByOffset<const float>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
|
const float* colorPtr = AccessByOffset<const float*>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
|
||||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,16 +71,16 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
||||||
*AccessByOffset<float>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
|
AccessByOffset<float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicMaterial::SetDiffuseColor(const Color& diffuse)
|
void BasicMaterial::SetDiffuseColor(const Color& diffuse)
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
||||||
float* colorPtr = AccessByOffset<float>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
|
float* colorPtr = AccessByOffset<float*>(mapper.GetPointer(), m_uniformOffsets.diffuseColor);
|
||||||
colorPtr[0] = diffuse.r / 255.f;
|
colorPtr[0] = diffuse.r / 255.f;
|
||||||
colorPtr[1] = diffuse.g / 255.f;
|
colorPtr[1] = diffuse.g / 255.f;
|
||||||
colorPtr[2] = diffuse.b / 255.f;
|
colorPtr[2] = diffuse.b / 255.f;
|
||||||
|
|
@ -92,31 +94,6 @@ namespace Nz
|
||||||
|
|
||||||
bool BasicMaterial::Initialize()
|
bool BasicMaterial::Initialize()
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
|
||||||
info.bindings.assign({
|
|
||||||
{
|
|
||||||
"MaterialAlphaMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
AlphaMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialDiffuseMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
DiffuseMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"TextureOverlay",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
TextureOverlayBinding
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
s_renderPipelineLayout = RenderPipelineLayout::New();
|
|
||||||
s_renderPipelineLayout->Create(info);
|
|
||||||
|
|
||||||
FieldOffsets fieldOffsets(StructLayout_Std140);
|
FieldOffsets fieldOffsets(StructLayout_Std140);
|
||||||
|
|
||||||
s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
|
s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
|
||||||
|
|
@ -140,15 +117,37 @@ namespace Nz
|
||||||
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
||||||
|
|
||||||
std::vector<UInt8> defaultValues(fieldOffsets.GetSize());
|
std::vector<UInt8> defaultValues(fieldOffsets.GetSize());
|
||||||
*AccessByOffset<Vector4f>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||||
*AccessByOffset<float>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
|
AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::Texture> textures;
|
||||||
|
s_textureIndexes.alpha = textures.size();
|
||||||
|
textures.push_back({
|
||||||
|
"MaterialAlphaMap",
|
||||||
|
"Alpha",
|
||||||
|
ImageType_2D
|
||||||
|
});
|
||||||
|
|
||||||
|
s_textureIndexes.diffuse = textures.size();
|
||||||
|
textures.push_back({
|
||||||
|
"MaterialDiffuseMap",
|
||||||
|
"Diffuse",
|
||||||
|
ImageType_2D
|
||||||
|
});
|
||||||
|
|
||||||
|
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
|
||||||
|
textures.push_back({
|
||||||
|
"TextureOverlay",
|
||||||
|
"Overlay",
|
||||||
|
ImageType_2D
|
||||||
|
});
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
||||||
s_uniformBlockIndex = uniformBlocks.size();
|
s_uniformBlockIndex = uniformBlocks.size();
|
||||||
uniformBlocks.assign({
|
uniformBlocks.assign({
|
||||||
{
|
{
|
||||||
"BasicSettings",
|
|
||||||
fieldOffsets.GetSize(),
|
fieldOffsets.GetSize(),
|
||||||
|
"BasicSettings",
|
||||||
"MaterialBasicSettings",
|
"MaterialBasicSettings",
|
||||||
std::move(variables),
|
std::move(variables),
|
||||||
std::move(defaultValues)
|
std::move(defaultValues)
|
||||||
|
|
@ -157,47 +156,28 @@ namespace Nz
|
||||||
|
|
||||||
std::vector<MaterialSettings::SharedUniformBlock> sharedUniformBlock;
|
std::vector<MaterialSettings::SharedUniformBlock> sharedUniformBlock;
|
||||||
|
|
||||||
predefinedBinding[PredefinedShaderBinding_UboInstanceData] = sharedUniformBlock.size();
|
predefinedBinding[PredefinedShaderBinding_UboInstanceData] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
|
||||||
sharedUniformBlock.push_back(PredefinedInstanceData::GetUniformBlock());
|
sharedUniformBlock.push_back(PredefinedInstanceData::GetUniformBlock());
|
||||||
predefinedBinding[PredefinedShaderBinding_UboViewerData] = sharedUniformBlock.size();
|
predefinedBinding[PredefinedShaderBinding_UboViewerData] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
|
||||||
sharedUniformBlock.push_back(PredefinedViewerData::GetUniformBlock());
|
sharedUniformBlock.push_back(PredefinedViewerData::GetUniformBlock());
|
||||||
|
|
||||||
std::vector<MaterialSettings::Texture> textures;
|
// Shaders
|
||||||
s_textureIndexes.alpha = textures.size();
|
MaterialSettings::DefaultShaders defaultShaders;
|
||||||
textures.push_back({
|
defaultShaders[UnderlyingCast(ShaderStageType::Fragment)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, r_fragmentShader, sizeof(r_fragmentShader));
|
||||||
"Alpha",
|
defaultShaders[UnderlyingCast(ShaderStageType::Vertex)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraBinary, r_vertexShader, sizeof(r_vertexShader));
|
||||||
ImageType_2D,
|
|
||||||
"MaterialAlphaMap"
|
|
||||||
});
|
|
||||||
|
|
||||||
s_textureIndexes.diffuse = textures.size();
|
|
||||||
textures.push_back({
|
|
||||||
"Diffuse",
|
|
||||||
ImageType_2D,
|
|
||||||
"MaterialDiffuseMap"
|
|
||||||
});
|
|
||||||
|
|
||||||
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
|
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding, std::move(defaultShaders));
|
||||||
textures.push_back({
|
|
||||||
"Overlay",
|
|
||||||
ImageType_2D,
|
|
||||||
"TextureOverlay"
|
|
||||||
});
|
|
||||||
|
|
||||||
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicMaterial::Uninitialize()
|
void BasicMaterial::Uninitialize()
|
||||||
{
|
{
|
||||||
s_renderPipelineLayout.Reset();
|
|
||||||
s_materialSettings.reset();
|
s_materialSettings.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
|
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
|
||||||
std::size_t BasicMaterial::s_uniformBlockIndex;
|
std::size_t BasicMaterial::s_uniformBlockIndex;
|
||||||
RenderPipelineLayoutRef BasicMaterial::s_renderPipelineLayout;
|
|
||||||
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
|
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
|
||||||
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
|
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,956 +0,0 @@
|
||||||
// Copyright (C) 2017 Jérôme Leclercq
|
|
||||||
// This file is part of the "Nazara Engine - Graphics module"
|
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
||||||
|
|
||||||
#include <Nazara/Graphics/BasicRenderQueue.hpp>
|
|
||||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
|
||||||
#include <Nazara/Utility/VertexStruct.hpp>
|
|
||||||
#include <limits>
|
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
|
||||||
|
|
||||||
///TODO: Replace sinus/cosinus by a lookup table (which will lead to a speed up about 10x)
|
|
||||||
|
|
||||||
namespace Nz
|
|
||||||
{
|
|
||||||
/*!
|
|
||||||
* \ingroup graphics
|
|
||||||
* \class Nz::BasicRenderQueue
|
|
||||||
* \brief Graphics class that represents a simple rendering queue
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Sizes of the billboards
|
|
||||||
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
|
||||||
* \param colorPtr Color of the billboards if null, Color::White is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
|
||||||
|
|
||||||
if (!sinCosPtr)
|
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
if (!colorPtr)
|
|
||||||
colorPtr.Reset(&Color::White, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
*colorPtr++,
|
|
||||||
*positionPtr++,
|
|
||||||
*sizePtr++,
|
|
||||||
*sinCosPtr++
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = *colorPtr++;
|
|
||||||
data->sinCos = *sinCosPtr++;
|
|
||||||
data->size = *sizePtr++;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Sizes of the billboards
|
|
||||||
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
|
||||||
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
|
||||||
|
|
||||||
if (!sinCosPtr)
|
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
|
||||||
|
|
||||||
if (!alphaPtr)
|
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
ComputeColor(*alphaPtr++),
|
|
||||||
*positionPtr++,
|
|
||||||
*sizePtr++,
|
|
||||||
*sinCosPtr++
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = ComputeColor(*alphaPtr++);
|
|
||||||
data->sinCos = *sinCosPtr++;
|
|
||||||
data->size = *sizePtr++;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Sizes of the billboards
|
|
||||||
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
|
||||||
* \param colorPtr Color of the billboards if null, Color::White is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
float defaultRotation = 0.f;
|
|
||||||
|
|
||||||
if (!anglePtr)
|
|
||||||
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
if (!colorPtr)
|
|
||||||
colorPtr.Reset(&Color::White, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
*colorPtr++,
|
|
||||||
*positionPtr++,
|
|
||||||
*sizePtr++,
|
|
||||||
ComputeSinCos(*anglePtr++)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = *colorPtr++;
|
|
||||||
data->sinCos = ComputeSinCos(*anglePtr++);
|
|
||||||
data->size = *sizePtr++;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Sizes of the billboards
|
|
||||||
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
|
||||||
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
float defaultRotation = 0.f;
|
|
||||||
|
|
||||||
if (!anglePtr)
|
|
||||||
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
|
||||||
|
|
||||||
if (!alphaPtr)
|
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
ComputeColor(*alphaPtr++),
|
|
||||||
*positionPtr++,
|
|
||||||
*sizePtr++,
|
|
||||||
ComputeSinCos(*anglePtr++)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = ComputeColor(*alphaPtr++);
|
|
||||||
data->sinCos = ComputeSinCos(*anglePtr++);
|
|
||||||
data->size = *sizePtr++;
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Size of the billboards
|
|
||||||
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
|
||||||
* \param colorPtr Color of the billboards if null, Color::White is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
|
||||||
|
|
||||||
if (!sinCosPtr)
|
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
if (!colorPtr)
|
|
||||||
colorPtr.Reset(&Color::White, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
*colorPtr++,
|
|
||||||
*positionPtr++,
|
|
||||||
ComputeSize(*sizePtr++),
|
|
||||||
*sinCosPtr++
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = *colorPtr++;
|
|
||||||
data->sinCos = *sinCosPtr++;
|
|
||||||
data->size = ComputeSize(*sizePtr++);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Size of the billboards
|
|
||||||
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
|
||||||
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
|
||||||
|
|
||||||
if (!sinCosPtr)
|
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
|
||||||
|
|
||||||
if (!alphaPtr)
|
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
ComputeColor(*alphaPtr++),
|
|
||||||
*positionPtr++,
|
|
||||||
ComputeSize(*sizePtr++),
|
|
||||||
*sinCosPtr++
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = ComputeColor(*alphaPtr++);
|
|
||||||
data->sinCos = *sinCosPtr++;
|
|
||||||
data->size = ComputeSize(*sizePtr++);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Size of the billboards
|
|
||||||
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
|
||||||
* \param colorPtr Color of the billboards if null, Color::White is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
float defaultRotation = 0.f;
|
|
||||||
|
|
||||||
if (!anglePtr)
|
|
||||||
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
if (!colorPtr)
|
|
||||||
colorPtr.Reset(&Color::White, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
*colorPtr++,
|
|
||||||
*positionPtr++,
|
|
||||||
ComputeSize(*sizePtr++),
|
|
||||||
ComputeSinCos(*anglePtr++)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = *colorPtr++;
|
|
||||||
data->sinCos = ComputeSinCos(*anglePtr++);
|
|
||||||
data->size = ComputeSize(*sizePtr++);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds multiple billboards to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the billboards
|
|
||||||
* \param count Number of billboards
|
|
||||||
* \param positionPtr Position of the billboards
|
|
||||||
* \param sizePtr Size of the billboards
|
|
||||||
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
|
||||||
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::AddBillboards(int renderOrder, const Material* material, std::size_t billboardCount, const Recti& scissorRect, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
float defaultRotation = 0.f;
|
|
||||||
|
|
||||||
if (!anglePtr)
|
|
||||||
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
|
||||||
|
|
||||||
if (!alphaPtr)
|
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
depthSortedBillboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
{
|
|
||||||
ComputeColor(*alphaPtr++),
|
|
||||||
*positionPtr++,
|
|
||||||
ComputeSize(*sizePtr++),
|
|
||||||
ComputeSinCos(*anglePtr++)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::size_t billboardIndex = m_billboards.size();
|
|
||||||
m_billboards.resize(billboardIndex + billboardCount);
|
|
||||||
BillboardData* data = &m_billboards[billboardIndex];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < billboardCount; ++i)
|
|
||||||
{
|
|
||||||
data->center = *positionPtr++;
|
|
||||||
data->color = ComputeColor(*alphaPtr++);
|
|
||||||
data->sinCos = ComputeSinCos(*anglePtr++);
|
|
||||||
data->size = ComputeSize(*sizePtr++);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
|
|
||||||
billboards.Insert({
|
|
||||||
renderOrder,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
billboardCount,
|
|
||||||
billboardIndex
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds drawable to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param drawable Drawable user defined
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraError if drawable is invalid
|
|
||||||
*/
|
|
||||||
void BasicRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable)
|
|
||||||
{
|
|
||||||
NazaraAssert(drawable, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
customDrawables.Insert({
|
|
||||||
renderOrder,
|
|
||||||
drawable
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds mesh to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the mesh
|
|
||||||
* \param meshData Data of the mesh
|
|
||||||
* \param meshAABB Box of the mesh
|
|
||||||
* \param transformMatrix Matrix of the mesh
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
void BasicRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Nz::Matrix4f& transformMatrix, std::size_t instanceIndex, const Recti& scissorRect)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
Spheref obbSphere(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius());
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
depthSortedModels.Insert({
|
|
||||||
renderOrder,
|
|
||||||
instanceIndex,
|
|
||||||
meshData,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
obbSphere
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
models.Insert({
|
|
||||||
renderOrder,
|
|
||||||
instanceIndex,
|
|
||||||
meshData,
|
|
||||||
material,
|
|
||||||
scissorRect,
|
|
||||||
obbSphere
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds sprites to the queue
|
|
||||||
*
|
|
||||||
* \param renderOrder Order of rendering
|
|
||||||
* \param material Material of the sprites
|
|
||||||
* \param vertices Buffer of data for the sprites
|
|
||||||
* \param spriteCount Number of sprites
|
|
||||||
* \param overlay Texture of the sprites
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraAssert if material is invalid
|
|
||||||
*/
|
|
||||||
void BasicRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Recti& scissorRect, const Texture* overlay /*= nullptr*/)
|
|
||||||
{
|
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
RegisterLayer(renderOrder);
|
|
||||||
|
|
||||||
if (material->IsDepthSortingEnabled())
|
|
||||||
{
|
|
||||||
depthSortedSprites.Insert({
|
|
||||||
renderOrder,
|
|
||||||
spriteCount,
|
|
||||||
material,
|
|
||||||
overlay,
|
|
||||||
vertices,
|
|
||||||
scissorRect
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
basicSprites.Insert({
|
|
||||||
renderOrder,
|
|
||||||
spriteCount,
|
|
||||||
material,
|
|
||||||
overlay,
|
|
||||||
vertices,
|
|
||||||
scissorRect
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Clears the queue
|
|
||||||
*
|
|
||||||
* \param fully Should everything be cleared or we can keep layers
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BasicRenderQueue::Clear(bool fully)
|
|
||||||
{
|
|
||||||
AbstractRenderQueue::Clear(fully);
|
|
||||||
|
|
||||||
basicSprites.Clear();
|
|
||||||
billboards.Clear();
|
|
||||||
depthSortedBillboards.Clear();
|
|
||||||
depthSortedModels.Clear();
|
|
||||||
depthSortedSprites.Clear();
|
|
||||||
models.Clear();
|
|
||||||
|
|
||||||
m_pipelineCache.clear();
|
|
||||||
m_materialCache.clear();
|
|
||||||
m_overlayCache.clear();
|
|
||||||
m_shaderCache.clear();
|
|
||||||
m_textureCache.clear();
|
|
||||||
m_vertexBufferCache.clear();
|
|
||||||
|
|
||||||
m_billboards.clear();
|
|
||||||
m_renderLayers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Sorts the object according to the viewer position, furthest to nearest
|
|
||||||
*
|
|
||||||
* \param viewer Viewer of the scene
|
|
||||||
*/
|
|
||||||
void BasicRenderQueue::Sort(const AbstractViewer* viewer)
|
|
||||||
{
|
|
||||||
m_layerCache.clear();
|
|
||||||
for (int layer : m_renderLayers)
|
|
||||||
m_layerCache.emplace(layer, m_layerCache.size());
|
|
||||||
|
|
||||||
auto GetOrInsert = [](auto& container, auto&& value)
|
|
||||||
{
|
|
||||||
auto it = container.find(value);
|
|
||||||
if (it == container.end())
|
|
||||||
it = container.emplace(value, container.size()).first;
|
|
||||||
|
|
||||||
return it->second;
|
|
||||||
};
|
|
||||||
|
|
||||||
basicSprites.Sort([&](const SpriteChain& vertices)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Pipeline (8bits)
|
|
||||||
// - Material (8bits)
|
|
||||||
// - Shader? (8bits)
|
|
||||||
// - Textures (8bits)
|
|
||||||
// - Overlay (8bits)
|
|
||||||
// - Scissor (4bits)
|
|
||||||
// - ??? (4bits)
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[vertices.layerIndex];
|
|
||||||
UInt64 pipelineIndex = GetOrInsert(m_pipelineCache, vertices.material->GetPipeline());
|
|
||||||
UInt64 materialIndex = GetOrInsert(m_materialCache, vertices.material);
|
|
||||||
UInt64 shaderIndex = GetOrInsert(m_shaderCache, vertices.material->GetShader());
|
|
||||||
UInt64 textureIndex = 0;/* GetOrInsert(m_textureCache, vertices.material->GetDiffuseMap());*/
|
|
||||||
UInt64 overlayIndex = GetOrInsert(m_overlayCache, vertices.overlay);
|
|
||||||
UInt64 scissorIndex = 0; //< TODO
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(pipelineIndex & 0xFF) << 40 |
|
|
||||||
(materialIndex & 0xFF) << 32 |
|
|
||||||
(shaderIndex & 0xFF) << 24 |
|
|
||||||
(textureIndex & 0xFF) << 16 |
|
|
||||||
(overlayIndex & 0xFF) << 8 |
|
|
||||||
(scissorIndex & 0x0F) << 4;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
billboards.Sort([&](const BillboardChain& billboard)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Pipeline (8bits)
|
|
||||||
// - Material (8bits)
|
|
||||||
// - Shader? (8bits)
|
|
||||||
// - Textures (8bits)
|
|
||||||
// - Scissor (4bits)
|
|
||||||
// - ??? (12bits)
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[billboard.layerIndex];
|
|
||||||
UInt64 pipelineIndex = GetOrInsert(m_pipelineCache, billboard.material->GetPipeline());
|
|
||||||
UInt64 materialIndex = GetOrInsert(m_materialCache, billboard.material);
|
|
||||||
UInt64 shaderIndex = GetOrInsert(m_shaderCache, billboard.material->GetShader());
|
|
||||||
UInt64 textureIndex = 0; /*GetOrInsert(m_textureCache, billboard.material->GetDiffuseMap())*/;
|
|
||||||
UInt64 unknownIndex = 0; //< ???
|
|
||||||
UInt64 scissorIndex = 0; //< TODO
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(pipelineIndex & 0xFF) << 40 |
|
|
||||||
(materialIndex & 0xFF) << 32 |
|
|
||||||
(shaderIndex & 0xFF) << 24 |
|
|
||||||
(textureIndex & 0xFF) << 16 |
|
|
||||||
(scissorIndex & 0x0F) << 12 |
|
|
||||||
(unknownIndex & 0xFF) << 0;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
customDrawables.Sort([&](const CustomDrawable& drawable)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[drawable.layerIndex];
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
models.Sort([&](const Model& renderData)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Pipeline (8bits)
|
|
||||||
// - Material (8bits)
|
|
||||||
// - Shader? (8bits)
|
|
||||||
// - Textures (8bits)
|
|
||||||
// - Buffers (8bits)
|
|
||||||
// - Scissor (4bits)
|
|
||||||
// - ??? (4bits)
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[renderData.layerIndex];
|
|
||||||
UInt64 pipelineIndex = GetOrInsert(m_pipelineCache, renderData.material->GetPipeline());
|
|
||||||
UInt64 materialIndex = GetOrInsert(m_materialCache, renderData.material);
|
|
||||||
UInt64 shaderIndex = GetOrInsert(m_shaderCache, renderData.material->GetShader());
|
|
||||||
UInt64 textureIndex = 0;/* GetOrInsert(m_textureCache, renderData.material->GetDiffuseMap()) */;
|
|
||||||
UInt64 bufferIndex = GetOrInsert(m_vertexBufferCache, renderData.meshData.vertexBuffer);
|
|
||||||
UInt64 scissorIndex = 0; //< TODO
|
|
||||||
UInt64 depthIndex = 0; //< TODO
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(pipelineIndex & 0xFF) << 40 |
|
|
||||||
(materialIndex & 0xFF) << 32 |
|
|
||||||
(shaderIndex & 0xFF) << 24 |
|
|
||||||
(textureIndex & 0xFF) << 16 |
|
|
||||||
(bufferIndex & 0xFF) << 8 |
|
|
||||||
(scissorIndex & 0x0F) << 4;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
static_assert(std::numeric_limits<float>::is_iec559, "The following sorting functions relies on IEEE 754 floatings-points");
|
|
||||||
|
|
||||||
#if defined(arm) && \
|
|
||||||
((defined(__MAVERICK__) && defined(NAZARA_BIG_ENDIAN)) || \
|
|
||||||
(!defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__MAVERICK__)))
|
|
||||||
#error The following code relies on native-endian IEEE-754 representation, which your platform does not guarantee
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near);
|
|
||||||
|
|
||||||
depthSortedBillboards.Sort([&](const Billboard& billboard)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Depth (32bits)
|
|
||||||
// - ?? (16bits)
|
|
||||||
|
|
||||||
// Reinterpret depth as UInt32 (this will work as long as they're all either positive or negative,
|
|
||||||
// a negative distance may happen with billboard behind the camera which we don't care about since they'll not be rendered)
|
|
||||||
float depth = nearPlane.Distance(billboard.data.center);
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[billboard.layerIndex];
|
|
||||||
UInt64 depthIndex = ~reinterpret_cast<UInt32&>(depth);
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(depthIndex & 0xFFFFFFFF) << 16;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (viewer->GetProjectionType() == ProjectionType_Orthogonal)
|
|
||||||
{
|
|
||||||
depthSortedModels.Sort([&](const Model& model)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Depth (32bits)
|
|
||||||
// - ?? (16bits)
|
|
||||||
|
|
||||||
float depth = nearPlane.Distance(model.obbSphere.GetPosition());
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[model.layerIndex];
|
|
||||||
UInt64 depthIndex = ~reinterpret_cast<UInt32&>(depth);
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(depthIndex & 0xFFFFFFFF) << 16;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
depthSortedSprites.Sort([&](const SpriteChain& spriteChain)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Depth (32bits)
|
|
||||||
// - ?? (16bits)
|
|
||||||
|
|
||||||
float depth = nearPlane.Distance(spriteChain.vertices[0].position);
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[spriteChain.layerIndex];
|
|
||||||
UInt64 depthIndex = ~reinterpret_cast<UInt32&>(depth);
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(depthIndex & 0xFFFFFFFF) << 16;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector3f viewerPos = viewer->GetEyePosition();
|
|
||||||
|
|
||||||
depthSortedModels.Sort([&](const Model& model)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Depth (32bits)
|
|
||||||
// - ?? (16bits)
|
|
||||||
|
|
||||||
float depth = viewerPos.SquaredDistance(model.obbSphere.GetPosition());
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[model.layerIndex];
|
|
||||||
UInt64 depthIndex = ~reinterpret_cast<UInt32&>(depth);
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0x0F) << 48 |
|
|
||||||
(depthIndex & 0xFFFFFFFF) << 16;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
|
|
||||||
depthSortedSprites.Sort([&](const SpriteChain& sprites)
|
|
||||||
{
|
|
||||||
// RQ index:
|
|
||||||
// - Layer (16bits)
|
|
||||||
// - Depth (32bits)
|
|
||||||
// - ?? (16bits)
|
|
||||||
|
|
||||||
float depth = viewerPos.SquaredDistance(sprites.vertices[0].position);
|
|
||||||
|
|
||||||
UInt64 layerIndex = m_layerCache[sprites.layerIndex];
|
|
||||||
UInt64 depthIndex = ~reinterpret_cast<UInt32&>(depth);
|
|
||||||
|
|
||||||
UInt64 index = (layerIndex & 0xFFFF) << 48 |
|
|
||||||
(depthIndex & 0xFFFFFFFF) << 16;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
|
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
|
@ -11,9 +12,8 @@ namespace Nz
|
||||||
/*!
|
/*!
|
||||||
* \ingroup graphics
|
* \ingroup graphics
|
||||||
* \class Nz::Graphics
|
* \class Nz::Graphics
|
||||||
* \brief Audio class that represents the module initializer of Graphics
|
* \brief Graphics class that represents the module initializer of Graphics
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Graphics::Graphics(Config config) :
|
Graphics::Graphics(Config config) :
|
||||||
ModuleBase("Graphics", this)
|
ModuleBase("Graphics", this)
|
||||||
{
|
{
|
||||||
|
|
@ -37,6 +37,13 @@ namespace Nz
|
||||||
m_renderDevice = rendererImpl->InstanciateRenderDevice(bestRenderDeviceIndex);
|
m_renderDevice = rendererImpl->InstanciateRenderDevice(bestRenderDeviceIndex);
|
||||||
if (!m_renderDevice)
|
if (!m_renderDevice)
|
||||||
throw std::runtime_error("failed to instantiate render device");
|
throw std::runtime_error("failed to instantiate render device");
|
||||||
|
|
||||||
|
MaterialPipeline::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::~Graphics()
|
||||||
|
{
|
||||||
|
MaterialPipeline::Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics* Graphics::s_instance = nullptr;
|
Graphics* Graphics::s_instance = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,6 @@ namespace Nz
|
||||||
* \brief Graphics class that represents a material
|
* \brief Graphics class that represents a material
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Checks whether the parameters for the material are correct
|
|
||||||
* \return true If parameters are valid
|
|
||||||
*/
|
|
||||||
bool MaterialParams::IsValid() const
|
|
||||||
{
|
|
||||||
if (!UberShaderLibrary::Has(shaderName))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a Material object with default states
|
* \brief Constructs a Material object with default states
|
||||||
*
|
*
|
||||||
|
|
@ -36,13 +24,11 @@ namespace Nz
|
||||||
*/
|
*/
|
||||||
Material::Material(std::shared_ptr<const MaterialSettings> settings) :
|
Material::Material(std::shared_ptr<const MaterialSettings> settings) :
|
||||||
m_settings(std::move(settings)),
|
m_settings(std::move(settings)),
|
||||||
m_reflectionMode(ReflectionMode_Skybox),
|
|
||||||
m_pipelineUpdated(false),
|
m_pipelineUpdated(false),
|
||||||
m_shadowCastingEnabled(true),
|
m_shadowCastingEnabled(true)
|
||||||
m_reflectionSize(256)
|
|
||||||
{
|
{
|
||||||
m_pipelineInfo.settings = m_settings;
|
m_pipelineInfo.settings = m_settings;
|
||||||
SetShader("Basic");
|
m_pipelineInfo.shaders = m_settings->GetDefaultShaders();
|
||||||
|
|
||||||
m_textures.resize(m_settings->GetTextures().size());
|
m_textures.resize(m_settings->GetTextures().size());
|
||||||
|
|
||||||
|
|
@ -56,432 +42,4 @@ namespace Nz
|
||||||
m_uniformBuffers.emplace_back(std::move(ubo));
|
m_uniformBuffers.emplace_back(std::move(ubo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Applies shader to the material
|
|
||||||
*
|
|
||||||
* \param instance Pipeline instance to update
|
|
||||||
* \param textureUnit Unit for the texture GL_TEXTURE"i"
|
|
||||||
* \param lastUsedUnit Optional argument to get the last texture unit
|
|
||||||
*/
|
|
||||||
void Material::Apply(const MaterialPipeline::Instance& instance) const
|
|
||||||
{
|
|
||||||
const Shader* shader = instance.renderPipeline.GetInfo().shader;
|
|
||||||
|
|
||||||
unsigned int bindingIndex = 0;
|
|
||||||
|
|
||||||
for (const MaterialTexture& textureData : m_textures)
|
|
||||||
{
|
|
||||||
auto it = instance.bindings.find(bindingIndex++);
|
|
||||||
assert(it != instance.bindings.end());
|
|
||||||
|
|
||||||
unsigned int textureIndex = it->second;
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureIndex, textureData.texture);
|
|
||||||
Renderer::SetTextureSampler(textureIndex, textureData.sampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const UniformBufferRef& ubo : m_uniformBuffers)
|
|
||||||
{
|
|
||||||
auto it = instance.bindings.find(bindingIndex++);
|
|
||||||
assert(it != instance.bindings.end());
|
|
||||||
|
|
||||||
unsigned int uniformBufferIndex = it->second;
|
|
||||||
|
|
||||||
Renderer::SetUniformBuffer(uniformBufferIndex, ubo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (instance.uniforms[MaterialUniform_AlphaThreshold] != -1)
|
|
||||||
shader->SendFloat(instance.uniforms[MaterialUniform_AlphaThreshold], m_alphaThreshold);
|
|
||||||
|
|
||||||
if (instance.uniforms[MaterialUniform_Ambient] != -1)
|
|
||||||
shader->SendColor(instance.uniforms[MaterialUniform_Ambient], m_ambientColor);
|
|
||||||
|
|
||||||
if (instance.uniforms[MaterialUniform_Diffuse] != -1)
|
|
||||||
shader->SendColor(instance.uniforms[MaterialUniform_Diffuse], m_diffuseColor);
|
|
||||||
|
|
||||||
if (instance.uniforms[MaterialUniform_Shininess] != -1)
|
|
||||||
shader->SendFloat(instance.uniforms[MaterialUniform_Shininess], m_shininess);
|
|
||||||
|
|
||||||
if (instance.uniforms[MaterialUniform_Specular] != -1)
|
|
||||||
shader->SendColor(instance.uniforms[MaterialUniform_Specular], m_specularColor);*/
|
|
||||||
|
|
||||||
/*if (m_alphaMap && instance.uniforms[MaterialUniform_AlphaMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Alpha];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_alphaMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_diffuseMap && instance.uniforms[MaterialUniform_DiffuseMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Diffuse];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_diffuseMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_emissiveMap && instance.uniforms[MaterialUniform_EmissiveMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Emissive];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_emissiveMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_heightMap && instance.uniforms[MaterialUniform_HeightMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Height];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_heightMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_normalMap && instance.uniforms[MaterialUniform_NormalMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Normal];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_normalMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_specularMap && instance.uniforms[MaterialUniform_SpecularMap] != -1)
|
|
||||||
{
|
|
||||||
unsigned int textureUnit = s_textureUnits[TextureMap_Specular];
|
|
||||||
|
|
||||||
Renderer::SetTexture(textureUnit, m_specularMap);
|
|
||||||
Renderer::SetTextureSampler(textureUnit, m_specularSampler);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Builds the material from a parameter list
|
|
||||||
*
|
|
||||||
* \param matData Data information for the material
|
|
||||||
* \param matParams Additional parameters for the material
|
|
||||||
*/
|
|
||||||
void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams)
|
|
||||||
{
|
|
||||||
Color color;
|
|
||||||
bool isEnabled;
|
|
||||||
double dValue;
|
|
||||||
long long iValue;
|
|
||||||
String path;
|
|
||||||
|
|
||||||
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true);
|
|
||||||
|
|
||||||
/*if (matData.GetDoubleParameter(MaterialData::AlphaThreshold, &dValue))
|
|
||||||
SetAlphaThreshold(float(dValue));*/
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled))
|
|
||||||
EnableAlphaTest(isEnabled);
|
|
||||||
|
|
||||||
/*if (matData.GetColorParameter(MaterialData::AmbientColor, &color))
|
|
||||||
SetAmbientColor(color);*/
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::CullingSide, &iValue))
|
|
||||||
SetFaceCulling(static_cast<FaceSide>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::DepthFunc, &iValue))
|
|
||||||
SetDepthFunc(static_cast<RendererComparison>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::DepthSorting, &isEnabled))
|
|
||||||
EnableDepthSorting(isEnabled);
|
|
||||||
|
|
||||||
/*if (matData.GetColorParameter(MaterialData::DiffuseColor, &color))
|
|
||||||
SetDiffuseColor(color);*/
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::DstBlend, &iValue))
|
|
||||||
SetDstBlend(static_cast<BlendFunc>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue))
|
|
||||||
SetFaceFilling(static_cast<FaceFilling>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetDoubleParameter(MaterialData::LineWidth, &dValue))
|
|
||||||
SetLineWidth(float(dValue));
|
|
||||||
|
|
||||||
if (matData.GetDoubleParameter(MaterialData::PointSize, &dValue))
|
|
||||||
SetPointSize(float(dValue));
|
|
||||||
|
|
||||||
/*if (matData.GetColorParameter(MaterialData::SpecularColor, &color))
|
|
||||||
SetSpecularColor(color);
|
|
||||||
|
|
||||||
if (matData.GetDoubleParameter(MaterialData::Shininess, &dValue))
|
|
||||||
SetShininess(float(dValue));*/
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue))
|
|
||||||
SetSrcBlend(static_cast<BlendFunc>(iValue));
|
|
||||||
|
|
||||||
// RendererParameter
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::Blending, &isEnabled))
|
|
||||||
EnableBlending(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::ColorWrite, &isEnabled))
|
|
||||||
EnableColorWrite(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::DepthBuffer, &isEnabled))
|
|
||||||
EnableDepthBuffer(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::DepthWrite, &isEnabled))
|
|
||||||
EnableDepthWrite(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::FaceCulling, &isEnabled))
|
|
||||||
EnableFaceCulling(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::ScissorTest, &isEnabled))
|
|
||||||
EnableScissorTest(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::StencilTest, &isEnabled))
|
|
||||||
EnableStencilTest(isEnabled);
|
|
||||||
|
|
||||||
if (matData.GetBooleanParameter(MaterialData::VertexColor, &isEnabled))
|
|
||||||
EnableVertexColor(isEnabled);
|
|
||||||
|
|
||||||
// Samplers
|
|
||||||
/*if (matData.GetIntegerParameter(MaterialData::DiffuseAnisotropyLevel, &iValue))
|
|
||||||
m_diffuseSampler.SetAnisotropyLevel(static_cast<UInt8>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::DiffuseFilter, &iValue))
|
|
||||||
m_diffuseSampler.SetFilterMode(static_cast<SamplerFilter>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::DiffuseWrap, &iValue))
|
|
||||||
m_diffuseSampler.SetWrapMode(static_cast<SamplerWrap>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::SpecularAnisotropyLevel, &iValue))
|
|
||||||
m_specularSampler.SetAnisotropyLevel(static_cast<UInt8>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::SpecularFilter, &iValue))
|
|
||||||
m_specularSampler.SetFilterMode(static_cast<SamplerFilter>(iValue));
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::SpecularWrap, &iValue))
|
|
||||||
m_specularSampler.SetWrapMode(static_cast<SamplerWrap>(iValue));*/
|
|
||||||
|
|
||||||
// Stencil
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue))
|
|
||||||
m_pipelineInfo.stencilCompare.front = static_cast<RendererComparison>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue))
|
|
||||||
m_pipelineInfo.stencilFail.front = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue))
|
|
||||||
m_pipelineInfo.stencilPass.front = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue))
|
|
||||||
m_pipelineInfo.stencilDepthFail.front = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue))
|
|
||||||
m_pipelineInfo.stencilWriteMask.front = static_cast<UInt32>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue))
|
|
||||||
m_pipelineInfo.stencilReference.front = static_cast<unsigned int>(iValue);
|
|
||||||
|
|
||||||
// Stencil (back)
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue))
|
|
||||||
m_pipelineInfo.stencilCompare.back = static_cast<RendererComparison>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue))
|
|
||||||
m_pipelineInfo.stencilFail.back = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue))
|
|
||||||
m_pipelineInfo.stencilPass.back = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue))
|
|
||||||
m_pipelineInfo.stencilDepthFail.back = static_cast<StencilOperation>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue))
|
|
||||||
m_pipelineInfo.stencilWriteMask.back = static_cast<UInt32>(iValue);
|
|
||||||
|
|
||||||
if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue))
|
|
||||||
m_pipelineInfo.stencilReference.back = static_cast<unsigned int>(iValue);
|
|
||||||
|
|
||||||
InvalidatePipeline();
|
|
||||||
|
|
||||||
// Textures
|
|
||||||
/*if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path))
|
|
||||||
SetAlphaMap(path);
|
|
||||||
|
|
||||||
if (matParams.loadDiffuseMap && matData.GetStringParameter(MaterialData::DiffuseTexturePath, &path))
|
|
||||||
SetDiffuseMap(path);
|
|
||||||
|
|
||||||
if (matParams.loadEmissiveMap && matData.GetStringParameter(MaterialData::EmissiveTexturePath, &path))
|
|
||||||
SetEmissiveMap(path);
|
|
||||||
|
|
||||||
if (matParams.loadHeightMap && matData.GetStringParameter(MaterialData::HeightTexturePath, &path))
|
|
||||||
SetHeightMap(path);
|
|
||||||
|
|
||||||
if (matParams.loadNormalMap && matData.GetStringParameter(MaterialData::NormalTexturePath, &path))
|
|
||||||
SetNormalMap(path);
|
|
||||||
|
|
||||||
if (matParams.loadSpecularMap && matData.GetStringParameter(MaterialData::SpecularTexturePath, &path))
|
|
||||||
SetSpecularMap(path);*/
|
|
||||||
|
|
||||||
SetShader(matParams.shaderName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Builds a ParameterList with material data
|
|
||||||
*
|
|
||||||
* \param matData Destination parameter list which will receive material data
|
|
||||||
*/
|
|
||||||
void Material::SaveToParameters(ParameterList* matData)
|
|
||||||
{
|
|
||||||
NazaraAssert(matData, "Invalid ParameterList");
|
|
||||||
|
|
||||||
matData->SetParameter(MaterialData::AlphaTest, IsAlphaTestEnabled());
|
|
||||||
//matData->SetParameter(MaterialData::AlphaThreshold, GetAlphaThreshold());
|
|
||||||
//matData->SetParameter(MaterialData::AmbientColor, GetAmbientColor());
|
|
||||||
matData->SetParameter(MaterialData::CullingSide, static_cast<long long>(GetFaceCulling()));
|
|
||||||
matData->SetParameter(MaterialData::DepthFunc, static_cast<long long>(GetDepthFunc()));
|
|
||||||
matData->SetParameter(MaterialData::DepthSorting, IsDepthSortingEnabled());
|
|
||||||
//matData->SetParameter(MaterialData::DiffuseColor, GetDiffuseColor());
|
|
||||||
matData->SetParameter(MaterialData::DstBlend, static_cast<long long>(GetDstBlend()));
|
|
||||||
matData->SetParameter(MaterialData::FaceFilling, static_cast<long long>(GetFaceFilling()));
|
|
||||||
matData->SetParameter(MaterialData::LineWidth, GetLineWidth());
|
|
||||||
matData->SetParameter(MaterialData::PointSize, GetPointSize());
|
|
||||||
//matData->SetParameter(MaterialData::Shininess, GetShininess());
|
|
||||||
//matData->SetParameter(MaterialData::SpecularColor, GetSpecularColor());
|
|
||||||
matData->SetParameter(MaterialData::SrcBlend, static_cast<long long>(GetSrcBlend()));
|
|
||||||
|
|
||||||
// RendererParameter
|
|
||||||
matData->SetParameter(MaterialData::Blending, IsBlendingEnabled());
|
|
||||||
matData->SetParameter(MaterialData::ColorWrite, IsColorWriteEnabled());
|
|
||||||
matData->SetParameter(MaterialData::DepthBuffer, IsDepthBufferEnabled());
|
|
||||||
matData->SetParameter(MaterialData::DepthWrite, IsDepthWriteEnabled());
|
|
||||||
matData->SetParameter(MaterialData::FaceCulling, IsFaceCullingEnabled());
|
|
||||||
matData->SetParameter(MaterialData::ScissorTest, IsScissorTestEnabled());
|
|
||||||
matData->SetParameter(MaterialData::StencilTest, IsStencilTestEnabled());
|
|
||||||
matData->SetParameter(MaterialData::VertexColor, HasVertexColor());
|
|
||||||
|
|
||||||
// Samplers
|
|
||||||
/*matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, static_cast<long long>(GetDiffuseSampler().GetAnisotropicLevel()));
|
|
||||||
matData->SetParameter(MaterialData::DiffuseFilter, static_cast<long long>(GetDiffuseSampler().GetFilterMode()));
|
|
||||||
matData->SetParameter(MaterialData::DiffuseWrap, static_cast<long long>(GetDiffuseSampler().GetWrapMode()));
|
|
||||||
|
|
||||||
matData->SetParameter(MaterialData::SpecularAnisotropyLevel, static_cast<long long>(GetSpecularSampler().GetAnisotropicLevel()));
|
|
||||||
matData->SetParameter(MaterialData::SpecularFilter, static_cast<long long>(GetSpecularSampler().GetFilterMode()));
|
|
||||||
matData->SetParameter(MaterialData::SpecularWrap, static_cast<long long>(GetSpecularSampler().GetWrapMode()));*/
|
|
||||||
|
|
||||||
// Stencil
|
|
||||||
matData->SetParameter(MaterialData::StencilCompare, static_cast<long long>(GetPipelineInfo().stencilCompare.front));
|
|
||||||
matData->SetParameter(MaterialData::StencilFail, static_cast<long long>(GetPipelineInfo().stencilFail.front));
|
|
||||||
matData->SetParameter(MaterialData::StencilPass, static_cast<long long>(GetPipelineInfo().stencilPass.front));
|
|
||||||
matData->SetParameter(MaterialData::StencilZFail, static_cast<long long>(GetPipelineInfo().stencilDepthFail.front));
|
|
||||||
matData->SetParameter(MaterialData::StencilMask, static_cast<long long>(GetPipelineInfo().stencilWriteMask.front));
|
|
||||||
matData->SetParameter(MaterialData::StencilReference, static_cast<long long>(GetPipelineInfo().stencilReference.front));
|
|
||||||
|
|
||||||
// Stencil (back)
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilCompare, static_cast<long long>(GetPipelineInfo().stencilCompare.back));
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilFail, static_cast<long long>(GetPipelineInfo().stencilFail.back));
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilPass, static_cast<long long>(GetPipelineInfo().stencilPass.back));
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilZFail, static_cast<long long>(GetPipelineInfo().stencilDepthFail.back));
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilMask, static_cast<long long>(GetPipelineInfo().stencilWriteMask.back));
|
|
||||||
matData->SetParameter(MaterialData::BackFaceStencilReference, static_cast<long long>(GetPipelineInfo().stencilReference.back));
|
|
||||||
|
|
||||||
// Textures
|
|
||||||
/*if (HasAlphaMap())
|
|
||||||
{
|
|
||||||
const String& path = GetAlphaMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::AlphaTexturePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasDiffuseMap())
|
|
||||||
{
|
|
||||||
const String& path = GetDiffuseMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::DiffuseTexturePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasEmissiveMap())
|
|
||||||
{
|
|
||||||
const String& path = GetEmissiveMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::EmissiveTexturePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasHeightMap())
|
|
||||||
{
|
|
||||||
const String& path = GetHeightMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::HeightTexturePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasNormalMap())
|
|
||||||
{
|
|
||||||
const String& path = GetNormalMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::NormalTexturePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasSpecularMap())
|
|
||||||
{
|
|
||||||
const String& path = GetSpecularMap()->GetFilePath();
|
|
||||||
if (!path.IsEmpty())
|
|
||||||
matData->SetParameter(MaterialData::SpecularTexturePath, path);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Initializes the material librairies
|
|
||||||
* \return true If successful
|
|
||||||
*
|
|
||||||
* \remark Produces a NazaraError if the material library failed to be initialized
|
|
||||||
*/
|
|
||||||
bool Material::Initialize()
|
|
||||||
{
|
|
||||||
if (!MaterialLibrary::Initialize())
|
|
||||||
{
|
|
||||||
NazaraError("Failed to initialise library");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!MaterialManager::Initialize())
|
|
||||||
{
|
|
||||||
NazaraError("Failed to initialise manager");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_defaultMaterial = New(BasicMaterial::GetSettings());
|
|
||||||
s_defaultMaterial->EnableFaceCulling(false);
|
|
||||||
s_defaultMaterial->SetFaceFilling(FaceFilling_Line);
|
|
||||||
MaterialLibrary::Register("Default", s_defaultMaterial);
|
|
||||||
|
|
||||||
unsigned int textureUnit = 0;
|
|
||||||
|
|
||||||
s_textureUnits[TextureMap_Diffuse] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Alpha] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Specular] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Normal] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Emissive] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Overlay] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_ReflectionCube] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Height] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Shadow2D_1] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_ShadowCube_1] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Shadow2D_2] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_ShadowCube_2] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_Shadow2D_3] = textureUnit++;
|
|
||||||
s_textureUnits[TextureMap_ShadowCube_3] = textureUnit++;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Uninitializes the material librairies
|
|
||||||
*/
|
|
||||||
void Material::Uninitialize()
|
|
||||||
{
|
|
||||||
s_defaultMaterial.Reset();
|
|
||||||
|
|
||||||
MaterialManager::Uninitialize();
|
|
||||||
MaterialLibrary::Uninitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<int, TextureMap_Max + 1> Material::s_textureUnits;
|
|
||||||
MaterialLibrary::LibraryMap Material::s_library;
|
|
||||||
MaterialLoader::LoaderList Material::s_loaders;
|
|
||||||
MaterialManager::ManagerMap Material::s_managerMap;
|
|
||||||
MaterialManager::ManagerParams Material::s_managerParameters;
|
|
||||||
MaterialRef Material::s_defaultMaterial = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,50 +8,11 @@
|
||||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||||
|
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const UInt8 r_basicFragmentShader[] = {
|
|
||||||
#include <Nazara/Graphics/Resources/Shaders/Basic/core.frag.h>
|
|
||||||
};
|
|
||||||
|
|
||||||
const UInt8 r_basicVertexShader[] = {
|
|
||||||
#include <Nazara/Graphics/Resources/Shaders/Basic/core.vert.h>
|
|
||||||
};
|
|
||||||
|
|
||||||
const UInt8 r_phongLightingFragmentShader[] = {
|
|
||||||
#include <Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h>
|
|
||||||
};
|
|
||||||
|
|
||||||
const UInt8 r_phongLightingVertexShader[] = {
|
|
||||||
#include <Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h>
|
|
||||||
};
|
|
||||||
|
|
||||||
void OverrideShader(const String& path, String* source)
|
|
||||||
{
|
|
||||||
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled);
|
|
||||||
|
|
||||||
File shaderFile(path, Nz::OpenMode_ReadOnly | Nz::OpenMode_Text);
|
|
||||||
if (shaderFile.IsOpen())
|
|
||||||
{
|
|
||||||
StringStream shaderSource;
|
|
||||||
|
|
||||||
while (!shaderFile.EndOfFile())
|
|
||||||
{
|
|
||||||
shaderSource << shaderFile.ReadLine();
|
|
||||||
shaderSource << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
*source = shaderSource;
|
|
||||||
|
|
||||||
NazaraNotice(path + " will be used to override built-in shader");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup graphics
|
* \ingroup graphics
|
||||||
* \class Nz::MaterialPipeline
|
* \class Nz::MaterialPipeline
|
||||||
|
|
@ -59,6 +20,41 @@ namespace Nz
|
||||||
* \brief Graphics class used to contains all rendering states that are not allowed to change individually on rendering devices
|
* \brief Graphics class used to contains all rendering states that are not allowed to change individually on rendering devices
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Retrieve (and generate if required) a pipeline instance using shader flags without applying it
|
||||||
|
*
|
||||||
|
* \param flags Shader flags
|
||||||
|
*
|
||||||
|
* \return Pipeline instance
|
||||||
|
*/
|
||||||
|
const std::shared_ptr<RenderPipeline>& MaterialPipeline::GetRenderPipeline(const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers) const
|
||||||
|
{
|
||||||
|
for (const auto& pipeline : m_renderPipelines)
|
||||||
|
{
|
||||||
|
const auto& pipelineInfo = pipeline->GetPipelineInfo();
|
||||||
|
|
||||||
|
bool isEqual = std::equal(pipelineInfo.vertexBuffers.begin(), pipelineInfo.vertexBuffers.end(), vertexBuffers.begin(), [](const auto& v1, const auto& v2)
|
||||||
|
{
|
||||||
|
return v1.binding == v2.binding && v1.declaration == v2.declaration;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isEqual)
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderPipelineInfo renderPipelineInfo;
|
||||||
|
static_cast<RenderStates&>(renderPipelineInfo).operator=(m_pipelineInfo); // Not my proudest line
|
||||||
|
|
||||||
|
renderPipelineInfo.pipelineLayout = m_pipelineInfo.settings->GetRenderPipelineLayout();
|
||||||
|
|
||||||
|
for (const auto& shaderStage : m_pipelineInfo.shaders)
|
||||||
|
{
|
||||||
|
if (shaderStage)
|
||||||
|
renderPipelineInfo.shaderStages.push_back(shaderStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_renderPipelines.emplace_back(Graphics::Instance()->GetRenderDevice().InstantiateRenderPipeline(std::move(renderPipelineInfo)));
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns a reference to a MaterialPipeline built with MaterialPipelineInfo
|
* \brief Returns a reference to a MaterialPipeline built with MaterialPipelineInfo
|
||||||
*
|
*
|
||||||
|
|
@ -66,156 +62,19 @@ namespace Nz
|
||||||
*
|
*
|
||||||
* \param pipelineInfo Pipeline informations used to build/retrieve a MaterialPipeline object
|
* \param pipelineInfo Pipeline informations used to build/retrieve a MaterialPipeline object
|
||||||
*/
|
*/
|
||||||
MaterialPipelineRef MaterialPipeline::GetPipeline(const MaterialPipelineInfo& pipelineInfo)
|
const std::shared_ptr<MaterialPipeline>& MaterialPipeline::Get(const MaterialPipelineInfo& pipelineInfo)
|
||||||
{
|
{
|
||||||
auto it = s_pipelineCache.find(pipelineInfo);
|
auto it = s_pipelineCache.find(pipelineInfo);
|
||||||
if (it == s_pipelineCache.end())
|
if (it == s_pipelineCache.end())
|
||||||
it = s_pipelineCache.insert(it, PipelineCache::value_type(pipelineInfo, New(pipelineInfo)));
|
it = s_pipelineCache.insert(it, PipelineCache::value_type(pipelineInfo, std::make_shared<MaterialPipeline>(pipelineInfo, Token{})));
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialPipeline::GenerateRenderPipeline(UInt32 flags) const
|
|
||||||
{
|
|
||||||
NazaraAssert(m_pipelineInfo.settings, "Material pipeline has no settings");
|
|
||||||
NazaraAssert(m_pipelineInfo.uberShader, "Material pipeline has no uber shader");
|
|
||||||
|
|
||||||
const auto& textures = m_pipelineInfo.settings->GetTextures();
|
|
||||||
|
|
||||||
ParameterList list;
|
|
||||||
for (std::size_t i = 0, texCount = textures.size(); i < texCount; ++i)
|
|
||||||
{
|
|
||||||
const auto& texture = textures[i];
|
|
||||||
String parameterName = "HAS_" + texture.name.ToUpper() + "_TEXTURE";
|
|
||||||
|
|
||||||
list.SetParameter(parameterName, (m_pipelineInfo.textures & (1 << i)) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest);
|
|
||||||
list.SetParameter("REFLECTION_MAPPING", m_pipelineInfo.reflectionMapping);
|
|
||||||
list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive);
|
|
||||||
list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.textures != 0 ||
|
|
||||||
m_pipelineInfo.reflectionMapping || flags & ShaderFlags_TextureOverlay);
|
|
||||||
list.SetParameter("TRANSFORM", true);
|
|
||||||
|
|
||||||
list.SetParameter("FLAG_BILLBOARD", static_cast<bool>((flags & ShaderFlags_Billboard) != 0));
|
|
||||||
list.SetParameter("FLAG_DEFERRED", static_cast<bool>((flags & ShaderFlags_Deferred) != 0));
|
|
||||||
list.SetParameter("FLAG_INSTANCING", static_cast<bool>((flags & ShaderFlags_Instancing) != 0));
|
|
||||||
list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast<bool>((flags & ShaderFlags_TextureOverlay) != 0));
|
|
||||||
list.SetParameter("FLAG_VERTEXCOLOR", m_pipelineInfo.hasVertexColor || static_cast<bool>((flags & ShaderFlags_VertexColor) != 0));
|
|
||||||
|
|
||||||
Instance& instance = m_instances[flags];
|
|
||||||
instance.uberInstance = m_pipelineInfo.uberShader->Get(list);
|
|
||||||
|
|
||||||
RenderPipelineInfo renderPipelineInfo;
|
|
||||||
static_cast<RenderStates&>(renderPipelineInfo).operator=(m_pipelineInfo); // Not my proudest line
|
|
||||||
|
|
||||||
renderPipelineInfo.shader = instance.uberInstance->GetShader();
|
|
||||||
|
|
||||||
instance.renderPipeline.Create(renderPipelineInfo);
|
|
||||||
|
|
||||||
// Send texture units (those never changes)
|
|
||||||
const RenderPipelineLayout* pipelineLayout = m_pipelineInfo.pipelineLayout;
|
|
||||||
if (!pipelineLayout)
|
|
||||||
pipelineLayout = m_pipelineInfo.settings->GetRenderPipelineLayout();
|
|
||||||
|
|
||||||
instance.bindings = renderPipelineInfo.shader->ApplyLayout(pipelineLayout);
|
|
||||||
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("ReflectionMap"), Material::GetTextureUnit(TextureMap_ReflectionCube));
|
|
||||||
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_Shadow2D_1));
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_Shadow2D_2));
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_Shadow2D_3));
|
|
||||||
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_ShadowCube_1));
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_ShadowCube_2));
|
|
||||||
renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_ShadowCube_3));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MaterialPipeline::Initialize()
|
bool MaterialPipeline::Initialize()
|
||||||
{
|
{
|
||||||
// Basic shader
|
BasicMaterial::Initialize();
|
||||||
{
|
PhongLightingMaterial::Initialize();
|
||||||
UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New();
|
|
||||||
|
|
||||||
String fragmentShader(reinterpret_cast<const char*>(r_basicFragmentShader), sizeof(r_basicFragmentShader));
|
|
||||||
String vertexShader(reinterpret_cast<const char*>(r_basicVertexShader), sizeof(r_basicVertexShader));
|
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
|
||||||
OverrideShader("Shaders/Basic/core.frag", &fragmentShader);
|
|
||||||
OverrideShader("Shaders/Basic/core.vert", &vertexShader);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY AUTO_TEXCOORDS HAS_ALPHA_TEXTURE HAS_DIFFUSE_TEXTURE TEXTURE_MAPPING");
|
|
||||||
uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH");
|
|
||||||
|
|
||||||
UberShaderLibrary::Register("Basic", uberShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BasicMaterial::Initialize())
|
|
||||||
{
|
|
||||||
NazaraError("Failed to initialize phong lighting materials");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PhongLighting shader
|
|
||||||
{
|
|
||||||
UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New();
|
|
||||||
|
|
||||||
String fragmentShader(reinterpret_cast<const char*>(r_phongLightingFragmentShader), sizeof(r_phongLightingFragmentShader));
|
|
||||||
String vertexShader(reinterpret_cast<const char*>(r_phongLightingVertexShader), sizeof(r_phongLightingVertexShader));
|
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
|
||||||
OverrideShader("Shaders/PhongLighting/core.frag", &fragmentShader);
|
|
||||||
OverrideShader("Shaders/PhongLighting/core.vert", &vertexShader);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_TEST AUTO_TEXCOORDS HAS_ALPHA_TEXTURE HAS_DIFFUSE_TEXTURE HAS_EMISSIVE_TEXTURE HAS_NORMAL_TEXTURE HAS_HEIGHT_TEXTURE HAS_SPECULAR_TEXTURE REFLECTION_MAPPING SHADOW_MAPPING");
|
|
||||||
uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR HAS_NORMAL_TEXTURE SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH");
|
|
||||||
|
|
||||||
UberShaderLibrary::Register("PhongLighting", uberShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PhongLightingMaterial::Initialize())
|
|
||||||
{
|
|
||||||
NazaraError("Failed to initialize phong lighting materials");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once the base shaders are registered, we can now set some default materials
|
|
||||||
MaterialPipelineInfo pipelineInfo;
|
|
||||||
pipelineInfo.settings = BasicMaterial::GetSettings();
|
|
||||||
pipelineInfo.uberShader = UberShaderLibrary::Get("Basic");
|
|
||||||
|
|
||||||
// Basic 2D - No depth write/face culling with scissoring
|
|
||||||
pipelineInfo.depthWrite = false;
|
|
||||||
pipelineInfo.faceCulling = false;
|
|
||||||
pipelineInfo.scissorTest = true;
|
|
||||||
|
|
||||||
MaterialPipelineLibrary::Register("Basic2D", GetPipeline(pipelineInfo));
|
|
||||||
|
|
||||||
// Translucent 2D - Alpha blending with no depth write/face culling and scissoring
|
|
||||||
pipelineInfo.blending = true;
|
|
||||||
pipelineInfo.depthWrite = false;
|
|
||||||
pipelineInfo.faceCulling = false;
|
|
||||||
pipelineInfo.depthSorting = false;
|
|
||||||
pipelineInfo.scissorTest = true;
|
|
||||||
pipelineInfo.dstBlend = BlendFunc_InvSrcAlpha;
|
|
||||||
pipelineInfo.srcBlend = BlendFunc_SrcAlpha;
|
|
||||||
|
|
||||||
MaterialPipelineLibrary::Register("Translucent2D", GetPipeline(pipelineInfo));
|
|
||||||
|
|
||||||
// Translucent 3D - Alpha blending with depth buffer and no depth write/face culling
|
|
||||||
pipelineInfo.blending = true;
|
|
||||||
pipelineInfo.depthBuffer = true;
|
|
||||||
pipelineInfo.depthWrite = false;
|
|
||||||
pipelineInfo.faceCulling = false;
|
|
||||||
pipelineInfo.depthSorting = true;
|
|
||||||
pipelineInfo.scissorTest = false;
|
|
||||||
pipelineInfo.dstBlend = BlendFunc_InvSrcAlpha;
|
|
||||||
pipelineInfo.srcBlend = BlendFunc_SrcAlpha;
|
|
||||||
|
|
||||||
MaterialPipelineLibrary::Register("Translucent3D", GetPipeline(pipelineInfo));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -223,13 +82,9 @@ namespace Nz
|
||||||
void MaterialPipeline::Uninitialize()
|
void MaterialPipeline::Uninitialize()
|
||||||
{
|
{
|
||||||
s_pipelineCache.clear();
|
s_pipelineCache.clear();
|
||||||
UberShaderLibrary::Unregister("PhongLighting");
|
|
||||||
PhongLightingMaterial::Uninitialize();
|
PhongLightingMaterial::Uninitialize();
|
||||||
UberShaderLibrary::Unregister("Basic");
|
|
||||||
BasicMaterial::Uninitialize();
|
BasicMaterial::Uninitialize();
|
||||||
MaterialPipelineLibrary::Uninitialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialPipelineLibrary::LibraryMap MaterialPipeline::s_library;
|
|
||||||
MaterialPipeline::PipelineCache MaterialPipeline::s_pipelineCache;
|
MaterialPipeline::PipelineCache MaterialPipeline::s_pipelineCache;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,24 +15,11 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
PhongLightingMaterial::PhongLightingMaterial(Material& material) :
|
||||||
{
|
|
||||||
constexpr std::size_t AlphaMapBinding = 0;
|
|
||||||
constexpr std::size_t DiffuseMapBinding = 1;
|
|
||||||
constexpr std::size_t EmissiveMapBinding = 2;
|
|
||||||
constexpr std::size_t HeightMapBinding = 3;
|
|
||||||
constexpr std::size_t NormalMapBinding = 4;
|
|
||||||
constexpr std::size_t SpecularMapBinding = 5;
|
|
||||||
constexpr std::size_t TextureOverlayBinding = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhongLightingMaterial::PhongLightingMaterial(Material* material) :
|
|
||||||
m_material(material)
|
m_material(material)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
|
||||||
|
|
||||||
// Most common case: don't fetch texture indexes as a little optimization
|
// Most common case: don't fetch texture indexes as a little optimization
|
||||||
const std::shared_ptr<const MaterialSettings>& materialSettings = material->GetSettings();
|
const std::shared_ptr<const MaterialSettings>& materialSettings = m_material.GetSettings();
|
||||||
if (materialSettings == s_materialSettings)
|
if (materialSettings == s_materialSettings)
|
||||||
{
|
{
|
||||||
m_textureIndexes = s_textureIndexes;
|
m_textureIndexes = s_textureIndexes;
|
||||||
|
|
@ -62,17 +49,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
||||||
return *AccessByOffset<const float>(mapper.GetPointer(), m_phongUniformOffsets.alphaThreshold);
|
return AccessByOffset<const float&>(mapper.GetPointer(), m_phongUniformOffsets.alphaThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color PhongLightingMaterial::GetAmbientColor() const
|
Color PhongLightingMaterial::GetAmbientColor() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
||||||
|
|
||||||
const float* colorPtr = AccessByOffset<const float>(mapper.GetPointer(), m_phongUniformOffsets.ambientColor);
|
const float* colorPtr = AccessByOffset<const float*>(mapper.GetPointer(), m_phongUniformOffsets.ambientColor);
|
||||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,9 +67,9 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
||||||
|
|
||||||
const float* colorPtr = AccessByOffset<const float>(mapper.GetPointer(), m_phongUniformOffsets.diffuseColor);
|
const float* colorPtr = AccessByOffset<const float*>(mapper.GetPointer(), m_phongUniformOffsets.diffuseColor);
|
||||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,17 +77,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasShininess(), "Material has no shininess uniform");
|
NazaraAssert(HasShininess(), "Material has no shininess uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
||||||
return *AccessByOffset<const float>(mapper.GetPointer(), m_phongUniformOffsets.shininess);
|
return AccessByOffset<const float&>(mapper.GetPointer(), m_phongUniformOffsets.shininess);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color PhongLightingMaterial::GetSpecularColor() const
|
Color PhongLightingMaterial::GetSpecularColor() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_ReadOnly);
|
||||||
|
|
||||||
const float* colorPtr = AccessByOffset<const float>(mapper.GetPointer(), m_phongUniformOffsets.specularColor);
|
const float* colorPtr = AccessByOffset<const float*>(mapper.GetPointer(), m_phongUniformOffsets.specularColor);
|
||||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,16 +95,16 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
||||||
*AccessByOffset<float>(mapper.GetPointer(), m_phongUniformOffsets.alphaThreshold) = alphaThreshold;
|
AccessByOffset<float&>(mapper.GetPointer(), m_phongUniformOffsets.alphaThreshold) = alphaThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhongLightingMaterial::SetAmbientColor(const Color& ambient)
|
void PhongLightingMaterial::SetAmbientColor(const Color& ambient)
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
NazaraAssert(HasAmbientColor(), "Material has no ambient color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
||||||
float* colorPtr = AccessByOffset<float>(mapper.GetPointer(), m_phongUniformOffsets.ambientColor);
|
float* colorPtr = AccessByOffset<float*>(mapper.GetPointer(), m_phongUniformOffsets.ambientColor);
|
||||||
colorPtr[0] = ambient.r / 255.f;
|
colorPtr[0] = ambient.r / 255.f;
|
||||||
colorPtr[1] = ambient.g / 255.f;
|
colorPtr[1] = ambient.g / 255.f;
|
||||||
colorPtr[2] = ambient.b / 255.f;
|
colorPtr[2] = ambient.b / 255.f;
|
||||||
|
|
@ -128,8 +115,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
||||||
float* colorPtr = AccessByOffset<float>(mapper.GetPointer(), m_phongUniformOffsets.diffuseColor);
|
float* colorPtr = AccessByOffset<float*>(mapper.GetPointer(), m_phongUniformOffsets.diffuseColor);
|
||||||
colorPtr[0] = diffuse.r / 255.f;
|
colorPtr[0] = diffuse.r / 255.f;
|
||||||
colorPtr[1] = diffuse.g / 255.f;
|
colorPtr[1] = diffuse.g / 255.f;
|
||||||
colorPtr[2] = diffuse.b / 255.f;
|
colorPtr[2] = diffuse.b / 255.f;
|
||||||
|
|
@ -140,8 +127,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
NazaraAssert(HasSpecularColor(), "Material has no specular color uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material->GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_phongUniformIndex), BufferAccess_WriteOnly);
|
||||||
float* colorPtr = AccessByOffset<float>(mapper.GetPointer(), m_phongUniformOffsets.specularColor);
|
float* colorPtr = AccessByOffset<float*>(mapper.GetPointer(), m_phongUniformOffsets.specularColor);
|
||||||
colorPtr[0] = diffuse.r / 255.f;
|
colorPtr[0] = diffuse.r / 255.f;
|
||||||
colorPtr[1] = diffuse.g / 255.f;
|
colorPtr[1] = diffuse.g / 255.f;
|
||||||
colorPtr[2] = diffuse.b / 255.f;
|
colorPtr[2] = diffuse.b / 255.f;
|
||||||
|
|
@ -155,51 +142,6 @@ namespace Nz
|
||||||
|
|
||||||
bool PhongLightingMaterial::Initialize()
|
bool PhongLightingMaterial::Initialize()
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
|
||||||
info.bindings.assign({
|
|
||||||
{
|
|
||||||
"MaterialAlphaMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
AlphaMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialDiffuseMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
DiffuseMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialEmissiveMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
EmissiveMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialHeightMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
HeightMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialNormalMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
NormalMapBinding
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"MaterialSpecularMap",
|
|
||||||
ShaderBindingType_Texture,
|
|
||||||
ShaderStageType_Fragment,
|
|
||||||
SpecularMapBinding
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
s_renderPipelineLayout = RenderPipelineLayout::New();
|
|
||||||
s_renderPipelineLayout->Create(info);
|
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
|
||||||
|
|
||||||
// MaterialPhongSettings
|
// MaterialPhongSettings
|
||||||
FieldOffsets phongUniformStruct(StructLayout_Std140);
|
FieldOffsets phongUniformStruct(StructLayout_Std140);
|
||||||
|
|
||||||
|
|
@ -239,16 +181,18 @@ namespace Nz
|
||||||
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");
|
||||||
|
|
||||||
std::vector<UInt8> defaultValues(phongUniformStruct.GetSize());
|
std::vector<UInt8> defaultValues(phongUniformStruct.GetSize());
|
||||||
*AccessByOffset<Vector4f>(defaultValues.data(), s_phongUniformOffsets.ambientColor) = Vector4f(0.5f, 0.5f, 0.5f, 1.f);
|
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.ambientColor) = Vector4f(0.5f, 0.5f, 0.5f, 1.f);
|
||||||
*AccessByOffset<Vector4f>(defaultValues.data(), s_phongUniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||||
*AccessByOffset<Vector4f>(defaultValues.data(), s_phongUniformOffsets.specularColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
AccessByOffset<Vector4f&>(defaultValues.data(), s_phongUniformOffsets.specularColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||||
*AccessByOffset<float>(defaultValues.data(), s_phongUniformOffsets.alphaThreshold) = 0.2f;
|
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.alphaThreshold) = 0.2f;
|
||||||
*AccessByOffset<float>(defaultValues.data(), s_phongUniformOffsets.shininess) = 50.f;
|
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.shininess) = 50.f;
|
||||||
|
|
||||||
|
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
||||||
|
|
||||||
s_phongUniformBlockIndex = uniformBlocks.size();
|
s_phongUniformBlockIndex = uniformBlocks.size();
|
||||||
uniformBlocks.push_back({
|
uniformBlocks.push_back({
|
||||||
"PhongSettings",
|
|
||||||
phongUniformStruct.GetSize(),
|
phongUniformStruct.GetSize(),
|
||||||
|
"PhongSettings",
|
||||||
"MaterialPhongSettings",
|
"MaterialPhongSettings",
|
||||||
std::move(phongVariables),
|
std::move(phongVariables),
|
||||||
std::move(defaultValues)
|
std::move(defaultValues)
|
||||||
|
|
@ -265,67 +209,65 @@ namespace Nz
|
||||||
std::vector<MaterialSettings::Texture> textures;
|
std::vector<MaterialSettings::Texture> textures;
|
||||||
s_textureIndexes.alpha = textures.size();
|
s_textureIndexes.alpha = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialAlphaMap",
|
||||||
"Alpha",
|
"Alpha",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialAlphaMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.diffuse = textures.size();
|
s_textureIndexes.diffuse = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialDiffuseMap",
|
||||||
"Diffuse",
|
"Diffuse",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialDiffuseMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.emissive = textures.size();
|
s_textureIndexes.emissive = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialEmissiveMap",
|
||||||
"Emissive",
|
"Emissive",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialEmissiveMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.height = textures.size();
|
s_textureIndexes.height = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialHeightMap",
|
||||||
"Height",
|
"Height",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialHeightMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.normal = textures.size();
|
s_textureIndexes.normal = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialNormalMap",
|
||||||
"Normal",
|
"Normal",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialNormalMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.specular = textures.size();
|
s_textureIndexes.specular = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"MaterialSpecularMap",
|
||||||
"Specular",
|
"Specular",
|
||||||
ImageType_2D,
|
ImageType_2D
|
||||||
"MaterialSpecularMap"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
|
predefinedBinding[PredefinedShaderBinding_TexOverlay] = textures.size();
|
||||||
textures.push_back({
|
textures.push_back({
|
||||||
|
"TextureOverlay",
|
||||||
"Overlay",
|
"Overlay",
|
||||||
ImageType_2D,
|
ImageType_2D,
|
||||||
"TextureOverlay"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding);
|
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding, MaterialSettings::DefaultShaders{});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhongLightingMaterial::Uninitialize()
|
void PhongLightingMaterial::Uninitialize()
|
||||||
{
|
{
|
||||||
s_renderPipelineLayout.Reset();
|
|
||||||
s_materialSettings.reset();
|
s_materialSettings.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MaterialSettings> PhongLightingMaterial::s_materialSettings;
|
std::shared_ptr<MaterialSettings> PhongLightingMaterial::s_materialSettings;
|
||||||
std::size_t PhongLightingMaterial::s_phongUniformBlockIndex;
|
std::size_t PhongLightingMaterial::s_phongUniformBlockIndex;
|
||||||
RenderPipelineLayoutRef PhongLightingMaterial::s_renderPipelineLayout;
|
|
||||||
PhongLightingMaterial::TextureIndexes PhongLightingMaterial::s_textureIndexes;
|
PhongLightingMaterial::TextureIndexes PhongLightingMaterial::s_textureIndexes;
|
||||||
PhongLightingMaterial::PhongUniformOffsets PhongLightingMaterial::s_phongUniformOffsets;
|
PhongLightingMaterial::PhongUniformOffsets PhongLightingMaterial::s_phongUniformOffsets;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ namespace Nz
|
||||||
return uniformBlock;
|
return uniformBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
PredefinedInstanceData PredefinedInstanceData::GetOffset()
|
PredefinedInstanceData PredefinedInstanceData::GetOffsets()
|
||||||
{
|
{
|
||||||
FieldOffsets viewerStruct(StructLayout_Std140);
|
FieldOffsets viewerStruct(StructLayout_Std140);
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Nz
|
||||||
|
|
||||||
MaterialSettings::SharedUniformBlock PredefinedInstanceData::GetUniformBlock()
|
MaterialSettings::SharedUniformBlock PredefinedInstanceData::GetUniformBlock()
|
||||||
{
|
{
|
||||||
PredefinedInstanceData instanceData = GetOffset();
|
PredefinedInstanceData instanceData = GetOffsets();
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> instanceDataVariables;
|
std::vector<MaterialSettings::UniformVariable> instanceDataVariables;
|
||||||
instanceDataVariables.assign({
|
instanceDataVariables.assign({
|
||||||
|
|
@ -92,7 +92,7 @@ namespace Nz
|
||||||
return uniformBlock;
|
return uniformBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
PredefinedViewerData PredefinedViewerData::GetOffset()
|
PredefinedViewerData PredefinedViewerData::GetOffsets()
|
||||||
{
|
{
|
||||||
FieldOffsets viewerStruct(StructLayout_Std140);
|
FieldOffsets viewerStruct(StructLayout_Std140);
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ namespace Nz
|
||||||
|
|
||||||
MaterialSettings::SharedUniformBlock PredefinedViewerData::GetUniformBlock()
|
MaterialSettings::SharedUniformBlock PredefinedViewerData::GetUniformBlock()
|
||||||
{
|
{
|
||||||
PredefinedViewerData viewerData = GetOffset();
|
PredefinedViewerData viewerData = GetOffsets();
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> viewerDataVariables;
|
std::vector<MaterialSettings::UniformVariable> viewerDataVariables;
|
||||||
viewerDataVariables.assign({
|
viewerDataVariables.assign({
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
||||||
|
78,83,72,82,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,3,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,1,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,1,0,0,0,0,0,0,0,6,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,16,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,0,0,0,0,10,1,0,0,0,0,0,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,1,0,0,0,1,0,0,0,0,14,84,101,120,116,117,114,101,79,118,101,114,108,97,121,0,0,0,0,10,1,0,0,0,2,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,13,0,0,0,3,0,0,0,7,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,5,0,0,0,5,0,0,0,0,191,52,253,244,63,52,253,244,0,0,0,7,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,2,0,0,0,9,0,0,0,1,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,9,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,11,0,0,0,9,0,0,0,5,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,0,0,0,9,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,84,97,114,103,101,116,48,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,11,0,0,0,9,0,0,0,5,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,0,0,0,9,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,10,109,97,116,68,105,102,102,117,115,101,0,0,0,0,4,
|
||||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
||||||
|
78,83,72,82,0,0,0,1,0,0,0,1,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,3,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,3,0,0,0,5,105,110,80,111,115,0,0,0,0,3,1,0,0,0,0,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,1,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,1,0,0,0,2,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,3,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,13,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,9,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,9,0,0,0,1,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,9,0,0,0,1,0,0,0,5,105,110,80,111,115,0,0,0,0,3,0,0,0,5,0,0,0,1,63,128,0,0,255,255,255,255,255,255,255,255,
|
||||||
Loading…
Reference in New Issue