From 9d526741b9537c011a2c9db8c41d6b45ed9b1e78 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Mon, 4 Apr 2022 09:02:00 +0200 Subject: [PATCH] Add proper support for IndexType and uint32 indices --- examples/DeferredShading/main.cpp | 4 +- examples/RenderTest/main.cpp | 2 +- include/Nazara/Graphics/GraphicalMesh.hpp | 2 + include/Nazara/Graphics/GraphicalMesh.inl | 6 +++ include/Nazara/Graphics/RenderSubmesh.hpp | 4 +- include/Nazara/Graphics/RenderSubmesh.inl | 8 +++- include/Nazara/Graphics/SubmeshRenderer.hpp | 1 + .../OpenGLRenderer/OpenGLCommandBuffer.hpp | 3 +- .../OpenGLRenderer/OpenGLCommandBuffer.inl | 3 +- .../OpenGLCommandBufferBuilder.hpp | 2 +- include/Nazara/OpenGLRenderer/Utils.hpp | 1 + include/Nazara/OpenGLRenderer/Utils.inl | 13 ++++++ .../Nazara/Renderer/CommandBufferBuilder.hpp | 2 +- include/Nazara/Utility/Enums.hpp | 9 ++++ include/Nazara/Utility/IndexBuffer.hpp | 11 +++-- include/Nazara/Utility/IndexBuffer.inl | 25 ++++++++--- include/Nazara/VulkanRenderer/Utils.hpp | 1 + include/Nazara/VulkanRenderer/Utils.inl | 13 ++++++ .../VulkanCommandBufferBuilder.hpp | 2 +- plugins/Assimp/Plugin.cpp | 4 +- src/Nazara/Graphics/GraphicalMesh.cpp | 1 + src/Nazara/Graphics/Model.cpp | 5 ++- src/Nazara/Graphics/SpriteChainRenderer.cpp | 2 +- src/Nazara/Graphics/SubmeshRenderer.cpp | 3 +- .../OpenGLRenderer/OpenGLCommandBuffer.cpp | 10 ++++- .../OpenGLCommandBufferBuilder.cpp | 4 +- src/Nazara/Physics3D/Collider3D.cpp | 2 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 2 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 6 +-- src/Nazara/Utility/Formats/OBJLoader.cpp | 4 +- src/Nazara/Utility/IndexBuffer.cpp | 20 ++++----- src/Nazara/Utility/IndexMapper.cpp | 42 +++++++++++++++++-- src/Nazara/Utility/Mesh.cpp | 24 ++++++++--- .../VulkanCommandBufferBuilder.cpp | 4 +- 34 files changed, 188 insertions(+), 57 deletions(-) diff --git a/examples/DeferredShading/main.cpp b/examples/DeferredShading/main.cpp index 8598e76a4..b5beeb096 100644 --- a/examples/DeferredShading/main.cpp +++ b/examples/DeferredShading/main.cpp @@ -875,7 +875,7 @@ int main() builder.SetViewport(env.renderRect); //builder.BindVertexBuffer(0, vertexBuffer.get()); - builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get()); + builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get(), Nz::IndexType::U16); builder.BindVertexBuffer(0, *coneMeshGfx->GetVertexBuffer(0).get()); builder.BindShaderBinding(0, *gbufferShaderBinding); @@ -907,7 +907,7 @@ int main() builder.BindShaderBinding(0, *skyboxShaderBinding); - builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0)); + builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0), Nz::IndexType::U16); builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0)); builder.BindPipeline(*skyboxPipeline); diff --git a/examples/RenderTest/main.cpp b/examples/RenderTest/main.cpp index e7705b8de..8651af0c6 100644 --- a/examples/RenderTest/main.cpp +++ b/examples/RenderTest/main.cpp @@ -404,7 +404,7 @@ int main() { builder.BeginRenderPass(windowRT->GetFramebuffer(frame.GetFramebufferIndex()), windowRT->GetRenderPass(), renderRect, { clearValues[0], clearValues[1] }); { - builder.BindIndexBuffer(renderBufferIB); + builder.BindIndexBuffer(renderBufferIB, Nz::IndexType::U16); builder.BindPipeline(*pipeline); builder.BindVertexBuffer(0, renderBufferVB); builder.BindShaderBinding(0, *viewerShaderBinding); diff --git a/include/Nazara/Graphics/GraphicalMesh.hpp b/include/Nazara/Graphics/GraphicalMesh.hpp index 7fa8d338d..122c5e415 100644 --- a/include/Nazara/Graphics/GraphicalMesh.hpp +++ b/include/Nazara/Graphics/GraphicalMesh.hpp @@ -26,6 +26,7 @@ namespace Nz inline const std::shared_ptr& GetIndexBuffer(std::size_t subMesh) const; inline std::size_t GetIndexCount(std::size_t subMesh) const; + inline IndexType GetIndexType(std::size_t subMesh) const; inline const std::shared_ptr& GetVertexBuffer(std::size_t subMesh) const; inline const std::shared_ptr& GetVertexDeclaration(std::size_t subMesh) const; inline std::size_t GetSubMeshCount() const; @@ -40,6 +41,7 @@ namespace Nz std::shared_ptr vertexBuffer; std::size_t indexCount; std::shared_ptr vertexDeclaration; + IndexType indexType; }; std::vector m_subMeshes; diff --git a/include/Nazara/Graphics/GraphicalMesh.inl b/include/Nazara/Graphics/GraphicalMesh.inl index b93786dcf..695f7ce74 100644 --- a/include/Nazara/Graphics/GraphicalMesh.inl +++ b/include/Nazara/Graphics/GraphicalMesh.inl @@ -20,6 +20,12 @@ namespace Nz return m_subMeshes[subMesh].indexCount; } + inline IndexType GraphicalMesh::GetIndexType(std::size_t subMesh) const + { + assert(subMesh < m_subMeshes.size()); + return m_subMeshes[subMesh].indexType; + } + inline const std::shared_ptr& GraphicalMesh::GetVertexBuffer(std::size_t subMesh) const { assert(subMesh < m_subMeshes.size()); diff --git a/include/Nazara/Graphics/RenderSubmesh.hpp b/include/Nazara/Graphics/RenderSubmesh.hpp index 00d80f1bc..677793e27 100644 --- a/include/Nazara/Graphics/RenderSubmesh.hpp +++ b/include/Nazara/Graphics/RenderSubmesh.hpp @@ -23,13 +23,14 @@ namespace Nz class RenderSubmesh : public RenderElement { public: - inline RenderSubmesh(int renderLayer, std::shared_ptr materialPass, std::shared_ptr renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr indexBuffer, std::shared_ptr vertexBuffer, const Recti& scissorBox); + inline RenderSubmesh(int renderLayer, std::shared_ptr materialPass, std::shared_ptr renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr indexBuffer, std::shared_ptr vertexBuffer, const Recti& scissorBox); ~RenderSubmesh() = default; inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override; inline const RenderBuffer* GetIndexBuffer() const; inline std::size_t GetIndexCount() const; + inline IndexType GetIndexType() const; inline const MaterialPass& GetMaterialPass() const; inline const RenderPipeline* GetRenderPipeline() const; inline const Recti& GetScissorBox() const; @@ -45,6 +46,7 @@ namespace Nz std::shared_ptr m_renderPipeline; std::size_t m_indexCount; const WorldInstance& m_worldInstance; + IndexType m_indexType; Recti m_scissorBox; int m_renderLayer; }; diff --git a/include/Nazara/Graphics/RenderSubmesh.inl b/include/Nazara/Graphics/RenderSubmesh.inl index 6e7d6295d..b2afc5117 100644 --- a/include/Nazara/Graphics/RenderSubmesh.inl +++ b/include/Nazara/Graphics/RenderSubmesh.inl @@ -9,7 +9,7 @@ namespace Nz { - inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr materialPass, std::shared_ptr renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, std::shared_ptr indexBuffer, std::shared_ptr vertexBuffer, const Recti& scissorBox) : + inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr materialPass, std::shared_ptr renderPipeline, const WorldInstance& worldInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr indexBuffer, std::shared_ptr vertexBuffer, const Recti& scissorBox) : RenderElement(BasicRenderElement::Submesh), m_indexBuffer(std::move(indexBuffer)), m_vertexBuffer(std::move(vertexBuffer)), @@ -17,6 +17,7 @@ namespace Nz m_renderPipeline(std::move(renderPipeline)), m_indexCount(indexCount), m_worldInstance(worldInstance), + m_indexType(indexType), m_scissorBox(scissorBox), m_renderLayer(renderLayer) { @@ -80,6 +81,11 @@ namespace Nz return m_indexCount; } + inline IndexType RenderSubmesh::GetIndexType() const + { + return m_indexType; + } + inline const MaterialPass& RenderSubmesh::GetMaterialPass() const { return *m_materialPass; diff --git a/include/Nazara/Graphics/SubmeshRenderer.hpp b/include/Nazara/Graphics/SubmeshRenderer.hpp index 6fa71df76..f537cb283 100644 --- a/include/Nazara/Graphics/SubmeshRenderer.hpp +++ b/include/Nazara/Graphics/SubmeshRenderer.hpp @@ -43,6 +43,7 @@ namespace Nz const ShaderBinding* shaderBinding; std::size_t firstIndex; std::size_t indexCount; + IndexType indexType; Recti scissorBox; }; diff --git a/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp b/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp index a4cee563b..ed923ec49 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp @@ -37,7 +37,7 @@ namespace Nz inline void BeginDebugRegion(const std::string_view& regionName, const Color& color); - inline void BindIndexBuffer(GLuint indexBuffer, UInt64 offset = 0); + inline void BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset = 0); inline void BindPipeline(const OpenGLRenderPipeline* pipeline); inline void BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding); inline void BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset = 0); @@ -122,6 +122,7 @@ namespace Nz GLuint indexBuffer = 0; const OpenGLRenderPipeline* pipeline = nullptr; UInt64 indexBufferOffset; + IndexType indexBufferType; std::optional scissorRegion; std::optional viewportRegion; std::vector> shaderBindings; diff --git a/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.inl b/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.inl index 038cfb2b2..b8aeec962 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.inl +++ b/include/Nazara/OpenGLRenderer/OpenGLCommandBuffer.inl @@ -33,10 +33,11 @@ namespace Nz m_commands.emplace_back(std::move(beginDebugRegion)); } - inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, UInt64 offset) + inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset) { m_currentStates.indexBuffer = indexBuffer; m_currentStates.indexBufferOffset = offset; + m_currentStates.indexBufferType = indexType; } inline void OpenGLCommandBuffer::BindPipeline(const OpenGLRenderPipeline* pipeline) diff --git a/include/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp b/include/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp index 2ed4b7e8c..9df5e0da2 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp @@ -26,7 +26,7 @@ namespace Nz void BeginDebugRegion(const std::string_view& regionName, const Color& color) override; void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, const ClearValues* clearValues, std::size_t clearValueCount) override; - void BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset = 0) override; + void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override; void BindPipeline(const RenderPipeline& pipeline) override; void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override; void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override; diff --git a/include/Nazara/OpenGLRenderer/Utils.hpp b/include/Nazara/OpenGLRenderer/Utils.hpp index ec4503689..a73bed0e5 100644 --- a/include/Nazara/OpenGLRenderer/Utils.hpp +++ b/include/Nazara/OpenGLRenderer/Utils.hpp @@ -34,6 +34,7 @@ namespace Nz inline GLenum ToOpenGL(FaceFilling filling); inline GLenum ToOpenGL(FaceSide side); inline GLenum ToOpenGL(FrontFace face); + inline GLenum ToOpenGL(IndexType indexType); inline GLenum ToOpenGL(PrimitiveMode primitiveMode); inline GLenum ToOpenGL(SamplerFilter filter); inline GLenum ToOpenGL(SamplerFilter minFilter, SamplerMipmapMode mipmapFilter); diff --git a/include/Nazara/OpenGLRenderer/Utils.inl b/include/Nazara/OpenGLRenderer/Utils.inl index 07983abe7..178064730 100644 --- a/include/Nazara/OpenGLRenderer/Utils.inl +++ b/include/Nazara/OpenGLRenderer/Utils.inl @@ -120,6 +120,19 @@ namespace Nz return {}; } + inline GLenum ToOpenGL(IndexType indexType) + { + switch (indexType) + { + case IndexType::U8: return GL_UNSIGNED_BYTE; + case IndexType::U16: return GL_UNSIGNED_SHORT; + case IndexType::U32: return GL_UNSIGNED_INT; + } + + NazaraError("Unhandled IndexType 0x" + NumberToString(UnderlyingCast(indexType), 16)); + return {}; + } + inline GLenum ToOpenGL(PrimitiveMode primitiveMode) { switch (primitiveMode) diff --git a/include/Nazara/Renderer/CommandBufferBuilder.hpp b/include/Nazara/Renderer/CommandBufferBuilder.hpp index 480255f76..5a9fb2af2 100644 --- a/include/Nazara/Renderer/CommandBufferBuilder.hpp +++ b/include/Nazara/Renderer/CommandBufferBuilder.hpp @@ -42,7 +42,7 @@ namespace Nz inline void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect); inline void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, std::initializer_list clearValues); - virtual void BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset = 0) = 0; + virtual void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) = 0; virtual void BindPipeline(const RenderPipeline& pipeline) = 0; virtual void BindShaderBinding(UInt32 set, const ShaderBinding& binding) = 0; virtual void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) = 0; diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 3a5788e4f..fbfffd4c4 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -180,6 +180,15 @@ namespace Nz constexpr std::size_t ImageTypeCount = static_cast(ImageType::Max) + 1; + enum class IndexType + { + U8, + U16, + U32, + + Max = U32 + }; + enum class NodeType { Default, // Node diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 390c5b9ed..0715a34d7 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -16,9 +16,9 @@ namespace Nz { public: IndexBuffer() = default; - IndexBuffer(bool largeIndices, std::shared_ptr buffer); - IndexBuffer(bool largeIndices, std::shared_ptr buffer, UInt64 offset, UInt64 size); - IndexBuffer(bool largeIndices, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData = nullptr); + IndexBuffer(IndexType indexType, std::shared_ptr buffer); + IndexBuffer(IndexType indexType, std::shared_ptr buffer, UInt64 offset, UInt64 size); + IndexBuffer(IndexType indexType, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData = nullptr); IndexBuffer(const IndexBuffer&) = default; IndexBuffer(IndexBuffer&&) noexcept = default; ~IndexBuffer() = default; @@ -31,11 +31,10 @@ namespace Nz inline const std::shared_ptr& GetBuffer() const; inline UInt64 GetEndOffset() const; inline UInt64 GetIndexCount() const; + inline IndexType GetIndexType() const; inline UInt64 GetStride() const; inline UInt64 GetStartOffset() const; - inline bool HasLargeIndices() const; - inline bool IsValid() const; inline void* Map(UInt64 startIndex, UInt64 length); @@ -52,10 +51,10 @@ namespace Nz private: std::shared_ptr m_buffer; + IndexType m_indexType; UInt32 m_indexCount; UInt64 m_endOffset; UInt64 m_startOffset; - bool m_largeIndices; }; } diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index b0ab5260b..0890418c3 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -23,9 +23,27 @@ namespace Nz return m_indexCount; } + inline IndexType IndexBuffer::GetIndexType() const + { + return m_indexType; + } + inline UInt64 IndexBuffer::GetStride() const { - return (m_largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + switch (m_indexType) + { + case IndexType::U8: + return sizeof(UInt8); + + case IndexType::U16: + return sizeof(UInt16); + + case IndexType::U32: + return sizeof(UInt32); + } + + NazaraError("invalid index size"); + return 0; } inline UInt64 IndexBuffer::GetStartOffset() const @@ -33,11 +51,6 @@ namespace Nz return m_startOffset; } - inline bool IndexBuffer::HasLargeIndices() const - { - return m_largeIndices; - } - inline bool IndexBuffer::IsValid() const { return m_buffer != nullptr; diff --git a/include/Nazara/VulkanRenderer/Utils.hpp b/include/Nazara/VulkanRenderer/Utils.hpp index 97ed0f38e..280b10c98 100644 --- a/include/Nazara/VulkanRenderer/Utils.hpp +++ b/include/Nazara/VulkanRenderer/Utils.hpp @@ -25,6 +25,7 @@ namespace Nz inline VkCullModeFlagBits ToVulkan(FaceSide faceSide); inline VkPolygonMode ToVulkan(FaceFilling faceFilling); inline VkFrontFace ToVulkan(FrontFace frontFace); + inline VkIndexType ToVulkan(IndexType indexType); inline VkAccessFlagBits ToVulkan(MemoryAccess memoryAccess); inline VkAccessFlags ToVulkan(MemoryAccessFlags memoryAccessFlags); inline VkPipelineStageFlagBits ToVulkan(PipelineStage pipelineStage); diff --git a/include/Nazara/VulkanRenderer/Utils.inl b/include/Nazara/VulkanRenderer/Utils.inl index ba698b072..16f045a41 100644 --- a/include/Nazara/VulkanRenderer/Utils.inl +++ b/include/Nazara/VulkanRenderer/Utils.inl @@ -169,6 +169,19 @@ namespace Nz return {}; } + inline VkIndexType ToVulkan(IndexType indexType) + { + switch (indexType) + { + case IndexType::U8: return VK_INDEX_TYPE_UINT8_EXT; + case IndexType::U16: return VK_INDEX_TYPE_UINT16; + case IndexType::U32: return VK_INDEX_TYPE_UINT32; + } + + NazaraError("Unhandled IndexType 0x" + NumberToString(UnderlyingCast(indexType), 16)); + return {}; + } + inline VkAccessFlagBits ToVulkan(MemoryAccess memoryAccess) { switch (memoryAccess) diff --git a/include/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp b/include/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp index f53f9363d..dd0feaab9 100644 --- a/include/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp +++ b/include/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp @@ -27,7 +27,7 @@ namespace Nz void BeginDebugRegion(const std::string_view& regionName, const Color& color) override; void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, const ClearValues* clearValues, std::size_t clearValueCount) override; - void BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset = 0) override; + void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override; void BindPipeline(const RenderPipeline& pipeline) override; void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override; void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override; diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index afbe12083..f880cece3 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -307,7 +307,7 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - std::shared_ptr indexBuffer = std::make_shared(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); + std::shared_ptr indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); IndexMapper indexMapper(*indexBuffer); IndexIterator index = indexMapper.begin(); @@ -465,7 +465,7 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - std::shared_ptr indexBuffer = std::make_shared(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); + std::shared_ptr indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); IndexMapper indexMapper(*indexBuffer); IndexIterator index = indexMapper.begin(); diff --git a/src/Nazara/Graphics/GraphicalMesh.cpp b/src/Nazara/Graphics/GraphicalMesh.cpp index 6c3d724c3..364de6350 100644 --- a/src/Nazara/Graphics/GraphicalMesh.cpp +++ b/src/Nazara/Graphics/GraphicalMesh.cpp @@ -39,6 +39,7 @@ namespace Nz throw std::runtime_error("failed to fill index buffer"); submeshData.indexCount = indexBuffer->GetIndexCount(); + submeshData.indexType = indexBuffer->GetIndexType(); submeshData.vertexBuffer = renderDevice->InstantiateBuffer(BufferType::Vertex, vertexBuffer->GetStride() * vertexBuffer->GetVertexCount(), BufferUsage::DeviceLocal | BufferUsage::Write); if (!submeshData.vertexBuffer->Fill(vertexBufferContent->GetData() + vertexBuffer->GetStartOffset(), 0, vertexBuffer->GetEndOffset() - vertexBuffer->GetStartOffset())) diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index fe2be425c..5791c076a 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -46,7 +46,10 @@ namespace Nz const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i); const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData); - elements.emplace_back(std::make_unique(GetRenderLayer(), materialPass, renderPipeline, worldInstance, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer, scissorBox)); + std::size_t indexCount = m_graphicalMesh->GetIndexCount(i); + IndexType indexType = m_graphicalMesh->GetIndexType(i); + + elements.emplace_back(std::make_unique(GetRenderLayer(), materialPass, renderPipeline, worldInstance, indexCount, indexType, indexBuffer, vertexBuffer, scissorBox)); } } diff --git a/src/Nazara/Graphics/SpriteChainRenderer.cpp b/src/Nazara/Graphics/SpriteChainRenderer.cpp index 60dba6ec4..f8a7ba619 100644 --- a/src/Nazara/Graphics/SpriteChainRenderer.cpp +++ b/src/Nazara/Graphics/SpriteChainRenderer.cpp @@ -275,7 +275,7 @@ namespace Nz { auto& data = static_cast(rendererData); - commandBuffer.BindIndexBuffer(*m_indexBuffer); + commandBuffer.BindIndexBuffer(*m_indexBuffer, Nz::IndexType::U16); Vector2f targetSize = viewerInstance.GetTargetSize(); Recti fullscreenScissorBox(0, 0, SafeCast(std::floor(targetSize.x)), SafeCast(std::floor(targetSize.y))); diff --git a/src/Nazara/Graphics/SubmeshRenderer.cpp b/src/Nazara/Graphics/SubmeshRenderer.cpp index 7882d2679..ed3a7143b 100644 --- a/src/Nazara/Graphics/SubmeshRenderer.cpp +++ b/src/Nazara/Graphics/SubmeshRenderer.cpp @@ -169,6 +169,7 @@ namespace Nz drawCall.firstIndex = 0; drawCall.indexBuffer = currentIndexBuffer; drawCall.indexCount = submesh.GetIndexCount(); + drawCall.indexType = submesh.GetIndexType(); drawCall.renderPipeline = currentPipeline; drawCall.scissorBox = currentScissorBox; drawCall.shaderBinding = currentShaderBinding; @@ -217,7 +218,7 @@ namespace Nz if (currentIndexBuffer != drawData.indexBuffer) { - commandBuffer.BindIndexBuffer(*drawData.indexBuffer); + commandBuffer.BindIndexBuffer(*drawData.indexBuffer, drawData.indexType); currentIndexBuffer = drawData.indexBuffer; } diff --git a/src/Nazara/OpenGLRenderer/OpenGLCommandBuffer.cpp b/src/Nazara/OpenGLRenderer/OpenGLCommandBuffer.cpp index ad9b165ae..4ba7c15f0 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLCommandBuffer.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLCommandBuffer.cpp @@ -105,9 +105,17 @@ namespace Nz else if constexpr (std::is_same_v) { const UInt8* origin = 0; //< For an easy way to cast an integer to a pointer + origin += command.states.indexBufferOffset; + + switch (command.states.indexBufferType) + { + case IndexType::U8: origin += command.firstIndex * sizeof(UInt8); break; + case IndexType::U16: origin += command.firstIndex * sizeof(UInt16); break; + case IndexType::U32: origin += command.firstIndex * sizeof(UInt32); break; + } ApplyStates(*context, command.states); - context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, GL_UNSIGNED_SHORT, origin + command.firstIndex * sizeof(UInt16), command.instanceCount); + context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, ToOpenGL(command.states.indexBufferType), origin, command.instanceCount); } else if constexpr (std::is_same_v) { diff --git a/src/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.cpp b/src/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.cpp index 71a79f7ca..27d7cd612 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.cpp @@ -25,11 +25,11 @@ namespace Nz m_commandBuffer.SetFramebuffer(static_cast(framebuffer), static_cast(renderPass), clearValues, clearValueCount); } - void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset) + void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset) { const OpenGLBuffer& glBuffer = static_cast(indexBuffer); - m_commandBuffer.BindIndexBuffer(glBuffer.GetBuffer().GetObjectId(), offset); + m_commandBuffer.BindIndexBuffer(glBuffer.GetBuffer().GetObjectId(), indexType, offset); } void OpenGLCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline) diff --git a/src/Nazara/Physics3D/Collider3D.cpp b/src/Nazara/Physics3D/Collider3D.cpp index 5b01784b5..3e2a68882 100644 --- a/src/Nazara/Physics3D/Collider3D.cpp +++ b/src/Nazara/Physics3D/Collider3D.cpp @@ -170,7 +170,7 @@ namespace Nz }); std::shared_ptr colliderVB = std::make_shared(VertexDeclaration::Get(VertexLayout::XYZ), colliderVertices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderVertices.data()); - std::shared_ptr colliderIB = std::make_shared(false, colliderIndices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderIndices.data()); + std::shared_ptr colliderIB = std::make_shared(IndexType::U16, colliderIndices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderIndices.data()); std::shared_ptr colliderSubMesh = std::make_shared(std::move(colliderVB), std::move(colliderIB)); colliderSubMesh->GenerateAABB(); diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index e799490fa..1bd7e27e8 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -108,7 +108,7 @@ namespace Nz } } - std::shared_ptr indexBuffer = std::make_shared(false, 3 * header.num_tris, parameters.indexBufferFlags, parameters.bufferFactory); + std::shared_ptr indexBuffer = std::make_shared(IndexType::U16, 3 * header.num_tris, parameters.indexBufferFlags, parameters.bufferFactory); // Extract triangles data std::vector triangles(header.num_tris); diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 15039a427..66f649f61 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -96,7 +96,7 @@ namespace Nz bool largeIndices = (vertexCount > std::numeric_limits::max()); - std::shared_ptr indexBuffer = std::make_shared(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); + std::shared_ptr indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); std::shared_ptr vertexBuffer = std::make_shared(VertexDeclaration::Get(VertexLayout::XYZ_Normal_UV_Tangent_Skinning), UInt32(vertexCount), parameters.vertexBufferFlags, parameters.bufferFactory); // Index buffer @@ -241,7 +241,7 @@ namespace Nz // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - std::shared_ptr indexBuffer = std::make_shared(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); + std::shared_ptr indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory); IndexMapper indexMapper(*indexBuffer); IndexIterator index = indexMapper.begin(); @@ -293,7 +293,7 @@ namespace Nz // Vertex colors (.md5mesh files have no vertex color) if (auto colorPtr = vertexMapper.GetComponentPtr(VertexComponent::Color)) { - for (std::size_t i = 0; i < md5Mesh.vertices.size(); ++i) + for (std::size_t j = 0; j < md5Mesh.vertices.size(); ++j) *colorPtr++ = Color::White; } diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 2c6b9086e..79f87de05 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -254,7 +254,9 @@ namespace Nz } // Création des buffers - std::shared_ptr indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indices.size(), parameters.indexBufferFlags, parameters.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + std::shared_ptr indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indices.size(), parameters.indexBufferFlags, parameters.bufferFactory); std::shared_ptr vertexBuffer = std::make_shared(parameters.vertexDeclaration, vertexCount, parameters.vertexBufferFlags, parameters.bufferFactory); // Remplissage des indices diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index cd83d0af9..f4b79f41f 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -13,11 +13,11 @@ namespace Nz { - IndexBuffer::IndexBuffer(bool largeIndices, std::shared_ptr buffer) : + IndexBuffer::IndexBuffer(IndexType indexType, std::shared_ptr buffer) : m_buffer(std::move(buffer)), + m_indexType(indexType), m_endOffset(m_buffer->GetSize()), - m_startOffset(0), - m_largeIndices(largeIndices) + m_startOffset(0) { NazaraAssert(m_buffer, "invalid buffer"); NazaraAssert(m_buffer->GetType() == BufferType::Index, "buffer must be an index buffer"); @@ -26,23 +26,23 @@ namespace Nz m_indexCount = m_endOffset / GetStride(); } - IndexBuffer::IndexBuffer(bool largeIndices, std::shared_ptr buffer, UInt64 offset, UInt64 size) : + IndexBuffer::IndexBuffer(IndexType indexType, std::shared_ptr buffer, UInt64 offset, UInt64 size) : m_buffer(std::move(buffer)), + m_indexType(indexType), m_endOffset(offset + size), - m_startOffset(offset), - m_largeIndices(largeIndices) + m_startOffset(offset) { NazaraAssert(m_buffer, "invalid buffer"); NazaraAssert(m_buffer->GetType() == BufferType::Index, "buffer must be an index buffer"); - NazaraAssert(size > 0, "invalid size"); + NazaraAssert(size > 0, "invalid buffer size"); m_indexCount = size / GetStride(); } - IndexBuffer::IndexBuffer(bool largeIndices, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData) : + IndexBuffer::IndexBuffer(IndexType indexType, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData) : + m_indexType(indexType), m_indexCount(indexCount), - m_startOffset(0), - m_largeIndices(largeIndices) + m_startOffset(0) { NazaraAssert(indexCount > 0, "invalid index count"); diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index c7c567b38..ec4354035 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -19,6 +19,12 @@ namespace Nz return static_cast(i); } + UInt32 Getter8(const void* buffer, std::size_t i) + { + const UInt8* ptr = static_cast(buffer); + return ptr[i]; + } + UInt32 Getter16(const void* buffer, std::size_t i) { const UInt16* ptr = static_cast(buffer); @@ -37,10 +43,16 @@ namespace Nz return 0; } + void Setter8(void* buffer, std::size_t i, UInt32 value) + { + UInt8* ptr = static_cast(buffer); + ptr[i] = SafeCast(value); + } + void Setter16(void* buffer, std::size_t i, UInt32 value) { UInt16* ptr = static_cast(buffer); - ptr[i] = static_cast(value); + ptr[i] = SafeCast(value); } void Setter32(void* buffer, std::size_t i, UInt32 value) @@ -63,13 +75,37 @@ namespace Nz if (!m_mapper.Map(indexBuffer, 0, m_indexCount)) NazaraError("Failed to map buffer"); ///TODO: Unexcepted + Getter rightGetter = nullptr; + Setter rightSetter = nullptr; + + switch (indexBuffer.GetIndexType()) + { + case IndexType::U8: + rightGetter = Getter8; + rightSetter = Setter8; + break; + + case IndexType::U16: + rightGetter = Getter16; + rightSetter = Setter16; + break; + + case IndexType::U32: + rightGetter = Getter32; + rightSetter = Setter32; + break; + } + + if (!rightGetter) + NazaraError("unexpected index size"); ///TODO: Unexcepted + if (indexBuffer.GetBuffer()->GetUsageFlags().Test(BufferUsage::Read)) - m_getter = (indexBuffer.HasLargeIndices()) ? Getter32 : Getter16; + m_getter = rightGetter; else m_getter = GetterError; if (indexBuffer.GetBuffer()->GetUsageFlags().Test(BufferUsage::Write)) - m_setter = (indexBuffer.HasLargeIndices()) ? Setter32 : Setter16; + m_setter = rightSetter; else m_setter = SetterError; } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index effec5af5..cec59e535 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -100,7 +100,9 @@ namespace Nz std::size_t vertexCount; ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); @@ -122,7 +124,9 @@ namespace Nz std::size_t vertexCount; ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); @@ -144,7 +148,9 @@ namespace Nz std::size_t vertexCount; ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); @@ -170,7 +176,9 @@ namespace Nz std::size_t vertexCount; ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); @@ -192,7 +200,9 @@ namespace Nz std::size_t vertexCount; ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); @@ -214,7 +224,9 @@ namespace Nz std::size_t vertexCount; ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount); - indexBuffer = std::make_shared(vertexCount > std::numeric_limits::max(), indexCount, params.indexBufferFlags, params.bufferFactory); + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + indexBuffer = std::make_shared((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory); vertexBuffer = std::make_shared(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory); VertexMapper vertexMapper(*vertexBuffer); diff --git a/src/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.cpp b/src/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.cpp index f917e745c..54bc5a52b 100644 --- a/src/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.cpp +++ b/src/Nazara/VulkanRenderer/VulkanCommandBufferBuilder.cpp @@ -72,11 +72,11 @@ namespace Nz m_currentSubpassIndex = 0; } - void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset) + void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset) { const VulkanBuffer& vkBuffer = static_cast(indexBuffer); - m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, VK_INDEX_TYPE_UINT16); //< Fuck me right? + m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, ToVulkan(indexType)); } void VulkanCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)