From 62ba4f172b450807ffd86185fe0b8775a951d8e6 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Thu, 16 Jun 2022 18:19:48 +0200 Subject: [PATCH] Graphics/GraphicalMesh: Allow to update submeshes --- examples/DeferredShading/main.cpp | 14 +++++------ examples/GraphicsTest/main.cpp | 2 +- examples/PhysicsDemo/main.cpp | 4 ++-- include/Nazara/Graphics/GraphicalMesh.hpp | 29 ++++++++++++++++------- include/Nazara/Graphics/GraphicalMesh.inl | 27 ++++++++++++++++++++- include/Nazara/Graphics/Model.hpp | 4 +++- src/Nazara/Graphics/GraphicalMesh.cpp | 13 ++++++---- src/Nazara/Graphics/Model.cpp | 5 ++++ 8 files changed, 73 insertions(+), 25 deletions(-) diff --git a/examples/DeferredShading/main.cpp b/examples/DeferredShading/main.cpp index 04c3d9c3e..5b142ea5a 100644 --- a/examples/DeferredShading/main.cpp +++ b/examples/DeferredShading/main.cpp @@ -109,7 +109,7 @@ int main() return __LINE__; } - std::shared_ptr gfxMesh = std::make_shared(*spaceship); + std::shared_ptr gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*spaceship); Nz::TextureParams texParams; texParams.renderDevice = device; @@ -125,7 +125,7 @@ int main() //planeMesh->BuildSubMesh(Nz::Primitive::Cone(1.f, 1.f, 16, Nz::Matrix4f::Rotate(Nz::EulerAnglesf(90.f, 0.f, 0.f))), planeParams); planeMesh->SetMaterialCount(1); - std::shared_ptr planeMeshGfx = std::make_shared(*planeMesh); + std::shared_ptr planeMeshGfx = Nz::GraphicalMesh::BuildFromMesh(*planeMesh); // Skybox meshPrimitiveParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ); @@ -135,7 +135,7 @@ int main() cubeMesh->BuildSubMesh(Nz::Primitive::Box(Nz::Vector3f::Unit(), Nz::Vector3ui(0), Nz::Matrix4f::Scale({ 1.f, -1.f, 1.f })), meshPrimitiveParams); cubeMesh->SetMaterialCount(1); - std::shared_ptr cubeMeshGfx = std::make_shared(*cubeMesh); + std::shared_ptr cubeMeshGfx = Nz::GraphicalMesh::BuildFromMesh(*cubeMesh); Nz::RenderPipelineLayoutInfo skyboxPipelineLayoutInfo; skyboxPipelineLayoutInfo.bindings.push_back({ @@ -187,7 +187,7 @@ int main() coneMesh->BuildSubMesh(Nz::Primitive::Cone(1.f, 1.f, 16, Nz::Matrix4f::Rotate(Nz::EulerAnglesf(90.f, 0.f, 0.f))), meshPrimitiveParams); coneMesh->SetMaterialCount(1); - std::shared_ptr coneMeshGfx = std::make_shared(*coneMesh); + std::shared_ptr coneMeshGfx = Nz::GraphicalMesh::BuildFromMesh(*coneMesh); auto customSettings = Nz::BasicMaterial::GetSettings()->GetBuilderData(); customSettings.shaders.clear(); @@ -572,8 +572,6 @@ int main() std::shared_ptr godRaysBlitShaderBinding; - const std::shared_ptr& lightingVertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_UV); - std::shared_ptr fullscreenPipeline = device->InstantiateRenderPipeline(fullscreenPipelineInfo); Nz::RenderPipelineInfo lightingPipelineInfo; @@ -1201,8 +1199,8 @@ int main() case Nz::WindowEventType::Resized: { - Nz::Vector2ui windowSize = window.GetSize(); - viewerInstance.UpdateProjectionMatrix(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f)); + Nz::Vector2ui newSize = window.GetSize(); + viewerInstance.UpdateProjectionMatrix(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(newSize.x) / newSize.y, 0.1f, 1000.f)); break; } diff --git a/examples/GraphicsTest/main.cpp b/examples/GraphicsTest/main.cpp index e6bd76849..da4e02c1d 100644 --- a/examples/GraphicsTest/main.cpp +++ b/examples/GraphicsTest/main.cpp @@ -46,7 +46,7 @@ int main() return __LINE__; } - std::shared_ptr gfxMesh = std::make_shared(*spaceshipMesh); + std::shared_ptr gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*spaceshipMesh); // Texture std::shared_ptr diffuseImage = Nz::Image::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png"); diff --git a/examples/PhysicsDemo/main.cpp b/examples/PhysicsDemo/main.cpp index cf85bcf05..06199aa5e 100644 --- a/examples/PhysicsDemo/main.cpp +++ b/examples/PhysicsDemo/main.cpp @@ -61,7 +61,7 @@ int main() } const Nz::Boxf& spaceshipAABB = spaceshipMesh->GetAABB(); - std::shared_ptr gfxMesh = std::make_shared(*spaceshipMesh); + std::shared_ptr gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*spaceshipMesh); // Texture std::shared_ptr material = std::make_shared(); @@ -151,7 +151,7 @@ int main() std::shared_ptr colliderModel; { std::shared_ptr colliderMesh = Nz::Mesh::Build(shipCollider->GenerateMesh()); - std::shared_ptr colliderGraphicalMesh = std::make_shared(*colliderMesh); + std::shared_ptr colliderGraphicalMesh = Nz::GraphicalMesh::BuildFromMesh(*colliderMesh); colliderModel = std::make_shared(colliderGraphicalMesh, spaceshipAABB); for (std::size_t i = 0; i < colliderModel->GetSubMeshCount(); ++i) diff --git a/include/Nazara/Graphics/GraphicalMesh.hpp b/include/Nazara/Graphics/GraphicalMesh.hpp index 122c5e415..8b16d745b 100644 --- a/include/Nazara/Graphics/GraphicalMesh.hpp +++ b/include/Nazara/Graphics/GraphicalMesh.hpp @@ -8,6 +8,7 @@ #define NAZARA_GRAPHICS_GRAPHICALMESH_HPP #include +#include #include #include #include @@ -19,32 +20,44 @@ namespace Nz class NAZARA_GRAPHICS_API GraphicalMesh { public: - GraphicalMesh(const Mesh& mesh); + struct SubMesh; + + GraphicalMesh() = default; GraphicalMesh(const GraphicalMesh&) = delete; GraphicalMesh(GraphicalMesh&&) noexcept = default; ~GraphicalMesh() = default; + inline std::size_t AddSubMesh(SubMesh subMesh); + + inline void Clear(); + inline const std::shared_ptr& GetIndexBuffer(std::size_t subMesh) const; - inline std::size_t GetIndexCount(std::size_t subMesh) const; + inline UInt32 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; - GraphicalMesh& operator=(const GraphicalMesh&) = delete; - GraphicalMesh& operator=(GraphicalMesh&&) noexcept = default; + inline void UpdateSubMeshIndexCount(std::size_t subMeshIndex, UInt32 indexCount); - private: - struct GraphicalSubMesh + GraphicalMesh& operator=(const GraphicalMesh&) = delete; + GraphicalMesh& operator=(GraphicalMesh&&) = delete; + + struct SubMesh { std::shared_ptr indexBuffer; std::shared_ptr vertexBuffer; - std::size_t indexCount; std::shared_ptr vertexDeclaration; IndexType indexType; + UInt32 indexCount; }; - std::vector m_subMeshes; + static std::shared_ptr BuildFromMesh(const Mesh& mesh); + + NazaraSignal(OnInvalidated, GraphicalMesh* /*gfxMesh*/); + + private: + std::vector m_subMeshes; }; } diff --git a/include/Nazara/Graphics/GraphicalMesh.inl b/include/Nazara/Graphics/GraphicalMesh.inl index 695f7ce74..042072c83 100644 --- a/include/Nazara/Graphics/GraphicalMesh.inl +++ b/include/Nazara/Graphics/GraphicalMesh.inl @@ -8,13 +8,30 @@ namespace Nz { + inline std::size_t GraphicalMesh::AddSubMesh(SubMesh subMesh) + { + std::size_t subMeshIndex = m_subMeshes.size(); + m_subMeshes.emplace_back(std::move(subMesh)); + + OnInvalidated(this); + + return subMeshIndex; + } + + inline void GraphicalMesh::Clear() + { + m_subMeshes.clear(); + + OnInvalidated(this); + } + inline const std::shared_ptr& GraphicalMesh::GetIndexBuffer(std::size_t subMesh) const { assert(subMesh < m_subMeshes.size()); return m_subMeshes[subMesh].indexBuffer; } - inline std::size_t GraphicalMesh::GetIndexCount(std::size_t subMesh) const + inline UInt32 GraphicalMesh::GetIndexCount(std::size_t subMesh) const { assert(subMesh < m_subMeshes.size()); return m_subMeshes[subMesh].indexCount; @@ -42,6 +59,14 @@ namespace Nz { return m_subMeshes.size(); } + + inline void GraphicalMesh::UpdateSubMeshIndexCount(std::size_t subMeshIndex, UInt32 indexCount) + { + NazaraAssert(subMeshIndex < m_subMeshes.size(), "invalid submesh index"); + m_subMeshes[subMeshIndex].indexCount = indexCount; + + OnInvalidated(this); + } } #include diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index b35f6f5c2..c10884b17 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -17,7 +18,6 @@ namespace Nz { - class GraphicalMesh; class Material; class NAZARA_GRAPHICS_API Model : public InstancedRenderable @@ -50,6 +50,8 @@ namespace Nz std::vector vertexBufferData; }; + NazaraSlot(GraphicalMesh, OnInvalidated, m_onInvalidated); + std::shared_ptr m_graphicalMesh; std::vector m_submeshes; Recti m_scissorBox; diff --git a/src/Nazara/Graphics/GraphicalMesh.cpp b/src/Nazara/Graphics/GraphicalMesh.cpp index 364de6350..3dc57bec9 100644 --- a/src/Nazara/Graphics/GraphicalMesh.cpp +++ b/src/Nazara/Graphics/GraphicalMesh.cpp @@ -11,16 +11,17 @@ namespace Nz { - GraphicalMesh::GraphicalMesh(const Mesh& mesh) + std::shared_ptr GraphicalMesh::BuildFromMesh(const Mesh& mesh) { assert(mesh.GetAnimationType() == AnimationType::Static); const std::shared_ptr& renderDevice = Graphics::Instance()->GetRenderDevice(); - m_subMeshes.reserve(mesh.GetSubMeshCount()); + std::shared_ptr gfxMesh = std::make_shared(); + for (std::size_t i = 0; i < mesh.GetSubMeshCount(); ++i) { - const SubMesh& subMesh = *mesh.GetSubMesh(i); + const Nz::SubMesh& subMesh = *mesh.GetSubMesh(i); const StaticMesh& staticMesh = static_cast(subMesh); @@ -33,7 +34,7 @@ namespace Nz assert(vertexBuffer->GetBuffer()->GetStorage() == DataStorage::Software); const SoftwareBuffer* vertexBufferContent = static_cast(vertexBuffer->GetBuffer().get()); - auto& submeshData = m_subMeshes.emplace_back(); + GraphicalMesh::SubMesh submeshData; submeshData.indexBuffer = renderDevice->InstantiateBuffer(BufferType::Index, indexBuffer->GetStride() * indexBuffer->GetIndexCount(), BufferUsage::DeviceLocal | BufferUsage::Write); if (!submeshData.indexBuffer->Fill(indexBufferContent->GetData() + indexBuffer->GetStartOffset(), 0, indexBuffer->GetEndOffset() - indexBuffer->GetStartOffset())) throw std::runtime_error("failed to fill index buffer"); @@ -46,6 +47,10 @@ namespace Nz throw std::runtime_error("failed to fill vertex buffer"); submeshData.vertexDeclaration = vertexBuffer->GetVertexDeclaration(); + + gfxMesh->AddSubMesh(std::move(submeshData)); } + + return gfxMesh; } } diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 5791c076a..081b63f24 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -29,6 +29,11 @@ namespace Nz }; } + m_onInvalidated.Connect(m_graphicalMesh->OnInvalidated, [this](GraphicalMesh*) + { + OnElementInvalidated(this); + }); + UpdateAABB(aabb); }