Added shader support to materials

Also fixed a lot of bugs related to materials


Former-commit-id: 54086eb3aa36c1a7b31b55056967275e6c24a4c6
This commit is contained in:
Lynix 2013-01-09 20:15:42 +01:00
parent e3293c6fe1
commit e5731bee91
2 changed files with 108 additions and 13 deletions

View File

@ -23,6 +23,7 @@ struct NAZARA_API NzMaterialParams
}; };
class NzMaterial; class NzMaterial;
class NzShader;
using NzMaterialLoader = NzResourceLoader<NzMaterial, NzMaterialParams>; using NzMaterialLoader = NzResourceLoader<NzMaterial, NzMaterialParams>;
@ -39,6 +40,7 @@ class NAZARA_API NzMaterial : public NzResource
void Apply() const; void Apply() const;
void EnableAlphaBlending(bool alphaBlending); void EnableAlphaBlending(bool alphaBlending);
void EnableLighting(bool lighting);
void EnableZTest(bool zTest); void EnableZTest(bool zTest);
void EnableZWrite(bool zWrite); void EnableZWrite(bool zWrite);
@ -52,6 +54,7 @@ class NAZARA_API NzMaterial : public NzResource
nzFaceFilling GetFaceFilling() const; nzFaceFilling GetFaceFilling() const;
const NzTexture* GetHeightMap() const; const NzTexture* GetHeightMap() const;
const NzTexture* GetNormalMap() const; const NzTexture* GetNormalMap() const;
const NzShader* GetShader() const;
float GetShininess() const; float GetShininess() const;
NzColor GetSpecularColor() const; NzColor GetSpecularColor() const;
const NzTexture* GetSpecularMap() const; const NzTexture* GetSpecularMap() const;
@ -61,6 +64,7 @@ class NAZARA_API NzMaterial : public NzResource
nzRendererComparison GetZTestCompare() const; nzRendererComparison GetZTestCompare() const;
bool IsAlphaBlendingEnabled() const; bool IsAlphaBlendingEnabled() const;
bool IsLightingEnabled() const;
bool IsZTestEnabled() const; bool IsZTestEnabled() const;
bool IsZWriteEnabled() const; bool IsZWriteEnabled() const;
@ -79,7 +83,7 @@ class NAZARA_API NzMaterial : public NzResource
void SetFaceFilling(nzFaceFilling filling); void SetFaceFilling(nzFaceFilling filling);
void SetHeightMap(const NzTexture* map); void SetHeightMap(const NzTexture* map);
void SetNormalMap(const NzTexture* map); void SetNormalMap(const NzTexture* map);
void SetSamplerWrap(nzSamplerWrap wrapMode); void SetShader(const NzShader* shader);
void SetShininess(float shininess); void SetShininess(float shininess);
void SetSpecularColor(const NzColor& specular); void SetSpecularColor(const NzColor& specular);
void SetSpecularMap(const NzTexture* map); void SetSpecularMap(const NzTexture* map);
@ -93,6 +97,8 @@ class NAZARA_API NzMaterial : public NzResource
static const NzMaterial* GetDefault(); static const NzMaterial* GetDefault();
private: private:
void UpdateShader() const;
nzBlendFunc m_dstBlend; nzBlendFunc m_dstBlend;
nzBlendFunc m_srcBlend; nzBlendFunc m_srcBlend;
nzFaceCulling m_faceCulling; nzFaceCulling m_faceCulling;
@ -103,11 +109,14 @@ class NAZARA_API NzMaterial : public NzResource
NzColor m_specularColor; NzColor m_specularColor;
NzTextureSampler m_diffuseSampler; NzTextureSampler m_diffuseSampler;
NzTextureSampler m_specularSampler; NzTextureSampler m_specularSampler;
mutable const NzShader* m_shader;
const NzTexture* m_diffuseMap; const NzTexture* m_diffuseMap;
const NzTexture* m_heightMap; const NzTexture* m_heightMap;
const NzTexture* m_normalMap; const NzTexture* m_normalMap;
const NzTexture* m_specularMap; const NzTexture* m_specularMap;
bool m_alphaBlendingEnabled; bool m_alphaBlendingEnabled;
bool m_autoShader;
bool m_lightingEnabled;
bool m_zTestEnabled; bool m_zTestEnabled;
bool m_zWriteEnabled; bool m_zWriteEnabled;
float m_shininess; float m_shininess;

View File

@ -5,6 +5,7 @@
#include <Nazara/Renderer/Material.hpp> #include <Nazara/Renderer/Material.hpp>
#include <Nazara/Renderer/Renderer.hpp> #include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/Shader.hpp> #include <Nazara/Renderer/Shader.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <cstring> #include <cstring>
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
@ -14,6 +15,7 @@ bool NzMaterialParams::IsValid() const
} }
NzMaterial::NzMaterial() : NzMaterial::NzMaterial() :
m_shader(nullptr),
m_diffuseMap(nullptr), m_diffuseMap(nullptr),
m_heightMap(nullptr), m_heightMap(nullptr),
m_normalMap(nullptr), m_normalMap(nullptr),
@ -27,6 +29,7 @@ NzResource()
{ {
std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide 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) if (m_diffuseMap)
m_diffuseMap->AddResourceReference(); m_diffuseMap->AddResourceReference();
@ -36,30 +39,22 @@ NzResource()
if (m_normalMap) if (m_normalMap)
m_normalMap->AddResourceReference(); m_normalMap->AddResourceReference();
if (m_shader)
m_shader->AddResourceReference();
if (m_specularMap) if (m_specularMap)
m_specularMap->AddResourceReference(); m_specularMap->AddResourceReference();
} }
NzMaterial::NzMaterial(NzMaterial&& material) 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 std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide
// Comme ça nous volons la référence du matériau // Comme ça nous volons la référence du matériau
material.m_diffuseMap = nullptr; material.m_diffuseMap = nullptr;
material.m_heightMap = nullptr; material.m_heightMap = nullptr;
material.m_normalMap = nullptr; material.m_normalMap = nullptr;
material.m_shader = nullptr;
material.m_specularMap = nullptr; material.m_specularMap = nullptr;
} }
@ -74,6 +69,9 @@ NzMaterial::~NzMaterial()
if (m_normalMap) if (m_normalMap)
m_normalMap->RemoveResourceReference(); m_normalMap->RemoveResourceReference();
if (m_shader)
m_shader->RemoveResourceReference();
if (m_specularMap) if (m_specularMap)
m_specularMap->RemoveResourceReference(); m_specularMap->RemoveResourceReference();
} }
@ -181,6 +179,14 @@ void NzMaterial::EnableAlphaBlending(bool alphaBlending)
m_alphaBlendingEnabled = alphaBlending; m_alphaBlendingEnabled = alphaBlending;
} }
void NzMaterial::EnableLighting(bool lighting)
{
m_lightingEnabled = lighting;
if (m_autoShader)
m_shader = nullptr;
}
void NzMaterial::EnableZTest(bool zTest) void NzMaterial::EnableZTest(bool zTest)
{ {
m_zTestEnabled = zTest; m_zTestEnabled = zTest;
@ -241,6 +247,14 @@ const NzTexture* NzMaterial::GetNormalMap() const
return m_diffuseMap; return m_diffuseMap;
} }
const NzShader* NzMaterial::GetShader() const
{
if (!m_shader)
UpdateShader();
return m_shader;
}
float NzMaterial::GetShininess() const float NzMaterial::GetShininess() const
{ {
return m_shininess; return m_shininess;
@ -281,6 +295,11 @@ bool NzMaterial::IsAlphaBlendingEnabled() const
return m_alphaBlendingEnabled; return m_alphaBlendingEnabled;
} }
bool NzMaterial::IsLightingEnabled() const
{
return m_lightingEnabled;
}
bool NzMaterial::IsZTestEnabled() const bool NzMaterial::IsZTestEnabled() const
{ {
return m_zTestEnabled; return m_zTestEnabled;
@ -326,6 +345,12 @@ void NzMaterial::Reset()
m_normalMap = nullptr; m_normalMap = nullptr;
} }
if (m_shader)
{
m_shader->RemoveResourceReference();
m_shader = nullptr;
}
if (m_specularMap) if (m_specularMap)
{ {
m_specularMap->RemoveResourceReference(); m_specularMap->RemoveResourceReference();
@ -334,11 +359,13 @@ void NzMaterial::Reset()
m_alphaBlendingEnabled = false; m_alphaBlendingEnabled = false;
m_ambientColor = NzColor(128, 128, 128); m_ambientColor = NzColor(128, 128, 128);
m_autoShader = true;
m_diffuseColor = NzColor::White; m_diffuseColor = NzColor::White;
m_diffuseSampler = NzTextureSampler(); m_diffuseSampler = NzTextureSampler();
m_dstBlend = nzBlendFunc_Zero; m_dstBlend = nzBlendFunc_Zero;
m_faceCulling = nzFaceCulling_Back; m_faceCulling = nzFaceCulling_Back;
m_faceFilling = nzFaceFilling_Fill; m_faceFilling = nzFaceFilling_Fill;
m_lightingEnabled = true;
m_shininess = 50.f; m_shininess = 50.f;
m_specularColor = NzColor::White; m_specularColor = NzColor::White;
m_specularSampler = NzTextureSampler(); m_specularSampler = NzTextureSampler();
@ -408,6 +435,17 @@ void NzMaterial::SetNormalMap(const NzTexture* map)
m_normalMap->AddResourceReference(); 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) void NzMaterial::SetShininess(float shininess)
{ {
m_shininess = shininess; m_shininess = shininess;
@ -448,14 +486,30 @@ NzMaterial& NzMaterial::operator=(const NzMaterial& material)
if (m_diffuseMap) if (m_diffuseMap)
m_diffuseMap->RemoveResourceReference(); m_diffuseMap->RemoveResourceReference();
if (m_heightMap)
m_heightMap->RemoveResourceReference();
if (m_normalMap)
m_normalMap->RemoveResourceReference();
if (m_specularMap) if (m_specularMap)
m_specularMap->RemoveResourceReference(); m_specularMap->RemoveResourceReference();
std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide 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) if (m_diffuseMap)
m_diffuseMap->AddResourceReference(); m_diffuseMap->AddResourceReference();
if (m_heightMap)
m_heightMap->AddResourceReference();
if (m_normalMap)
m_normalMap->AddResourceReference();
if (m_shader)
m_shader->AddResourceReference();
if (m_specularMap) if (m_specularMap)
m_specularMap->AddResourceReference(); m_specularMap->AddResourceReference();
@ -467,6 +521,15 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material)
if (m_diffuseMap) if (m_diffuseMap)
m_diffuseMap->RemoveResourceReference(); m_diffuseMap->RemoveResourceReference();
if (m_heightMap)
m_heightMap->RemoveResourceReference();
if (m_normalMap)
m_normalMap->RemoveResourceReference();
if (m_shader)
m_shader->RemoveResourceReference();
if (m_specularMap) if (m_specularMap)
m_specularMap->RemoveResourceReference(); m_specularMap->RemoveResourceReference();
@ -474,6 +537,9 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material)
// Comme ça nous volons la référence du matériau // Comme ça nous volons la référence du matériau
material.m_diffuseMap = nullptr; material.m_diffuseMap = nullptr;
material.m_heightMap = nullptr;
material.m_normalMap = nullptr;
material.m_shader = nullptr;
material.m_specularMap = nullptr; material.m_specularMap = nullptr;
return *this; return *this;
@ -496,4 +562,24 @@ const NzMaterial* NzMaterial::GetDefault()
return &defaultMaterial; 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; NzMaterialLoader::LoaderList NzMaterial::s_loaders;