OBJLoader now support transparency

Mesh::AddSubMesh no longer return bool

Former-commit-id: 71217618d179c5853683f4615901565cb7cd3ab8
This commit is contained in:
Lynix 2013-06-26 15:17:53 +02:00
parent f3603a0b31
commit d7a66d08b6
5 changed files with 57 additions and 40 deletions

View File

@ -21,7 +21,11 @@
struct NAZARA_API NzMaterialParams struct NAZARA_API NzMaterialParams
{ {
bool loadAlphaMap = true;
bool loadDiffuseMap = true; bool loadDiffuseMap = true;
bool loadEmissiveMap = true;
bool loadHeightMap = true;
bool loadNormalMap = true;
bool loadSpecularMap = true; bool loadSpecularMap = true;
bool IsValid() const; bool IsValid() const;

View File

@ -59,10 +59,10 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
NzMesh() = default; NzMesh() = default;
~NzMesh(); ~NzMesh();
bool AddSubMesh(NzSubMesh* subMesh); void AddSubMesh(NzSubMesh* subMesh);
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh); void AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
void BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params = NzMeshParams()); NzSubMesh* BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params = NzMeshParams());
void BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params = NzMeshParams()); void BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params = NzMeshParams());
bool CreateSkeletal(unsigned int jointCount); bool CreateSkeletal(unsigned int jointCount);

View File

@ -34,6 +34,7 @@ namespace
bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters) bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters)
{ {
NzOBJParser parser(stream); NzOBJParser parser(stream);
if (!parser.Parse()) if (!parser.Parse())
{ {
NazaraError("OBJ parser failed"); NazaraError("OBJ parser failed");
@ -173,10 +174,8 @@ namespace
else else
subMesh->GenerateNormals(); subMesh->GenerateNormals();
if (mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh.get())) mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh.get());
subMesh.release(); subMesh.release();
else
NazaraError("Failed to add SubMesh to Mesh");
} }
mesh->SetMaterialCount(parser.GetMaterialCount()); mesh->SetMaterialCount(parser.GetMaterialCount());
@ -218,6 +217,23 @@ namespace
material->SetSpecularColor(specularColor); material->SetSpecularColor(specularColor);
material->SetShininess(mtlMat->shininess); material->SetShininess(mtlMat->shininess);
bool hasAlphaMap = false;;
if (parameters.material.loadAlphaMap && !mtlMat->alphaMap.IsEmpty())
{
std::unique_ptr<NzTexture> alphaMap(new NzTexture);
alphaMap->SetPersistent(false);
if (alphaMap->LoadFromFile(baseDir + mtlMat->alphaMap))
{
hasAlphaMap = true;
material->SetAlphaMap(alphaMap.get());
alphaMap.release();
}
else
NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')');
}
if (parameters.material.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty()) if (parameters.material.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty())
{ {
std::unique_ptr<NzTexture> diffuseMap(new NzTexture); std::unique_ptr<NzTexture> diffuseMap(new NzTexture);
@ -246,6 +262,17 @@ namespace
NazaraWarning("Failed to load specular map (" + mtlMat->diffuseMap + ')'); NazaraWarning("Failed to load specular map (" + mtlMat->diffuseMap + ')');
} }
// Si nous avons une alpha map ou des couleurs transparentes,
// nous devons configurer le matériau pour accepter la transparence au mieux
if (hasAlphaMap || !NzNumberEquals(mtlMat->alpha, 1.f))
{
// On paramètre le matériau pour accepter la transparence au mieux
material->Enable(nzRendererParameter_Blend, true);
material->Enable(nzRendererParameter_DepthWrite, false);
material->SetDstBlend(nzBlendFunc_InvSrcAlpha);
material->SetSrcBlend(nzBlendFunc_SrcAlpha);
}
model->SetMaterial(meshes[i].material, material.get()); model->SetMaterial(meshes[i].material, material.get());
material.release(); material.release();
} }

View File

@ -260,12 +260,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
mesh->SetMaterial(i, baseDir + md5Mesh.shader); mesh->SetMaterial(i, baseDir + md5Mesh.shader);
subMesh->SetMaterialIndex(i); subMesh->SetMaterialIndex(i);
if (!mesh->AddSubMesh(subMesh.get())) mesh->AddSubMesh(subMesh.get());
{
NazaraError("Failed to add submesh");
continue;
}
subMesh.release(); subMesh.release();
// Animation // Animation
@ -360,12 +355,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
subMesh->GenerateNormalsAndTangents(); subMesh->GenerateNormalsAndTangents();
subMesh->SetMaterialIndex(i); subMesh->SetMaterialIndex(i);
if (!mesh->AddSubMesh(subMesh.get())) mesh->AddSubMesh(subMesh.get());
{
NazaraError("Failed to add submesh");
continue;
}
subMesh.release(); subMesh.release();
} }
} }

View File

@ -69,25 +69,25 @@ NzMesh::~NzMesh()
Destroy(); Destroy();
} }
bool NzMesh::AddSubMesh(NzSubMesh* subMesh) void NzMesh::AddSubMesh(NzSubMesh* subMesh)
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
{ {
NazaraError("Mesh not created"); NazaraError("Mesh not created");
return false; return;
} }
if (!subMesh) if (!subMesh)
{ {
NazaraError("Invalid submesh"); NazaraError("Invalid submesh");
return false; return;
} }
if (subMesh->GetAnimationType() != m_impl->animationType) if (subMesh->GetAnimationType() != m_impl->animationType)
{ {
NazaraError("Submesh animation type must match mesh animation type"); NazaraError("Submesh animation type must match mesh animation type");
return false; return;
} }
#endif #endif
@ -95,42 +95,40 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh)
m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->aabbUpdated = false; // On invalide l'AABB
m_impl->subMeshes.push_back(subMesh); m_impl->subMeshes.push_back(subMesh);
return true;
} }
bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
{ {
NazaraError("Mesh not created"); NazaraError("Mesh not created");
return false; return;
} }
if (identifier.IsEmpty()) if (identifier.IsEmpty())
{ {
NazaraError("Identifier is empty"); NazaraError("Identifier is empty");
return false; return;
} }
auto it = m_impl->subMeshMap.find(identifier); auto it = m_impl->subMeshMap.find(identifier);
if (it != m_impl->subMeshMap.end()) if (it != m_impl->subMeshMap.end())
{ {
NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); NazaraError("SubMesh identifier \"" + identifier + "\" is already used");
return false; return;
} }
if (!subMesh) if (!subMesh)
{ {
NazaraError("Invalid submesh"); NazaraError("Invalid submesh");
return false; return;
} }
if (m_impl->animationType != subMesh->GetAnimationType()) if (m_impl->animationType != subMesh->GetAnimationType())
{ {
NazaraError("Submesh animation type must match mesh animation type"); NazaraError("Submesh animation type must match mesh animation type");
return false; return;
} }
#endif #endif
@ -141,29 +139,27 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->aabbUpdated = false; // On invalide l'AABB
m_impl->subMeshes.push_back(subMesh); m_impl->subMeshes.push_back(subMesh);
m_impl->subMeshMap[identifier] = index; m_impl->subMeshMap[identifier] = index;
return true;
} }
void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params) NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params)
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_impl) if (!m_impl)
{ {
NazaraError("Mesh not created"); NazaraError("Mesh not created");
return; return nullptr;
} }
if (m_impl->animationType != nzAnimationType_Static) if (m_impl->animationType != nzAnimationType_Static)
{ {
NazaraError("Mesh must be static"); NazaraError("Mesh must be static");
return; return nullptr;
} }
if (!params.IsValid()) if (!params.IsValid())
{ {
NazaraError("Parameters must be valid"); NazaraError("Parameters must be valid");
return; return nullptr;
} }
#endif #endif
@ -283,7 +279,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
if (!subMesh->Create(vertexBuffer.get())) if (!subMesh->Create(vertexBuffer.get()))
{ {
NazaraError("Failed to create StaticMesh"); NazaraError("Failed to create StaticMesh");
return; return nullptr;
} }
vertexBuffer.release(); vertexBuffer.release();
@ -294,9 +290,9 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
indexBuffer.release(); indexBuffer.release();
subMesh->SetAABB(aabb); subMesh->SetAABB(aabb);
AddSubMesh(subMesh.get());
if (AddSubMesh(subMesh.get())) return subMesh.release();
subMesh.release();
} }
void NzMesh::BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params) void NzMesh::BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params)