From 5d3e4d7aeb6ca119b3faaa325d7d62423f785283 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 26 Nov 2015 23:57:48 +0100 Subject: [PATCH 1/6] Core/GuillotineBinPack: Fix search error Former-commit-id: 8b7428f59b0a1258c8096df2f784910523dee79d --- src/Nazara/Core/GuillotineBinPack.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index b3aedccc0..05f8736b5 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -154,7 +154,7 @@ namespace Nz bool bestFlipped; std::size_t bestFreeRect; std::size_t bestRect; - std::size_t bestScore = std::numeric_limits::max(); + int bestScore = std::numeric_limits::max(); for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) { @@ -170,7 +170,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = false; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -180,7 +180,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = true; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -212,7 +212,7 @@ namespace Nz } // If we didn't manage to find any rectangle to pack, abort. - if (bestScore == std::numeric_limits::max()) + if (bestScore == std::numeric_limits::max()) { // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés if (inserted) From 0a0e6d00f770e171b2a5eb9f910a684d618db316 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 27 Nov 2015 23:38:54 +0100 Subject: [PATCH 2/6] Graphics: Add render order Former-commit-id: 881ae69c214e024846dc0165f3476f76f5bcc0b5 --- .../NDK/Components/GraphicsComponent.hpp | 2 +- .../NDK/Components/GraphicsComponent.inl | 3 +- .../Nazara/Graphics/AbstractRenderQueue.hpp | 24 +-- .../Nazara/Graphics/DeferredRenderQueue.hpp | 36 ++-- .../Nazara/Graphics/ForwardRenderQueue.hpp | 44 ++-- .../Graphics/ForwardRenderTechnique.hpp | 8 +- .../Nazara/Graphics/InstancedRenderable.hpp | 1 + src/Nazara/Graphics/Billboard.cpp | 2 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 179 ++++++++-------- src/Nazara/Graphics/DeferredRenderQueue.cpp | 123 +++++++---- src/Nazara/Graphics/ForwardRenderQueue.cpp | 192 ++++++++++++------ .../Graphics/ForwardRenderTechnique.cpp | 46 +++-- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Graphics/SkeletalModel.cpp | 2 +- src/Nazara/Graphics/Sprite.cpp | 2 +- src/Nazara/Graphics/TextSprite.cpp | 2 +- 16 files changed, 404 insertions(+), 264 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 8d1e3e2f7..4a3ee80c9 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -24,7 +24,7 @@ namespace Ndk inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const; - inline void Attach(Nz::InstancedRenderableRef renderable); + inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); inline void EnsureTransformMatrixUpdate() const; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 56b003b00..c571384f8 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -32,10 +32,11 @@ namespace Ndk } } - inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable) + inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder) { m_renderables.emplace_back(m_transformMatrix); Renderable& r = m_renderables.back(); + r.data.renderOrder = renderOrder; r.renderable = std::move(renderable); r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1)); } diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index d5e4554b9..6c069e1d9 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -38,21 +38,21 @@ namespace Nz // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, // mais je n'ai pas d'autre solution tout aussi performante pour le moment... - virtual void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; - virtual void AddDrawable(const Drawable* drawable) = 0; + virtual void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddDrawable(int renderOrder, const Drawable* drawable) = 0; virtual void AddDirectionalLight(const DirectionalLight& light); - virtual void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; + virtual void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; virtual void AddPointLight(const PointLight& light); virtual void AddSpotLight(const SpotLight& light); - virtual void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; + virtual void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; virtual void Clear(bool fully = false); diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index b69204174..76bff6926 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -29,18 +29,18 @@ namespace Nz DeferredRenderQueue(ForwardRenderQueue* forwardQueue); ~DeferredRenderQueue() = default; - void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddDrawable(const Drawable* drawable) override; - void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; - void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(int renderOrder, const Drawable* drawable) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false); @@ -75,7 +75,17 @@ namespace Nz typedef std::map ModelBatches; - ModelBatches opaqueModels; + struct Layer + { + ModelBatches opaqueModels; + unsigned int clearCount = 0; + }; + + std::map layers; + + private: + Layer& GetLayer(unsigned int i); ///TODO: Inline + ForwardRenderQueue* m_forwardQueue; void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index df3d82a81..3a5d3ef33 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -31,18 +31,18 @@ namespace Nz ForwardRenderQueue() = default; ~ForwardRenderQueue() = default; - void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddDrawable(const Drawable* drawable) override; - void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; - void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(int renderOrder, const Drawable* drawable) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false); @@ -145,14 +145,22 @@ namespace Nz typedef std::vector TransparentModelContainer; - BatchedBillboardContainer billboards; - BasicSpriteBatches basicSprites; - ModelBatches opaqueModels; - TransparentModelContainer transparentModels; - std::vector transparentModelData; - std::vector otherDrawables; + struct Layer + { + BatchedBillboardContainer billboards; + BasicSpriteBatches basicSprites; + ModelBatches opaqueModels; + TransparentModelContainer transparentModels; + std::vector transparentModelData; + std::vector otherDrawables; + unsigned int clearCount = 0; + }; + + std::map layers; private: + Layer& GetLayer(int i); ///TODO: Inline + void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); void OnMaterialInvalidation(const Material* material); void OnTextureInvalidation(const Texture* texture); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 855eb9461..920a6c0bd 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -39,10 +39,10 @@ namespace Nz struct ShaderUniforms; void ChooseLights(const Spheref& object, bool includeDirectionalLights = true) const; - void DrawBasicSprites(const SceneData& sceneData) const; - void DrawBillboards(const SceneData& sceneData) const; - void DrawOpaqueModels(const SceneData& sceneData) const; - void DrawTransparentModels(const SceneData& sceneData) const; + void DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; void OnShaderInvalidated(const Shader* shader) const; void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index f3f17d866..561cc4c97 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -64,6 +64,7 @@ namespace Nz BoundingVolumef volume; Matrix4f& transformMatrix; UInt32 flags; + int renderOrder; }; protected: diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 1e9de412c..3e5173c89 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -17,7 +17,7 @@ namespace Nz if (!m_material) return; - renderQueue->AddBillboard(m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); + renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); } void Billboard::MakeBoundingVolume() const diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 3781cd23f..2ae39ed9b 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -54,118 +54,123 @@ namespace Nz const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : m_renderQueue->opaqueModels) + for (auto& pair : m_renderQueue->layers) { - auto& matEntry = matIt.second; + DeferredRenderQueue::Layer& layer = pair.second; - if (matEntry.enabled) + for (auto& matIt : layer.opaqueModels) { - DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + auto& matEntry = matIt.second; - if (!meshInstances.empty()) + if (matEntry.enabled) { - const Material* material = matIt.first; + DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - - // On commence par récupérer le programme du matériau - UInt32 flags = ShaderFlags_Deferred; - if (useInstancing) - flags |= ShaderFlags_Instancing; - - const Shader* shader = material->Apply(flags); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + if (!meshInstances.empty()) { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + const Material* material = matIt.first; - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - lastShader = shader; - } + // On commence par récupérer le programme du matériau + UInt32 flags = ShaderFlags_Deferred; + if (useInstancing) + flags |= ShaderFlags_Instancing; - // Meshes - for (auto& meshIt : meshInstances) - { - const MeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + const Shader* shader = material->Apply(flags); - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - const IndexBuffer* indexBuffer = meshData.indexBuffer; - const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - // Gestion du draw call avant la boucle de rendu - Renderer::DrawCall drawFunc; - Renderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - if (indexBuffer) + lastShader = shader; + } + + // Meshes + for (auto& meshIt : meshInstances) + { + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) { - drawFunc = Renderer::DrawIndexedPrimitives; - instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = Renderer::DrawPrimitives; - instancedDrawFunc = Renderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - Renderer::SetIndexBuffer(indexBuffer); - Renderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (useInstancing) - { - // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices - VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - - const Matrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer - - while (instanceCount > 0) + if (indexBuffer) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; - - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; - - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); } - } - else - { - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const Matrix4f& matrix : instances) + else { - Renderer::SetMatrix(MatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); } - } - instances.clear(); + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (useInstancing) + { + // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + + instances.clear(); + } } } - } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 0e4512cdd..5bd0931e3 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -17,63 +17,66 @@ namespace Nz { } - void DeferredRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { - m_forwardQueue->AddBillboard(material, position, size, sinCos, color); + m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } - void DeferredRenderQueue::AddDrawable(const Drawable* drawable) + void DeferredRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { - m_forwardQueue->AddDrawable(drawable); + m_forwardQueue->AddDrawable(renderOrder, drawable); } - void DeferredRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_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); + m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix); else { + Layer& currentLayer = GetLayer(renderOrder); + auto& opaqueModels = currentLayer.opaqueModels; + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { @@ -110,9 +113,9 @@ namespace Nz } } - void DeferredRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { - m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); + m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay); } void DeferredRenderQueue::Clear(bool fully) @@ -120,44 +123,80 @@ namespace Nz AbstractRenderQueue::Clear(fully); if (fully) - opaqueModels.clear(); + layers.clear(); + else + { + for (auto it = layers.begin(); it != layers.end(); ++it) + { + Layer& layer = it->second; + if (layer.clearCount++ >= 100) + it = layers.erase(it); + } + } m_forwardQueue->Clear(fully); } + DeferredRenderQueue::Layer& DeferredRenderQueue::GetLayer(unsigned int i) + { + auto it = layers.find(i); + if (it == layers.end()) + it = layers.insert(std::make_pair(i, Layer())).first; + + Layer& layer = it->second; + layer.clearCount = 0; + + return layer; + } + void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } void DeferredRenderQueue::OnMaterialInvalidation(const Material* material) { - opaqueModels.erase(material); + for (auto& pair : layers) + { + Layer& layer = pair.second; + + layer.opaqueModels.erase(material); + } } void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index a6cb47ba1..d9527a646 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -11,10 +11,12 @@ namespace Nz { - void ForwardRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { NazaraAssert(material, "Invalid material"); + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -30,7 +32,7 @@ namespace Nz billboardVector.push_back(BillboardData{color, position, size, sinCos}); } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -43,6 +45,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -69,7 +73,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -84,6 +88,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -110,7 +116,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -123,6 +129,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -153,7 +161,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -168,6 +176,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -198,7 +208,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -211,6 +221,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -237,7 +249,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -252,6 +264,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -278,7 +292,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -291,6 +305,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -321,7 +337,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -336,6 +352,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -366,7 +384,7 @@ namespace Nz } } - void ForwardRenderQueue::AddDrawable(const Drawable* drawable) + void ForwardRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { #if NAZARA_GRAPHICS_SAFE if (!drawable) @@ -376,13 +394,19 @@ namespace Nz } #endif + auto& otherDrawables = GetLayer(renderOrder).otherDrawables; + otherDrawables.push_back(drawable); } - void ForwardRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_Blend)) { + Layer& currentLayer = GetLayer(renderOrder); + auto& transparentModels = currentLayer.transparentModels; + auto& transparentModelData = currentLayer.transparentModelData; + // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) unsigned int index = transparentModelData.size(); transparentModelData.resize(index+1); @@ -397,6 +421,9 @@ namespace Nz } else { + Layer& currentLayer = GetLayer(renderOrder); + auto& opaqueModels = currentLayer.opaqueModels; + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { @@ -434,8 +461,11 @@ namespace Nz } } - void ForwardRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { + Layer& currentLayer = GetLayer(renderOrder); + auto& basicSprites = currentLayer.basicSprites; + auto matIt = basicSprites.find(material); if (matIt == basicSprites.end()) { @@ -468,15 +498,22 @@ namespace Nz { AbstractRenderQueue::Clear(fully); - otherDrawables.clear(); - transparentModels.clear(); - transparentModelData.clear(); - if (fully) + layers.clear(); + else { - basicSprites.clear(); - billboards.clear(); - opaqueModels.clear(); + for (auto it = layers.begin(); it != layers.end(); ++it) + { + Layer& layer = it->second; + if (layer.clearCount++ >= 100) + it = layers.erase(it); + else + { + layer.otherDrawables.clear(); + layer.transparentModels.clear(); + layer.transparentModelData.clear(); + } + } } } @@ -486,78 +523,113 @@ namespace Nz Vector3f viewerPos = viewer->GetEyePosition(); Vector3f viewerNormal = viewer->GetForward(); - std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) + for (auto& pair : layers) { - const Spheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; - const Spheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; + Layer& layer = pair.second; - Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); - Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); - - return nearPlane.Distance(position1) > nearPlane.Distance(position2); - }); - - for (auto& pair : billboards) - { - const Material* mat = pair.first; - - if (mat->IsDepthSortingEnabled()) + std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2) { - BatchedBillboardEntry& entry = pair.second; - auto& billboardVector = entry.billboards; + const Spheref& sphere1 = layer.transparentModelData[index1].squaredBoundingSphere; + const Spheref& sphere2 = layer.transparentModelData[index2].squaredBoundingSphere; - std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) + Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); + Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); + + return nearPlane.Distance(position1) > nearPlane.Distance(position2); + }); + + for (auto& pair : layer.billboards) + { + const Material* mat = pair.first; + + if (mat->IsDepthSortingEnabled()) { - return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); - }); + BatchedBillboardEntry& entry = pair.second; + auto& billboardVector = entry.billboards; + + std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos] (const BillboardData& data1, const BillboardData& data2) + { + return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); + }); + } } } } + ForwardRenderQueue::Layer& ForwardRenderQueue::GetLayer(int i) + { + auto it = layers.find(i); + if (it == layers.end()) + it = layers.insert(std::make_pair(i, Layer())).first; + + Layer& layer = it->second; + layer.clearCount = 0; + + return layer; + } + void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } void ForwardRenderQueue::OnMaterialInvalidation(const Material* material) { - basicSprites.erase(material); - billboards.erase(material); - opaqueModels.erase(material); + for (auto& pair : layers) + { + Layer& layer = pair.second; + + layer.basicSprites.erase(material); + layer.billboards.erase(material); + layer.opaqueModels.erase(material); + } } void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture) { - for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) + for (auto& pair : layers) { - auto& overlayMap = matIt->second.overlayMap; - overlayMap.erase(texture); + Layer& layer = pair.second; + for (auto matIt = layer.basicSprites.begin(); matIt != layer.basicSprites.end(); ++matIt) + { + auto& overlayMap = matIt->second.overlayMap; + overlayMap.erase(texture); + } } } void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 6eeb41575..2db03b7f9 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -62,21 +62,25 @@ namespace Nz if (sceneData.background) sceneData.background->Draw(sceneData.viewer); - if (!m_renderQueue.opaqueModels.empty()) - DrawOpaqueModels(sceneData); + for (auto& pair : m_renderQueue.layers) + { + ForwardRenderQueue::Layer& layer = pair.second; - if (!m_renderQueue.transparentModels.empty()) - DrawTransparentModels(sceneData); + if (!layer.opaqueModels.empty()) + DrawOpaqueModels(sceneData, layer); - if (!m_renderQueue.basicSprites.empty()) - DrawBasicSprites(sceneData); + if (!layer.transparentModels.empty()) + DrawTransparentModels(sceneData, layer); - if (!m_renderQueue.billboards.empty()) - DrawBillboards(sceneData); + if (!layer.basicSprites.empty()) + DrawBasicSprites(sceneData, layer); - // Les autres drawables (Exemple: Terrain) - for (const Drawable* drawable : m_renderQueue.otherDrawables) - drawable->Draw(); + if (!layer.billboards.empty()) + DrawBillboards(sceneData, layer); + + for (const Drawable* drawable : layer.otherDrawables) + drawable->Draw(); + } return true; } @@ -203,7 +207,7 @@ namespace Nz }); } - void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -214,7 +218,7 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& matIt : m_renderQueue.basicSprites) + for (auto& matIt : layer.basicSprites) { const Material* material = matIt.first; auto& matEntry = matIt.second; @@ -309,7 +313,7 @@ namespace Nz } } - void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -323,7 +327,7 @@ namespace Nz Renderer::SetVertexBuffer(&s_quadVertexBuffer); - for (auto& matIt : m_renderQueue.billboards) + for (auto& matIt : layer.billboards) { const Material* material = matIt.first; auto& entry = matIt.second; @@ -372,7 +376,7 @@ namespace Nz Renderer::SetIndexBuffer(&s_quadIndexBuffer); Renderer::SetVertexBuffer(&m_billboardPointBuffer); - for (auto& matIt : m_renderQueue.billboards) + for (auto& matIt : layer.billboards) { const Material* material = matIt.first; auto& entry = matIt.second; @@ -454,14 +458,14 @@ namespace Nz } } - void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : m_renderQueue.opaqueModels) + for (auto& matIt : layer.opaqueModels) { auto& matEntry = matIt.second; @@ -657,7 +661,7 @@ namespace Nz } } - void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -665,9 +669,9 @@ namespace Nz const ShaderUniforms* shaderUniforms = nullptr; unsigned int lightCount = 0; - for (unsigned int index : m_renderQueue.transparentModels) + for (unsigned int index : layer.transparentModels) { - const ForwardRenderQueue::TransparentModelData& modelData = m_renderQueue.transparentModelData[index]; + const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index]; // Matériau const Material* material = modelData.material; diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 954f3ff01..e8954a886 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -50,7 +50,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = mesh->GetVertexBuffer(); - renderQueue->AddMesh(material, meshData, mesh->GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, mesh->GetAABB(), instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 97889764d..12bf10b6d 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -47,7 +47,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = SkinningManager::GetBuffer(mesh, &m_skeleton); - renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 33a27d1a6..970254294 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -17,7 +17,7 @@ namespace Nz return; const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, vertices, 1); + renderQueue->AddSprites(instanceData.renderOrder, m_material, vertices, 1); } void Sprite::MakeBoundingVolume() const diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index b746756d9..4ea284a42 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -26,7 +26,7 @@ namespace Nz if (indices.count > 0) { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, &vertices[indices.first*4], indices.count, overlay); + renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first*4], indices.count, overlay); } } } From 6bc285cb00c34061941144782fb5aa8c219a8a19 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 02:07:56 +0100 Subject: [PATCH 3/6] Fix compilation for GCC Former-commit-id: 7c51c59904fa86f952b704d175b09b32640d9395 --- include/Nazara/Core/Algorithm.inl | 7 ++++--- include/Nazara/Math/Vector3.inl | 2 +- src/Nazara/Core/Stream.cpp | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 2e9661dd9..7c117e626 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -7,6 +7,7 @@ // Merci aussi à Freedom de siteduzero.com #include +#include #include #include #include @@ -45,17 +46,17 @@ namespace Nz return Detail::ApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); } - template + template ByteArray ComputeHash(HashType hash, const T& v) { return ComputeHash(AbstractHash::Get(hash).get(), v); } - template + template ByteArray ComputeHash(AbstractHash* hash, const T& v) { hash->Begin(); - + HashAppend(hash, v); return hash->End(); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 0626cb8eb..9a04ad97b 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -115,7 +115,7 @@ namespace Nz template float Vector3::GetLengthf() const { - return std::sqrt(static_cast(GetSquaredLength())); + return std::sqrt(static_cast(GetSquaredLength())); } template diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 78760ccea..f8aab413e 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace Nz From 89156199344d43e94c9c9b862150ec1cef36e949 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 02:51:42 +0100 Subject: [PATCH 4/6] Lua: Add automatic method binding Former-commit-id: fccd5f3682f6581db6b6b5976f4d0d3e0afa324c --- include/Nazara/Lua/LuaClass.hpp | 16 ++-- include/Nazara/Lua/LuaClass.inl | 39 ++++++++ include/Nazara/Lua/LuaInstance.hpp | 2 + include/Nazara/Lua/LuaInstance.inl | 143 ++++++++++++++++++++++++----- 4 files changed, 169 insertions(+), 31 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 4f47f36f1..96e271a31 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include //#include @@ -22,12 +23,12 @@ namespace Nz //static_assert(std::is_same::value || std::is_base_of::value, "P must be a base of T"); public: - using ClassFunc = int (*)(LuaInstance& lua, T& instance); - using ClassIndexFunc = bool (*)(LuaInstance& lua, T& instance); - using ConstructorFunc = T* (*)(LuaInstance& lua); - using FinalizerFunc = bool (*)(LuaInstance& lua, T& instance); - using StaticIndexFunc = bool (*)(LuaInstance& lua); - using StaticFunc = int (*)(LuaInstance& lua); + using ClassFunc = std::function; + using ClassIndexFunc = std::function; + using ConstructorFunc = std::function; + using FinalizerFunc = std::function; + using StaticIndexFunc = std::function; + using StaticFunc = std::function; LuaClass(const String& name); @@ -41,9 +42,12 @@ namespace Nz void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); void SetMethod(const String& name, ClassFunc method); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...)); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); + template void SetStaticMethod(const String& name, R(*func)(Args...)); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 9fa445ffa..545fa08ba 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -174,6 +174,32 @@ namespace Nz { m_methods[name] = method; } + + template + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...)) + { + SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + { + LuaImplMethodProxy handler(instance, object); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + + template + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const) + { + SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + { + LuaImplMethodProxy handler(instance, object); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } template void LuaClass::SetSetter(ClassIndexFunc setter) @@ -193,6 +219,19 @@ namespace Nz m_staticMethods[name] = method; } + template + template + void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...)) + { + SetStaticMethod(name, [func] (LuaInstance& instance) -> int + { + LuaImplFunctionProxy handler(instance); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + template void LuaClass::SetStaticSetter(StaticIndexFunc setter) { diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 24e9a4f7d..1124ce72a 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -42,6 +42,7 @@ namespace Nz bool Call(unsigned int argCount); bool Call(unsigned int argCount, unsigned int resultCount); + template T Check(int index); void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; @@ -110,6 +111,7 @@ namespace Nz void Pop(unsigned int n = 1U); + template int Push(T arg); void PushBoolean(bool value); void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index beef1fe6d..0274bb0be 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -23,9 +23,22 @@ namespace Nz return static_cast(instance.CheckNumber(index)); } - int LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { - return static_cast(instance.CheckInteger(index)); + return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); + } + + template + std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(instance.CheckInteger(index)); + } + + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); } std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) @@ -50,51 +63,62 @@ namespace Nz return LuaImplQueryArg(instance, index, TypeTag()); } - template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) - { - return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); - } - // Function returns - int LuaImplReplyVal(LuaInstance& instance, bool&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, bool val, TypeTag) { instance.PushBoolean(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, double&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, double val, TypeTag) { instance.PushNumber(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, float&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, float val, TypeTag) { instance.PushNumber(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, int&& val, TypeTag) + template + std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + { + using EnumT = typename std::underlying_type::type; + + return LuaImplReplyVal(instance, static_cast(val), TypeTag()); + } + + template + std::enable_if_t::value && !std::is_unsigned::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) { instance.PushInteger(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, std::string&& val, TypeTag) + template + std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + { + using SignedT = typename std::make_signed::type; + + return LuaImplReplyVal(instance, static_cast(val), TypeTag()); + } + + int LuaImplReplyVal(LuaInstance& instance, std::string val, TypeTag) { instance.PushString(val.c_str(), val.size()); return 1; } - int LuaImplReplyVal(LuaInstance& instance, String&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, String val, TypeTag) { instance.PushString(std::move(val)); return 1; } template - int LuaImplReplyVal(LuaInstance& instance, std::pair&& val, TypeTag>) + int LuaImplReplyVal(LuaInstance& instance, std::pair val, TypeTag>) { int retVal = 0; @@ -104,14 +128,6 @@ namespace Nz return retVal; } - template - std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T&& val, TypeTag) - { - using SignedT = typename std::make_signed::type; - - return LuaImplReplyVal(instance, val, TypeTag()); - } - template class LuaImplFunctionProxy { @@ -152,12 +168,89 @@ namespace Nz } private: - LuaInstance& m_instance; std::tuple m_args; + LuaInstance& m_instance; }; + template + class LuaImplMethodProxy + { + public: + LuaImplMethodProxy(LuaInstance& instance, T& object) : + m_instance(instance), + m_object(object) + { + } + + template + void ProcessArgs() + { + } + + template + void ProcessArgs() + { + std::get(m_args) = std::move(LuaImplQueryArg(m_instance, N + 1, TypeTag())); + } + + template + void ProcessArgs() + { + ProcessArgs(); + ProcessArgs(); + } + + void ProcessArgs() + { + ProcessArgs<0, Args...>(); + } + + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) + { + Apply(m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } + + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) + { + Apply(m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } + + private: + std::tuple m_args; + LuaInstance& m_instance; + T& m_object; + }; + + template + T LuaInstance::Check(int index) + { + return LuaImplQueryArg(*this, index, TypeTag()); + } + + template + int LuaInstance::Push(T arg) + { + return LuaImplReplyVal(*this, std::move(arg), TypeTag()); + } + template - void LuaInstance::PushFunction(R(*func)(Args...)) + void LuaInstance::PushFunction(R (*func)(Args...)) { PushFunction([func](LuaInstance& instance) -> int { From 840c591b6e546d63d9cbbd7b039c288281145243 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 13:53:26 +0100 Subject: [PATCH 5/6] Fix linking problem in United mode Former-commit-id: 6c78f8bb7fba17bda69a622a8028c59d2fadcca2 --- src/Nazara/Network/{Algorithm.cpp => AlgorithmNetwork.cpp} | 0 src/Nazara/Utility/{Algorithm.cpp => AlgorithmUtility.cpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/Nazara/Network/{Algorithm.cpp => AlgorithmNetwork.cpp} (100%) rename src/Nazara/Utility/{Algorithm.cpp => AlgorithmUtility.cpp} (100%) diff --git a/src/Nazara/Network/Algorithm.cpp b/src/Nazara/Network/AlgorithmNetwork.cpp similarity index 100% rename from src/Nazara/Network/Algorithm.cpp rename to src/Nazara/Network/AlgorithmNetwork.cpp diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp similarity index 100% rename from src/Nazara/Utility/Algorithm.cpp rename to src/Nazara/Utility/AlgorithmUtility.cpp From 5e8f8549af85eeb81fc2b076b5f1a4e7d783f5ee Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 Nov 2015 12:50:56 +0100 Subject: [PATCH 6/6] Core/Posix: Fix file opening in ReadWrite mode Former-commit-id: 7c4a5d3e31e9449fa3c23cfad58523ed54b7834a --- src/Nazara/Core/Posix/FileImpl.cpp | 32 ++++++++++-------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index d0d0bf7ee..ddd8d4253 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -18,8 +18,8 @@ namespace Nz void FileImpl::Close() { - if (m_fileDescriptor != -1) - close(m_fileDescriptor); + if (m_fileDescriptor != -1) + close(m_fileDescriptor); } bool FileImpl::EndOfFile() const @@ -54,30 +54,20 @@ namespace Nz int flags; mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (mode & OpenMode_ReadOnly) - flags = O_RDONLY; - else if (mode & OpenMode_ReadWrite) - { + if (mode & OpenMode_ReadWrite) flags = O_CREAT | O_RDWR; - - if (mode & OpenMode_Append) - flags |= O_APPEND; - - if (mode & OpenMode_Truncate) - flags |= O_TRUNC; - } + else if (mode & OpenMode_ReadOnly) + flags = O_RDONLY; else if (mode & OpenMode_WriteOnly) - { flags = O_CREAT | O_WRONLY; - - if (mode & OpenMode_Append) - flags |= O_APPEND; - - if (mode & OpenMode_Truncate) - flags |= O_TRUNC; - } else return false; + + if (mode & OpenMode_Append) + flags |= O_APPEND; + + if (mode & OpenMode_Truncate) + flags |= O_TRUNC; ///TODO: lock // if ((mode & OpenMode_Lock) == 0)