From abf1b729904d8f2f6741f382219c4bfe45cf1821 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Wed, 24 Jul 2024 10:47:52 +0300 Subject: [PATCH] extend geometry API --- openVulkanoCpp/Scene/Geometry.cpp | 112 +++++++++++++++++- openVulkanoCpp/Scene/Geometry.hpp | 44 ++++--- .../Vulkan/Resources/ResourceManager.cpp | 4 + 3 files changed, 137 insertions(+), 23 deletions(-) diff --git a/openVulkanoCpp/Scene/Geometry.cpp b/openVulkanoCpp/Scene/Geometry.cpp index 8cfd270..c2b28db 100644 --- a/openVulkanoCpp/Scene/Geometry.cpp +++ b/openVulkanoCpp/Scene/Geometry.cpp @@ -19,6 +19,102 @@ namespace OpenVulkano::Scene { + Geometry::Geometry(const Geometry& other) + { + this->vertexCount = other.vertexCount; + this->indexCount = other.indexCount; + this->indexType = other.indexType; + this->aabb = other.aabb; + this->ownsMemory = other.ownsMemory; + this->freeAfterUpload = other.freeAfterUpload; + this->renderGeo = nullptr; + this->vertices = new Vertex[vertexCount]; + if (other.vertices) + { + std::copy(other.vertices, other.vertices + other.vertexCount, this->vertices); + } + this->indices = malloc(static_cast(Utils::EnumAsInt(other.indexType)) * other.indexCount); + if (other.indices) + { + if (other.indexType == VertexIndexType::UINT16) + { + std::copy(static_cast(other.indices), + static_cast(other.indices) + other.indexCount, + static_cast(this->indices)); + } + else + { + std::copy(static_cast(other.indices), + static_cast(other.indices) + other.indexCount, + static_cast(this->indices)); + } + } + } + + Geometry& Geometry::operator=(const Geometry& other) + { + Geometry tmp(other); + this->Swap(tmp); + return *this; + } + + Geometry::Geometry(Geometry&& other) noexcept + { + this->vertexCount = other.vertexCount; + this->indexCount = other.indexCount; + this->indexType = other.indexType; + this->ownsMemory = other.ownsMemory; + this->freeAfterUpload = other.freeAfterUpload; + this->aabb = std::move(other.aabb); + this->vertices = other.vertices; + this->indices = other.indices; + this->renderGeo = other.renderGeo; + other.vertexCount = other.indexCount = 0; + other.vertices = nullptr; + other.indices = nullptr; + other.renderGeo = nullptr; + } + + Geometry& Geometry::operator=(Geometry&& other) noexcept + { + if (this != &other) + { + Close(); + this->vertexCount = other.vertexCount; + this->indexCount = other.indexCount; + this->indexType = other.indexType; + this->ownsMemory = other.ownsMemory; + this->freeAfterUpload = other.freeAfterUpload; + this->aabb = std::move(other.aabb); + this->vertices = other.vertices; + this->indices = other.indices; + this->renderGeo = other.renderGeo; + other.vertexCount = other.indexCount = 0; + other.vertices = nullptr; + other.indices = nullptr; + other.renderGeo = nullptr; + } + return *this; + } + + Geometry::~Geometry() + { + Geometry::Close(); + } + + void Geometry::Swap(Geometry& other) noexcept + { + std::swap(this->vertexCount, other.vertexCount); + std::swap(this->indexCount, other.indexCount); + std::swap(this->aabb, other.aabb); + std::swap(this->indexType, other.indexType); + std::swap(this->vertices, other.vertices); + std::swap(this->indices, other.indices); + std::swap(this->renderGeo, other.renderGeo); + std::swap(this->ownsMemory, other.ownsMemory); + std::swap(this->freeAfterUpload, other.freeAfterUpload); + } + void Geometry::Init(uint32_t vertexCount, uint32_t indexCount) { if (this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized."); @@ -110,11 +206,17 @@ namespace OpenVulkano::Scene void Geometry::Close() { - vertexCount = 0; - indexCount = 0; - Free(); - renderGeo->Close(); - renderGeo = nullptr; + if (ownsMemory) + { + vertexCount = 0; + indexCount = 0; + Free(); + } + if (renderGeo) + { + renderGeo->Close(); + renderGeo = nullptr; + } } void Geometry::Free() diff --git a/openVulkanoCpp/Scene/Geometry.hpp b/openVulkanoCpp/Scene/Geometry.hpp index 40880ae..c38b9cb 100644 --- a/openVulkanoCpp/Scene/Geometry.hpp +++ b/openVulkanoCpp/Scene/Geometry.hpp @@ -8,6 +8,7 @@ #include "Base/ICloseable.hpp" #include "Math/AABB.hpp" +#include "Base/Utils.hpp" #include class aiMesh; @@ -27,18 +28,19 @@ namespace OpenVulkano { public: uint32_t vertexCount = 0, indexCount = 0; - Vertex* vertices; - void* indices; - VertexIndexType indexType; + Vertex* vertices = nullptr; + void* indices = nullptr; + VertexIndexType indexType = VertexIndexType::UINT16; + bool ownsMemory = true, freeAfterUpload = true; Math::AABB aabb; ICloseable* renderGeo = nullptr; - - Vertex* GetVertices() const { return vertices; } - void* GetIndices() const { return indices; } - uint16_t* GetIndices16() const { return static_cast(indices); } - uint32_t* GetIndices32() const { return static_cast(indices); } - uint32_t GetIndexCount() const { return indexCount; } - uint32_t GetVertexCount() const { return vertexCount; } + public: + Geometry() = default; + Geometry(const Geometry& other); + Geometry& operator=(const Geometry& other); + Geometry(Geometry&& other) noexcept; + Geometry& operator=(Geometry&& other) noexcept; + ~Geometry(); static Geometry* LoadFromFile(const std::string& file) { @@ -47,13 +49,6 @@ namespace OpenVulkano return mesh; } - Geometry() : vertexCount(0), indexCount(0), vertices(nullptr), indices(nullptr), indexType(VertexIndexType::UINT16) {} - - ~Geometry() - { - if (vertices) Geometry::Close(); - } - void InitFromFile(const std::string& file); /** @@ -68,8 +63,21 @@ namespace OpenVulkano void SetIndices(const uint32_t* data, uint32_t size, uint32_t offset = 0) const; void Close() override; - + void Free(); + + Vertex* GetVertices() const { return vertices; } + void* GetIndices() const { return indices; } + uint16_t* GetIndices16() const { return static_cast(indices); } + uint32_t* GetIndices32() const { return static_cast(indices); } + uint32_t GetIndexCount() const { return indexCount; } + uint32_t GetVertexCount() const { return vertexCount; } + bool OwnsMemory() const { return ownsMemory; } + void SetOwnsMemory(bool val) { ownsMemory = val; } + bool FreeAfterUpload() const { return freeAfterUpload; } + void SetFreeAfterUpload(bool val) { freeAfterUpload = val; } + private: + void Swap(Geometry& other) noexcept; }; } } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index c49030a..f3cf95f 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -157,6 +157,10 @@ namespace OpenVulkano::Vulkan VulkanGeometry* vkGeo = new VulkanGeometry(geometry, vertexBuffer, indexBuffer); geometries.emplace_back(vkGeo); geometry->renderGeo = vkGeo; + if (geometry->ownsMemory && geometry->freeAfterUpload) + { + geometry->Free(); + } return vkGeo; } return dynamic_cast(geometry->renderGeo);