diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index 7e6f041b3..1421a8371 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -21,7 +21,11 @@ struct NAZARA_API NzMaterialParams { + bool loadAlphaMap = true; bool loadDiffuseMap = true; + bool loadEmissiveMap = true; + bool loadHeightMap = true; + bool loadNormalMap = true; bool loadSpecularMap = true; bool IsValid() const; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index aba547d3b..5dae25937 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -59,10 +59,10 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener NzMesh() = default; ~NzMesh(); - bool AddSubMesh(NzSubMesh* subMesh); - bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh); + void AddSubMesh(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()); bool CreateSkeletal(unsigned int jointCount); diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index 0891a57ab..86f58e568 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -34,6 +34,7 @@ namespace bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters) { NzOBJParser parser(stream); + if (!parser.Parse()) { NazaraError("OBJ parser failed"); @@ -173,10 +174,8 @@ namespace else subMesh->GenerateNormals(); - if (mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh.get())) - subMesh.release(); - else - NazaraError("Failed to add SubMesh to Mesh"); + mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh.get()); + subMesh.release(); } mesh->SetMaterialCount(parser.GetMaterialCount()); @@ -218,6 +217,23 @@ namespace material->SetSpecularColor(specularColor); material->SetShininess(mtlMat->shininess); + bool hasAlphaMap = false;; + if (parameters.material.loadAlphaMap && !mtlMat->alphaMap.IsEmpty()) + { + std::unique_ptr 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()) { std::unique_ptr diffuseMap(new NzTexture); @@ -246,6 +262,17 @@ namespace 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()); material.release(); } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index 7c984182d..0b4468368 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -260,12 +260,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) mesh->SetMaterial(i, baseDir + md5Mesh.shader); subMesh->SetMaterialIndex(i); - if (!mesh->AddSubMesh(subMesh.get())) - { - NazaraError("Failed to add submesh"); - continue; - } - + mesh->AddSubMesh(subMesh.get()); subMesh.release(); // Animation @@ -360,12 +355,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) subMesh->GenerateNormalsAndTangents(); subMesh->SetMaterialIndex(i); - if (!mesh->AddSubMesh(subMesh.get())) - { - NazaraError("Failed to add submesh"); - continue; - } - + mesh->AddSubMesh(subMesh.get()); subMesh.release(); } } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 83c846c00..01b557f76 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -69,25 +69,25 @@ NzMesh::~NzMesh() Destroy(); } -bool NzMesh::AddSubMesh(NzSubMesh* subMesh) +void NzMesh::AddSubMesh(NzSubMesh* subMesh) { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Mesh not created"); - return false; + return; } if (!subMesh) { NazaraError("Invalid submesh"); - return false; + return; } if (subMesh->GetAnimationType() != m_impl->animationType) { NazaraError("Submesh animation type must match mesh animation type"); - return false; + return; } #endif @@ -95,42 +95,40 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh) m_impl->aabbUpdated = false; // On invalide l'AABB 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 (!m_impl) { NazaraError("Mesh not created"); - return false; + return; } if (identifier.IsEmpty()) { NazaraError("Identifier is empty"); - return false; + return; } auto it = m_impl->subMeshMap.find(identifier); if (it != m_impl->subMeshMap.end()) { NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); - return false; + return; } if (!subMesh) { NazaraError("Invalid submesh"); - return false; + return; } if (m_impl->animationType != subMesh->GetAnimationType()) { NazaraError("Submesh animation type must match mesh animation type"); - return false; + return; } #endif @@ -141,29 +139,27 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); 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 (!m_impl) { NazaraError("Mesh not created"); - return; + return nullptr; } if (m_impl->animationType != nzAnimationType_Static) { NazaraError("Mesh must be static"); - return; + return nullptr; } if (!params.IsValid()) { NazaraError("Parameters must be valid"); - return; + return nullptr; } #endif @@ -283,7 +279,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para if (!subMesh->Create(vertexBuffer.get())) { NazaraError("Failed to create StaticMesh"); - return; + return nullptr; } vertexBuffer.release(); @@ -294,9 +290,9 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para indexBuffer.release(); subMesh->SetAABB(aabb); + AddSubMesh(subMesh.get()); - if (AddSubMesh(subMesh.get())) - subMesh.release(); + return subMesh.release(); } void NzMesh::BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params)