From e5731bee91101c6d0e5b22d45c361bfb7fb9abe6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Jan 2013 20:15:42 +0100 Subject: [PATCH] Added shader support to materials Also fixed a lot of bugs related to materials Former-commit-id: 54086eb3aa36c1a7b31b55056967275e6c24a4c6 --- include/Nazara/Renderer/Material.hpp | 11 ++- src/Nazara/Renderer/Material.cpp | 110 ++++++++++++++++++++++++--- 2 files changed, 108 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index 6cadc0d3c..576131501 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -23,6 +23,7 @@ struct NAZARA_API NzMaterialParams }; class NzMaterial; +class NzShader; using NzMaterialLoader = NzResourceLoader; @@ -39,6 +40,7 @@ class NAZARA_API NzMaterial : public NzResource void Apply() const; void EnableAlphaBlending(bool alphaBlending); + void EnableLighting(bool lighting); void EnableZTest(bool zTest); void EnableZWrite(bool zWrite); @@ -52,6 +54,7 @@ class NAZARA_API NzMaterial : public NzResource nzFaceFilling GetFaceFilling() const; const NzTexture* GetHeightMap() const; const NzTexture* GetNormalMap() const; + const NzShader* GetShader() const; float GetShininess() const; NzColor GetSpecularColor() const; const NzTexture* GetSpecularMap() const; @@ -61,6 +64,7 @@ class NAZARA_API NzMaterial : public NzResource nzRendererComparison GetZTestCompare() const; bool IsAlphaBlendingEnabled() const; + bool IsLightingEnabled() const; bool IsZTestEnabled() const; bool IsZWriteEnabled() const; @@ -79,7 +83,7 @@ class NAZARA_API NzMaterial : public NzResource void SetFaceFilling(nzFaceFilling filling); void SetHeightMap(const NzTexture* map); void SetNormalMap(const NzTexture* map); - void SetSamplerWrap(nzSamplerWrap wrapMode); + void SetShader(const NzShader* shader); void SetShininess(float shininess); void SetSpecularColor(const NzColor& specular); void SetSpecularMap(const NzTexture* map); @@ -93,6 +97,8 @@ class NAZARA_API NzMaterial : public NzResource static const NzMaterial* GetDefault(); private: + void UpdateShader() const; + nzBlendFunc m_dstBlend; nzBlendFunc m_srcBlend; nzFaceCulling m_faceCulling; @@ -103,11 +109,14 @@ class NAZARA_API NzMaterial : public NzResource NzColor m_specularColor; NzTextureSampler m_diffuseSampler; NzTextureSampler m_specularSampler; + mutable const NzShader* m_shader; const NzTexture* m_diffuseMap; const NzTexture* m_heightMap; const NzTexture* m_normalMap; const NzTexture* m_specularMap; bool m_alphaBlendingEnabled; + bool m_autoShader; + bool m_lightingEnabled; bool m_zTestEnabled; bool m_zWriteEnabled; float m_shininess; diff --git a/src/Nazara/Renderer/Material.cpp b/src/Nazara/Renderer/Material.cpp index 2a49c218a..d1a83bfab 100644 --- a/src/Nazara/Renderer/Material.cpp +++ b/src/Nazara/Renderer/Material.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -14,6 +15,7 @@ bool NzMaterialParams::IsValid() const } NzMaterial::NzMaterial() : +m_shader(nullptr), m_diffuseMap(nullptr), m_heightMap(nullptr), m_normalMap(nullptr), @@ -27,6 +29,7 @@ NzResource() { std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide + // Cependant comme nous sommes une entité à part nous devons ajouter les références aux ressources if (m_diffuseMap) m_diffuseMap->AddResourceReference(); @@ -36,30 +39,22 @@ NzResource() if (m_normalMap) m_normalMap->AddResourceReference(); + if (m_shader) + m_shader->AddResourceReference(); + if (m_specularMap) m_specularMap->AddResourceReference(); } NzMaterial::NzMaterial(NzMaterial&& material) { - if (m_diffuseMap) - m_diffuseMap->RemoveResourceReference(); - - if (m_heightMap) - m_heightMap->AddResourceReference(); - - if (m_normalMap) - m_normalMap->AddResourceReference(); - - if (m_specularMap) - m_specularMap->RemoveResourceReference(); - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide // Comme ça nous volons la référence du matériau material.m_diffuseMap = nullptr; material.m_heightMap = nullptr; material.m_normalMap = nullptr; + material.m_shader = nullptr; material.m_specularMap = nullptr; } @@ -74,6 +69,9 @@ NzMaterial::~NzMaterial() if (m_normalMap) m_normalMap->RemoveResourceReference(); + if (m_shader) + m_shader->RemoveResourceReference(); + if (m_specularMap) m_specularMap->RemoveResourceReference(); } @@ -181,6 +179,14 @@ void NzMaterial::EnableAlphaBlending(bool alphaBlending) m_alphaBlendingEnabled = alphaBlending; } +void NzMaterial::EnableLighting(bool lighting) +{ + m_lightingEnabled = lighting; + + if (m_autoShader) + m_shader = nullptr; +} + void NzMaterial::EnableZTest(bool zTest) { m_zTestEnabled = zTest; @@ -241,6 +247,14 @@ const NzTexture* NzMaterial::GetNormalMap() const return m_diffuseMap; } +const NzShader* NzMaterial::GetShader() const +{ + if (!m_shader) + UpdateShader(); + + return m_shader; +} + float NzMaterial::GetShininess() const { return m_shininess; @@ -281,6 +295,11 @@ bool NzMaterial::IsAlphaBlendingEnabled() const return m_alphaBlendingEnabled; } +bool NzMaterial::IsLightingEnabled() const +{ + return m_lightingEnabled; +} + bool NzMaterial::IsZTestEnabled() const { return m_zTestEnabled; @@ -326,6 +345,12 @@ void NzMaterial::Reset() m_normalMap = nullptr; } + if (m_shader) + { + m_shader->RemoveResourceReference(); + m_shader = nullptr; + } + if (m_specularMap) { m_specularMap->RemoveResourceReference(); @@ -334,11 +359,13 @@ void NzMaterial::Reset() m_alphaBlendingEnabled = false; m_ambientColor = NzColor(128, 128, 128); + m_autoShader = true; m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); m_dstBlend = nzBlendFunc_Zero; m_faceCulling = nzFaceCulling_Back; m_faceFilling = nzFaceFilling_Fill; + m_lightingEnabled = true; m_shininess = 50.f; m_specularColor = NzColor::White; m_specularSampler = NzTextureSampler(); @@ -408,6 +435,17 @@ void NzMaterial::SetNormalMap(const NzTexture* map) m_normalMap->AddResourceReference(); } +void NzMaterial::SetShader(const NzShader* shader) +{ + if (m_shader) + m_shader->RemoveResourceReference(); + + m_autoShader = (shader == nullptr); + m_shader = shader; + if (m_shader) + m_shader->AddResourceReference(); +} + void NzMaterial::SetShininess(float shininess) { m_shininess = shininess; @@ -448,14 +486,30 @@ NzMaterial& NzMaterial::operator=(const NzMaterial& material) if (m_diffuseMap) m_diffuseMap->RemoveResourceReference(); + if (m_heightMap) + m_heightMap->RemoveResourceReference(); + + if (m_normalMap) + m_normalMap->RemoveResourceReference(); + if (m_specularMap) m_specularMap->RemoveResourceReference(); std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide + // Cependant comme nous sommes une entité à part nous devons ajouter les références aux ressources if (m_diffuseMap) m_diffuseMap->AddResourceReference(); + if (m_heightMap) + m_heightMap->AddResourceReference(); + + if (m_normalMap) + m_normalMap->AddResourceReference(); + + if (m_shader) + m_shader->AddResourceReference(); + if (m_specularMap) m_specularMap->AddResourceReference(); @@ -467,6 +521,15 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material) if (m_diffuseMap) m_diffuseMap->RemoveResourceReference(); + if (m_heightMap) + m_heightMap->RemoveResourceReference(); + + if (m_normalMap) + m_normalMap->RemoveResourceReference(); + + if (m_shader) + m_shader->RemoveResourceReference(); + if (m_specularMap) m_specularMap->RemoveResourceReference(); @@ -474,6 +537,9 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material) // Comme ça nous volons la référence du matériau material.m_diffuseMap = nullptr; + material.m_heightMap = nullptr; + material.m_normalMap = nullptr; + material.m_shader = nullptr; material.m_specularMap = nullptr; return *this; @@ -496,4 +562,24 @@ const NzMaterial* NzMaterial::GetDefault() return &defaultMaterial; } +void NzMaterial::UpdateShader() const +{ + nzUInt32 shaderFlags = 0; + if (m_diffuseMap) + shaderFlags |= nzShaderBuilder_DiffuseMapping; + + if (m_lightingEnabled) + { + shaderFlags |= nzShaderBuilder_Lighting; + + if (m_normalMap) + shaderFlags |= nzShaderBuilder_NormalMapping; + + if (m_specularMap) + shaderFlags |= nzShaderBuilder_SpecularMapping; + } + + m_shader = NzShaderBuilder::Get(shaderFlags); +} + NzMaterialLoader::LoaderList NzMaterial::s_loaders;