From 6b949afb9b070c35f7ae195097ff41db34dfc024 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 Jan 2017 01:52:00 +0100 Subject: [PATCH] Graphics: Add support of skins to InstancedRenderable + big clean up --- SDK/src/NDK/Lua/LuaBinding_Graphics.cpp | 149 +++++++- include/Nazara/Graphics/Billboard.hpp | 4 +- include/Nazara/Graphics/Billboard.inl | 76 ++-- .../Nazara/Graphics/InstancedRenderable.hpp | 25 +- .../Nazara/Graphics/InstancedRenderable.inl | 183 ++++++++++ include/Nazara/Graphics/Model.hpp | 26 +- include/Nazara/Graphics/Model.inl | 8 + include/Nazara/Graphics/SkeletalModel.hpp | 2 - include/Nazara/Graphics/Sprite.hpp | 6 +- include/Nazara/Graphics/Sprite.inl | 87 +++-- include/Nazara/Graphics/TextSprite.hpp | 3 +- include/Nazara/Graphics/TextSprite.inl | 26 +- include/Nazara/Graphics/TileMap.hpp | 5 +- include/Nazara/Graphics/TileMap.inl | 53 +-- src/Nazara/Graphics/Billboard.cpp | 5 +- src/Nazara/Graphics/Formats/MeshLoader.cpp | 2 - src/Nazara/Graphics/Model.cpp | 332 ++---------------- src/Nazara/Graphics/SkeletalModel.cpp | 13 +- src/Nazara/Graphics/Sprite.cpp | 69 +++- src/Nazara/Graphics/TextSprite.cpp | 5 +- src/Nazara/Graphics/TileMap.cpp | 4 +- 21 files changed, 579 insertions(+), 504 deletions(-) diff --git a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp index b626f9665..43c34dc73 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp @@ -32,6 +32,40 @@ namespace Ndk /*********************************** Nz::InstancedRenderable ***********************************/ instancedRenderable.Reset("InstancedRenderable"); { + instancedRenderable.BindMethod("GetMaterial", [] (Nz::LuaInstance& lua, Nz::InstancedRenderable* instance, std::size_t argumentCount) -> int + { + std::size_t argCount = std::min(argumentCount, 2U); + switch (argCount) + { + case 0: + case 1: + { + int argIndex = 2; + std::size_t matIndex(lua.Check(&argIndex, 0)); + + return lua.Push(instance->GetMaterial(matIndex)); + } + + case 2: + { + int argIndex = 2; + std::size_t skinIndex(lua.Check(&argIndex)); + std::size_t matIndex(lua.Check(&argIndex)); + + return lua.Push(instance->GetMaterial(skinIndex, matIndex)); + } + } + + lua.Error("No matching overload for method GetMaterial"); + return 0; + }); + + instancedRenderable.BindMethod("GetMaterialCount", &Nz::InstancedRenderable::GetMaterialCount); + instancedRenderable.BindMethod("GetSkin", &Nz::InstancedRenderable::GetSkin); + instancedRenderable.BindMethod("GetSkinCount", &Nz::InstancedRenderable::GetSkinCount); + + instancedRenderable.BindMethod("SetSkin", &Nz::InstancedRenderable::SetSkin); + instancedRenderable.BindMethod("SetSkinCount", &Nz::InstancedRenderable::SetSkinCount); } /*********************************** Nz::Material ***********************************/ @@ -269,22 +303,72 @@ namespace Ndk return true; }); - //model.BindMethod("GetMaterial", &Nz::Model::GetMaterial); - model.BindMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); - model.BindMethod("GetSkin", &Nz::Model::GetSkin); - model.BindMethod("GetSkinCount", &Nz::Model::GetSkinCount); model.BindMethod("IsAnimated", &Nz::Model::IsAnimated); model.BindMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); - model.BindMethod("Reset", &Nz::Model::Reset); - //model.BindMethod("SetMaterial", &Nz::Model::SetMaterial); + model.BindMethod("SetMaterial", [] (Nz::LuaInstance& lua, Nz::Model* instance, std::size_t argumentCount) -> int + { + std::size_t argCount = std::min(argumentCount, 3U); + switch (argCount) + { + case 2: + { + int argIndex = 2; + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t matIndex(lua.Check(&argIndex)); + Nz::MaterialRef material(lua.Check(&argIndex)); + + instance->SetMaterial(matIndex, std::move(material)); + return 0; + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + Nz::String subMesh(lua.Check(&argIndex)); + Nz::MaterialRef material(lua.Check(&argIndex)); + + instance->SetMaterial(subMesh, std::move(material)); + return 0; + } + + break; + } + + case 3: + { + int argIndex = 2; + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + std::size_t matIndex(lua.Check(&argIndex)); + Nz::MaterialRef material(lua.Check(&argIndex)); + + instance->SetMaterial(skinIndex, matIndex, std::move(material)); + return 0; + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + Nz::String subMesh(lua.Check(&argIndex)); + Nz::MaterialRef material(lua.Check(&argIndex)); + + instance->SetMaterial(skinIndex, subMesh, std::move(material)); + return 0; + } + + break; + } + } + + lua.Error("No matching overload for method SetMaterial"); + return 0; + }); + //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); - model.BindMethod("SetSkin", &Nz::Model::SetSkin); - model.BindMethod("SetSkinCount", &Nz::Model::SetSkinCount); } /*********************************** Nz::Sprite ***********************************/ @@ -303,7 +387,6 @@ namespace Ndk sprite.BindMethod("GetColor", &Nz::Sprite::GetColor); sprite.BindMethod("GetCornerColor", &Nz::Sprite::GetCornerColor); - sprite.BindMethod("GetMaterial", &Nz::Sprite::GetMaterial); sprite.BindMethod("GetOrigin", &Nz::Sprite::GetOrigin); sprite.BindMethod("GetSize", &Nz::Sprite::GetSize); sprite.BindMethod("GetTextureCoords", &Nz::Sprite::GetTextureCoords); @@ -319,12 +402,28 @@ namespace Ndk sprite.BindMethod("SetMaterial", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; - bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); - if (lua.IsOfType(argIndex, "Material")) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + instance->SetMaterial(*static_cast(lua.ToUserdata(argIndex)), resizeSprite); - else - instance->SetMaterial(lua.Check(&argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + instance->SetMaterial(lua.ToString(argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + if (lua.IsOfType(argIndex, "Material")) + instance->SetMaterial(skinIndex, *static_cast(lua.ToUserdata(argIndex)), resizeSprite); + else + instance->SetMaterial(skinIndex, lua.Check(&argIndex), resizeSprite); + } return 0; }); @@ -332,12 +431,28 @@ namespace Ndk sprite.BindMethod("SetTexture", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; - bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); - if (lua.IsOfType(argIndex, "Texture")) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + instance->SetTexture(*static_cast(lua.ToUserdata(argIndex)), resizeSprite); - else - instance->SetTexture(lua.Check(&argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_String)) + { + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + instance->SetTexture(lua.ToString(argIndex), resizeSprite); + } + else if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + std::size_t skinIndex(lua.Check(&argIndex)); + bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); + + if (lua.IsOfType(argIndex, "Texture")) + instance->SetTexture(skinIndex, *static_cast(lua.ToUserdata(argIndex)), resizeSprite); + else + instance->SetTexture(skinIndex, lua.Check(&argIndex), resizeSprite); + } return 0; }); diff --git a/include/Nazara/Graphics/Billboard.hpp b/include/Nazara/Graphics/Billboard.hpp index 68a64a4b5..8cf340d68 100644 --- a/include/Nazara/Graphics/Billboard.hpp +++ b/include/Nazara/Graphics/Billboard.hpp @@ -32,17 +32,18 @@ namespace Nz void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; inline const Color& GetColor() const; - inline const MaterialRef& GetMaterial() const; inline float GetRotation() const; inline const Vector2f& GetSize() const; inline void SetColor(const Color& color); inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material, bool resizeBillboard = true); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeBillboard = true); inline void SetRotation(float rotation); inline void SetSize(const Vector2f& size); inline void SetSize(float sizeX, float sizeY); inline void SetTexture(TextureRef texture, bool resizeBillboard = true); + inline void SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeBillboard = true); inline Billboard& operator=(const Billboard& billboard); Billboard& operator=(Billboard&&) = delete; @@ -53,7 +54,6 @@ namespace Nz void MakeBoundingVolume() const override; Color m_color; - MaterialRef m_material; Vector2f m_sinCos; Vector2f m_size; float m_rotation; diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 45c2ef918..e539995a2 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include @@ -13,6 +14,8 @@ namespace Nz inline Billboard::Billboard() { + ResetMaterials(1); + SetColor(Color::White); SetDefaultMaterial(); SetRotation(0.f); @@ -27,6 +30,8 @@ namespace Nz inline Billboard::Billboard(MaterialRef material) { + ResetMaterials(1); + SetColor(Color::White); SetMaterial(std::move(material), true); SetRotation(0.f); @@ -41,6 +46,8 @@ namespace Nz inline Billboard::Billboard(Texture* texture) { + ResetMaterials(1); + SetColor(Color::White); SetRotation(0.f); SetSize(64.f, 64.f); @@ -56,7 +63,6 @@ namespace Nz inline Billboard::Billboard(const Billboard& billboard) : InstancedRenderable(billboard), m_color(billboard.m_color), - m_material(billboard.m_material), m_sinCos(billboard.m_sinCos), m_size(billboard.m_size), m_rotation(billboard.m_rotation) @@ -73,16 +79,6 @@ namespace Nz return m_color; } - /*! - * \brief Gets the material of the billboard - * \return Current material - */ - - inline const MaterialRef& Billboard::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the rotation of the billboard * \return Current rotation @@ -132,15 +128,30 @@ namespace Nz * \param material Material for the billboard * \param resizeBillboard Should billboard be resized to the material size (diffuse map) */ - inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) { - m_material = std::move(material); - if (m_material && resizeBillboard) + SetMaterial(GetSkin(), std::move(material), resizeBillboard); + } + + /*! + * \brief Sets the material of the billboard + * + * \param skinIndex Skin index to change + * \param material Material for the billboard + * \param resizeBillboard Should billboard be resized to the material size (diffuse map) + */ + inline void Billboard::SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeBillboard) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); + + if (resizeBillboard) { - Texture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + if (const MaterialRef& material = GetMaterial()) + { + const TextureRef& diffuseMap = material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } } } @@ -188,18 +199,36 @@ namespace Nz * \param texture Texture for the billboard * \param resizeBillboard Should billboard be resized to the texture size */ - inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) { - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = Material::New(*m_material); // Copie + SetTexture(GetSkin(), std::move(texture), resizeBillboard); + } + /*! + * \brief Sets the texture of the billboard for a specific index + * + * This function changes the diffuse map of the material associated with the specified skin index + * + * \param skinIndex Skin index to change + * \param texture Texture for the billboard + * \param resizeBillboard Should billboard be resized to the texture size + */ + inline void Billboard::SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeBillboard) + { if (resizeBillboard && texture && texture->IsValid()) SetSize(Vector2f(Vector2ui(texture->GetSize()))); - m_material->SetDiffuseMap(std::move(texture)); + const MaterialRef& material = GetMaterial(skinIndex); + + if (material->GetReferenceCount() > 1) + { + MaterialRef newMat = Material::New(*material); // Copy + newMat->SetDiffuseMap(std::move(texture)); + + SetMaterial(skinIndex, std::move(newMat)); + } + else + material->SetDiffuseMap(std::move(texture)); } /*! @@ -214,7 +243,6 @@ namespace Nz InstancedRenderable::operator=(billboard); m_color = billboard.m_color; - m_material = billboard.m_material; m_size = billboard.m_size; InvalidateBoundingVolume(); diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 3f117c84b..965b06dbb 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,18 @@ namespace Nz inline void EnsureBoundingVolumeUpdated() const; virtual const BoundingVolumef& GetBoundingVolume() const; + + inline const MaterialRef& GetMaterial(std::size_t matIndex = 0) const; + inline const MaterialRef& GetMaterial(std::size_t skinIndex, std::size_t matIndex) const; + inline std::size_t GetMaterialCount() const; + inline std::size_t GetSkin() const; + inline std::size_t GetSkinCount() const; + virtual void InvalidateData(InstanceData* instanceData, UInt32 flags) const; + + inline void SetSkin(std::size_t skinIndex); + inline void SetSkinCount(std::size_t skinCount); + virtual void UpdateBoundingVolume(InstanceData* instanceData) const; virtual void UpdateData(InstanceData* instanceData) const; @@ -89,14 +101,23 @@ namespace Nz protected: inline void InvalidateBoundingVolume(); inline void InvalidateInstanceData(UInt32 flags); - + virtual void MakeBoundingVolume() const = 0; + inline void ResetMaterials(std::size_t matCount, std::size_t skinCount = 1); + + inline void SetMaterial(std::size_t matIndex, MaterialRef material); + inline void SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material); + mutable BoundingVolumef m_boundingVolume; private: inline void UpdateBoundingVolume() const; - + + std::size_t m_matCount; + std::size_t m_skin; + std::size_t m_skinCount; + std::vector m_materials; mutable bool m_boundingVolumeUpdated; static InstancedRenderableLibrary::LibraryMap s_library; diff --git a/include/Nazara/Graphics/InstancedRenderable.inl b/include/Nazara/Graphics/InstancedRenderable.inl index 5ee49dc6a..62e1c8966 100644 --- a/include/Nazara/Graphics/InstancedRenderable.inl +++ b/include/Nazara/Graphics/InstancedRenderable.inl @@ -2,6 +2,9 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include +#include + namespace Nz { /*! @@ -20,6 +23,10 @@ namespace Nz inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) : RefCounted(), m_boundingVolume(renderable.m_boundingVolume), + m_matCount(renderable.m_matCount), + m_skin(renderable.m_skin), + m_skinCount(renderable.m_skinCount), + m_materials(renderable.m_materials), m_boundingVolumeUpdated(renderable.m_boundingVolumeUpdated) { } @@ -34,6 +41,111 @@ namespace Nz UpdateBoundingVolume(); } + /*! + * \brief Gets one of the material used by the object. + * \return A reference to the material. + * + * This function returns the active material at the specified index, depending on the current active skin. + * + * \param matIndex Material index to query + * + * \see GetSkin, GetMaterialCount, SetSkin + */ + inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t matIndex) const + { + return GetMaterial(m_skin, matIndex); + } + + /*! + * \brief Gets one of the material used by the object, independently from the active skin. + * \return A reference to the material. + * + * This function returns the active material at the specified index and the specified skin index. + * This function is the only way to query a material independently from the active skin. + * + * \param skinIndex Skin index to query + * \param matIndex Material index to query + * + * \see GetSkinCount, GetMaterialCount, SetSkin + */ + inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t skinIndex, std::size_t matIndex) const + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds"); + + return m_materials[m_matCount * skinIndex + matIndex]; + } + + /*! + * \brief Gets the number of material per skin. + * \return The current material count per skin + * + * This function returns how many different materials entries exists per skin + * and is independent from the number of skin. + */ + inline std::size_t InstancedRenderable::GetMaterialCount() const + { + return m_matCount; + } + + /*! + * \brief Gets the current active skin index + * \return Current skin index + * + * \see SetSkin + */ + inline std::size_t InstancedRenderable::GetSkin() const + { + return m_skin; + } + + /*! + * \brief Gets the number of skins this object has + * \return Skin count + * + * \see GetSkin, SetSkinCount + */ + inline std::size_t InstancedRenderable::GetSkinCount() const + { + return m_skinCount; + } + + /*! + * \brief Changes the active skin + * + * Each InstancedRenderable has the possibility to have multiples skins, which are sets of materials. + * Using this function allows you to have an object reference multiple materials, while using only some of thems (depending on the type of the object, see GetMaterialCount). + * + * \param skinIndex Skin index to change to + * + * \see SetSkinCount + */ + inline void InstancedRenderable::SetSkin(std::size_t skinIndex) + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + + m_skin = skinIndex; + + // Force render queue invalidation + InvalidateInstanceData(0); + } + + /*! + * \brief Changes the maximum skin count of the object + * + * This functions allows the object to store up to skinCount skins, which can then be switched to using SetSkin. + * Please note that the possibly new skins will be set to the default material, which should not be changed. + * + * \param skinCount Skin index to change to + * + * \see SetSkin + */ + inline void InstancedRenderable::SetSkinCount(std::size_t skinCount) + { + m_materials.resize(m_matCount * skinCount, Material::GetDefault()); + m_skinCount = skinCount; + } + /*! * \brief Invalidates the bounding volume */ @@ -56,6 +168,71 @@ namespace Nz OnInstancedRenderableInvalidateData(this, flags); } + /*! + * \brief Resets the materials, material count and skin count + * + * This function clears the materials in use by the InstancedRenderable and resets its material count per skin along with its skin count. + * This is the only way of setting the material count per skin and should be called at least by the constructor of the derived class. + * Please note that all materials will be set to the default material, which should not be changed. + * + * This function also resets the current skin to the first one. + * + * \param matCount The new material count per skin value, must be at least 1 + * \param skinCount The new skin count value + * + * \see GetMaterial, GetMaterialCount, GetSkinCount, SetSkinCount + */ + inline void InstancedRenderable::ResetMaterials(std::size_t matCount, std::size_t skinCount) + { + NazaraAssert(skinCount != 0, "Invalid skin count (cannot be zero)"); + + m_materials.clear(); + m_materials.resize(matCount * skinCount, Material::GetDefault()); + + m_matCount = matCount; + m_skinCount = skinCount; + m_skin = 0; + } + + /*! + * \brief Changes the material used at the specified index by another one + * + * This function changes the active material at the specified index, depending on the current active skin, to the one passed as parameter. + * + * \param matIndex Material index + * \param material New material, cannot be null + * + * \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault) + * + * \see SetMaterial + */ + inline void InstancedRenderable::SetMaterial(std::size_t matIndex, MaterialRef material) + { + SetMaterial(m_skin, matIndex, std::move(material)); + } + + /*! + * \brief Changes the material used at the specified index by another one, independently from the active skin. + * + * This function changes the active material at the specified index and for the specified skin index, to the one passed as parameter. + * + * \param skinIndex Skin index + * \param matIndex Material index + * \param material New material, cannot be null + * + * \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault) + * + * \see SetMaterial + */ + inline void InstancedRenderable::SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material) + { + NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds"); + NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds"); + NazaraAssert(material.IsValid(), "Material must be valid"); + + m_materials[m_matCount * skinIndex + matIndex] = std::move(material); + } + /*! * \brief Sets the current instanced renderable with the content of the other one * \return A reference to this @@ -67,6 +244,10 @@ namespace Nz { m_boundingVolume = renderable.m_boundingVolume; m_boundingVolumeUpdated = renderable.m_boundingVolumeUpdated; + m_matCount = renderable.m_matCount; + m_materials = renderable.m_materials; + m_skin = renderable.m_skin; + m_skinCount = renderable.m_skinCount; return *this; } @@ -82,3 +263,5 @@ namespace Nz m_boundingVolumeUpdated = true; } } + +#include diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index b1755c7d8..c43825b77 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -39,7 +39,7 @@ namespace Nz friend ModelLoader; public: - Model(); + inline Model(); Model(const Model& model) = default; Model(Model&& model) = default; virtual ~Model(); @@ -47,13 +47,9 @@ namespace Nz void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; inline void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix, unsigned int renderOrder = 0); - Material* GetMaterial(const String& subMeshName) const; - Material* GetMaterial(unsigned int matIndex) const; - Material* GetMaterial(unsigned int skinIndex, const String& subMeshName) const; - Material* GetMaterial(unsigned int skinIndex, unsigned int matIndex) const; - unsigned int GetMaterialCount() const; - unsigned int GetSkin() const; - unsigned int GetSkinCount() const; + using InstancedRenderable::GetMaterial; + const MaterialRef& GetMaterial(const String& subMeshName) const; + const MaterialRef& GetMaterial(std::size_t skinIndex, const String& subMeshName) const; Mesh* GetMesh() const; virtual bool IsAnimated() const; @@ -62,15 +58,11 @@ namespace Nz bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); bool LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters()); - void Reset(); + using InstancedRenderable::SetMaterial; + bool SetMaterial(const String& subMeshName, MaterialRef material); + bool SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material); - bool SetMaterial(const String& subMeshName, Material* material); - void SetMaterial(unsigned int matIndex, Material* material); - bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material); - void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material); virtual void SetMesh(Mesh* mesh); - void SetSkin(unsigned int skin); - void SetSkinCount(unsigned int skinCount); Model& operator=(const Model& node) = default; Model& operator=(Model&& node) = default; @@ -80,11 +72,7 @@ namespace Nz protected: void MakeBoundingVolume() const override; - std::vector m_materials; MeshRef m_mesh; - unsigned int m_matCount; - unsigned int m_skin; - unsigned int m_skinCount; static ModelLoader::LoaderList s_loaders; }; diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index 8e659e869..88fbbac63 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -7,6 +7,14 @@ namespace Nz { + /*! + * \brief Constructs a Model object by default + */ + Model::Model() + { + ResetMaterials(0); + } + /*! * \brief Adds this model to a render queue, using user-specified transform matrix and render order * diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 99791168a..5457a3218 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -61,8 +61,6 @@ namespace Nz bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters()); bool LoadFromStream(Stream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); - void Reset(); - bool SetAnimation(Animation* animation); void SetMesh(Mesh* mesh) override; bool SetSequence(const String& sequenceName); diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 2c42f4ce1..d57cdc444 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -38,7 +38,6 @@ namespace Nz inline const Color& GetColor() const; inline const Color& GetCornerColor(RectCorner corner) const; - inline const MaterialRef& GetMaterial() const; inline const Vector3f& GetOrigin() const; inline const Vector2f& GetSize() const; inline const Rectf& GetTextureCoords() const; @@ -48,11 +47,15 @@ namespace Nz inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material, bool resizeSprite = true); bool SetMaterial(String materialName, bool resizeSprite = true); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeSprite = true); + bool SetMaterial(std::size_t skinIndex, String materialName, bool resizeSprite = true); inline void SetOrigin(const Vector3f& origin); inline void SetSize(const Vector2f& size); inline void SetSize(float sizeX, float sizeY); bool SetTexture(String textureName, bool resizeSprite = true); inline void SetTexture(TextureRef texture, bool resizeSprite = true); + bool SetTexture(std::size_t skinIndex, String textureName, bool resizeSprite = true); + inline void SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeSprite = true); inline void SetTextureCoords(const Rectf& coords); inline void SetTextureRect(const Rectui& rect); @@ -71,7 +74,6 @@ namespace Nz std::array m_cornerColor; Color m_color; - MaterialRef m_material; Rectf m_textureCoords; Vector2f m_size; Vector3f m_origin; diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index deec75959..a52820c94 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -2,9 +2,10 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include -#include +#include namespace Nz { @@ -56,7 +57,6 @@ namespace Nz inline Sprite::Sprite(const Sprite& sprite) : InstancedRenderable(sprite), m_color(sprite.m_color), - m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), m_origin(sprite.m_origin) @@ -94,15 +94,6 @@ namespace Nz return m_cornerColor[corner]; } - /*! - * \brief Gets the material of the sprite - * \return Current material - */ - inline const MaterialRef& Sprite::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the origin of the sprite * @@ -187,16 +178,32 @@ namespace Nz * \brief Changes the material of the sprite * * \param material Material for the sprite - * \param resizeSprite Should the sprite be resized to the texture size? + * \param resizeSprite Should billboard be resized to the material size (diffuse map) */ inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite) { - m_material = std::move(material); - if (m_material && resizeSprite) + SetMaterial(GetSkin(), std::move(material), resizeSprite); + } + + /*! + * \brief Sets the material of the sprite + * + * \param skinIndex Skin index to change + * \param material Material for the sprite + * \param resizeBillboard Should billboard be resized to the material size (diffuse map) + */ + inline void Sprite::SetMaterial(std::size_t skinIndex, MaterialRef material, bool resizeSprite) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); + + if (resizeSprite) { - Texture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + if (const MaterialRef& material = GetMaterial()) + { + const TextureRef& diffuseMap = material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } } } @@ -246,9 +253,9 @@ namespace Nz } /*! - * \brief Sets the texture of the sprite + * \brief Sets the texture of the sprite for the current skin * - * Assign a texture to the sprite material + * This function changes the diffuse map of the material associated with the current skin * * \param texture Texture for the sprite * \param resizeSprite Should the sprite be resized to the texture size? @@ -257,15 +264,36 @@ namespace Nz */ inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite) { - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = Material::New(*m_material); // Copy the material + SetTexture(GetSkin(), std::move(texture), resizeSprite); + } + /*! + * \brief Sets the texture of the sprite for a specific skin + * + * This function changes the diffuse map of the material associated with the specified skin + * + * \param skinIndex Skin index to change + * \param texture Texture for the sprite + * \param resizeSprite Should the sprite be resized to the texture size? + * + * \remark The sprite material gets copied to prevent accidentally changing other drawable materials + */ + inline void Sprite::SetTexture(std::size_t skinIndex, TextureRef texture, bool resizeSprite) + { if (resizeSprite && texture && texture->IsValid()) SetSize(Vector2f(Vector2ui(texture->GetSize()))); - m_material->SetDiffuseMap(std::move(texture)); + const MaterialRef& material = GetMaterial(skinIndex); + + if (material->GetReferenceCount() > 1) + { + MaterialRef newMat = Material::New(*material); // Copy + newMat->SetDiffuseMap(std::move(texture)); + + SetMaterial(skinIndex, std::move(newMat)); + } + else + material->SetDiffuseMap(std::move(texture)); } /*! @@ -277,6 +305,7 @@ namespace Nz inline void Sprite::SetTextureCoords(const Rectf& coords) { m_textureCoords = coords; + InvalidateVertices(); } @@ -291,10 +320,10 @@ namespace Nz inline void Sprite::SetTextureRect(const Rectui& rect) { - NazaraAssert(m_material, "Sprite has no material"); - NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); + const MaterialRef& material = GetMaterial(); + NazaraAssert(material->HasDiffuseMap(), "Sprite material has no diffuse map"); - Texture* diffuseMap = m_material->GetDiffuseMap(); + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -314,7 +343,6 @@ namespace Nz InstancedRenderable::operator=(sprite); m_color = sprite.m_color; - m_material = sprite.m_material; m_origin = sprite.m_origin; m_textureCoords = sprite.m_textureCoords; m_size = sprite.m_size; @@ -352,5 +380,4 @@ namespace Nz } } -#include -#include "Sprite.hpp" +#include diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 3e05c2795..bc296c559 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -37,12 +37,12 @@ namespace Nz inline void Clear(); inline const Color& GetColor() const; - inline const MaterialRef& GetMaterial() const; inline float GetScale() const; inline void SetColor(const Color& color); inline void SetDefaultMaterial(); inline void SetMaterial(MaterialRef material); + inline void SetMaterial(std::size_t skinIndex, MaterialRef material); inline void SetScale(float scale); void Update(const AbstractTextDrawer& drawer); @@ -76,7 +76,6 @@ namespace Nz mutable std::unordered_map m_renderInfos; mutable std::vector m_localVertices; Color m_color; - MaterialRef m_material; Recti m_localBounds; float m_scale; diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index d5db90805..b22ebd7a6 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -2,8 +2,9 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include -#include +#include namespace Nz { @@ -15,6 +16,8 @@ namespace Nz m_color(Color::White), m_scale(1.f) { + ResetMaterials(1U); + SetDefaultMaterial(); } @@ -41,7 +44,6 @@ namespace Nz m_renderInfos(sprite.m_renderInfos), m_localVertices(sprite.m_localVertices), m_color(sprite.m_color), - m_material(sprite.m_material), m_localBounds(sprite.m_localBounds), m_scale(sprite.m_scale) { @@ -78,16 +80,6 @@ namespace Nz return m_color; } - /*! - * \brief Gets the material of the text sprite - * \return Current material - */ - - inline const MaterialRef& TextSprite::GetMaterial() const - { - return m_material; - } - /*! * \brief Gets the current scale of the text sprite * \return Current scale @@ -136,7 +128,12 @@ namespace Nz inline void TextSprite::SetMaterial(MaterialRef material) { - m_material = std::move(material); + InstancedRenderable::SetMaterial(0, std::move(material)); + } + + inline void TextSprite::SetMaterial(std::size_t skinIndex, MaterialRef material) + { + InstancedRenderable::SetMaterial(skinIndex, 0, std::move(material)); } /*! @@ -167,7 +164,6 @@ namespace Nz m_atlases.clear(); m_color = text.m_color; - m_material = text.m_material; m_renderInfos = text.m_renderInfos; m_localBounds = text.m_localBounds; m_localVertices = text.m_localVertices; @@ -216,4 +212,4 @@ namespace Nz } } -#include +#include diff --git a/include/Nazara/Graphics/TileMap.hpp b/include/Nazara/Graphics/TileMap.hpp index 02371c33c..01ad3eecc 100644 --- a/include/Nazara/Graphics/TileMap.hpp +++ b/include/Nazara/Graphics/TileMap.hpp @@ -50,8 +50,6 @@ namespace Nz inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); - inline const MaterialRef& GetMaterial(std::size_t index) const; - inline std::size_t GetMaterialCount() const; inline const Vector2ui& GetMapSize() const; inline Vector2f GetSize() const; inline const Tile& GetTile(const Vector2ui& tilePos) const; @@ -59,7 +57,7 @@ namespace Nz inline bool IsIsometricModeEnabled() const; - inline void SetMaterial(std::size_t index, MaterialRef material); + using InstancedRenderable::SetMaterial; inline TileMap& operator=(const TileMap& TileMap); TileMap& operator=(TileMap&& TileMap) = delete; @@ -83,7 +81,6 @@ namespace Nz struct Layer { - MaterialRef material; std::set tiles; }; diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index f8faa7b54..2631b56fa 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -32,8 +32,7 @@ namespace Nz NazaraAssert(m_tileSize.x > 0 && m_tileSize.y > 0, "Invalid tile size"); NazaraAssert(m_layers.size() != 0U, "Invalid material count"); - for (Layer& layer : m_layers) - layer.material = Material::GetDefault(); + ResetMaterials(materialCount); InvalidateBoundingVolume(); } @@ -183,9 +182,11 @@ namespace Nz inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color, std::size_t materialIndex) { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + const MaterialRef& material = GetMaterial(materialIndex); + NazaraAssert(material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -246,7 +247,7 @@ namespace Nz { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + Texture* diffuseMap = GetMaterial(materialIndex)->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -321,9 +322,11 @@ namespace Nz inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color, std::size_t materialIndex) { NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); - NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); - Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + const MaterialRef& material = GetMaterial(materialIndex); + NazaraAssert(material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = material->GetDiffuseMap(); float invWidth = 1.f / diffuseMap->GetWidth(); float invHeight = 1.f / diffuseMap->GetHeight(); @@ -331,29 +334,6 @@ namespace Nz EnableTiles(tilesPos, tileCount, unnormalizedCoords, color, materialIndex); } - /*! - * \brief Gets the material at position index used by the TileMap - * - * \param index Index of the material to query - * - * \return Material at index - */ - inline const MaterialRef& TileMap::GetMaterial(std::size_t index) const - { - NazaraAssert(index < m_layers.size(), "Material out of bounds"); - - return m_layers[index].material; - } - - /*! - * \brief Gets the maximum material count this TileMap can use - * \return Material count - */ - inline std::size_t TileMap::GetMaterialCount() const - { - return m_layers.size(); - } - /*! * \brief Gets the tilemap size (i.e. number of tiles in each dimension) * \return Number of tiles in each dimension @@ -415,19 +395,6 @@ namespace Nz return m_isometricModeEnabled; } - /*! - * \brief Sets a material of the TileMap - * - * \param index Index of the material to change - * \param material Material for the TileMap - */ - inline void TileMap::SetMaterial(std::size_t index, MaterialRef material) - { - NazaraAssert(index < m_layers.size(), "Material out of bounds"); - - m_layers[index].material = std::move(material); - } - /*! * \brief Sets the current TileMap with the content of the other one * \return A reference to this diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 4aed923ae..de2635029 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -27,11 +27,8 @@ namespace Nz void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - Nz::Vector3f position = instanceData.transformMatrix.GetTranslation(); - renderQueue->AddBillboards(instanceData.renderOrder, m_material, 1, &position, &m_size, &m_sinCos, &m_color); + renderQueue->AddBillboards(instanceData.renderOrder, GetMaterial(), 1, &position, &m_size, &m_sinCos, &m_color); } /* diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index 38f836e90..3481e9103 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -77,7 +77,6 @@ namespace Nz return false; } - model->Reset(); model->SetMesh(mesh); if (parameters.loadMaterials) @@ -114,7 +113,6 @@ namespace Nz return false; } - model->Reset(); model->SetMesh(mesh); if (parameters.loadMaterials) diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index d382c77d9..e4f511850 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -41,26 +41,9 @@ namespace Nz } /*! - * \brief Constructs a Model object by default + * \brief Destructs the object and cleans resources */ - - Model::Model() : - m_matCount(0), - m_skin(0), - m_skinCount(1) - { - } - - /*! - * \brief Destructs the object and calls Reset - * - * \see Reset - */ - - Model::~Model() - { - Reset(); - } + Model::~Model() = default; /*! * \brief Adds this model to the render queue @@ -75,7 +58,7 @@ namespace Nz for (unsigned int i = 0; i < submeshCount; ++i) { const StaticMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - Material* material = m_materials[mesh->GetMaterialIndex()]; + const MaterialRef& material = GetMaterial(mesh->GetMaterialIndex()); MeshData meshData; meshData.indexBuffer = mesh->GetIndexBuffer(); @@ -96,54 +79,20 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material is invalid */ - - Material* Model::GetMaterial(const String& subMeshName) const + const MaterialRef& Model::GetMaterial(const String& subMeshName) const { - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - return nullptr; - } - #endif + NazaraAssert(m_mesh, "Model has no mesh"); SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; + + static MaterialRef Invalid; + return Invalid; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - - return m_materials[m_skin * m_matCount + matIndex]; - } - - /*! - * \brief Gets the material by index - * \return Pointer to the current material - * - * \param matIndex Index of the material - * - * \remark Produces a NazaraError if index is invalid - */ - - Material* Model::GetMaterial(unsigned int matIndex) const - { - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - #endif - - return m_materials[m_skin * m_matCount + matIndex]; + return GetMaterial(subMesh->GetMaterialIndex()); } /*! @@ -157,72 +106,20 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material index is invalid */ - - Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const + const MaterialRef& Model::GetMaterial(std::size_t skinIndex, const String& subMeshName) const { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_mesh, "Model has no mesh"); SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; + + static MaterialRef Invalid; + return Invalid; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - - return m_materials[skinIndex * m_matCount + matIndex]; - } - - /*! - * \brief Gets the material by index with skin - * \return Pointer to the current material - * - * \param skinIndex Index of the skin - * \param matIndex Index of the material - * - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid - */ - - Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const - { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); - return nullptr; - } - - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return nullptr; - } - #endif - - return m_materials[skinIndex * m_matCount + matIndex]; - } - - /*! - * \brief Gets the number of materials - * \return Current number of materials - */ - - unsigned int Model::GetMaterialCount() const - { - return m_matCount; + return GetMaterial(subMesh->GetMaterialIndex()); } /*! @@ -235,26 +132,6 @@ namespace Nz return m_mesh; } - /*! - * \brief Gets the skin - * \return Current skin - */ - - unsigned int Model::GetSkin() const - { - return m_skin; - } - - /*! - * \brief Gets the number of skins - * \return Current number of skins - */ - - unsigned int Model::GetSkinCount() const - { - return m_skinCount; - } - /*! * \brief Checks whether the model is animated * \return false @@ -305,22 +182,6 @@ namespace Nz return ModelLoader::LoadFromStream(this, stream, params); } - /*! - * \brief Resets the model, cleans everything - */ - - void Model::Reset() - { - m_matCount = 0; - m_skinCount = 0; - - if (m_mesh) - { - m_mesh.Reset(); - m_materials.clear(); - } - } - /*! * \brief Sets the material of the named submesh * \return true If successful @@ -332,7 +193,7 @@ namespace Nz * \remark Produces a NazaraError if material index is invalid */ - bool Model::SetMaterial(const String& subMeshName, Material* material) + bool Model::SetMaterial(const String& subMeshName, MaterialRef material) { SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) @@ -341,51 +202,10 @@ namespace Nz return false; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); - return false; - } - - unsigned int index = m_skin * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - + SetMaterial(subMesh->GetMaterialIndex(), std::move(material)); return true; } - /*! - * \brief Sets the material by index - * \return true If successful - * - * \param matIndex Index of the material - * \param material Pointer to the material - * - * \remark Produces a NazaraError with if NAZARA_GRAPHICS_SAFE defined index is invalid - */ - - void Model::SetMaterial(unsigned int matIndex, Material* material) - { - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return; - } - #endif - - unsigned int index = m_skin * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - } - /*! * \brief Sets the material by index of the named submesh * \return true If successful @@ -398,17 +218,8 @@ namespace Nz * \remark Produces a NazaraError if there is no subMesh with that name * \remark Produces a NazaraError if material index is invalid */ - - bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material) + bool Model::SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material) { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); - return false; - } - #endif - SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { @@ -416,59 +227,10 @@ namespace Nz return false; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return false; - } - - unsigned int index = skinIndex * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - + SetMaterial(skinIndex, subMesh->GetMaterialIndex(), std::move(material)); return true; } - /*! - * \brief Sets the material by index with skin - * \return true If successful - * - * \param skinIndex Index of the skin - * \param matIndex Index of the material - * \param material Pointer to the material - * - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid - * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid - */ - - void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material) - { - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); - return; - } - - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); - return; - } - #endif - - unsigned int index = skinIndex * m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = Material::GetDefault(); - } - /*! * \brief Sets the mesh * @@ -490,65 +252,13 @@ namespace Nz m_mesh = mesh; if (m_mesh) - { - m_matCount = mesh->GetMaterialCount(); - m_materials.clear(); - m_materials.resize(m_matCount, Material::GetDefault()); - m_skinCount = 1; - } + ResetMaterials(mesh->GetMaterialCount()); else - { - m_matCount = 0; - m_materials.clear(); - m_skinCount = 0; - } + ResetMaterials(0); InvalidateBoundingVolume(); } - /*! - * \brief Sets the skin - * - * \param skin Skin to use - * - * \remark Produces a NazaraError if skin is invalid - */ - - void Model::SetSkin(unsigned int skin) - { - #if NAZARA_GRAPHICS_SAFE - if (skin >= m_skinCount) - { - NazaraError("Skin index out of range (" + String::Number(skin) + " >= " + String::Number(m_skinCount) + ')'); - return; - } - #endif - - m_skin = skin; - } - - /*! - * \brief Sets the number of skins - * - * \param skinCount Number of skins - * - * \remark Produces a NazaraError if skinCount equals zero - */ - - void Model::SetSkinCount(unsigned int skinCount) - { - #if NAZARA_GRAPHICS_SAFE - if (skinCount == 0) - { - NazaraError("Skin count must be over zero"); - return; - } - #endif - - m_materials.resize(m_matCount*skinCount, Material::GetDefault()); - m_skinCount = skinCount; - } - /* * \brief Makes the bounding volume of this billboard */ diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b91ac0076..87e086fac 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -62,7 +62,7 @@ namespace Nz for (unsigned int i = 0; i < submeshCount; ++i) { const SkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - const Material* material = m_materials[mesh->GetMaterialIndex()]; + const Material* material = GetMaterial(mesh->GetMaterialIndex()); MeshData meshData; meshData.indexBuffer = mesh->GetIndexBuffer(); @@ -261,17 +261,6 @@ namespace Nz return SkeletalModelLoader::LoadFromStream(this, stream, params); } - /*! - * \brief Resets the model - */ - - void SkeletalModel::Reset() - { - Model::Reset(); - - m_skeleton.Destroy(); - } - /*! * \brief Sets the animation for the model * \return true If successful diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index d23fe4122..f866bdb8c 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -26,11 +26,8 @@ namespace Nz void Sprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(instanceData.renderOrder, m_material, vertices, 1); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(), vertices, 1); } /*! @@ -73,7 +70,37 @@ namespace Nz } /*! - * \brief Sets the texture of the sprite from a name + * \brief Sets the material of the sprite from a name for a specific skin + * + * Tries to get a material from the MaterialLibrary and then the MaterialManager (which will treat the name as a path) + * Fails if the texture name is not a part of the MaterialLibrary nor the MaterialManager (which fails if it couldn't load the texture from its filepath) + * + * \param skinIndex Skin index to change + * \param materialName Named texture for the material + * \param resizeSprite Should the sprite be resized to the material diffuse map size? + * + * \return True if the material was found or loaded from its name/path, false if it couldn't + */ + bool Sprite::SetMaterial(std::size_t skinIndex, String materialName, bool resizeSprite) + { + MaterialRef material = MaterialLibrary::Query(materialName); + if (!material) + { + material = MaterialManager::Get(materialName); + if (!material) + { + NazaraError("Failed to get material \"" + materialName + "\""); + return false; + } + } + + SetMaterial(skinIndex, std::move(material), resizeSprite); + return true; + } + + /*! + * \brief Sets the texture of the sprite from a name for the current skin + * \return True if the texture was found or loaded from its name/path, false if it couldn't * * Tries to get a texture from the TextureLibrary and then the TextureManager (which will treat the name as a path) * Fails if the texture name is not a part of the TextureLibrary nor the TextureManager (which fails if it couldn't load the texture from its filepath) @@ -81,8 +108,6 @@ namespace Nz * \param textureName Named texture for the sprite * \param resizeSprite Should the sprite be resized to the texture size? * - * \return True if the texture was found or loaded from its name/path, false if it couldn't - * * \remark The sprite material gets copied to prevent accidentally changing other drawable materials */ bool Sprite::SetTexture(String textureName, bool resizeSprite) @@ -102,6 +127,36 @@ namespace Nz return true; } + /*! + * \brief Sets the texture of the sprite from a name for a specific skin + * \return True if the texture was found or loaded from its name/path, false if it couldn't + * + * Tries to get a texture from the TextureLibrary and then the TextureManager (which will treat the name as a path) + * Fails if the texture name is not a part of the TextureLibrary nor the TextureManager (which fails if it couldn't load the texture from its filepath) + * + * \param skinIndex Named texture for the sprite + * \param textureName Named texture for the sprite + * \param resizeSprite Should the sprite be resized to the texture size? + * + * \remark The sprite material gets copied to prevent accidentally changing other drawable materials + */ + bool Sprite::SetTexture(std::size_t skinIndex, String textureName, bool resizeSprite) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + { + NazaraError("Failed to get texture \"" + textureName + "\""); + return false; + } + } + + SetTexture(skinIndex, std::move(texture), resizeSprite); + return true; + } + /*! * \brief Updates the data of the sprite * diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 5b3eb2cf6..6409017c3 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -28,9 +28,6 @@ namespace Nz void TextSprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - if (!m_material) - return; - for (auto& pair : m_renderInfos) { Texture* overlay = pair.first; @@ -39,7 +36,7 @@ namespace Nz if (indices.count > 0) { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first * 4], indices.count, overlay); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(), &vertices[indices.first * 4], indices.count, overlay); } } } diff --git a/src/Nazara/Graphics/TileMap.cpp b/src/Nazara/Graphics/TileMap.cpp index ab035a7e4..b977fe9a5 100644 --- a/src/Nazara/Graphics/TileMap.cpp +++ b/src/Nazara/Graphics/TileMap.cpp @@ -29,11 +29,11 @@ namespace Nz { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + std::size_t matCount = 0; std::size_t spriteCount = 0; for (const Layer& layer : m_layers) { - if (layer.material) - renderQueue->AddSprites(instanceData.renderOrder, layer.material, &vertices[spriteCount], layer.tiles.size()); + renderQueue->AddSprites(instanceData.renderOrder, GetMaterial(matCount++), &vertices[spriteCount], layer.tiles.size()); spriteCount += layer.tiles.size(); }