diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 2a0157102..202095be4 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -33,10 +33,15 @@ namespace Ndk inline const std::vector& GetEntities() const; inline SystemIndex GetIndex() const; + inline float GetUpdateRate() const; inline World& GetWorld() const; inline bool HasEntity(const Entity* entity) const; + inline void SetUpdateRate(float updatePerSecond); + + inline void Update(float elapsedTime); + BaseSystem& operator=(const BaseSystem&) = delete; BaseSystem& operator=(BaseSystem&&) noexcept = default; @@ -55,6 +60,8 @@ namespace Ndk template void RequiresAny(); inline void RequiresAnyComponent(ComponentIndex index); + virtual void OnUpdate(float elapsedTime) = 0; + private: inline void AddEntity(Entity* entity); @@ -79,6 +86,8 @@ namespace Ndk NzBitset<> m_requiredComponents; SystemIndex m_systemIndex; World* m_world; + float m_updateCounter; + float m_updateRate; static SystemIndex s_nextIndex; }; diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 2d43bc15c..ceacd1e78 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -10,12 +10,15 @@ namespace Ndk inline BaseSystem::BaseSystem(SystemIndex systemId) : m_systemIndex(systemId) { + SetUpdateRate(30); } inline BaseSystem::BaseSystem(const BaseSystem& system) : m_excludedComponents(system.m_excludedComponents), m_requiredComponents(system.m_requiredComponents), - m_systemIndex(system.m_systemIndex) + m_systemIndex(system.m_systemIndex), + m_updateCounter(0.f), + m_updateRate(system.m_updateRate) { } @@ -29,6 +32,11 @@ namespace Ndk return m_systemIndex; } + inline float BaseSystem::GetUpdateRate() const + { + return 1.f / m_updateRate; + } + inline World& BaseSystem::GetWorld() const { return *m_world; @@ -42,6 +50,22 @@ namespace Ndk return m_entityBits.UnboundedTest(entity->GetId()); } + inline void BaseSystem::SetUpdateRate(float updatePerSecond) + { + m_updateCounter = 0.f; + m_updateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit + } + + inline void BaseSystem::Update(float elapsedTime) + { + m_updateCounter -= elapsedTime; + if (m_updateCounter < 0.f) + { + m_updateCounter += m_updateRate; + OnUpdate(elapsedTime); + } + } + template void BaseSystem::Excludes() { diff --git a/SDK/include/NDK/Systems/ListenerSystem.hpp b/SDK/include/NDK/Systems/ListenerSystem.hpp index a3de7b149..6f40fcdf9 100644 --- a/SDK/include/NDK/Systems/ListenerSystem.hpp +++ b/SDK/include/NDK/Systems/ListenerSystem.hpp @@ -17,9 +17,10 @@ namespace Ndk ListenerSystem(); ~ListenerSystem() = default; - void Update(float elapsedTime); - static SystemIndex systemIndex; + + private: + void OnUpdate(float elapsedTime) override; }; } diff --git a/SDK/include/NDK/Systems/PhysicsSystem.hpp b/SDK/include/NDK/Systems/PhysicsSystem.hpp index 227ee1f9d..95d4bfe13 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem.hpp @@ -23,12 +23,11 @@ namespace Ndk NzPhysWorld& GetWorld(); const NzPhysWorld& GetWorld() const; - void Update(float elapsedTime); - static SystemIndex systemIndex; private: void OnEntityValidation(Entity* entity, bool justAdded) override; + void OnUpdate(float elapsedTime) override; EntityList m_dynamicObjects; EntityList m_staticObjects; diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 522f1c775..6952abc3f 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -24,13 +24,12 @@ namespace Ndk inline RenderSystem(const RenderSystem& renderSystem); ~RenderSystem() = default; - void Update(float elapsedTime); - static SystemIndex systemIndex; private: void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; + void OnUpdate(float elapsedTime) override; EntityList m_cameras; EntityList m_drawables; diff --git a/SDK/include/NDK/Systems/VelocitySystem.hpp b/SDK/include/NDK/Systems/VelocitySystem.hpp index b297d1959..71edcbe7e 100644 --- a/SDK/include/NDK/Systems/VelocitySystem.hpp +++ b/SDK/include/NDK/Systems/VelocitySystem.hpp @@ -17,9 +17,10 @@ namespace Ndk VelocitySystem(); ~VelocitySystem() = default; - void Update(float elapsedTime); - static SystemIndex systemIndex; + + private: + void OnUpdate(float elapsedTime) override; }; } diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 55c06d0ea..794f5fb2a 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -58,6 +58,7 @@ namespace Ndk template void RemoveSystem(); void Update(); + inline void Update(float elapsedTime); private: inline void Invalidate(); diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index f15cbed47..3040e3d6c 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -130,6 +130,15 @@ namespace Ndk RemoveSystem(index); } + inline void World::Update(float elapsedTime) + { + Update(); //< Update entities + + // And then update systems + for (auto& systemPtr : m_systems) + systemPtr->Update(elapsedTime); + } + inline void World::Invalidate() { m_dirtyEntities.Resize(m_entities.size(), false); diff --git a/SDK/src/NDK/Systems/ListenerSystem.cpp b/SDK/src/NDK/Systems/ListenerSystem.cpp index d7cede524..a943b55e5 100644 --- a/SDK/src/NDK/Systems/ListenerSystem.cpp +++ b/SDK/src/NDK/Systems/ListenerSystem.cpp @@ -15,7 +15,7 @@ namespace Ndk Requires(); } - void ListenerSystem::Update(float elapsedTime) + void ListenerSystem::OnUpdate(float elapsedTime) { NazaraUnused(elapsedTime); diff --git a/SDK/src/NDK/Systems/PhysicsSystem.cpp b/SDK/src/NDK/Systems/PhysicsSystem.cpp index a54c776a2..150aaaac7 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem.cpp @@ -22,7 +22,21 @@ namespace Ndk { } - void PhysicsSystem::Update(float elapsedTime) + void PhysicsSystem::OnEntityValidation(Entity* entity, bool justAdded) + { + // Si l'entité ne vient pas d'être ajoutée au système, il est possible qu'elle fasse partie du mauvais tableau + if (!justAdded) + { + // On prend le tableau inverse de celui dont l'entité devrait faire partie + auto& entities = (entity->HasComponent()) ? m_staticObjects : m_dynamicObjects; + entities.Remove(entity); + } + + auto& entities = (entity->HasComponent()) ? m_dynamicObjects : m_staticObjects; + entities.Insert(entity); + } + + void PhysicsSystem::OnUpdate(float elapsedTime) { m_world.Step(elapsedTime); @@ -75,19 +89,5 @@ namespace Ndk } } - void PhysicsSystem::OnEntityValidation(Entity* entity, bool justAdded) - { - // Si l'entité ne vient pas d'être ajoutée au système, il est possible qu'elle fasse partie du mauvais tableau - if (!justAdded) - { - // On prend le tableau inverse de celui dont l'entité devrait faire partie - auto& entities = (entity->HasComponent()) ? m_staticObjects : m_dynamicObjects; - entities.Remove(entity); - } - - auto& entities = (entity->HasComponent()) ? m_dynamicObjects : m_staticObjects; - entities.Insert(entity); - } - SystemIndex PhysicsSystem::systemIndex; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 1f781e951..41efa7462 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -15,7 +15,38 @@ namespace Ndk { } - void RenderSystem::Update(float elapsedTime) + void RenderSystem::OnEntityRemoved(Entity* entity) + { + m_cameras.Remove(entity); + m_drawables.Remove(entity); + m_lights.Remove(entity); + } + + void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) + { + if (entity->HasComponent() && entity->HasComponent()) + { + m_cameras.Insert(entity); + std::sort(m_cameras.begin(), m_cameras.end(), [](const EntityHandle& handle1, const EntityHandle& handle2) + { + return handle1->GetComponent().GetLayer() < handle2->GetComponent().GetLayer(); + }); + } + else + m_cameras.Remove(entity); + + if (entity->HasComponent() && entity->HasComponent()) + m_drawables.Insert(entity); + else + m_drawables.Remove(entity); + + if (entity->HasComponent() && entity->HasComponent()) + m_lights.Insert(entity); + else + m_lights.Remove(entity); + } + + void RenderSystem::OnUpdate(float elapsedTime) { for (const Ndk::EntityHandle& camera : m_cameras) { @@ -52,36 +83,5 @@ namespace Ndk } } - void RenderSystem::OnEntityRemoved(Entity* entity) - { - m_cameras.Remove(entity); - m_drawables.Remove(entity); - m_lights.Remove(entity); - } - - void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) - { - if (entity->HasComponent() && entity->HasComponent()) - { - m_cameras.Insert(entity); - std::sort(m_cameras.begin(), m_cameras.end(), [](const EntityHandle& handle1, const EntityHandle& handle2) - { - return handle1->GetComponent().GetLayer() < handle2->GetComponent().GetLayer(); - }); - } - else - m_cameras.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_drawables.Insert(entity); - else - m_drawables.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_lights.Insert(entity); - else - m_lights.Remove(entity); - } - SystemIndex RenderSystem::systemIndex; } diff --git a/SDK/src/NDK/Systems/VelocitySystem.cpp b/SDK/src/NDK/Systems/VelocitySystem.cpp index a3968a053..882b45728 100644 --- a/SDK/src/NDK/Systems/VelocitySystem.cpp +++ b/SDK/src/NDK/Systems/VelocitySystem.cpp @@ -15,7 +15,7 @@ namespace Ndk Excludes(); } - void VelocitySystem::Update(float elapsedTime) + void VelocitySystem::OnUpdate(float elapsedTime) { for (const Ndk::EntityHandle& entity : GetEntities()) { diff --git a/build/scripts/common.lua b/build/scripts/common.lua index a321c1369..311137d3d 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -5,9 +5,7 @@ function NazaraBuild:Execute() return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien end - if (self.Actions[_ACTION] ~= nil) then - self.Actions[_ACTION].Function() - else + if (self.Actions[_ACTION] == nil) then if (#self.OrderedExtLibs > 0) then solution("NazaraExtlibs") platforms({"x32", "x64"}) @@ -325,66 +323,66 @@ function NazaraBuild:Execute() configuration({}) end - end - for k, exampleTable in ipairs(self.OrderedExamples) do - project("Demo" .. exampleTable.Name) + for k, exampleTable in ipairs(self.OrderedExamples) do + project("Demo" .. exampleTable.Name) - location(_ACTION .. "/examples") + location(_ACTION .. "/examples") - if (exampleTable.Console) then - kind("ConsoleApp") - else - kind("Window") + if (exampleTable.Console) then + kind("ConsoleApp") + else + kind("Window") + end + + debugdir("../examples/bin") + includedirs({ + "../include", + "../extlibs/include" + }) + libdirs("../lib") + targetdir("../examples/bin") + + files(exampleTable.Files) + excludes(exampleTable.FilesExclusion) + + defines(exampleTable.Defines) + flags(exampleTable.Flags) + includedirs(exampleTable.Includes) + links(exampleTable.Libraries) + + configuration("x32") + libdirs("../extlibs/lib/common/x86") + + configuration("x64") + defines("NAZARA_PLATFORM_x64") + libdirs("../extlibs/lib/common/x64") + + configuration({"codeblocks or codelite or gmake", "x32"}) + libdirs("../lib/mingw/x86") + + configuration({"codeblocks or codelite or gmake", "x64"}) + libdirs("../lib/mingw/x64") + + configuration({"vs*", "x32"}) + libdirs("../lib/msvc/x86") + + configuration({"vs*", "x64"}) + libdirs("../lib/msvc/x64") + + configuration({"xcode3 or xcode4", "x32"}) + libdirs("../lib/xcode/x86") + + configuration({"xcode3 or xcode4", "x64"}) + libdirs("../lib/xcode/x64") + + for k,v in pairs(exampleTable.ConfigurationLibraries) do + configuration(k) + links(v) + end + + configuration({}) end - - debugdir("../examples/bin") - includedirs({ - "../include", - "../extlibs/include" - }) - libdirs("../lib") - targetdir("../examples/bin") - - files(exampleTable.Files) - excludes(exampleTable.FilesExclusion) - - defines(exampleTable.Defines) - flags(exampleTable.Flags) - includedirs(exampleTable.Includes) - links(exampleTable.Libraries) - - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") - - configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../lib/mingw/x86") - - configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../lib/mingw/x64") - - configuration({"vs*", "x32"}) - libdirs("../lib/msvc/x86") - - configuration({"vs*", "x64"}) - libdirs("../lib/msvc/x64") - - configuration({"xcode3 or xcode4", "x32"}) - libdirs("../lib/xcode/x86") - - configuration({"xcode3 or xcode4", "x64"}) - libdirs("../lib/xcode/x64") - - for k,v in pairs(exampleTable.ConfigurationLibraries) do - configuration(k) - links(v) - end - - configuration({}) end end @@ -590,7 +588,7 @@ function NazaraBuild:RegisterAction(actionTable) { trigger = lowerCaseName, description = actionTable.Description, - execute = actionTable.Function + execute = function () actionTable:Function() end } return true diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 502254e36..babb30546 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -8,56 +8,60 @@ #define NAZARA_SPRITE_HPP #include +#include #include #include #include #include -class NAZARA_GRAPHICS_API NzSprite : public NzSceneNode +class NzSprite; + +using NzSpriteConstRef = NzObjectRef; +using NzSpriteLibrary = NzObjectLibrary; +using NzSpriteRef = NzObjectRef; + +class NAZARA_GRAPHICS_API NzSprite : public NzInstancedRenderable { public: - NzSprite(); - NzSprite(NzTexture* texture); - NzSprite(const NzSprite& sprite); + inline NzSprite(); + inline NzSprite(NzMaterialRef material); + inline NzSprite(NzTexture* texture); + inline NzSprite(const NzSprite& sprite); ~NzSprite() = default; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - NzSprite* Clone() const; - NzSprite* Create() const; + inline const NzColor& GetColor() const; + inline const NzMaterialRef& GetMaterial() const; + inline const NzVector2f& GetSize() const; + inline const NzRectf& GetTextureCoords() const; - const NzColor& GetColor() const; - NzMaterial* GetMaterial() const; - nzSceneNodeType GetSceneNodeType() const override; - const NzVector2f& GetSize() const; - const NzRectf& GetTextureCoords() const; + inline void SetColor(const NzColor& color); + inline void SetDefaultMaterial(); + inline void SetMaterial(NzMaterialRef material, bool resizeSprite = true); + inline void SetSize(const NzVector2f& size); + inline void SetSize(float sizeX, float sizeY); + inline void SetTexture(NzTextureRef texture, bool resizeSprite = true); + inline void SetTextureCoords(const NzRectf& coords); + inline void SetTextureRect(const NzRectui& rect); - bool IsDrawable() const; + inline NzSprite& operator=(const NzSprite& sprite); - void SetColor(const NzColor& color); - void SetDefaultMaterial(); - void SetMaterial(NzMaterial* material, bool resizeSprite = true); - void SetSize(const NzVector2f& size); - void SetSize(float sizeX, float sizeY); - void SetTexture(NzTexture* texture, bool resizeSprite = true); - void SetTextureCoords(const NzRectf& coords); - void SetTextureRect(const NzRectui& rect); - - NzSprite& operator=(const NzSprite& sprite); + template static NzSpriteRef New(Args&&... args); private: - void InvalidateNode() override; + inline void InvalidateVertices(); void MakeBoundingVolume() const override; - void Register() override; - void Unregister() override; - void UpdateVertices() const; + void UpdateData(InstanceData* instanceData) const override; NzColor m_color; NzMaterialRef m_material; NzRectf m_textureCoords; NzVector2f m_size; - mutable std::array m_vertices; - mutable bool m_verticesUpdated; + + static NzSpriteLibrary::LibraryMap s_library; }; +#include + #endif // NAZARA_SPRITE_HPP diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl new file mode 100644 index 000000000..1ce1cf534 --- /dev/null +++ b/include/Nazara/Graphics/Sprite.inl @@ -0,0 +1,165 @@ +// Copyright (C) 2015 Jérôme Leclercq +// 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 + +inline NzSprite::NzSprite() : +m_color(NzColor::White), +m_textureCoords(0.f, 0.f, 1.f, 1.f), +m_size(64.f, 64.f) +{ + SetDefaultMaterial(); +} + +inline NzSprite::NzSprite(NzMaterialRef material) : +m_color(NzColor::White), +m_textureCoords(0.f, 0.f, 1.f, 1.f), +m_size(64.f, 64.f) +{ + SetMaterial(std::move(material), true); +} + +inline NzSprite::NzSprite(NzTexture* texture) : +m_color(NzColor::White), +m_textureCoords(0.f, 0.f, 1.f, 1.f), +m_size(64.f, 64.f) +{ + SetTexture(texture, true); +} + +inline NzSprite::NzSprite(const NzSprite& sprite) : +NzInstancedRenderable(sprite), +m_color(sprite.m_color), +m_material(sprite.m_material), +m_textureCoords(sprite.m_textureCoords), +m_size(sprite.m_size) +{ +} + +inline const NzColor& NzSprite::GetColor() const +{ + return m_color; +} + +inline const NzMaterialRef& NzSprite::GetMaterial() const +{ + return m_material; +} + +inline const NzVector2f& NzSprite::GetSize() const +{ + return m_size; +} + +inline const NzRectf& NzSprite::GetTextureCoords() const +{ + return m_textureCoords; +} + +inline void NzSprite::SetColor(const NzColor& color) +{ + m_color = color; + + InvalidateVertices(); +} + +inline void NzSprite::SetDefaultMaterial() +{ + NzMaterialRef material = NzMaterial::New(); + material->Enable(nzRendererParameter_FaceCulling, false); + material->EnableLighting(false); + + SetMaterial(material); +} + +inline void NzSprite::SetMaterial(NzMaterialRef material, bool resizeSprite) +{ + m_material = std::move(material); + if (m_material && resizeSprite) + { + NzTexture* diffuseMap = m_material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); + } +} + +inline void NzSprite::SetSize(const NzVector2f& size) +{ + m_size = size; + + // On invalide la bounding box + InvalidateBoundingVolume(); + InvalidateVertices(); +} + +inline void NzSprite::SetSize(float sizeX, float sizeY) +{ + SetSize(NzVector2f(sizeX, sizeY)); +} + +inline void NzSprite::SetTexture(NzTextureRef texture, bool resizeSprite) +{ + if (!m_material) + SetDefaultMaterial(); + else if (m_material->GetReferenceCount() > 1) + m_material = NzMaterial::New(*m_material); // Copie + + if (resizeSprite && texture && texture->IsValid()) + SetSize(NzVector2f(NzVector2ui(texture->GetSize()))); + + m_material->SetDiffuseMap(std::move(texture)); +} + +inline void NzSprite::SetTextureCoords(const NzRectf& coords) +{ + m_textureCoords = coords; + InvalidateVertices(); +} + +inline void NzSprite::SetTextureRect(const NzRectui& rect) +{ + NazaraAssert(m_material, "Sprite has no material"); + NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); + + NzTexture* diffuseMap = m_material->GetDiffuseMap(); + + float invWidth = 1.f/diffuseMap->GetWidth(); + float invHeight = 1.f/diffuseMap->GetHeight(); + + SetTextureCoords(NzRectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); +} + +inline NzSprite& NzSprite::operator=(const NzSprite& sprite) +{ + NzInstancedRenderable::operator=(sprite); + + m_color = sprite.m_color; + m_material = sprite.m_material; + m_textureCoords = sprite.m_textureCoords; + m_size = sprite.m_size; + + // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon + InvalidateBoundingVolume(); + InvalidateVertices(); + + return *this; +} + +inline void NzSprite::InvalidateVertices() +{ + InvalidateInstanceData(0); +} + +template +NzSpriteRef NzSprite::New(Args&&... args) +{ + std::unique_ptr object(new NzSprite(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +#include diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 606ae51c5..3eebe9d10 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -25,36 +25,31 @@ using NzTextSpriteRef = NzObjectRef; class NAZARA_GRAPHICS_API NzTextSprite : public NzInstancedRenderable { public: - NzTextSprite(); - NzTextSprite(const NzTextSprite& sprite); + inline NzTextSprite(); + inline NzTextSprite(const NzTextSprite& sprite); ~NzTextSprite() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - void Clear(); + inline void Clear(); - NzTextSprite* Clone() const; - NzTextSprite* Create() const; + inline const NzColor& GetColor() const; + inline const NzMaterialRef& GetMaterial() const; + inline float GetScale() const; - const NzColor& GetColor() const; - NzMaterial* GetMaterial() const; - float GetScale() const; - - void InvalidateVertices(); - bool IsDrawable() const; - - void SetColor(const NzColor& color); - void SetDefaultMaterial(); - void SetMaterial(NzMaterial* material); - void SetScale(float scale); + inline void SetColor(const NzColor& color); + inline void SetDefaultMaterial(); + inline void SetMaterial(NzMaterialRef material); + inline void SetScale(float scale); void Update(const NzAbstractTextDrawer& drawer); - NzTextSprite& operator=(const NzTextSprite& text); + inline NzTextSprite& operator=(const NzTextSprite& text); template static NzTextSpriteRef New(Args&&... args); private: + inline void InvalidateVertices(); void MakeBoundingVolume() const override; void OnAtlasInvalidated(const NzAbstractAtlas* atlas); void OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index 85d23d517..a940ff212 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -5,6 +5,123 @@ #include #include +inline NzTextSprite::NzTextSprite() : +m_color(NzColor::White), +m_scale(1.f) +{ + SetDefaultMaterial(); +} + +inline NzTextSprite::NzTextSprite(const NzTextSprite& sprite) : +NzInstancedRenderable(sprite), +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) +{ + for (auto it = sprite.m_atlases.begin(); it != sprite.m_atlases.end(); ++it) + { + const NzAbstractAtlas* atlas = it->first; + AtlasSlots& slots = m_atlases[atlas]; + + slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); + slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); + slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); + } +} + +inline void NzTextSprite::Clear() +{ + m_atlases.clear(); + m_boundingVolume.MakeNull(); + m_localVertices.clear(); + m_renderInfos.clear(); +} + +inline const NzColor& NzTextSprite::GetColor() const +{ + return m_color; +} + +inline const NzMaterialRef& NzTextSprite::GetMaterial() const +{ + return m_material; +} + +inline float NzTextSprite::GetScale() const +{ + return m_scale; +} + +inline void NzTextSprite::SetColor(const NzColor& color) +{ + m_color = color; + + InvalidateVertices(); +} + +inline void NzTextSprite::SetDefaultMaterial() +{ + NzMaterialRef material = NzMaterial::New(); + material->Enable(nzRendererParameter_Blend, true); + material->Enable(nzRendererParameter_DepthWrite, false); + material->Enable(nzRendererParameter_FaceCulling, false); + material->EnableLighting(false); + material->SetDstBlend(nzBlendFunc_InvSrcAlpha); + material->SetSrcBlend(nzBlendFunc_SrcAlpha); + + SetMaterial(material); +} + +inline void NzTextSprite::SetMaterial(NzMaterialRef material) +{ + m_material = std::move(material); +} + +inline void NzTextSprite::SetScale(float scale) +{ + m_scale = scale; + + InvalidateVertices(); +} + +inline void NzTextSprite::InvalidateVertices() +{ + InvalidateInstanceData(0); +} + +inline NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) +{ + NzInstancedRenderable::operator=(text); + + 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; + m_scale = text.m_scale; + + // Connect to the slots of the new atlases + for (auto it = text.m_atlases.begin(); it != text.m_atlases.end(); ++it) + { + const NzAbstractAtlas* atlas = it->first; + AtlasSlots& slots = m_atlases[atlas]; + + slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); + slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); + slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); + } + + InvalidateBoundingVolume(); + InvalidateVertices(); + + return *this; +} + template NzTextSpriteRef NzTextSprite::New(Args&&... args) { diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 1856d012b..6130e4184 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -26,8 +26,8 @@ struct NzRenderTextureImpl; class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable { public: - NzRenderTexture() = default; - ~NzRenderTexture(); + inline NzRenderTexture(); + inline ~NzRenderTexture(); bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer); bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format, unsigned int width, unsigned int height); @@ -38,18 +38,18 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable void Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index); - unsigned int GetHeight() const; + unsigned int GetHeight() const override; NzRenderTargetParameters GetParameters() const; NzVector2ui GetSize() const; - unsigned int GetWidth() const; + unsigned int GetWidth() const override; bool IsComplete() const; bool IsRenderable() const; - bool IsValid() const; + inline bool IsValid() const; bool Lock() const; - void SetColorTarget(nzUInt8 target) const; + inline void SetColorTarget(nzUInt8 target) const; void SetColorTargets(const nzUInt8* targets, unsigned int targetCount) const; void SetColorTargets(const std::initializer_list& targets) const; @@ -59,7 +59,7 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable unsigned int GetOpenGLID() const; bool HasContext() const override; - static void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); + static inline void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static bool IsSupported(); @@ -69,6 +69,9 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable void EnsureTargetUpdated() const override; private: + inline void InvalidateDrawBuffers() const; + inline void InvalidateSize() const; + inline void InvalidateTargets() const; void OnContextDestroy(const NzContext* context); void OnRenderBufferDestroy(const NzRenderBuffer* renderBuffer, unsigned int attachmentIndex); void OnTextureDestroy(const NzTexture* texture, unsigned int attachmentIndex); @@ -76,7 +79,13 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable void UpdateSize() const; void UpdateTargets() const; - NzRenderTextureImpl* m_impl = nullptr; + NzRenderTextureImpl* m_impl; + mutable bool m_checked ; + mutable bool m_drawBuffersUpdated; + mutable bool m_sizeUpdated; + mutable bool m_targetsUpdated; }; +#include + #endif // NAZARA_RENDERTEXTURE_HPP diff --git a/include/Nazara/Renderer/RenderTexture.inl b/include/Nazara/Renderer/RenderTexture.inl new file mode 100644 index 000000000..d104eab39 --- /dev/null +++ b/include/Nazara/Renderer/RenderTexture.inl @@ -0,0 +1,53 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +inline NzRenderTexture::NzRenderTexture() : +m_impl(nullptr) +{ +} + +inline NzRenderTexture::~NzRenderTexture() +{ + Destroy(); +} + +inline bool NzRenderTexture::IsValid() const +{ + return m_impl != nullptr; +} + +inline void NzRenderTexture::SetColorTarget(nzUInt8 target) const +{ + SetColorTargets(&target, 1); +} + +inline void NzRenderTexture::Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers, bool bilinearFilter) +{ + Blit(src, src->GetSize(), dst, dst->GetSize(), buffers, bilinearFilter); +} + +inline void NzRenderTexture::InvalidateDrawBuffers() const +{ + m_drawBuffersUpdated = false; +} + +inline void NzRenderTexture::InvalidateSize() const +{ + m_sizeUpdated = false; + + OnRenderTargetSizeChange(this); +} + +inline void NzRenderTexture::InvalidateTargets() const +{ + m_checked = false; + m_drawBuffersUpdated = false; + m_targetsUpdated = false; +} + +#include diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 5e4d45e22..9820d24b6 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -18,6 +18,9 @@ namespace { + constexpr unsigned int s_allocatedId = 0xDEADB33FUL; + constexpr unsigned int s_freedId = 0x4B1DUL; + struct Block { std::size_t size; @@ -31,7 +34,6 @@ namespace bool s_allocationLogging = false; bool s_initialized = false; - const unsigned int s_magic = 0xDEADB33FUL; const char* s_logFileName = "NazaraMemory.log"; thread_local const char* s_nextFreeFile = "(Internal error)"; thread_local unsigned int s_nextFreeLine = 0; @@ -44,7 +46,7 @@ namespace &s_list, false, 0, - s_magic + 0 }; unsigned int s_allocationCount = 0; @@ -101,7 +103,7 @@ void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, ptr->file = file; ptr->line = line; ptr->size = size; - ptr->magic = s_magic; + ptr->magic = s_allocatedId; ptr->prev = s_list.prev; ptr->next = &s_list; @@ -147,8 +149,22 @@ void NzMemoryManager::Free(void* pointer, bool multi) return; Block* ptr = reinterpret_cast(reinterpret_cast(pointer) - sizeof(Block)); - if (ptr->magic != s_magic) + if (ptr->magic != s_allocatedId) + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* log = std::fopen(s_logFileName, "a"); + + const char* error = (ptr->magic == s_freedId) ? "double-delete" : "possible delete of dangling pointer"; + if (s_nextFreeFile) + std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); + else + std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); + + std::fclose(log); return; + } #if defined(NAZARA_PLATFORM_WINDOWS) EnterCriticalSection(&s_mutex); @@ -167,12 +183,12 @@ void NzMemoryManager::Free(void* pointer, bool multi) if (s_nextFreeFile) std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); else - std::fprintf(log, "%s Warning: %s at unknown position\n", error, timeStr); + std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); std::fclose(log); } - ptr->magic = 0; // Évitons des problèmes + ptr->magic = s_freedId; ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index a4cf6eed3..7ad9b797f 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -10,230 +10,42 @@ #include #include -NzSprite::NzSprite() : -m_color(NzColor::White), -m_textureCoords(0.f, 0.f, 1.f, 1.f), -m_size(64.f, 64.f), -m_verticesUpdated(false) -{ - SetDefaultMaterial(); -} - -NzSprite::NzSprite(NzTexture* texture) : -m_color(NzColor::White), -m_textureCoords(0.f, 0.f, 1.f, 1.f), -m_size(64.f, 64.f), -m_verticesUpdated(false) -{ - SetTexture(texture, true); -} - -NzSprite::NzSprite(const NzSprite& sprite) : -NzSceneNode(sprite), -m_color(sprite.m_color), -m_material(sprite.m_material), -m_textureCoords(sprite.m_textureCoords), -m_size(sprite.m_size), -m_vertices(sprite.m_vertices), -m_verticesUpdated(sprite.m_verticesUpdated) -{ - SetParent(sprite.GetParent()); -} - -void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const -{ - if (!m_verticesUpdated) - UpdateVertices(); - - renderQueue->AddSprites(m_material, m_vertices.data(), 1); -} - -NzSprite* NzSprite::Clone() const -{ - return new NzSprite(*this); -} - -NzSprite* NzSprite::Create() const -{ - return new NzSprite; -} - -const NzColor& NzSprite::GetColor() const -{ - return m_color; -} - -NzMaterial* NzSprite::GetMaterial() const -{ - return m_material; -} - -nzSceneNodeType NzSprite::GetSceneNodeType() const -{ - return nzSceneNodeType_Sprite; -} - -const NzVector2f& NzSprite::GetSize() const -{ - return m_size; -} - -const NzRectf& NzSprite::GetTextureCoords() const -{ - return m_textureCoords; -} - -bool NzSprite::IsDrawable() const -{ - return m_material != nullptr; -} - -void NzSprite::SetColor(const NzColor& color) -{ - m_color = color; - m_verticesUpdated = false; -} - -void NzSprite::SetDefaultMaterial() -{ - NzMaterialRef material = NzMaterial::New(); - material->Enable(nzRendererParameter_FaceCulling, false); - material->EnableLighting(false); - - SetMaterial(material); -} - -void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) -{ - m_material = material; - if (m_material && resizeSprite) - { - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); - } -} - -void NzSprite::SetSize(const NzVector2f& size) -{ - m_size = size; - - // On invalide la bounding box - m_boundingVolume.MakeNull(); - m_boundingVolumeUpdated = false; - m_verticesUpdated = false; -} - -void NzSprite::SetSize(float sizeX, float sizeY) -{ - SetSize(NzVector2f(sizeX, sizeY)); -} - -void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite) +void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = NzMaterial::New(*m_material); // Copie - - m_material->SetDiffuseMap(texture); - if (resizeSprite && texture && texture->IsValid()) - SetSize(NzVector2f(NzVector2ui(texture->GetSize()))); -} - -void NzSprite::SetTextureCoords(const NzRectf& coords) -{ - m_textureCoords = coords; - m_verticesUpdated = false; -} - -void NzSprite::SetTextureRect(const NzRectui& rect) -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_material) - { - NazaraError("Sprite has no material"); return; - } - if (!m_material->HasDiffuseMap()) - { - NazaraError("Sprite material has no diffuse map"); - return; - } - #endif - - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - - float invWidth = 1.f/diffuseMap->GetWidth(); - float invHeight = 1.f/diffuseMap->GetHeight(); - - SetTextureCoords(NzRectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); -} - -NzSprite& NzSprite::operator=(const NzSprite& sprite) -{ - NzSceneNode::operator=(sprite); - - m_color = sprite.m_color; - m_material = sprite.m_material; - m_textureCoords = sprite.m_textureCoords; - m_size = sprite.m_size; - - // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - m_verticesUpdated = false; - - return *this; -} - -void NzSprite::InvalidateNode() -{ - NzSceneNode::InvalidateNode(); - - m_verticesUpdated = false; -} - -void NzSprite::Register() -{ - // Le changement de scène peut affecter les sommets - m_verticesUpdated = false; -} - -void NzSprite::Unregister() -{ + const NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + renderQueue->AddSprites(m_material, vertices, 1); } void NzSprite::MakeBoundingVolume() const { - NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); - NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); - - m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); + m_boundingVolume.Set(NzVector3f(0.f), m_size.x*NzVector3f::Right() + m_size.y*NzVector3f::Down()); } -void NzSprite::UpdateVertices() const +void NzSprite::UpdateData(InstanceData* instanceData) const { - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); + instanceData->data.resize(4 * sizeof(NzVertexStruct_XYZ_Color_UV)); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); - NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); - NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); + NzSparsePtr colorPtr(&vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); + NzSparsePtr posPtr(&vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); + NzSparsePtr texCoordPtr(&vertices[0].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); - m_vertices[0].color = m_color; - m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f)); - m_vertices[0].uv.Set(m_textureCoords.GetCorner(nzRectCorner_LeftTop)); + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(NzVector3f(0.f)); + *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_LeftTop); - m_vertices[1].color = m_color; - m_vertices[1].position = m_transformMatrix.Transform(m_size.x*right); - m_vertices[1].uv.Set(m_textureCoords.GetCorner(nzRectCorner_RightTop)); + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*NzVector3f::Right()); + *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_RightTop); - m_vertices[2].color = m_color; - m_vertices[2].position = m_transformMatrix.Transform(m_size.y*down); - m_vertices[2].uv.Set(m_textureCoords.GetCorner(nzRectCorner_LeftBottom)); + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.y*NzVector3f::Down()); + *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_LeftBottom); - m_vertices[3].color = m_color; - m_vertices[3].position = m_transformMatrix.Transform(m_size.x*right + m_size.y*down); - m_vertices[3].uv.Set(m_textureCoords.GetCorner(nzRectCorner_RightBottom)); - - m_verticesUpdated = true; + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*NzVector3f::Right() + m_size.y*NzVector3f::Down()); + *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_RightBottom); } diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 609d37dd1..bcc318a55 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -11,35 +11,11 @@ #include #include -NzTextSprite::NzTextSprite() : -m_color(NzColor::White), -m_scale(1.f) -{ - SetDefaultMaterial(); -} - -NzTextSprite::NzTextSprite(const NzTextSprite& sprite) : -NzInstancedRenderable(sprite), -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) -{ - for (auto it = sprite.m_atlases.begin(); it != sprite.m_atlases.end(); ++it) - { - const NzAbstractAtlas* atlas = it->first; - AtlasSlots& slots = m_atlases[atlas]; - - slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); - slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); - slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); - } -} - void NzTextSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { + if (!m_material) + return; + for (auto& pair : m_renderInfos) { NzTexture* overlay = pair.first; @@ -53,81 +29,6 @@ void NzTextSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const In } } -void NzTextSprite::Clear() -{ - m_atlases.clear(); - m_boundingVolume.MakeNull(); - m_localVertices.clear(); - m_renderInfos.clear(); -} - -NzTextSprite* NzTextSprite::Clone() const -{ - return new NzTextSprite(*this); -} - -NzTextSprite* NzTextSprite::Create() const -{ - return new NzTextSprite; -} - -const NzColor& NzTextSprite::GetColor() const -{ - return m_color; -} - -NzMaterial* NzTextSprite::GetMaterial() const -{ - return m_material; -} - -float NzTextSprite::GetScale() const -{ - return m_scale; -} - -void NzTextSprite::InvalidateVertices() -{ - InvalidateInstanceData(0); -} - -bool NzTextSprite::IsDrawable() const -{ - return m_material != nullptr; -} - -void NzTextSprite::SetColor(const NzColor& color) -{ - m_color = color; - - InvalidateVertices(); -} - -void NzTextSprite::SetDefaultMaterial() -{ - NzMaterialRef material = NzMaterial::New(); - material->Enable(nzRendererParameter_Blend, true); - material->Enable(nzRendererParameter_DepthWrite, false); - material->Enable(nzRendererParameter_FaceCulling, false); - material->EnableLighting(false); - material->SetDstBlend(nzBlendFunc_InvSrcAlpha); - material->SetSrcBlend(nzBlendFunc_SrcAlpha); - - SetMaterial(material); -} - -void NzTextSprite::SetMaterial(NzMaterial* material) -{ - m_material = material; -} - -void NzTextSprite::SetScale(float scale) -{ - m_scale = scale; - - InvalidateInstanceData(0); -} - void NzTextSprite::Update(const NzAbstractTextDrawer& drawer) { m_atlases.clear(); @@ -142,15 +43,7 @@ void NzTextSprite::Update(const NzAbstractTextDrawer& drawer) { NzFont* font = drawer.GetFont(i); const NzAbstractAtlas* atlas = font->GetAtlas().get(); - - #if NAZARA_GRAPHICS_SAFE - if ((atlas->GetStorage() & nzDataStorage_Hardware) == 0) - { - // Cet atlas ne nous donnera pas de texture, nous ne pouvons pas l'utiliser - NazaraError("Font " + NzString::Pointer(font) + " uses a non-hardware atlas which cannot be used by text sprites"); - return; - } - #endif + NazaraAssert(atlas->GetStorage() & nzDataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); if (m_atlases.find(atlas) == m_atlases.end()) { @@ -243,36 +136,6 @@ void NzTextSprite::Update(const NzAbstractTextDrawer& drawer) clearOnFail.Reset(); } -NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) -{ - NzInstancedRenderable::operator=(text); - - 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; - m_scale = text.m_scale; - - // Connect to the slots of the new atlases - for (auto it = text.m_atlases.begin(); it != text.m_atlases.end(); ++it) - { - const NzAbstractAtlas* atlas = it->first; - AtlasSlots& slots = m_atlases[atlas]; - - slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); - slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); - slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); - } - - InvalidateBoundingVolume(); - InvalidateVertices(); - - return *this; -} - void NzTextSprite::MakeBoundingVolume() const { NzRectf bounds(m_localBounds); diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index f2dc61bfc..b574de8d9 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -63,21 +63,12 @@ struct NzRenderTextureImpl std::vector colorTargets; mutable std::vector drawBuffers; const NzContext* context; - bool checked = false; bool complete = false; bool userDefinedTargets = false; - mutable bool drawBuffersUpdated = true; - mutable bool sizeUpdated = false; - mutable bool targetsUpdated = true; unsigned int height; unsigned int width; }; -NzRenderTexture::~NzRenderTexture() -{ - Destroy(); -} - bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer) { #if NAZARA_RENDERER_SAFE @@ -148,6 +139,9 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.buffer = buffer; @@ -157,15 +151,11 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in attachment.height = buffer->GetHeight(); attachment.width = buffer->GetWidth(); - m_impl->checked = false; - m_impl->sizeUpdated = false; + InvalidateSize(); + InvalidateTargets(); if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - { m_impl->colorTargets.push_back(index); - m_impl->drawBuffersUpdated = false; - m_impl->targetsUpdated = false; - } return true; } @@ -286,6 +276,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.isBuffer = false; @@ -295,15 +288,11 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i attachment.textureDestroySlot.Connect(texture->OnTextureDestroy, std::bind(&NzRenderTexture::OnTextureDestroy, this, std::placeholders::_1, attachIndex)); attachment.width = texture->GetWidth(); - m_impl->checked = false; - m_impl->sizeUpdated = false; + InvalidateSize(); + InvalidateTargets(); if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - { m_impl->colorTargets.push_back(index); - m_impl->drawBuffersUpdated = false; - m_impl->targetsUpdated = false; - } return true; } @@ -341,6 +330,11 @@ bool NzRenderTexture::Create(bool lock) m_impl->context = NzContext::GetCurrent(); m_impl->contextDestroySlot.Connect(m_impl->context->OnContextDestroy, this, &NzRenderTexture::OnContextDestroy); + m_checked = false; + m_drawBuffersUpdated = true; + m_sizeUpdated = false; + m_targetsUpdated = true; + if (lock) { // En cas d'exception, la ressource sera quand même libérée @@ -430,30 +424,21 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) attachement.textureDestroySlot.Disconnect(); } - m_impl->sizeUpdated = false; + InvalidateSize(); if (attachement.attachmentPoint == nzAttachmentPoint_Color) - { - m_impl->drawBuffersUpdated = false; - m_impl->targetsUpdated = false; - } + InvalidateTargets(); Unlock(); - m_impl->checked = false; + m_checked = false; } unsigned int NzRenderTexture::GetHeight() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); - if (!m_impl->sizeUpdated) + if (!m_sizeUpdated) UpdateSize(); return m_impl->height; @@ -461,13 +446,7 @@ unsigned int NzRenderTexture::GetHeight() const NzRenderTargetParameters NzRenderTexture::GetParameters() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return NzRenderTargetParameters(); - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); ///TODO return NzRenderTargetParameters(); @@ -475,15 +454,9 @@ NzRenderTargetParameters NzRenderTexture::GetParameters() const NzVector2ui NzRenderTexture::GetSize() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); - if (!m_impl->sizeUpdated) + if (!m_sizeUpdated) UpdateSize(); return NzVector2ui(m_impl->width, m_impl->height); @@ -491,15 +464,9 @@ NzVector2ui NzRenderTexture::GetSize() const unsigned int NzRenderTexture::GetWidth() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); - if (!m_impl->sizeUpdated) + if (!m_sizeUpdated) UpdateSize(); return m_impl->width; @@ -507,15 +474,9 @@ unsigned int NzRenderTexture::GetWidth() const bool NzRenderTexture::IsComplete() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); - if (!m_impl->checked) + if (!m_checked) { if (!Lock()) { @@ -566,7 +527,7 @@ bool NzRenderTexture::IsComplete() const NazaraInternalError("Unknown error"); } - m_impl->checked = true; + m_checked = true; } return m_impl->complete; @@ -577,20 +538,11 @@ bool NzRenderTexture::IsRenderable() const return IsComplete() && !m_impl->attachments.empty(); } -bool NzRenderTexture::IsValid() const -{ - return m_impl != nullptr; -} - bool NzRenderTexture::Lock() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return false; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE if (NzContext::GetCurrent() != m_impl->context) { NazaraError("RenderTexture cannot be used with this context"); @@ -612,20 +564,11 @@ bool NzRenderTexture::Lock() const return true; } -void NzRenderTexture::SetColorTarget(nzUInt8 target) const -{ - SetColorTargets(&target, 1); -} - void NzRenderTexture::SetColorTargets(const nzUInt8* targets, unsigned int targetCount) const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE for (unsigned int i = 0; i < targetCount; ++i) { unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + targets[i]; @@ -640,20 +583,15 @@ void NzRenderTexture::SetColorTargets(const nzUInt8* targets, unsigned int targe m_impl->colorTargets.resize(targetCount); std::memcpy(&m_impl->colorTargets[0], targets, targetCount*sizeof(nzUInt8)); - m_impl->drawBuffersUpdated = false; - m_impl->targetsUpdated = false; m_impl->userDefinedTargets = true; + InvalidateDrawBuffers(); } void NzRenderTexture::SetColorTargets(const std::initializer_list& targets) const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE for (nzUInt8 target : targets) { unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + target; @@ -671,20 +609,15 @@ void NzRenderTexture::SetColorTargets(const std::initializer_list& targ for (nzUInt8 index : targets) *ptr++ = index; - m_impl->drawBuffersUpdated = false; - m_impl->targetsUpdated = false; m_impl->userDefinedTargets = true; + InvalidateDrawBuffers(); } void NzRenderTexture::Unlock() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE if (NzContext::GetCurrent() != m_impl->context) { NazaraError("RenderTexture cannot be used with this context"); @@ -704,13 +637,9 @@ void NzRenderTexture::Unlock() const unsigned int NzRenderTexture::GetOpenGLID() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return 0; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE if (NzContext::GetCurrent() != m_impl->context) { NazaraError("RenderTexture cannot be used with this context"); @@ -731,46 +660,18 @@ bool NzRenderTexture::IsSupported() return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); } -void NzRenderTexture::Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers, bool bilinearFilter) -{ - #if NAZARA_RENDERER_SAFE - if (!src) - { - NazaraError("Invalid source render texture"); - return; - } - - if (!dst) - { - NazaraError("Invalid source render texture"); - return; - } - #endif - - Blit(src, src->GetSize(), dst, dst->GetSize(), buffers, bilinearFilter); -} - void NzRenderTexture::Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers, bool bilinearFilter) { - #if NAZARA_RENDERER_SAFE - if (!src || !src->IsValid()) - { - NazaraError("Invalid source render texture"); - return; - } + NazaraAssert(src && src->IsValid(), "Invalid source render texture"); + NazaraAssert(dst && dst->IsValid(), "Invalid destination render texture"); + #if NAZARA_RENDERER_SAFE if (srcRect.x+srcRect.width > src->GetWidth() || srcRect.y+srcRect.height > src->GetHeight()) { NazaraError("Source rectangle dimensions are out of bounds"); return; } - if (!dst || !dst->IsValid()) - { - NazaraError("Invalid source render texture"); - return; - } - if (dstRect.x+dstRect.width > dst->GetWidth() || dstRect.y+dstRect.height > dst->GetHeight()) { NazaraError("Destination rectangle dimensions are out of bounds"); @@ -811,13 +712,9 @@ void NzRenderTexture::Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTextu bool NzRenderTexture::Activate() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return false; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE if (NzContext::GetCurrent() != m_impl->context) { NazaraError("RenderTexture cannot be used with this context"); @@ -827,20 +724,16 @@ bool NzRenderTexture::Activate() const glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); - m_impl->drawBuffersUpdated = false; + m_drawBuffersUpdated = false; return true; } void NzRenderTexture::Desactivate() const { - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return; - } + NazaraAssert(m_impl, "Invalid render texture"); + #if NAZARA_RENDERER_SAFE if (NzContext::GetCurrent() != m_impl->context) { NazaraError("RenderTexture cannot be used with this context"); @@ -855,7 +748,7 @@ void NzRenderTexture::Desactivate() const void NzRenderTexture::EnsureTargetUpdated() const { - if (!m_impl->drawBuffersUpdated) + if (!m_drawBuffersUpdated) UpdateDrawBuffers(); for (nzUInt8 index : m_impl->colorTargets) @@ -894,8 +787,7 @@ void NzRenderTexture::OnRenderBufferDestroy(const NzRenderBuffer* renderBuffer, attachment.isUsed = false; attachment.renderBufferDestroySlot.Disconnect(); - m_impl->checked = false; - m_impl->targetsUpdated = false; + InvalidateTargets(); } void NzRenderTexture::OnTextureDestroy(const NzTexture* texture, unsigned int attachmentIndex) @@ -905,23 +797,17 @@ void NzRenderTexture::OnTextureDestroy(const NzTexture* texture, unsigned int at NazaraAssert(!m_impl->attachments[attachmentIndex].isBuffer, "Invalid attachment state"); NazaraUnused(texture); - Attachment& attachment = m_impl->attachments[attachmentIndex]; - attachment.isUsed = false; - attachment.texture = nullptr; - attachment.textureDestroySlot.Disconnect(); - - m_impl->checked = false; - m_impl->targetsUpdated = false; + InvalidateTargets(); } void NzRenderTexture::UpdateDrawBuffers() const { - if (!m_impl->targetsUpdated) + if (!m_targetsUpdated) UpdateTargets(); glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]); - m_impl->drawBuffersUpdated = true; + m_drawBuffersUpdated = true; } void NzRenderTexture::UpdateSize() const @@ -937,7 +823,7 @@ void NzRenderTexture::UpdateSize() const } } - m_impl->sizeUpdated = true; + m_sizeUpdated = true; } void NzRenderTexture::UpdateTargets() const @@ -955,5 +841,5 @@ void NzRenderTexture::UpdateTargets() const *ptr++ = GL_COLOR_ATTACHMENT0 + index; } - m_impl->targetsUpdated = true; + m_targetsUpdated = true; }