diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 346d26e68..7f5480cfd 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,9 @@ struct NzSoundBufferParams class NzSound; class NzSoundBuffer; +using NzSoundBufferConstListener = NzResourceListenerWrapper; using NzSoundBufferConstRef = NzResourceRef; +using NzSoundBufferListener = NzResourceListenerWrapper; using NzSoundBufferLoader = NzResourceLoader; using NzSoundBufferRef = NzResourceRef; diff --git a/include/Nazara/Core/ResourceListenerWrapper.hpp b/include/Nazara/Core/ResourceListenerWrapper.hpp new file mode 100644 index 000000000..fc60a2430 --- /dev/null +++ b/include/Nazara/Core/ResourceListenerWrapper.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RESOURCELISTENERWRAPPER_HPP +#define NAZARA_RESOURCELISTENERWRAPPER_HPP + +#include +#include +#include +#include + +template +class NzResourceListenerWrapper +{ + static_assert(std::is_base_of::value, "ResourceRef should only be used with resource type"); + + public: + NzResourceListenerWrapper(NzResourceListener* listener, int index = 0, T* resource = nullptr); + NzResourceListenerWrapper(const NzResourceListenerWrapper& listener); + NzResourceListenerWrapper(NzResourceListenerWrapper&& listener); + ~NzResourceListenerWrapper(); + + bool IsValid() const; + void Reset(T* resource = nullptr); + + operator bool() const; + operator T*() const; + T* operator->() const; + + NzResourceListenerWrapper& operator=(T* resource); + NzResourceListenerWrapper& operator=(const NzResourceListenerWrapper& listener); + NzResourceListenerWrapper& operator=(NzResourceListenerWrapper&& listener); + + private: + T* m_resource; + NzResourceListener* m_listener; + int m_index; +}; + +#include + +#endif // NAZARA_RESOURCELISTENERWRAPPER_HPP diff --git a/include/Nazara/Core/ResourceListenerWrapper.inl b/include/Nazara/Core/ResourceListenerWrapper.inl new file mode 100644 index 000000000..4b88cf594 --- /dev/null +++ b/include/Nazara/Core/ResourceListenerWrapper.inl @@ -0,0 +1,108 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(NzResourceListener* listener, int index, T* resource) : +m_resource(nullptr), +m_listener(listener), +m_index(index) +{ + Reset(resource); +} + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(const NzResourceListenerWrapper& listener) : +m_resource(nullptr), +m_listener(listener.m_listener), +m_index(listener.m_index) +{ + Reset(listener.m_resource); +} + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(NzResourceListenerWrapper&& listener) : +m_resource(listener.m_resource), +m_listener(listener.m_listener), +m_index(listener.m_index) +{ + listener.m_resource = nullptr; +} + +template +NzResourceListenerWrapper::~NzResourceListenerWrapper() +{ + Reset(nullptr); +} + +template +bool NzResourceListenerWrapper::IsValid() const +{ + return m_resource != nullptr; +} + +template +void NzResourceListenerWrapper::Reset(T* resource) +{ + if (resource) + resource->AddResourceListener(m_listener, m_index); + + if (m_resource) + m_resource->RemoveResourceListener(m_listener); + + m_resource = resource; +} + +template +NzResourceListenerWrapper::operator bool() const +{ + return IsValid(); +} + +template +NzResourceListenerWrapper::operator T*() const +{ + return m_resource; +} + +template +T* NzResourceListenerWrapper::operator->() const +{ + return m_resource; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(T* resource) +{ + Reset(resource); + + return *this; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(const NzResourceListenerWrapper& listener) +{ + m_index = listener.m_index; + m_listener = listener.m_listener; + Reset(listener.m_resource); + + return *this; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(NzResourceListenerWrapper&& listener) +{ + Reset(); + + m_index = listener.m_index; + m_listener = listener.m_listener; + m_resource = listener.m_resource; + + listener.m_resource = nullptr; + + return *this; +} + +#include diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 8ad147042..8f9d92ddc 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -11,22 +11,22 @@ #include #include #include +#include #include #include +#include #include +#include #include #include class NzForwardRenderQueue; -class NzMaterial; -class NzSkeletalMesh; -class NzStaticMesh; class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourceListener { public: NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); - ~NzDeferredRenderQueue(); + ~NzDeferredRenderQueue() = default; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; @@ -35,28 +35,48 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc void Clear(bool fully); - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); - }; - - struct BatchedSpriteMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); - }; - struct MeshDataComparator { bool operator()(const NzMeshData& data1, const NzMeshData& data2); }; - typedef std::map, MeshDataComparator> MeshInstanceContainer; - typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BatchedSpriteContainer; + struct MeshInstanceEntry + { + MeshInstanceEntry(NzDeferredRenderQueue* listener, int indexBufferValue, int vertexBufferValue) : + indexBufferListener(listener, indexBufferValue), + vertexBufferListener(listener, vertexBufferValue) + { + } + + std::vector instances; + NzIndexBufferConstListener indexBufferListener; + NzVertexBufferConstListener vertexBufferListener; + }; + + typedef std::map MeshInstanceContainer; + + struct BatchedModelMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedModelEntry + { + BatchedModelEntry(NzDeferredRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; + + typedef std::map ModelBatches; typedef std::vector LightContainer; ModelBatches opaqueModels; - BatchedSpriteContainer sprites; LightContainer directionalLights; LightContainer pointLights; LightContainer spotLights; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index a7571a848..2657bc973 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -11,16 +11,16 @@ #include #include #include +#include #include #include +#include #include +#include #include #include class NzAbstractViewer; -class NzMaterial; -class NzSkeletalMesh; -class NzStaticMesh; class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResourceListener { @@ -28,7 +28,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource public: NzForwardRenderQueue() = default; - ~NzForwardRenderQueue(); + ~NzForwardRenderQueue() = default; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; @@ -49,17 +49,15 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource unsigned int spriteCount; }; - struct TransparentModelData + struct BatchedSpriteEntry { - NzMatrix4f transformMatrix; - NzMeshData meshData; - NzSpheref boundingSphere; - const NzMaterial* material; - }; + BatchedSpriteEntry(NzForwardRenderQueue* listener, int textureValue) : + textureListener(listener, textureValue) + { + } - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + std::vector spriteChains; + NzTextureConstListener textureListener; }; struct BatchedSpriteMaterialComparator @@ -67,15 +65,71 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); }; + typedef std::map BasicSpriteOverlayContainer; + + struct BatchedBasicSpriteEntry + { + BatchedBasicSpriteEntry(NzForwardRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + BasicSpriteOverlayContainer overlayMap; + bool enabled = false; + }; + + typedef std::map BasicSpriteBatches; + struct MeshDataComparator { bool operator()(const NzMeshData& data1, const NzMeshData& data2); }; - typedef std::map>, MeshDataComparator> MeshInstanceContainer; - typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BasicSpriteOverlayContainer; - typedef std::map BasicSpriteBatches; + struct MeshInstanceEntry + { + MeshInstanceEntry(NzForwardRenderQueue* listener, int indexBufferValue, int vertexBufferValue) : + indexBufferListener(listener, indexBufferValue), + vertexBufferListener(listener, vertexBufferValue) + { + } + + std::vector instances; + NzIndexBufferConstListener indexBufferListener; + NzSpheref squaredBoundingSphere; + NzVertexBufferConstListener vertexBufferListener; + }; + + typedef std::map MeshInstanceContainer; + + struct BatchedModelMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedModelEntry + { + BatchedModelEntry(NzForwardRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; + + typedef std::map ModelBatches; + + struct TransparentModelData + { + NzMatrix4f transformMatrix; + NzMeshData meshData; + NzSpheref squaredBoundingSphere; + const NzMaterial* material; + }; + typedef std::vector LightContainer; typedef std::vector TransparentModelContainer; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index ffe7f8217..e98232bbf 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,9 @@ struct NAZARA_API NzMaterialParams class NzMaterial; +using NzMaterialConstListener = NzResourceListenerWrapper; using NzMaterialConstRef = NzResourceRef; +using NzMaterialListener = NzResourceListenerWrapper; using NzMaterialLoader = NzResourceLoader; using NzMaterialRef = NzResourceRef; diff --git a/include/Nazara/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index 217680934..99e722cba 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,9 @@ class NzContext; +using NzContextConstListener = NzResourceListenerWrapper; using NzContextConstRef = NzResourceRef; +using NzContextListener = NzResourceListenerWrapper; using NzContextRef = NzResourceRef; class NzContextImpl; diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index 0c4415068..d3a038e41 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -10,12 +10,15 @@ #include #include #include +#include #include #include class NzRenderBuffer; +using NzRenderBufferConstListener = NzResourceListenerWrapper; using NzRenderBufferConstRef = NzResourceRef; +using NzRenderBufferListener = NzResourceListenerWrapper; using NzRenderBufferRef = NzResourceRef; class NAZARA_API NzRenderBuffer : public NzResource, NzNonCopyable diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 9c8f4e0dc..edf5f6582 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,9 @@ class NzShader; class NzShaderStage; +using NzShaderConstListener = NzResourceListenerWrapper; using NzShaderConstRef = NzResourceRef; +using NzShaderListener = NzResourceListenerWrapper; using NzShaderRef = NzResourceRef; class NAZARA_API NzShader : public NzResource, NzNonCopyable diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 02a1a208f..fb23834bd 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,9 @@ class NzTexture; +using NzTextureConstListener = NzResourceListenerWrapper; using NzTextureConstRef = NzResourceRef; +using NzTextureListener = NzResourceListenerWrapper; using NzTextureRef = NzResourceRef; struct NzTextureImpl; diff --git a/include/Nazara/Renderer/UberShader.hpp b/include/Nazara/Renderer/UberShader.hpp index c01d512d6..2582b6b4f 100644 --- a/include/Nazara/Renderer/UberShader.hpp +++ b/include/Nazara/Renderer/UberShader.hpp @@ -10,13 +10,16 @@ #include #include #include +#include #include #include #include class NzUberShader; +using NzUberShaderConstListener = NzResourceListenerWrapper; using NzUberShaderConstRef = NzResourceRef; +using NzUberShaderListener = NzResourceListenerWrapper; using NzUberShaderRef = NzResourceRef; class NAZARA_API NzUberShader : public NzResource diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index ae642bcc6..72a78db98 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -9,16 +9,18 @@ #include #include +#include #include #include #include #include #include +#include struct NAZARA_API NzAnimationParams { // La frame de fin à charger - unsigned int endFrame = static_cast(-1); + unsigned int endFrame = std::numeric_limits::max(); // La frame de début à charger unsigned int startFrame = 0; @@ -28,7 +30,9 @@ struct NAZARA_API NzAnimationParams class NzAnimation; class NzSkeleton; +using NzAnimationConstListener = NzResourceListenerWrapper; using NzAnimationConstRef = NzResourceRef; +using NzAnimationListener = NzResourceListenerWrapper; using NzAnimationLoader = NzResourceLoader; using NzAnimationRef = NzResourceRef; diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index b7a81e094..def55d0c4 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -10,12 +10,15 @@ #include #include #include +#include #include #include class NzBuffer; +using NzBufferConstListener = NzResourceListenerWrapper; using NzBufferConstRef = NzResourceRef; +using NzBufferListener = NzResourceListenerWrapper; using NzBufferRef = NzResourceRef; class NzAbstractBuffer; diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 6a87d71d2..1b01ad9f8 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -9,8 +9,9 @@ #include #include -#include +#include #include +#include #include #include #include @@ -25,7 +26,9 @@ class NzFontData; struct NzFontGlyph; +using NzFontConstListener = NzResourceListenerWrapper; using NzFontConstRef = NzResourceRef; +using NzFontListener = NzResourceListenerWrapper; using NzFontLoader = NzResourceLoader; using NzFontRef = NzResourceRef; diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 57c188822..39a79ae89 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,9 @@ struct NAZARA_API NzImageParams class NzImage; +using NzImageConstListener = NzResourceListenerWrapper; using NzImageConstRef = NzResourceRef; +using NzImageListener = NzResourceListenerWrapper; using NzImageLoader = NzResourceLoader; using NzImageRef = NzResourceRef; diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index cd1860199..a25c47421 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -9,12 +9,15 @@ #include #include +#include #include #include class NzIndexBuffer; +using NzIndexBufferConstListener = NzResourceListenerWrapper; using NzIndexBufferConstRef = NzResourceRef; +using NzIndexBufferListener = NzResourceListenerWrapper; using NzIndexBufferRef = NzResourceRef; class NAZARA_API NzIndexBuffer : public NzResource diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 296d72f7c..1e2896e0e 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -52,13 +52,15 @@ class NzPrimitiveList; typedef NzVertexStruct_XYZ_Normal_UV_Tangent NzMeshVertex; typedef NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning NzSkeletalMeshVertex; +using NzMeshConstListener = NzResourceListenerWrapper; using NzMeshConstRef = NzResourceRef; +using NzMeshListener = NzResourceListenerWrapper; using NzMeshLoader = NzResourceLoader; using NzMeshRef = NzResourceRef; struct NzMeshImpl; -class NAZARA_API NzMesh : public NzResource, NzResourceListener +class NAZARA_API NzMesh : public NzResource { friend NzMeshLoader; @@ -121,8 +123,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener void Transform(const NzMatrix4f& matrix); private: - void OnResourceReleased(const NzResource* resource, int index) override; - NzMeshImpl* m_impl = nullptr; static NzMeshLoader::LoaderList s_loaders; diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 47fa31517..4565b2a1e 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -19,7 +19,7 @@ class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceLis { public: NzSimpleTextDrawer(); - virtual ~NzSimpleTextDrawer(); + virtual ~NzSimpleTextDrawer() = default; const NzRectui& GetBounds() const; unsigned int GetCharacterSize() const; @@ -49,6 +49,7 @@ class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceLis mutable std::vector m_glyphs; NzColor m_color; NzFontRef m_font; + NzFontListener m_fontListener; // Doit se situer après le FontRef (pour être libéré avant) mutable NzRectui m_bounds; NzString m_text; nzUInt32 m_style; diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 2ac55cd82..72a0567ba 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -8,12 +8,16 @@ #define NAZARA_SKELETALMESH_HPP #include +#include +#include #include #include class NzSkeletalMesh; +using NzSkeletalMeshConstListener = NzResourceListenerWrapper; using NzSkeletalMeshConstRef = NzResourceRef; +using NzSkeletalMeshListener = NzResourceListenerWrapper; using NzSkeletalMeshRef = NzResourceRef; class NAZARA_API NzSkeletalMesh final : public NzSubMesh diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 7832c266d..12f088622 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,9 @@ class NzSkeleton; +using NzSkeletonConstListener = NzResourceListenerWrapper; using NzSkeletonConstRef = NzResourceRef; +using NzSkeletonListener = NzResourceListenerWrapper; using NzSkeletonRef = NzResourceRef; struct NzSkeletonImpl; diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index 4bd8b4bea..3af527155 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -9,11 +9,14 @@ #include #include +#include #include class NzStaticMesh; +using NzStaticMeshConstListener = NzResourceListenerWrapper; using NzStaticMeshConstRef = NzResourceRef; +using NzStaticMeshListener = NzResourceListenerWrapper; using NzStaticMeshRef = NzResourceRef; class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index f8a7be0f9..cfa031b22 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,9 @@ class NzMesh; class NzSubMesh; +using NzSubMeshConstListener = NzResourceListenerWrapper; using NzSubMeshConstRef = NzResourceRef; +using NzSubMeshListener = NzResourceListenerWrapper; using NzSubMeshRef = NzResourceRef; class NAZARA_API NzSubMesh : public NzResource diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index feb09ae16..51bbe75f0 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -9,13 +9,16 @@ #include #include +#include #include #include #include class NzVertexBuffer; +using NzVertexBufferConstListener = NzResourceListenerWrapper; using NzVertexBufferConstRef = NzResourceRef; +using NzVertexBufferListener = NzResourceListenerWrapper; using NzVertexBufferRef = NzResourceRef; class NAZARA_API NzVertexBuffer : public NzResource diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 3dd5dc6c3..27f6a7aee 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -9,12 +9,15 @@ #include #include +#include #include #include class NzVertexDeclaration; +using NzVertexDeclarationConstListener = NzResourceListenerWrapper; using NzVertexDeclarationConstRef = NzResourceRef; +using NzVertexDeclarationListener = NzResourceListenerWrapper; using NzVertexDeclarationRef = NzResourceRef; class NAZARA_API NzVertexDeclaration : public NzResource diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 4fe2b2905..228fdfe8c 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -54,17 +54,17 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor for (auto& matIt : m_renderQueue->opaqueModels) { - bool& used = std::get<0>(matIt.second); - if (used) + auto& matEntry = matIt.second; + + if (matEntry.enabled) { - bool& renderQueueInstancing = std::get<1>(matIt.second); - NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = std::get<2>(matIt.second); + NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; if (!meshInstances.empty()) { const NzMaterial* material = matIt.first; - bool useInstancing = instancingEnabled && renderQueueInstancing; + bool useInstancing = instancingEnabled && matEntry.instancingEnabled; // On commence par récupérer le programme du matériau nzUInt32 flags = nzShaderFlags_Deferred; @@ -88,8 +88,9 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor for (auto& meshIt : meshInstances) { const NzMeshData& meshData = meshIt.first; - std::vector& instances = meshIt.second; + auto& meshEntry = meshIt.second; + std::vector& instances = meshEntry.instances; if (!instances.empty()) { const NzIndexBuffer* indexBuffer = meshData.indexBuffer; @@ -158,8 +159,8 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor } // Et on remet à zéro les données - renderQueueInstancing = false; - used = false; + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 821e92d86..44238f9c0 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -3,12 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include -#include -#include -#include #include namespace @@ -26,11 +23,6 @@ m_forwardQueue(forwardQueue) { } -NzDeferredRenderQueue::~NzDeferredRenderQueue() -{ - Clear(true); -} - void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) { m_forwardQueue->AddDrawable(drawable); @@ -46,6 +38,7 @@ void NzDeferredRenderQueue::AddLight(const NzLight* light) } #endif + // On trie la lumière (elles sont traitées différement selon leur type) switch (light->GetLightType()) { case nzLightType_Directional: @@ -61,56 +54,53 @@ void NzDeferredRenderQueue::AddLight(const NzLight* light) break; } + // On envoie également la lumière au forward-shading + ///TODO: Possibilité pour une lumière de se réserver au Deferred Shading m_forwardQueue->AddLight(light); } void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) { if (material->IsEnabled(nzRendererParameter_Blend)) + // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis m_forwardQueue->AddMesh(material, meshData, meshAABB, transformMatrix); else { - ModelBatches::iterator it = opaqueModels.find(material); + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { - it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedModelEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; } - bool& used = std::get<0>(it->second); - bool& enableInstancing = std::get<1>(it->second); - MeshInstanceContainer& meshMap = std::get<2>(it->second); + BatchedModelEntry& entry = it->second; + entry.enabled = true; - used = true; + auto& meshMap = entry.meshMap; - MeshInstanceContainer::iterator it2 = meshMap.find(meshData); + auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { - it2 = meshMap.insert(std::make_pair(meshData, MeshInstanceContainer::mapped_type())).first; + MeshInstanceEntry instanceEntry(this, ResourceType_IndexBuffer, ResourceType_VertexBuffer); + instanceEntry.indexBufferListener = meshData.indexBuffer; + instanceEntry.vertexBufferListener = meshData.vertexBuffer; - if (meshData.indexBuffer) - meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer); - - meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer); + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - std::vector& instances = it2->second; + std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } } void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { - /*NzMaterial* material = sprite->GetMaterial(); - if (!material->IsLightingEnabled() || material->IsEnabled(nzRendererParameter_Blend)) - m_forwardQueue->AddSprite(sprite); - else - sprites[material].push_back(sprite);*/ - m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); } @@ -121,27 +111,7 @@ void NzDeferredRenderQueue::Clear(bool fully) spotLights.clear(); if (fully) - { - for (auto& matIt : opaqueModels) - { - const NzMaterial* material = matIt.first; - material->RemoveResourceListener(this); - - MeshInstanceContainer& instances = std::get<2>(matIt.second); - for (auto& instanceIt : instances) - { - const NzMeshData& renderData = instanceIt.first; - - if (renderData.indexBuffer) - renderData.indexBuffer->RemoveResourceListener(this); - - renderData.vertexBuffer->RemoveResourceListener(this); - } - } - opaqueModels.clear(); - sprites.clear(); - } m_forwardQueue->Clear(fully); } @@ -154,7 +124,7 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -168,14 +138,18 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in } case ResourceType_Material: - opaqueModels.erase(static_cast(resource)); + { + const NzMaterial* material = static_cast(resource); + + opaqueModels.erase(material); break; + } case ResourceType_VertexBuffer: { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -203,7 +177,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -233,7 +207,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -268,26 +242,6 @@ bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzM return mat1 < mat2; } -bool NzDeferredRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - bool NzDeferredRenderQueue::MeshDataComparator::operator()(const NzMeshData& data1, const NzMeshData& data2) { const NzBuffer* buffer1; diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index c148d56f1..23a099335 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -5,15 +5,8 @@ #include #include #include -#include -#include -#include -#include -#include #include -///FIXME: Régler ce problème de dépendance aux ressources - namespace { enum ResourceType @@ -25,11 +18,6 @@ namespace }; } -NzForwardRenderQueue::~NzForwardRenderQueue() -{ - Clear(true); -} - void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) { #if NAZARA_GRAPHICS_SAFE @@ -79,9 +67,9 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& transparentModelData.resize(index+1); TransparentModelData& data = transparentModelData.back(); - data.boundingSphere = NzSpheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.material = material; data.meshData = meshData; + data.squaredBoundingSphere = NzSpheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.transformMatrix = transformMatrix; transparentModels.push_back(index); @@ -91,36 +79,34 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& ModelBatches::iterator it = opaqueModels.find(material); if (it == opaqueModels.end()) { - it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedModelEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; } - bool& used = std::get<0>(it->second); - bool& enableInstancing = std::get<1>(it->second); - MeshInstanceContainer& meshMap = std::get<2>(it->second); + BatchedModelEntry& entry = it->second; + entry.enabled = true; - used = true; + auto& meshMap = entry.meshMap; - MeshInstanceContainer::iterator it2 = meshMap.find(meshData); + auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { - it2 = meshMap.insert(std::make_pair(meshData, MeshInstanceContainer::mapped_type())).first; + MeshInstanceEntry instanceEntry(this, ResourceType_IndexBuffer, ResourceType_VertexBuffer); + instanceEntry.indexBufferListener = meshData.indexBuffer; + instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere(); + instanceEntry.vertexBufferListener = meshData.vertexBuffer; - NzSpheref& squaredBoundingSphere = it2->second.first; - squaredBoundingSphere.Set(meshAABB.GetSquaredBoundingSphere()); - - if (meshData.indexBuffer) - meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer); - - meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer); + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - std::vector& instances = it2->second.second; + std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } } @@ -129,20 +115,27 @@ void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertex auto matIt = basicSprites.find(material); if (matIt == basicSprites.end()) { - matIt = basicSprites.insert(std::make_pair(material, BasicSpriteBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedBasicSpriteEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + matIt = basicSprites.insert(std::make_pair(material, std::move(entry))).first; } - auto& overlayMap = matIt->second; + BatchedBasicSpriteEntry& entry = matIt->second; + entry.enabled = true; + + auto& overlayMap = entry.overlayMap; + auto overlayIt = overlayMap.find(overlay); if (overlayIt == overlayMap.end()) { - overlayIt = overlayMap.insert(std::make_pair(overlay, BasicSpriteOverlayContainer::mapped_type())).first; - if (overlay) - overlay->AddResourceListener(this, ResourceType_Texture); + BatchedSpriteEntry overlayEntry(this, ResourceType_Texture); + overlayEntry.textureListener = overlay; + + overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; } - auto& spriteVector = overlayIt->second; + auto& spriteVector = overlayIt->second.spriteChains; spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } @@ -156,37 +149,7 @@ void NzForwardRenderQueue::Clear(bool fully) if (fully) { - for (auto& matPair : basicSprites) - { - const NzMaterial* material = matPair.first; - material->RemoveResourceListener(this); - - auto& overlayMap = matPair.second; - for (auto& overlayPair : overlayMap) - { - const NzTexture* overlay = overlayPair.first; - if (overlay) - overlay->RemoveResourceListener(this); - } - } basicSprites.clear(); - - for (auto& matPair : opaqueModels) - { - const NzMaterial* material = matPair.first; - material->RemoveResourceListener(this); - - MeshInstanceContainer& instances = std::get<2>(matPair.second); - for (auto& instanceIt : instances) - { - const NzMeshData& renderData = instanceIt.first; - - if (renderData.indexBuffer) - renderData.indexBuffer->RemoveResourceListener(this); - - renderData.vertexBuffer->RemoveResourceListener(this); - } - } opaqueModels.clear(); } } @@ -198,8 +161,8 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) { - const NzSpheref& sphere1 = transparentModelData[index1].boundingSphere; - const NzSpheref& sphere2 = transparentModelData[index2].boundingSphere; + const NzSpheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; + const NzSpheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; NzVector3f position1 = sphere1.GetNegativeVertex(viewerNormal); NzVector3f position2 = sphere2.GetNegativeVertex(viewerNormal); @@ -216,7 +179,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -230,15 +193,19 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind } case ResourceType_Material: - basicSprites.erase(static_cast(resource)); - opaqueModels.erase(static_cast(resource)); + { + const NzMaterial* material = static_cast(resource); + + basicSprites.erase(material); + opaqueModels.erase(material); break; + } case ResourceType_VertexBuffer: { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -266,7 +233,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -306,7 +273,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) { - auto& overlayMap = matIt->second; + auto& overlayMap = matIt->second.overlayMap; for (auto overlayIt = overlayMap.begin(); overlayIt != overlayMap.end(); ++overlayIt) { if (overlayIt->first == resource) @@ -324,7 +291,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 0a73e8641..e7f6168de 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -175,86 +175,93 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const for (auto& matIt : m_renderQueue.basicSprites) { const NzMaterial* material = matIt.first; - auto& overlayMap = matIt.second; + auto& matEntry = matIt.second; - for (auto& overlayIt : overlayMap) + if (matEntry.enabled) { - const NzTexture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second; - - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - nzUInt32 flags = nzShaderFlags_VertexColor; - if (overlay) - flags |= nzShaderFlags_TextureOverlay; + const NzTexture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; - nzUInt8 overlayUnit; - const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) { - overlayUnit++; - NzRenderer::SetTexture(overlayUnit, overlay); - NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + nzUInt32 flags = nzShaderFlags_VertexColor; + if (overlay) + flags |= nzShaderFlags_TextureOverlay; - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) - { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + nzUInt8 overlayUnit; + const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + if (overlay) + { + overlayUnit++; + NzRenderer::SetTexture(overlayUnit, overlay); + NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } - lastShader = shader; - } + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous - unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); - do - { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + lastShader = shader; + } - unsigned int spriteCount = 0; + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés do { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(s_maxSprites - spriteCount, currentChain.spriteCount - spriteChainOffset); + // On ouvre le buffer en écriture + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; + unsigned int spriteCount = 0; - spriteCount += count; - spriteChainOffset += count; - - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) + do { - spriteChain++; - spriteChainOffset = 0; + NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(s_maxSprites - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } } + while (spriteCount < s_maxSprites && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); } - while (spriteCount < s_maxSprites && spriteChain < spriteChainCount); + while (spriteChain < spriteChainCount); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + spriteChainVector.clear(); } - while (spriteChain < spriteChainCount); - - spriteChainVector.clear(); } + + // On remet à zéro + matEntry.enabled = false; } } } @@ -267,11 +274,11 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (auto& matIt : m_renderQueue.opaqueModels) { - bool& used = std::get<0>(matIt.second); - if (used) + auto& matEntry = matIt.second; + + if (matEntry.enabled) { - bool& renderQueueInstancing = std::get<1>(matIt.second); - NzForwardRenderQueue::MeshInstanceContainer& meshInstances = std::get<2>(matIt.second); + NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; if (!meshInstances.empty()) { @@ -280,7 +287,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches // (Le deferred shading n'a pas ce problème) - bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || m_lights.IsEmpty()) && renderQueueInstancing; + bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || m_lights.IsEmpty()) && matEntry.instancingEnabled; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) const NzShader* shader = material->Apply((instancing) ? nzShaderFlags_Instancing : 0); @@ -300,11 +307,13 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } // Meshes - for (auto& subMeshIt : meshInstances) + for (auto& meshIt : meshInstances) { - const NzMeshData& meshData = subMeshIt.first; - const NzSpheref& boundingSphere = subMeshIt.second.first; - std::vector& instances = subMeshIt.second.second; + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + const NzSpheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; if (!instances.empty()) { @@ -400,7 +409,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (const NzMatrix4f& matrix : instances) { unsigned int directionalLightCount = m_directionalLights.GetLightCount(); - unsigned int otherLightCount = m_lights.ComputeClosestLights(matrix.GetTranslation() + boundingSphere.GetPosition(), boundingSphere.radius, m_maxLightPassPerObject*NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - directionalLightCount); + unsigned int otherLightCount = m_lights.ComputeClosestLights(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius, m_maxLightPassPerObject*NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - directionalLightCount); unsigned int lightCount = directionalLightCount + otherLightCount; NzRenderer::SetMatrix(nzMatrixType_World, matrix); @@ -464,8 +473,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } // Et on remet à zéro les données - used = false; - renderQueueInstancing = false; + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } } @@ -534,7 +543,11 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const // Calcul des lumières les plus proches if (lightCount < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS && !m_lights.IsEmpty()) { - unsigned int count = std::min(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - lightCount, m_lights.ComputeClosestLights(matrix.GetTranslation() + modelData.boundingSphere.GetPosition(), modelData.boundingSphere.radius, NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); + NzVector3f position = matrix.GetTranslation() + modelData.squaredBoundingSphere.GetPosition(); + float radius = modelData.squaredBoundingSphere.radius; + unsigned int closestLightCount = m_lights.ComputeClosestLights(position, radius, NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS); + + unsigned int count = std::min(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - lightCount, closestLightCount); for (unsigned int i = 0; i < count; ++i) m_lights.GetResult(i)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*(lightCount++)); } diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 2e47fc11e..a29fb882e 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -35,8 +35,8 @@ namespace NzVertexBuffer* buffer; }; - using MeshMap = std::unordered_map; - using SkeletonMap = std::unordered_map; + using MeshMap = std::unordered_map>; + using SkeletonMap = std::unordered_map>; SkeletonMap s_cache; std::vector s_skinningQueue; @@ -51,7 +51,7 @@ namespace { for (auto& pair : s_cache) { - MeshMap& meshMap = pair.second; + MeshMap& meshMap = pair.second.second; meshMap.erase(static_cast(resource)); } break; @@ -75,17 +75,19 @@ namespace { for (auto& pair : s_cache) { - MeshMap& meshMap = pair.second; + MeshMap& meshMap = pair.second.second; for (auto& pair2 : meshMap) - pair2.second.updated = false; + pair2.second.second.updated = false; } break; } case ResourceType_Skeleton: { - for (auto& pair : s_cache.at(static_cast(resource))) - pair.second.updated = false; + const NzSkeleton* skeleton = static_cast(resource); + for (auto& pair : s_cache.at(skeleton).second) + pair.second.second.updated = false; + break; } } @@ -161,14 +163,11 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N SkeletonMap::iterator it = s_cache.find(skeleton); if (it == s_cache.end()) - { - it = s_cache.insert(std::make_pair(skeleton, SkeletonMap::mapped_type())).first; - skeleton->AddResourceListener(&listener, ResourceType_Skeleton); - } + it = s_cache.insert(std::make_pair(skeleton, std::make_pair(NzSkeletonConstListener(&listener, ResourceType_Skeleton, skeleton), MeshMap{}))).first; NzVertexBuffer* buffer; - MeshMap& meshMap = it->second; + MeshMap& meshMap = it->second.second; MeshMap::iterator it2 = meshMap.find(mesh); if (it2 == meshMap.end()) { @@ -177,9 +176,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N vertexBuffer->Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzDataStorage_Hardware, nzBufferUsage_Dynamic); BufferData data({vertexBuffer.get(), true}); - meshMap.insert(std::make_pair(mesh, data)); - - mesh->AddResourceListener(&listener, ResourceType_SkeletalMesh); + meshMap.insert(std::make_pair(mesh, std::make_pair(NzSkeletalMeshConstListener(&listener, ResourceType_SkeletalMesh, mesh), data))); s_skinningQueue.push_back(SkinningData{mesh, skeleton, vertexBuffer.get()}); @@ -187,7 +184,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N } else { - BufferData& data = it2->second; + BufferData& data = it2->second.second; if (!data.updated) { s_skinningQueue.push_back(SkinningData{mesh, skeleton, data.buffer}); @@ -221,13 +218,6 @@ bool NzSkinningManager::Initialize() void NzSkinningManager::Uninitialize() { - for (auto& pair : s_cache) - { - pair.first->RemoveResourceListener(&listener); - MeshMap& meshMap = pair.second; - for (auto& pair2 : meshMap) - pair2.first->RemoveResourceListener(&listener); - } s_cache.clear(); s_skinningQueue.clear(); } diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index ee53e0ed0..c42d6c044 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -19,8 +19,17 @@ namespace { struct Attachment { + Attachment(NzResourceListener* listener, int bufferIndex = 0, int textureIndex = 0) : + bufferListener(listener, bufferIndex), + textureListener(listener, textureIndex) + { + } + NzRenderBufferRef buffer; NzTextureRef texture; + // Les listeners doivent se trouver après les références (pour être libérés avant elles) + NzRenderBufferListener bufferListener; + NzTextureListener textureListener; nzAttachmentPoint attachmentPoint; bool isBuffer; @@ -51,11 +60,16 @@ namespace struct NzRenderTextureImpl { + NzRenderTextureImpl(NzResourceListener* listener, int contextIndex = 0) : + context(listener, contextIndex) + { + } + GLuint fbo; std::vector attachments; std::vector colorTargets; mutable std::vector drawBuffers; - const NzContext* context; + NzContextConstListener context; bool checked = false; bool complete = false; bool userDefinedTargets = false; @@ -139,20 +153,23 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; - if (m_impl->attachments.size() <= attachIndex) - m_impl->attachments.resize(attachIndex+1); + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + // On créé les attachements si ça n'a pas déjà été fait + for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i) + { + Attachment attachment(this, attachIndex, attachIndex); + m_impl->attachments.emplace_back(std::move(attachment)); + } Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.buffer = buffer; + attachment.bufferListener = buffer; attachment.isBuffer = true; attachment.isUsed = true; attachment.height = buffer->GetHeight(); attachment.width = buffer->GetWidth(); - buffer->AddResourceListener(this, attachIndex); - m_impl->checked = false; if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) @@ -283,9 +300,14 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; - if (m_impl->attachments.size() <= attachIndex) - m_impl->attachments.resize(attachIndex+1); + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + + // On créé les attachements si ça n'a pas déjà été fait + for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i) + { + Attachment attachment(this, attachIndex, attachIndex); + m_impl->attachments.emplace_back(std::move(attachment)); + } Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; @@ -293,10 +315,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i attachment.isUsed = true; attachment.height = texture->GetHeight(); attachment.texture = texture; + attachment.textureListener = texture; attachment.width = texture->GetWidth(); - texture->AddResourceListener(this, attachIndex); - m_impl->checked = false; if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) @@ -327,7 +348,7 @@ bool NzRenderTexture::Create(bool lock) } #endif - std::unique_ptr impl(new NzRenderTextureImpl); + std::unique_ptr impl(new NzRenderTextureImpl(this)); impl->fbo = 0; glGenFramebuffers(1, &impl->fbo); @@ -340,7 +361,6 @@ bool NzRenderTexture::Create(bool lock) m_impl = impl.release(); m_impl->context = NzContext::GetCurrent(); - m_impl->context->AddResourceListener(this); if (lock) { @@ -372,19 +392,6 @@ void NzRenderTexture::Destroy() if (IsActive()) NzRenderer::SetTarget(nullptr); - m_impl->context->RemoveResourceListener(this); - - for (const Attachment& attachment : m_impl->attachments) - { - if (attachment.isUsed) - { - if (attachment.isBuffer) - attachment.buffer->RemoveResourceListener(this); - else - attachment.texture->RemoveResourceListener(this); - } - } - // Le FBO devant être supprimé dans son contexte d'origine, nous déléguons sa suppression à la classe OpenGL // Celle-ci va libérer le FBO dès que possible (la prochaine fois que son contexte d'origine sera actif) NzOpenGL::DeleteFrameBuffer(m_impl->context, m_impl->fbo); @@ -410,7 +417,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) } #endif - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; if (attachIndex >= m_impl->attachments.size()) return; @@ -430,7 +437,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) { glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0); - attachement.buffer->RemoveResourceListener(this); + attachement.bufferListener = nullptr; attachement.buffer = nullptr; } else @@ -440,7 +447,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) else glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0, 0); - attachement.texture->RemoveResourceListener(this); + attachement.textureListener = nullptr; attachement.texture = nullptr; } diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 0e5b42855..ec806b69c 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -66,10 +66,38 @@ namespace bool samplerUpdated = false; }; - using VAO_Key = std::tuple; - using VAO_Map = std::map; + struct VAO_Entry + { + VAO_Entry(NzResourceListener* listener, int indexBufferIndex, int vertexBufferIndex, int vertexDeclarationIndex, int instancingDeclarationIndex) : + indexBufferListener(listener, indexBufferIndex), + vertexBufferListener(listener, vertexBufferIndex), + instancingDeclarationListener(listener, instancingDeclarationIndex), + vertexDeclarationListener(listener, vertexDeclarationIndex) + { + } - using Context_Map = std::unordered_map; + GLuint vao; + NzIndexBufferConstListener indexBufferListener; + NzVertexBufferConstListener vertexBufferListener; + NzVertexDeclarationConstListener instancingDeclarationListener; + NzVertexDeclarationConstListener vertexDeclarationListener; + }; + + using VAO_Key = std::tuple; + using VAO_Map = std::map; + + struct Context_Entry + { + Context_Entry(NzResourceListener* listener, int index) : + contextListener(listener, index) + { + } + + NzContextConstListener contextListener; + VAO_Map vaoMap; + }; + + using Context_Map = std::unordered_map; Context_Map s_vaos; std::vector s_dirtyTextureUnits; @@ -116,7 +144,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -131,7 +159,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -147,7 +175,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -162,7 +190,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -178,7 +206,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -194,7 +222,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -1533,28 +1561,14 @@ void NzRenderer::Uninitialize() for (auto& pair : s_vaos) { const NzContext* context = pair.first; + const Context_Entry& contextEntry = pair.second; - for (auto& pair2 : pair.second) + for (auto& pair2 : contextEntry.vaoMap) { - const VAO_Key& key = pair2.first; - const NzIndexBuffer* indexBuffer = std::get<0>(key); - const NzVertexBuffer* vertexBuffer = std::get<1>(key); - const NzVertexDeclaration* vertexDeclaration = std::get<2>(key); - const NzVertexDeclaration* instancingDeclaration = std::get<3>(key); - - if (indexBuffer) - indexBuffer->RemoveResourceListener(&s_listener); - - vertexBuffer->RemoveResourceListener(&s_listener); - vertexDeclaration->RemoveResourceListener(&s_listener); - - if (instancingDeclaration) - instancingDeclaration->RemoveResourceListener(&s_listener); - - NzOpenGL::DeleteVertexArray(context, pair2.second); + const VAO_Entry& entry = pair2.second; + NzOpenGL::DeleteVertexArray(context, entry.vao); } } - s_vaos.clear(); NzOpenGL::Uninitialize(); @@ -1719,16 +1733,16 @@ bool NzRenderer::EnsureStateUpdate() // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte const NzContext* context = NzContext::GetCurrent(); - VAO_Map* vaos; auto it = s_vaos.find(context); if (it == s_vaos.end()) { - context->AddResourceListener(&s_listener, ResourceType_Context); - auto pair = s_vaos.insert(std::make_pair(context, Context_Map::mapped_type())); - vaos = &pair.first->second; + Context_Entry entry(&s_listener, ResourceType_Context); + entry.contextListener = context; + + it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; } - else - vaos = &it->second; + + VAO_Map& vaoMap = it->second.vaoMap; // Notre clé est composée de ce qui définit un VAO const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); @@ -1736,23 +1750,22 @@ bool NzRenderer::EnsureStateUpdate() VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); // On recherche un VAO existant avec notre configuration - vaoIt = vaos->find(key); - if (vaoIt == vaos->end()) + vaoIt = vaoMap.find(key); + if (vaoIt == vaoMap.end()) { // On créé notre VAO glGenVertexArrays(1, &s_currentVAO); glBindVertexArray(s_currentVAO); // On l'ajoute à notre liste - vaoIt = vaos->insert(std::make_pair(key, s_currentVAO)).first; - if (s_indexBuffer) - s_indexBuffer->AddResourceListener(&s_listener, ResourceType_IndexBuffer); + VAO_Entry entry(&s_listener, ResourceType_IndexBuffer, ResourceType_VertexBuffer, ResourceType_VertexDeclaration, ResourceType_VertexDeclaration); + entry.indexBufferListener = std::get<0>(key); + entry.instancingDeclarationListener = std::get<3>(key); + entry.vertexBufferListener = std::get<1>(key); + entry.vertexDeclarationListener = std::get<2>(key); + entry.vao = s_currentVAO; - s_vertexBuffer->AddResourceListener(&s_listener, ResourceType_VertexBuffer); - vertexDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration); - - if (instancingDeclaration) - instancingDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration); + vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; // Et on indique qu'on veut le programmer update = true; @@ -1760,7 +1773,7 @@ bool NzRenderer::EnsureStateUpdate() else { // Notre VAO existe déjà, il est donc inutile de le reprogrammer - s_currentVAO = vaoIt->second; + s_currentVAO = vaoIt->second.vao; update = false; } @@ -1911,8 +1924,8 @@ bool NzRenderer::EnsureStateUpdate() if (updateFailed) { // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique - glDeleteVertexArrays(1, &vaoIt->second); - vaoIt->second = 0; + glDeleteVertexArrays(1, &vaoIt->second.vao); + vaoIt->second.vao = 0; s_currentVAO = 0; } else diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index ee6489dfc..031329ef4 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -55,7 +55,7 @@ struct NzMeshImpl std::unordered_map subMeshMap; std::vector materials; - std::vector subMeshes; + std::vector subMeshes; nzAnimationType animationType; NzBoxf aabb; NzSkeleton skeleton; // Uniquement pour les meshs squelettiques @@ -91,9 +91,6 @@ void NzMesh::AddSubMesh(NzSubMesh* subMesh) } #endif - subMesh->AddResourceListener(this, m_impl->subMeshes.size()); - subMesh->AddResourceReference(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); } @@ -135,9 +132,6 @@ void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) int index = m_impl->subMeshes.size(); - subMesh->AddResourceListener(this, index); - subMesh->AddResourceReference(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); m_impl->subMeshMap[identifier] = index; @@ -371,12 +365,6 @@ void NzMesh::Destroy() { NotifyDestroy(); - for (NzSubMesh* subMesh : m_impl->subMeshes) - { - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - } - delete m_impl; m_impl = nullptr; } @@ -864,11 +852,6 @@ void NzMesh::RemoveSubMesh(const NzString& identifier) auto it2 = m_impl->subMeshes.begin(); std::advance(it2, index); - // On libère la ressource - NzSubMesh* subMesh = *it2; - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - m_impl->subMeshes.erase(it2); m_impl->aabbUpdated = false; // On invalide l'AABB @@ -894,11 +877,6 @@ void NzMesh::RemoveSubMesh(unsigned int index) auto it = m_impl->subMeshes.begin(); std::advance(it, index); - // On libère la ressource - NzSubMesh* subMesh = *it; - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - m_impl->subMeshes.erase(it); m_impl->aabbUpdated = false; // On invalide l'AABB @@ -1011,11 +989,4 @@ void NzMesh::Transform(const NzMatrix4f& matrix) m_impl->aabbUpdated = false; } -void NzMesh::OnResourceReleased(const NzResource* resource, int index) -{ - NazaraUnused(resource); - - RemoveSubMesh(index); -} - NzMeshLoader::LoaderList NzMesh::s_loaders; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 64ac5a3ad..a6477d23d 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -8,17 +8,12 @@ NzSimpleTextDrawer::NzSimpleTextDrawer() : m_color(NzColor::White), +m_fontListener(this), m_style(nzTextStyle_Regular) { SetFont(NzFont::GetDefault()); } -NzSimpleTextDrawer::~NzSimpleTextDrawer() -{ - if (m_font) - m_font->RemoveResourceListener(this); -} - const NzRectui& NzSimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) @@ -63,12 +58,8 @@ void NzSimpleTextDrawer::SetColor(const NzColor& color) void NzSimpleTextDrawer::SetFont(NzFont* font) { - if (m_font) - m_font->RemoveResourceListener(this); - m_font = font; - if (m_font) - m_font->AddResourceListener(this); + m_fontListener = font; m_glyphUpdated = false; }