diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 605104c11..35d70bad2 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -148,14 +148,15 @@ enum nzShaderFlags { nzShaderFlags_None = 0, - nzShaderFlags_Deferred = 0x01, - nzShaderFlags_DiffuseMapping = 0x02, - nzShaderFlags_FlipUVs = 0x04, - nzShaderFlags_Instancing = 0x08, - nzShaderFlags_Lighting = 0x10, - nzShaderFlags_NormalMapping = 0x20, - nzShaderFlags_ParallaxMapping = 0x40, - nzShaderFlags_SpecularMapping = 0x80 + nzShaderFlags_Deferred = 0x001, + nzShaderFlags_DiffuseMapping = 0x002, + nzShaderFlags_EmissiveMapping = 0x004, + nzShaderFlags_FlipUVs = 0x008, + nzShaderFlags_Instancing = 0x010, + nzShaderFlags_Lighting = 0x020, + nzShaderFlags_NormalMapping = 0x040, + nzShaderFlags_ParallaxMapping = 0x080, + nzShaderFlags_SpecularMapping = 0x100 }; enum nzShaderLanguage diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index 93e81f406..46775567a 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -56,6 +56,7 @@ class NAZARA_API NzMaterial : public NzResource NzTextureSampler& GetDiffuseSampler(); const NzTextureSampler& GetDiffuseSampler() const; nzBlendFunc GetDstBlend() const; + NzTexture* GetEmissiveMap() const; nzFaceCulling GetFaceCulling() const; nzFaceFilling GetFaceFilling() const; NzTexture* GetHeightMap() const; @@ -88,6 +89,7 @@ class NAZARA_API NzMaterial : public NzResource void SetDiffuseMap(NzTexture* map); void SetDiffuseSampler(const NzTextureSampler& sampler); void SetDstBlend(nzBlendFunc func); + void SetEmissiveMap(NzTexture* map); void SetFaceCulling(nzFaceCulling culling); void SetFaceFilling(nzFaceFilling filling); void SetHeightMap(NzTexture* map); @@ -121,6 +123,7 @@ class NAZARA_API NzMaterial : public NzResource NzTextureSampler m_specularSampler; mutable NzShaderConstRef m_customShader; NzTextureRef m_diffuseMap; + NzTextureRef m_emissiveMap; NzTextureRef m_heightMap; NzTextureRef m_normalMap; NzTextureRef m_specularMap; diff --git a/src/Nazara/Renderer/Material.cpp b/src/Nazara/Renderer/Material.cpp index 1fbb918e2..c9bd092f9 100644 --- a/src/Nazara/Renderer/Material.cpp +++ b/src/Nazara/Renderer/Material.cpp @@ -32,6 +32,7 @@ NzMaterial::NzMaterial(NzMaterial&& material) // Nous "volons" la référence du matériau material.m_customShader = nullptr; material.m_diffuseMap = nullptr; + material.m_emissiveMap = nullptr; material.m_heightMap = nullptr; material.m_normalMap = nullptr; material.m_specularMap = nullptr; @@ -63,6 +64,19 @@ void NzMaterial::Apply(const NzShader* shader) const } } + if (m_emissiveMap) + { + int emissiveMapLocation = shader->GetUniformLocation("MaterialEmissiveMap"); + if (emissiveMapLocation != -1) + { + nzUInt8 textureUnit; + if (shader->SendTexture(emissiveMapLocation, m_emissiveMap, &textureUnit)) + NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); + else + NazaraWarning("Failed to send emissive map"); + } + } + if (m_heightMap) { int heightMapLocation = shader->GetUniformLocation("MaterialHeightMap"); @@ -195,6 +209,11 @@ nzBlendFunc NzMaterial::GetDstBlend() const return m_dstBlend; } +NzTexture* NzMaterial::GetEmissiveMap() const +{ + return m_emissiveMap; +} + nzFaceCulling NzMaterial::GetFaceCulling() const { return m_faceCulling; @@ -309,6 +328,7 @@ void NzMaterial::Reset() { m_customShader.Reset(); m_diffuseMap.Reset(); + m_emissiveMap.Reset(); m_heightMap.Reset(); m_normalMap.Reset(); m_specularMap.Reset(); @@ -366,6 +386,15 @@ void NzMaterial::SetDstBlend(nzBlendFunc func) m_dstBlend = func; } +void NzMaterial::SetEmissiveMap(NzTexture* map) +{ + m_emissiveMap = map; + if (m_emissiveMap) + m_shaderFlags |= nzShaderFlags_EmissiveMapping; + else + m_shaderFlags &= ~nzShaderFlags_EmissiveMapping; +} + void NzMaterial::SetFaceCulling(nzFaceCulling culling) { m_faceCulling = culling; @@ -438,6 +467,7 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material) // Comme ça nous volons la référence du matériau material.m_customShader = nullptr; material.m_diffuseMap = nullptr; + material.m_emissiveMap = nullptr; material.m_heightMap = nullptr; material.m_normalMap = nullptr; material.m_specularMap = nullptr; @@ -467,6 +497,7 @@ void NzMaterial::Copy(const NzMaterial& material) { m_customShader.Reset(); m_diffuseMap.Reset(); + m_emissiveMap.Reset(); m_heightMap.Reset(); m_normalMap.Reset(); m_specularMap.Reset(); @@ -476,6 +507,7 @@ void NzMaterial::Copy(const NzMaterial& material) // Ensuite une petite astuce pour récupérer correctement les références m_customShader.Release(); m_diffuseMap.Release(); + m_emissiveMap.Release(); m_heightMap.Release(); m_normalMap.Release(); m_specularMap.Release(); diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index 5e1cc45be..9ca032182 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -81,6 +81,9 @@ namespace if (flags & nzShaderFlags_DiffuseMapping) sourceCode += "uniform sampler2D MaterialDiffuseMap;\n"; + if (flags & nzShaderFlags_EmissiveMapping) + sourceCode += "uniform sampler2D MaterialEmissiveMap;\n"; + if (flags & nzShaderFlags_Lighting) { if (flags & nzShaderFlags_NormalMapping) @@ -124,6 +127,14 @@ namespace sourceCode += "void main()\n" "{\n"; + if (flags & nzShaderFlags_EmissiveMapping) + { + // Les emissive map court-circuitent l'éclairage + sourceCode += "vec3 emissive = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n" + "if (emissive == vec3(0.0, 0.0, 0.0))\n" + "{\n"; + } + if (flags & nzShaderFlags_Lighting) { sourceCode += "vec3 light = vec3(0.0, 0.0, 0.0);\n"; @@ -282,6 +293,14 @@ namespace else sourceCode += fragmentColorKW + " = MaterialDiffuse;\n"; + if (flags & nzShaderFlags_EmissiveMapping) + { + sourceCode += "}\n" + "else\n" + + fragmentColorKW + " = vec4(emissive, MaterialDiffuse.a);\n"; + } + + sourceCode += "}\n"; return sourceCode;