Added normal mapping

Former-commit-id: 7e54b1f01de7d5cf99c42d08d13ba606f73c453d
This commit is contained in:
Lynix 2013-01-09 01:36:18 +01:00
parent 946754d7be
commit e3293c6fe1
3 changed files with 141 additions and 15 deletions

View File

@ -50,6 +50,8 @@ class NAZARA_API NzMaterial : public NzResource
nzBlendFunc GetDstBlend() const;
nzFaceCulling GetFaceCulling() const;
nzFaceFilling GetFaceFilling() const;
const NzTexture* GetHeightMap() const;
const NzTexture* GetNormalMap() const;
float GetShininess() const;
NzColor GetSpecularColor() const;
const NzTexture* GetSpecularMap() const;
@ -75,6 +77,8 @@ class NAZARA_API NzMaterial : public NzResource
void SetDstBlend(nzBlendFunc func);
void SetFaceCulling(nzFaceCulling culling);
void SetFaceFilling(nzFaceFilling filling);
void SetHeightMap(const NzTexture* map);
void SetNormalMap(const NzTexture* map);
void SetSamplerWrap(nzSamplerWrap wrapMode);
void SetShininess(float shininess);
void SetSpecularColor(const NzColor& specular);
@ -100,6 +104,8 @@ class NAZARA_API NzMaterial : public NzResource
NzTextureSampler m_diffuseSampler;
NzTextureSampler m_specularSampler;
const NzTexture* m_diffuseMap;
const NzTexture* m_heightMap;
const NzTexture* m_normalMap;
const NzTexture* m_specularMap;
bool m_alphaBlendingEnabled;
bool m_zTestEnabled;

View File

@ -15,6 +15,8 @@ bool NzMaterialParams::IsValid() const
NzMaterial::NzMaterial() :
m_diffuseMap(nullptr),
m_heightMap(nullptr),
m_normalMap(nullptr),
m_specularMap(nullptr)
{
Reset();
@ -28,6 +30,12 @@ NzResource()
if (m_diffuseMap)
m_diffuseMap->AddResourceReference();
if (m_heightMap)
m_heightMap->AddResourceReference();
if (m_normalMap)
m_normalMap->AddResourceReference();
if (m_specularMap)
m_specularMap->AddResourceReference();
}
@ -37,6 +45,12 @@ 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();
@ -44,6 +58,8 @@ NzMaterial::NzMaterial(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_specularMap = nullptr;
}
@ -52,6 +68,12 @@ NzMaterial::~NzMaterial()
if (m_diffuseMap)
m_diffuseMap->RemoveResourceReference();
if (m_heightMap)
m_heightMap->RemoveResourceReference();
if (m_normalMap)
m_normalMap->RemoveResourceReference();
if (m_specularMap)
m_specularMap->RemoveResourceReference();
}
@ -91,6 +113,32 @@ void NzMaterial::Apply() const
}
}
if (m_heightMap)
{
int heightMapLocation = shader->GetUniformLocation("MaterialHeightMap");
if (heightMapLocation != -1)
{
nzUInt8 textureUnit;
if (shader->SendTexture(heightMapLocation, m_heightMap, &textureUnit))
NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler);
else
NazaraWarning("Failed to send height map");
}
}
if (m_normalMap)
{
int normalMapLocation = shader->GetUniformLocation("MaterialNormalMap");
if (normalMapLocation != -1)
{
nzUInt8 textureUnit;
if (shader->SendTexture(normalMapLocation, m_normalMap, &textureUnit))
NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler);
else
NazaraWarning("Failed to send normal map");
}
}
if (shininessLocation != -1)
shader->SendFloat(shininessLocation, m_shininess);
@ -106,7 +154,7 @@ void NzMaterial::Apply() const
if (shader->SendTexture(specularMapLocation, m_specularMap, &textureUnit))
NzRenderer::SetTextureSampler(textureUnit, m_specularSampler);
else
NazaraWarning("Failed to send diffuse map");
NazaraWarning("Failed to send specular map");
}
}
@ -183,6 +231,16 @@ nzFaceFilling NzMaterial::GetFaceFilling() const
return m_faceFilling;
}
const NzTexture* NzMaterial::GetHeightMap() const
{
return m_diffuseMap;
}
const NzTexture* NzMaterial::GetNormalMap() const
{
return m_diffuseMap;
}
float NzMaterial::GetShininess() const
{
return m_shininess;
@ -256,6 +314,18 @@ void NzMaterial::Reset()
m_diffuseMap = nullptr;
}
if (m_heightMap)
{
m_heightMap->RemoveResourceReference();
m_heightMap = nullptr;
}
if (m_normalMap)
{
m_normalMap->RemoveResourceReference();
m_normalMap = nullptr;
}
if (m_specularMap)
{
m_specularMap->RemoveResourceReference();
@ -318,6 +388,26 @@ void NzMaterial::SetFaceFilling(nzFaceFilling filling)
m_faceFilling = filling;
}
void NzMaterial::SetHeightMap(const NzTexture* map)
{
if (m_heightMap)
m_heightMap->RemoveResourceReference();
m_heightMap = map;
if (m_heightMap)
m_heightMap->AddResourceReference();
}
void NzMaterial::SetNormalMap(const NzTexture* map)
{
if (m_normalMap)
m_normalMap->RemoveResourceReference();
m_normalMap = map;
if (m_normalMap)
m_normalMap->AddResourceReference();
}
void NzMaterial::SetShininess(float shininess)
{
m_shininess = shininess;

View File

@ -79,23 +79,30 @@ namespace
if (flags & nzShaderBuilder_Lighting)
{
if (flags & nzShaderBuilder_NormalMapping)
sourceCode += "uniform sampler2D MaterialNormalMap;\n";
sourceCode += "uniform float MaterialShininess;\n"
"uniform vec4 MaterialSpecular;\n";
}
if (flags & nzShaderBuilder_SpecularMapping)
sourceCode += "uniform sampler2D MaterialSpecularMap;\n";
if (flags & nzShaderBuilder_Lighting)
sourceCode += "uniform vec4 SceneAmbient;\n";
}
sourceCode += '\n';
/********************Entrant********************/
if (flags & nzShaderBuilder_Lighting)
sourceCode += inKW + " vec3 vNormal;\n";
{
if (flags & nzShaderBuilder_NormalMapping)
sourceCode += inKW + " mat3 vLightToWorld;\n";
if (flags & nzShaderBuilder_DiffuseMapping)
sourceCode += inKW + " vec3 vNormal;\n";
}
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping)
sourceCode += inKW + " vec2 vTexCoord;\n";
if (flags & nzShaderBuilder_Lighting)
@ -120,8 +127,12 @@ namespace
if (flags & nzShaderBuilder_SpecularMapping)
sourceCode += "vec3 si = vec3(0.0, 0.0, 0.0);\n";
sourceCode += "vec3 normal = normalize(vNormal);\n"
"\n"
if (flags & nzShaderBuilder_NormalMapping)
sourceCode += "vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture2D(MaterialNormalMap, vTexCoord)) - 1.0));\n";
else
sourceCode += "vec3 normal = normalize(vNormal);\n";
sourceCode += "\n"
"for (int i = 0; i < LightCount; ++i)\n"
"{\n";
@ -303,10 +314,10 @@ namespace
sourceCode += inKW + " vec3 VertexPosition;\n";
if (flags & nzShaderBuilder_Lighting)
{
sourceCode += inKW + " vec3 VertexNormal;\n";
if (flags & nzShaderBuilder_Lighting)
sourceCode += inKW + " vec3 VertexTangent;\n";
}
if (flags & nzShaderBuilder_DiffuseMapping)
sourceCode += inKW + " vec2 VertexTexCoord0;\n";
@ -315,9 +326,14 @@ namespace
/********************Sortant********************/
if (flags & nzShaderBuilder_Lighting)
sourceCode += outKW + " vec3 vNormal;\n";
{
if (flags & nzShaderBuilder_NormalMapping)
sourceCode += outKW + " mat3 vLightToWorld;";
if (flags & nzShaderBuilder_DiffuseMapping)
sourceCode += outKW + " vec3 vNormal;\n";
}
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping)
sourceCode += outKW + " vec2 vTexCoord;\n";
if (flags & nzShaderBuilder_Lighting)
@ -331,9 +347,23 @@ namespace
"gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n";
if (flags & nzShaderBuilder_Lighting)
sourceCode += "vNormal = normalize(mat3(WorldMatrix) * VertexNormal);\n";
{
sourceCode += "mat3 RotationMatrix = mat3(WorldMatrix);\n";
if (flags & nzShaderBuilder_DiffuseMapping)
if (flags & nzShaderBuilder_NormalMapping)
{
sourceCode += "\n"
"vec3 binormal = cross(VertexNormal, VertexTangent);\n"
"vLightToWorld[0] = VertexTangent * RotationMatrix;\n"
"vLightToWorld[1] = binormal * RotationMatrix;\n"
"vLightToWorld[2] = normalize(VertexNormal * RotationMatrix);\n"
"\n";
}
sourceCode += "vNormal = normalize(RotationMatrix * VertexNormal);\n";
}
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping)
sourceCode += "vTexCoord = VertexTexCoord0;\n";
if (flags & nzShaderBuilder_Lighting)