Added alpha-mapping support
Former-commit-id: ba4598e9e5efc47e04e72dc709d64d214d77e9a1
This commit is contained in:
@@ -61,10 +61,12 @@ bool NzGLSLShader::Compile()
|
||||
static NzString successStr("Linkage successful");
|
||||
m_log = successStr;
|
||||
|
||||
// Pour éviter de se tromper entre le nom et la constante
|
||||
#define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = GetUniformLocation(#name)
|
||||
|
||||
CacheUniform(CameraPosition);
|
||||
CacheUniform(LightCount);
|
||||
CacheUniform(MaterialAlphaMap);
|
||||
CacheUniform(MaterialAmbient);
|
||||
CacheUniform(MaterialDiffuse);
|
||||
CacheUniform(MaterialDiffuseMap);
|
||||
|
||||
@@ -31,6 +31,7 @@ NzMaterial::NzMaterial(NzMaterial&& material)
|
||||
Copy(material);
|
||||
|
||||
// Nous "volons" la référence du matériau
|
||||
material.m_alphaMap = nullptr;
|
||||
material.m_customShader = nullptr;
|
||||
material.m_diffuseMap = nullptr;
|
||||
material.m_emissiveMap = nullptr;
|
||||
@@ -46,6 +47,19 @@ void NzMaterial::Apply(const NzShader* shader) const
|
||||
int shininessLocation = shader->GetUniformLocation(nzShaderUniform_MaterialShininess);
|
||||
int specularColorLocation = shader->GetUniformLocation(nzShaderUniform_MaterialSpecular);
|
||||
|
||||
if (m_alphaMap)
|
||||
{
|
||||
int alphaMapLocation = shader->GetUniformLocation(nzShaderUniform_MaterialAlphaMap);
|
||||
if (alphaMapLocation != -1)
|
||||
{
|
||||
nzUInt8 textureUnit;
|
||||
if (shader->SendTexture(alphaMapLocation, m_alphaMap, &textureUnit))
|
||||
NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler);
|
||||
else
|
||||
NazaraWarning("Failed to send diffuse map");
|
||||
}
|
||||
}
|
||||
|
||||
if (ambientColorLocation != -1)
|
||||
shader->SendColor(ambientColorLocation, m_ambientColor);
|
||||
|
||||
@@ -327,6 +341,7 @@ bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& p
|
||||
|
||||
void NzMaterial::Reset()
|
||||
{
|
||||
m_alphaMap.Reset();
|
||||
m_customShader.Reset();
|
||||
m_diffuseMap.Reset();
|
||||
m_emissiveMap.Reset();
|
||||
@@ -353,6 +368,32 @@ void NzMaterial::Reset()
|
||||
m_zWriteEnabled = true;
|
||||
}
|
||||
|
||||
bool NzMaterial::SetAlphaMap(const NzString& texturePath)
|
||||
{
|
||||
std::unique_ptr<NzTexture> texture(new NzTexture);
|
||||
if (!texture->LoadFromFile(texturePath))
|
||||
{
|
||||
NazaraError("Failed to load texture from \"" + texturePath + '"');
|
||||
return false;
|
||||
}
|
||||
|
||||
texture->SetPersistent(false);
|
||||
|
||||
SetAlphaMap(texture.get());
|
||||
texture.release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMaterial::SetAlphaMap(NzTexture* map)
|
||||
{
|
||||
m_alphaMap = map;
|
||||
if (m_alphaMap)
|
||||
m_shaderFlags |= nzShaderFlags_AlphaMapping;
|
||||
else
|
||||
m_shaderFlags &= ~nzShaderFlags_AlphaMapping;
|
||||
}
|
||||
|
||||
void NzMaterial::SetAmbientColor(const NzColor& ambient)
|
||||
{
|
||||
m_ambientColor = ambient;
|
||||
@@ -551,6 +592,7 @@ NzMaterial& NzMaterial::operator=(NzMaterial&& material)
|
||||
Copy(material);
|
||||
|
||||
// Comme ça nous volons la référence du matériau
|
||||
material.m_alphaMap = nullptr;
|
||||
material.m_customShader = nullptr;
|
||||
material.m_diffuseMap = nullptr;
|
||||
material.m_emissiveMap = nullptr;
|
||||
@@ -581,6 +623,7 @@ NzMaterial* NzMaterial::GetDefault()
|
||||
|
||||
void NzMaterial::Copy(const NzMaterial& material)
|
||||
{
|
||||
m_alphaMap.Reset();
|
||||
m_customShader.Reset();
|
||||
m_diffuseMap.Reset();
|
||||
m_emissiveMap.Reset();
|
||||
@@ -591,6 +634,7 @@ void NzMaterial::Copy(const NzMaterial& material)
|
||||
std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et bien plus rapide
|
||||
|
||||
// Ensuite une petite astuce pour récupérer correctement les références
|
||||
m_alphaMap.Release();
|
||||
m_customShader.Release();
|
||||
m_diffuseMap.Release();
|
||||
m_emissiveMap.Release();
|
||||
@@ -598,6 +642,7 @@ void NzMaterial::Copy(const NzMaterial& material)
|
||||
m_normalMap.Release();
|
||||
m_specularMap.Release();
|
||||
|
||||
m_alphaMap = material.m_alphaMap;
|
||||
m_customShader = material.m_customShader;
|
||||
m_diffuseMap = material.m_diffuseMap;
|
||||
m_heightMap = material.m_heightMap;
|
||||
|
||||
@@ -75,6 +75,9 @@ namespace
|
||||
"uniform vec4 MaterialAmbient;\n";
|
||||
}
|
||||
|
||||
if (flags & nzShaderFlags_AlphaMapping)
|
||||
sourceCode += "uniform sampler2D MaterialAlphaMap;\n";
|
||||
|
||||
if ((flags & nzShaderFlags_DiffuseMapping) == 0 || flags & nzShaderFlags_Lighting)
|
||||
sourceCode += "uniform vec4 MaterialDiffuse;\n";
|
||||
|
||||
@@ -280,17 +283,27 @@ namespace
|
||||
|
||||
sourceCode += ";\n";
|
||||
|
||||
if (flags & nzShaderFlags_AlphaMapping)
|
||||
sourceCode += "float alpha = " + textureLookupKW + "(MaterialAlphaMap, vTexCoord).r;\n";
|
||||
else
|
||||
sourceCode += "float alpha = MaterialDiffuse.a;\n";
|
||||
|
||||
if (flags & nzShaderFlags_EmissiveMapping)
|
||||
{
|
||||
sourceCode += "vec3 emission = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n"
|
||||
+ fragmentColorKW + " = vec4(mix(lighting, emission, length(emission)), MaterialDiffuse.a);";
|
||||
+ fragmentColorKW + " = vec4(mix(lighting, emission, length(emission)), alpha);\n";
|
||||
///NOTE: Pour un shader avec un coût réduit avec une qualité moyenne, il est possible de remplacer "length(emission)" par "dot(emission, emission)"
|
||||
}
|
||||
else
|
||||
sourceCode += fragmentColorKW + " = vec4(lighting, MaterialDiffuse.a);";
|
||||
sourceCode += fragmentColorKW + " = vec4(lighting, alpha);\n";
|
||||
}
|
||||
else if (flags & nzShaderFlags_DiffuseMapping)
|
||||
sourceCode += fragmentColorKW + " = " + textureLookupKW + "(MaterialDiffuseMap, vTexCoord);\n";
|
||||
{
|
||||
if (flags & nzShaderFlags_AlphaMapping)
|
||||
sourceCode += fragmentColorKW + " = vec4(" + textureLookupKW + "(MaterialDiffuseMap, vTexCoord).rgb, " + textureLookupKW + "(MaterialAlphaMap, vTexCoord).r);\n";
|
||||
else
|
||||
sourceCode += fragmentColorKW + " = " + textureLookupKW + "(MaterialDiffuseMap, vTexCoord);\n";
|
||||
}
|
||||
else
|
||||
sourceCode += fragmentColorKW + " = MaterialDiffuse;\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user