From 61fa1546a0632031020b3d6f5fcb1c0e2c477b68 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Fri, 3 Jan 2025 22:23:24 +0100 Subject: [PATCH 01/36] Use same shader instance for all labeldrawables --- .../Scene/Prefabs/LabelDrawable.cpp | 60 ++++++++++--------- .../Scene/Prefabs/LabelDrawable.hpp | 25 ++++---- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index e1ddfef..2a8c8a3 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -15,16 +15,42 @@ namespace OpenVulkano::Scene { using namespace Math; - LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, - bool isBillboard) - : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN) + namespace + { + Shader MakeLabelBgShader(bool billboard) + { + Shader backgroundShader; + if (!billboard) + { + backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/label"); + } + else + { + backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/labelBillboard"); + // binding for billboard's buffer + DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; + binding.stageFlags = ShaderProgramType::Type::VERTEX; + backgroundShader.AddDescriptorSetLayoutBinding(binding, 4); + } + backgroundShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/label"); + backgroundShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2); + backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 5); + backgroundShader.topology = Topology::TRIANGLE_STRIP; + backgroundShader.cullMode = CullMode::NONE; + return backgroundShader; + } + } + + Shader LabelDrawable::BACKGROUND_SHADER = MakeLabelBgShader(false); + Shader LabelDrawable::BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true); + + LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, bool isBillboard) + : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard) { if (atlasData->glyphs.empty() || !atlasData->texture.size) { throw std::runtime_error("Can't create label drawable. Either glyphs or texture is empty"); } - m_atlasData = atlasData; - m_isBillboard = isBillboard; SetLabelSettings(settings); SetupShaders(); SetupBuffers(); @@ -43,10 +69,7 @@ namespace OpenVulkano::Scene void LabelDrawable::AddText(const std::string& text, const TextConfig& config) { - if (text.empty()) - { - return; - } + if (text.empty()) return; TextDrawable& textDrawable = m_texts.emplace_back(m_atlasData, config); // do not render glyph's background @@ -104,24 +127,7 @@ namespace OpenVulkano::Scene void LabelDrawable::SetupShaders() { - if (!m_isBillboard) - { - m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/label"); - } - else - { - m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/labelBillboard"); - // binding for billboard's buffer - DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - binding.stageFlags = ShaderProgramType::Type::VERTEX; - m_backgroundShader.AddDescriptorSetLayoutBinding(binding, 4); - } - m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/label"); - m_backgroundShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2); - m_backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 5); - m_backgroundShader.topology = Topology::TRIANGLE_STRIP; - m_backgroundShader.cullMode = CullMode::NONE; - SetShader(&m_backgroundShader); + SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER); FontAtlasType fontAtlasType(static_cast(m_atlasData->meta.atlasType)); if (!m_isBillboard) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index ce29ae7..75f225f 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -46,6 +46,8 @@ namespace OpenVulkano::Scene class LabelDrawable final : public Drawable { + static Shader BACKGROUND_SHADER, BACKGROUND_BILLBOARD_SHADER; + public: LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings = LabelDrawableSettings(), bool isBillboard = false); @@ -53,25 +55,24 @@ namespace OpenVulkano::Scene void SetLabelSettings(const LabelDrawableSettings& settings); void SetBillboardSettings(const BillboardControlBlock& settings); void SetPosition(const Math::Vector3f& pos) { m_position = pos; } - std::list& GetTexts() { return m_texts; } - LabelDrawableSettings& GetSettings() { return m_settings; } - UniformBuffer* GetBillboardBuffer() { return &m_billboardBuffer; } - UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } - BillboardControlBlock& GetBillboardSettings() { return m_billboardSettings; } - Math::Vector3f& GetPosition() { return m_position; } - bool IsBillboard() const { return m_isBillboard; } - const Math::AABB& GetBoundingBox() const { return m_bbox; } + [[nodiscard]] std::list& GetTexts() { return m_texts; } + [[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; } + [[nodiscard]] UniformBuffer* GetBillboardBuffer() { return &m_billboardBuffer; } + [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } + [[nodiscard]] BillboardControlBlock& GetBillboardSettings() { return m_billboardSettings; } + [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } + [[nodiscard]] bool IsBillboard() const { return m_isBillboard; } + [[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; } std::optional Intersect(const Ray& ray) const override; + private: void RecalculateBbox(const Math::AABB& other); void SetupShaders(); void SetupBuffers(); - private: - Shader m_backgroundShader; + UniformBuffer m_billboardBuffer; UniformBuffer m_labelBuffer; - // list over vector to prevent memory reallocation and crash - std::list m_texts; + std::list m_texts; // Using list instead of vector for stable iterators Shader m_textShader; LabelDrawableSettings m_settings; LabelUniformData m_labelData; From 0e21159888cd763481cbdb40f7c8d88483a00cbc Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 00:53:08 +0100 Subject: [PATCH 02/36] Use AABB grow instead of custom function --- .../Scene/Prefabs/LabelDrawable.cpp | 19 +------------------ .../Scene/Prefabs/LabelDrawable.hpp | 1 - 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 2a8c8a3..76e1c72 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -78,7 +78,7 @@ namespace OpenVulkano::Scene double lineHeight = m_atlasData->meta.lineHeight; textDrawable.GenerateText(text, m_position); - RecalculateBbox(textDrawable.GetBoundingBox()); + m_bbox.Grow(textDrawable.GetBoundingBox()); // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; @@ -108,23 +108,6 @@ namespace OpenVulkano::Scene return ray.IntersectAABB(m_bbox); } - void LabelDrawable::RecalculateBbox(const Math::AABB& other) - { - if (m_bbox.IsEmpty()) - { - m_bbox = other; - } - else - { - auto& currentMin = m_bbox.GetMin(); - auto& currentMax = m_bbox.GetMax(); - currentMin.x = std::min(currentMin.x, other.min.x); - currentMin.y = std::min(currentMin.y, other.min.y); - currentMax.x = std::max(currentMax.x, other.max.x); - currentMax.y = std::max(currentMax.y, other.max.y); - } - } - void LabelDrawable::SetupShaders() { SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER); diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 75f225f..990e434 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -66,7 +66,6 @@ namespace OpenVulkano::Scene std::optional Intersect(const Ray& ray) const override; private: - void RecalculateBbox(const Math::AABB& other); void SetupShaders(); void SetupBuffers(); From d9763768e8a51b35d0f4bfb3046bd830047a0cca Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 00:53:17 +0100 Subject: [PATCH 03/36] Add operator --- openVulkanoCpp/Math/AABB.hpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/openVulkanoCpp/Math/AABB.hpp b/openVulkanoCpp/Math/AABB.hpp index 9fddbdb..5c0039b 100644 --- a/openVulkanoCpp/Math/AABB.hpp +++ b/openVulkanoCpp/Math/AABB.hpp @@ -14,12 +14,12 @@ namespace OpenVulkano::Math /** * \brief A class that represents an axis aligned bounding box */ - class AABB final : public Range + class AABB final : public Range { public: - AABB() : Range(Math::Vector3f(INFINITY), Math::Vector3f(-INFINITY)) {} + AABB() : Range(Vector3f(INFINITY), Vector3f(-INFINITY)) {} - AABB(const Math::Vector3f& min, const Math::Vector3f& max) : Range(min, max) {} + AABB(const Vector3f& min, const Vector3f& max) : Range(min, max) {} AABB(const Vector3f& point) : Range(point, point) {} @@ -31,18 +31,18 @@ namespace OpenVulkano::Math * \brief Initiates the AABB to a single point (min=max=point) * \param point The point that should be used as min and max of the AABB */ - void Init(const Math::Vector3f& point) + void Init(const Vector3f& point) { min = max = point; } - void Init(const Math::Vector3f& min, const Math::Vector3f& max) + void Init(const Vector3f& min, const Vector3f& max) { this->min = min; this->max = max; } - void Init(const Math::Vector3f& point, float radius) + void Init(const Vector3f& point, float radius) { min = point - radius; max = point + radius; @@ -58,7 +58,7 @@ namespace OpenVulkano::Math max = other.GetMax(); } - void Grow(const Math::Vector3f& point) + void Grow(const Vector3f& point) { min = Math::Utils::min(min, point); max = Math::Utils::max(max, point); @@ -75,12 +75,12 @@ namespace OpenVulkano::Math //TODO } - [[nodiscard]] Math::Vector3f GetDiagonal() const + [[nodiscard]] Vector3f GetDiagonal() const { return GetSize(); } - [[nodiscard]] Math::Vector3f GetCenter() const + [[nodiscard]] Vector3f GetCenter() const { return min + (GetDiagonal() * 0.5f); } @@ -96,7 +96,7 @@ namespace OpenVulkano::Math other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); } - [[nodiscard]] bool InBounds(const Math::Vector3f& position) const + [[nodiscard]] bool InBounds(const Vector3f& position) const { return Math::Utils::all(Math::Utils::lessThanEqual(min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, max)); } @@ -116,8 +116,10 @@ namespace OpenVulkano::Math */ void Reset() { - min = Math::Vector3f(INFINITY); - max = Math::Vector3f(-INFINITY); + min = Vector3f(INFINITY); + max = Vector3f(-INFINITY); } + + AABB& operator +=(const AABB& other) { Grow(other); return *this; } }; } From 54441024b3b7448699cf6b94dd0c50172eec78eb Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:02:37 +0100 Subject: [PATCH 04/36] Delete duplicated variable --- openVulkanoCpp/Scene/TextDrawable.cpp | 2 +- openVulkanoCpp/Scene/TextDrawable.hpp | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index adffe2b..f23262d 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -272,7 +272,7 @@ namespace OpenVulkano::Scene ++i; } m_bbox.Init(bmin, bmax); - SimpleDrawable::Init(m_shader, &m_geometry, &m_material, &m_uniBuffer); + SimpleDrawable::Init(nullptr, &m_geometry, &m_material, &m_uniBuffer); } void TextDrawable::SetAtlasData(const std::shared_ptr& atlasData) diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index f8d6e3f..8e07e74 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -47,11 +47,9 @@ namespace OpenVulkano::Scene TextDrawable(const std::shared_ptr& atlasData, const TextConfig& config = TextConfig()); void GenerateText(const std::string& text, const Math::Vector3f& pos = Math::Vector3f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } - void SetShader(Shader* shader) { m_shader = shader; } void SetAtlasData(const std::shared_ptr& atlasData); Math::AABB& GetBoundingBox() { return m_bbox; } TextConfig& GetConfig() { return m_cfg; } - Shader* GetShader() { return m_shader; } [[nodiscard]] const std::string& GetText() const { return m_text; } std::shared_ptr GetAtlasData() { return m_atlasData; } private: @@ -60,7 +58,6 @@ namespace OpenVulkano::Scene UniformBuffer m_uniBuffer; std::shared_ptr m_atlasData; Math::AABB m_bbox; - Shader* m_shader = nullptr; std::string m_text; TextConfig m_cfg; }; From c288f3ccba0a8ae31b0cecf197d0faa0638cc92e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:05:31 +0100 Subject: [PATCH 05/36] Remove redundant namespaces --- .../Scene/Prefabs/LabelDrawable.cpp | 12 ++++----- .../Scene/Prefabs/LabelDrawable.hpp | 1 - openVulkanoCpp/Scene/TextDrawable.cpp | 25 +++++++++---------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 76e1c72..48b03ab 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -17,7 +17,7 @@ namespace OpenVulkano::Scene namespace { - Shader MakeLabelBgShader(bool billboard) + Shader MakeLabelBgShader(const bool billboard) { Shader backgroundShader; if (!billboard) @@ -44,7 +44,7 @@ namespace OpenVulkano::Scene Shader LabelDrawable::BACKGROUND_SHADER = MakeLabelBgShader(false); Shader LabelDrawable::BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true); - LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, bool isBillboard) + LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, const bool isBillboard) : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard) { if (atlasData->glyphs.empty() || !atlasData->texture.size) @@ -115,11 +115,11 @@ namespace OpenVulkano::Scene FontAtlasType fontAtlasType(static_cast(m_atlasData->meta.atlasType)); if (!m_isBillboard) { - m_textShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/text"); + m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); } else { - m_textShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboard"); + m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/billboard"); DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX; m_textShader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4); @@ -128,9 +128,9 @@ namespace OpenVulkano::Scene DescriptorSetLayoutBinding textUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; textUniformBinding.stageFlags = ShaderProgramType::FRAGMENT; m_textShader.AddDescriptorSetLayoutBinding(textUniformBinding, 3); - m_textShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, + m_textShader.AddShaderProgram(ShaderProgramType::FRAGMENT, std::string(fontAtlasType.GetDefaultFragmentShader())); - m_textShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + m_textShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); m_textShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2); m_textShader.alphaBlend = true; m_textShader.cullMode = CullMode::NONE; diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 990e434..cb406d9 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -19,7 +19,6 @@ namespace OpenVulkano::Scene { - struct LabelDrawableSettings { Math::Vector4f backgroundColor = { 1, 0, 0, 1 }; diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index f23262d..476e064 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -26,9 +26,9 @@ namespace OpenVulkano::Scene static Shader sdfDefaultShader; if (once) { - sdfDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/sdfText"); - sdfDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/sdfText"); - sdfDefaultShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + sdfDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/sdfText"); + sdfDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/sdfText"); + sdfDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); sdfDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; desc.stageFlags = ShaderProgramType::FRAGMENT; @@ -46,9 +46,9 @@ namespace OpenVulkano::Scene static Shader msdfDefaultShader; if (once) { - msdfDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/sdfText"); - msdfDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/msdfText"); - msdfDefaultShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + msdfDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/sdfText"); + msdfDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/msdfText"); + msdfDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); msdfDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; desc.stageFlags = ShaderProgramType::FRAGMENT; @@ -66,9 +66,9 @@ namespace OpenVulkano::Scene static Shader bitmapDefaultShader; if (once) { - bitmapDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/text"); - bitmapDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/text"); - bitmapDefaultShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + bitmapDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); + bitmapDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/text"); + bitmapDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); bitmapDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; desc.stageFlags = ShaderProgramType::FRAGMENT; @@ -93,12 +93,12 @@ namespace OpenVulkano::Scene } TextDrawable::TextDrawable(const std::string& atlasMetadataFile, const TextConfig& config) - : TextDrawable(OpenVulkano::Utils::ReadFile(atlasMetadataFile), nullptr, config) + : TextDrawable(Utils::ReadFile(atlasMetadataFile), nullptr, config) { } TextDrawable::TextDrawable(const std::string& atlasMetadataFile, Texture* atlasTex, const TextConfig& config) - : TextDrawable(OpenVulkano::Utils::ReadFile(atlasMetadataFile), atlasTex, config) + : TextDrawable(Utils::ReadFile(atlasMetadataFile), atlasTex, config) { } @@ -114,8 +114,7 @@ namespace OpenVulkano::Scene if (isPacked) { m_material.texture = &m_atlasData->texture; - m_atlasData->img = Image::IImageLoader::loadData((const uint8_t*) atlasMetadata.Data(), - offsetToMetadata); + m_atlasData->img = Image::IImageLoader::loadData(reinterpret_cast(atlasMetadata.Data()), offsetToMetadata); m_material.texture->format = m_atlasData->img->dataFormat; m_material.texture->resolution = m_atlasData->img->resolution; m_material.texture->size = m_atlasData->img->data.Size(); From d96ced96c0209e62c2f9501c1887f4d1bb397982 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:15:25 +0100 Subject: [PATCH 06/36] Deduplicate shader creation function for text drawable --- openVulkanoCpp/Scene/TextDrawable.cpp | 66 ++++++--------------------- openVulkanoCpp/Scene/TextDrawable.hpp | 10 ++-- 2 files changed, 19 insertions(+), 57 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 476e064..c886987 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -20,65 +20,27 @@ namespace OpenVulkano::Scene { - Shader& TextDrawable::GetSdfDefaultShader() + namespace { - static bool once = true; - static Shader sdfDefaultShader; - if (once) + Shader MakeDefaultShader(const std::string& vertexShader, const std::string& fragmentShader) { - sdfDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/sdfText"); - sdfDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/sdfText"); - sdfDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); - sdfDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); + Shader shader; + shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/" + vertexShader); + shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/" + fragmentShader); + shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); + shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; desc.stageFlags = ShaderProgramType::FRAGMENT; - sdfDefaultShader.AddDescriptorSetLayoutBinding(desc); - sdfDefaultShader.alphaBlend = true; - sdfDefaultShader.cullMode = CullMode::NONE; - once = false; + shader.AddDescriptorSetLayoutBinding(desc); + shader.alphaBlend = true; + shader.cullMode = CullMode::NONE; + return shader; } - return sdfDefaultShader; } - Shader& TextDrawable::GetMsdfDefaultShader() - { - static bool once = true; - static Shader msdfDefaultShader; - if (once) - { - msdfDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/sdfText"); - msdfDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/msdfText"); - msdfDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); - msdfDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); - DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - desc.stageFlags = ShaderProgramType::FRAGMENT; - msdfDefaultShader.AddDescriptorSetLayoutBinding(desc); - msdfDefaultShader.alphaBlend = true; - msdfDefaultShader.cullMode = CullMode::NONE; - once = false; - } - return msdfDefaultShader; - } - - Shader& TextDrawable::GetBitmapDefaultShader() - { - static bool once = true; - static Shader bitmapDefaultShader; - if (once) - { - bitmapDefaultShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); - bitmapDefaultShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/text"); - bitmapDefaultShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); - bitmapDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); - DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - desc.stageFlags = ShaderProgramType::FRAGMENT; - bitmapDefaultShader.AddDescriptorSetLayoutBinding(desc); - bitmapDefaultShader.alphaBlend = true; - bitmapDefaultShader.cullMode = CullMode::NONE; - once = false; - } - return bitmapDefaultShader; - } + Shader TextDrawable::DEFAULT_SHADER_BITMAP = MakeDefaultShader("text", "text"); + Shader TextDrawable::DEFAULT_SHADER_SDF = MakeDefaultShader("sdfText", "sdfText"); + Shader TextDrawable::DEFAULT_SHADER_MSDF = MakeDefaultShader("sdfText", "msdfText"); TextDrawable::TextDrawable(const TextConfig& config) { diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 8e07e74..6bc1471 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -13,8 +13,6 @@ #include "UniformBuffer.hpp" #include "AtlasData.hpp" #include "Image/Image.hpp" -#include -#include namespace OpenVulkano::Scene { @@ -35,10 +33,12 @@ namespace OpenVulkano::Scene class TextDrawable : public SimpleDrawable { + static Shader DEFAULT_SHADER_BITMAP, DEFAULT_SHADER_SDF, DEFAULT_SHADER_MSDF; + public: - static Shader& GetSdfDefaultShader(); - static Shader& GetMsdfDefaultShader(); - static Shader& GetBitmapDefaultShader(); + [[nodiscard]] static Shader& GetSdfDefaultShader() { return DEFAULT_SHADER_SDF; } + [[nodiscard]] static Shader& GetMsdfDefaultShader() { return DEFAULT_SHADER_MSDF; } + [[nodiscard]] static Shader& GetBitmapDefaultShader() { return DEFAULT_SHADER_BITMAP; } TextDrawable(const TextConfig& config = TextConfig()); TextDrawable(const Array& atlasMetadata, const TextConfig& config = TextConfig()); TextDrawable(const std::string& atlasMetadataFile, const TextConfig& config = TextConfig()); From 207d02aab4fefa136fe0f4f19c36b2431d926612 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:25:04 +0100 Subject: [PATCH 07/36] Remove redundant lambda, use initializer, add nodiscard --- openVulkanoCpp/Scene/TextDrawable.cpp | 32 +++++---------------------- openVulkanoCpp/Scene/TextDrawable.hpp | 8 +++---- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index c886987..fd8df4c 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -42,27 +42,23 @@ namespace OpenVulkano::Scene Shader TextDrawable::DEFAULT_SHADER_SDF = MakeDefaultShader("sdfText", "sdfText"); Shader TextDrawable::DEFAULT_SHADER_MSDF = MakeDefaultShader("sdfText", "msdfText"); - TextDrawable::TextDrawable(const TextConfig& config) + TextDrawable::TextDrawable(const TextConfig& config) : m_cfg(config) { - m_cfg = config; m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; } TextDrawable::TextDrawable(const Array& atlasMetadata, const TextConfig& config) : TextDrawable(atlasMetadata, nullptr, config) - { - } + {} TextDrawable::TextDrawable(const std::string& atlasMetadataFile, const TextConfig& config) : TextDrawable(Utils::ReadFile(atlasMetadataFile), nullptr, config) - { - } + {} TextDrawable::TextDrawable(const std::string& atlasMetadataFile, Texture* atlasTex, const TextConfig& config) : TextDrawable(Utils::ReadFile(atlasMetadataFile), atlasTex, config) - { - } + {} TextDrawable::TextDrawable(const Array& atlasMetadata, Texture* atlasTex, const TextConfig& config) { @@ -130,27 +126,11 @@ namespace OpenVulkano::Scene void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos) { - if (text.empty()) - { - return; - } + if (text.empty()) return; m_text = text; - auto GetActualLength = [&]() - { - auto begin = text.begin(); - auto end = text.end(); - size_t len = 0; - while (begin != end) - { - uint32_t c = utf8::next(begin, end); - if (c == '\n') continue; - ++len; - } - return len; - }; - size_t len = GetActualLength(); + size_t len = utf8::distance(text.begin(), text.end()); m_geometry.Close(); m_geometry.Init(len * 4, len * 6); AtlasMetadata* meta; diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 6bc1471..134ba2e 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -16,7 +16,6 @@ namespace OpenVulkano::Scene { - class IFontAtlasGenerator; struct TextConfig @@ -48,10 +47,11 @@ namespace OpenVulkano::Scene void GenerateText(const std::string& text, const Math::Vector3f& pos = Math::Vector3f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } void SetAtlasData(const std::shared_ptr& atlasData); - Math::AABB& GetBoundingBox() { return m_bbox; } - TextConfig& GetConfig() { return m_cfg; } + [[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; } + [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } - std::shared_ptr GetAtlasData() { return m_atlasData; } + [[nodiscard]] const std::shared_ptr GetAtlasData() { return m_atlasData; } + private: Geometry m_geometry; Material m_material; From 519be60c8c09edae83e13685dafb9a2e5a7f1e09 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:31:13 +0100 Subject: [PATCH 08/36] Fix String::Trim --- openVulkanoCpp/Data/Containers/String.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Data/Containers/String.hpp b/openVulkanoCpp/Data/Containers/String.hpp index 9e69c3f..4233df0 100644 --- a/openVulkanoCpp/Data/Containers/String.hpp +++ b/openVulkanoCpp/Data/Containers/String.hpp @@ -105,7 +105,14 @@ namespace OpenVulkano String& Trim() noexcept { return TrimBack().TrimFront(); } - [[nodiscard]] String Trim() const { return Trim(); } + [[nodiscard]] String Trim() const + { + size_t start = m_string.find_first_not_of(" \t\n\r"); + if (start == std::string::npos) start = 0; + size_t end = m_string.find_last_not_of(" \t\n\r"); + if (end == std::string::npos) end = m_string.size(); + return { m_string.substr(start, end - start + 1) }; + } String& TrimFront() noexcept { From f124a2291032c0eb81a96f1fd73c83661e7bb9a0 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:52:11 +0100 Subject: [PATCH 09/36] Cleanup duplicated text shader --- openVulkanoCpp/Scene/AtlasData.hpp | 19 ++++++++++++------- openVulkanoCpp/Scene/TextDrawable.cpp | 14 ++++++++------ openVulkanoCpp/Shader/sdfText.vert | 26 -------------------------- 3 files changed, 20 insertions(+), 39 deletions(-) delete mode 100644 openVulkanoCpp/Shader/sdfText.vert diff --git a/openVulkanoCpp/Scene/AtlasData.hpp b/openVulkanoCpp/Scene/AtlasData.hpp index ed75309..f62c8de 100644 --- a/openVulkanoCpp/Scene/AtlasData.hpp +++ b/openVulkanoCpp/Scene/AtlasData.hpp @@ -29,20 +29,23 @@ namespace OpenVulkano::Scene public: enum Type : int16_t { - SDF = 0, + BITMAP = 0, + SDF, MSDF, - BITMAP, UNKNOWN }; - static constexpr std::string_view DEFAULT_FG_SHADERS[] = { "Shader/text", "Shader/msdfText" }; - public: - FontAtlasType(Type type) : m_type(type) {} - Type GetType() const { return m_type; } - const std::string_view& GetDefaultFragmentShader() const + static constexpr std::string_view DEFAULT_FG_SHADERS[] = { "Shader/text", "Shader/sdfText", "Shader/msdfText" }; + + constexpr FontAtlasType(Type type) : m_type(type) {} + + [[nodiscard]] constexpr Type GetType() const { return m_type; } + + [[nodiscard]] constexpr const std::string_view& GetDefaultFragmentShader() const { return DEFAULT_FG_SHADERS[static_cast(m_type)]; } + private: Type m_type; }; @@ -60,6 +63,8 @@ namespace OpenVulkano::Scene AtlasMetadata meta; Unique img; Texture texture; + + operator bool() const { return !glyphs.empty(); } }; } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index fd8df4c..036e199 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -22,11 +22,13 @@ namespace OpenVulkano::Scene { namespace { - Shader MakeDefaultShader(const std::string& vertexShader, const std::string& fragmentShader) + constexpr uint32_t MISSING_GLYPH_SYMBOL = '?'; + + Shader MakeDefaultShader(FontAtlasType type) { Shader shader; - shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/" + vertexShader); - shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/" + fragmentShader); + shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); + shader.AddShaderProgram(ShaderProgramType::FRAGMENT, std::string(type.GetDefaultFragmentShader())); shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; @@ -38,9 +40,9 @@ namespace OpenVulkano::Scene } } - Shader TextDrawable::DEFAULT_SHADER_BITMAP = MakeDefaultShader("text", "text"); - Shader TextDrawable::DEFAULT_SHADER_SDF = MakeDefaultShader("sdfText", "sdfText"); - Shader TextDrawable::DEFAULT_SHADER_MSDF = MakeDefaultShader("sdfText", "msdfText"); + Shader TextDrawable::DEFAULT_SHADER_BITMAP = MakeDefaultShader(FontAtlasType::BITMAP); + Shader TextDrawable::DEFAULT_SHADER_SDF = MakeDefaultShader(FontAtlasType::SDF); + Shader TextDrawable::DEFAULT_SHADER_MSDF = MakeDefaultShader(FontAtlasType::MSDF); TextDrawable::TextDrawable(const TextConfig& config) : m_cfg(config) { diff --git a/openVulkanoCpp/Shader/sdfText.vert b/openVulkanoCpp/Shader/sdfText.vert deleted file mode 100644 index c259c65..0000000 --- a/openVulkanoCpp/Shader/sdfText.vert +++ /dev/null @@ -1,26 +0,0 @@ -#version 450 -layout(location = 0) in vec3 position; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec3 tangent; -layout(location = 3) in vec3 biTangent; -layout(location = 4) in vec3 textureCoordinates; -layout(location = 5) in vec4 color; -layout(location = 1) out vec2 fragTextureCoordinates; - -layout(set = 0, binding = 0) uniform NodeData -{ - mat4 world; -} node; - -layout(set = 1, binding = 0) uniform CameraData -{ - mat4 viewProjection; - mat4 view; - mat4 projection; - vec4 camPos; -} cam; - -void main() { - gl_Position = cam.viewProjection * node.world * vec4(position, 1.0); - fragTextureCoordinates.xy = textureCoordinates.xy; -} From f156ff5892d0c492954246802d3e0ed479c99a78 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 01:52:41 +0100 Subject: [PATCH 10/36] Update fallback glyph handling --- openVulkanoCpp/Scene/TextDrawable.cpp | 25 +++++++++++++++---------- openVulkanoCpp/Scene/TextDrawable.hpp | 19 ++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 036e199..5619114 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -126,9 +126,22 @@ namespace OpenVulkano::Scene m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; } + uint32_t TextDrawable::GetFallbackGlyph() const + { + if (m_atlasData->glyphs.find(MISSING_GLYPH_SYMBOL) != m_atlasData->glyphs.end()) + { + return MISSING_GLYPH_SYMBOL; + } + Logger::RENDER->warn("Could not find glyph for character ? to use as fallback. Using first glyph instead"); + return m_atlasData->glyphs.begin()->first; + } + + void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos) { if (text.empty()) return; + if (!m_atlasData && !*m_atlasData) { Logger::RENDER->error("Must have glyphs"); return;} + const uint32_t fallbackGlyph = GetFallbackGlyph(); m_text = text; @@ -161,16 +174,8 @@ namespace OpenVulkano::Scene if (symbols->find(c) == symbols->end()) { - Logger::RENDER->error("Could not find glyph for character {}", c); - if (symbols->find(static_cast('?')) != symbols->end()) - { - c = static_cast('?'); - } - else - { - Logger::RENDER->error("Could not find glyph for character ? to replace glyph {}", c); - continue; - } + Logger::RENDER->warn("Could not find glyph for character {}, using fallback", c); + c = fallbackGlyph; } uint32_t vIdx = i * 4; diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 134ba2e..2554899 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -34,6 +34,16 @@ namespace OpenVulkano::Scene { static Shader DEFAULT_SHADER_BITMAP, DEFAULT_SHADER_SDF, DEFAULT_SHADER_MSDF; + Geometry m_geometry; + Material m_material; + UniformBuffer m_uniBuffer; + std::shared_ptr m_atlasData; + Math::AABB m_bbox; + std::string m_text; + TextConfig m_cfg; + + uint32_t GetFallbackGlyph() const; + public: [[nodiscard]] static Shader& GetSdfDefaultShader() { return DEFAULT_SHADER_SDF; } [[nodiscard]] static Shader& GetMsdfDefaultShader() { return DEFAULT_SHADER_MSDF; } @@ -51,14 +61,5 @@ namespace OpenVulkano::Scene [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } [[nodiscard]] const std::shared_ptr GetAtlasData() { return m_atlasData; } - - private: - Geometry m_geometry; - Material m_material; - UniformBuffer m_uniBuffer; - std::shared_ptr m_atlasData; - Math::AABB m_bbox; - std::string m_text; - TextConfig m_cfg; }; } From 884949f92f9fd4ccf886dbd88a21837929a01ce8 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 02:02:14 +0100 Subject: [PATCH 11/36] Deduplicate Atlas validity checking --- openVulkanoCpp/Scene/AtlasData.hpp | 2 +- openVulkanoCpp/Scene/TextDrawable.cpp | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/openVulkanoCpp/Scene/AtlasData.hpp b/openVulkanoCpp/Scene/AtlasData.hpp index f62c8de..7311239 100644 --- a/openVulkanoCpp/Scene/AtlasData.hpp +++ b/openVulkanoCpp/Scene/AtlasData.hpp @@ -64,7 +64,7 @@ namespace OpenVulkano::Scene Unique img; Texture texture; - operator bool() const { return !glyphs.empty(); } + operator bool() const { return !glyphs.empty() && texture.textureBuffer; } }; } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 5619114..bbe5c1e 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -63,6 +63,7 @@ namespace OpenVulkano::Scene {} TextDrawable::TextDrawable(const Array& atlasMetadata, Texture* atlasTex, const TextConfig& config) + : m_cfg(config) { uint32_t isPacked; std::memcpy(&isPacked, atlasMetadata.Data() + (atlasMetadata.Size() - sizeof(uint32_t)), sizeof(uint32_t)); @@ -105,7 +106,6 @@ namespace OpenVulkano::Scene read_bytes += sizeof(GlyphInfo); readMetadataBytes += sizeof(GlyphInfo); } - m_cfg = config; m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; if (m_atlasData->meta.atlasType == FontAtlasType::BITMAP) @@ -115,13 +115,9 @@ namespace OpenVulkano::Scene } TextDrawable::TextDrawable(const std::shared_ptr& atlasData, const TextConfig& config) + : m_atlasData(atlasData), m_cfg(config) { - if (!atlasData || atlasData->glyphs.empty() || !atlasData->texture.textureBuffer) - { - throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); - } - m_atlasData = atlasData; - m_cfg = config; + if (!atlasData || !*atlasData) throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; } @@ -140,7 +136,6 @@ namespace OpenVulkano::Scene void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos) { if (text.empty()) return; - if (!m_atlasData && !*m_atlasData) { Logger::RENDER->error("Must have glyphs"); return;} const uint32_t fallbackGlyph = GetFallbackGlyph(); m_text = text; @@ -225,10 +220,7 @@ namespace OpenVulkano::Scene void TextDrawable::SetAtlasData(const std::shared_ptr& atlasData) { - if (!atlasData || atlasData->glyphs.empty() || !atlasData->texture.textureBuffer) - { - throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); - } + if (!atlasData || !*atlasData) throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); m_atlasData = atlasData; } } \ No newline at end of file From bc78af70e8bdf97975286a2788bbd9063bb23479 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 02:45:46 +0100 Subject: [PATCH 12/36] Fix bugs introduced by refactoring --- openVulkanoCpp/Scene/AtlasData.hpp | 13 +++++++++---- openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/openVulkanoCpp/Scene/AtlasData.hpp b/openVulkanoCpp/Scene/AtlasData.hpp index 7311239..be784ec 100644 --- a/openVulkanoCpp/Scene/AtlasData.hpp +++ b/openVulkanoCpp/Scene/AtlasData.hpp @@ -12,6 +12,7 @@ #include "Scene/Texture.hpp" #include #include +#include namespace OpenVulkano::Scene { @@ -29,23 +30,27 @@ namespace OpenVulkano::Scene public: enum Type : int16_t { - BITMAP = 0, - SDF, + SDF = 0, MSDF, + BITMAP, UNKNOWN }; - static constexpr std::string_view DEFAULT_FG_SHADERS[] = { "Shader/text", "Shader/sdfText", "Shader/msdfText" }; + static constexpr std::string_view DEFAULT_FG_SHADERS[] = { "Shader/sdfText", "Shader/msdfText", "Shader/text" }; constexpr FontAtlasType(Type type) : m_type(type) {} [[nodiscard]] constexpr Type GetType() const { return m_type; } + [[nodiscard]] constexpr auto GetName() const { return magic_enum::enum_name(m_type); } + [[nodiscard]] constexpr const std::string_view& GetDefaultFragmentShader() const { return DEFAULT_FG_SHADERS[static_cast(m_type)]; } + [[nodiscard]] constexpr operator Type() const { return m_type; } + private: Type m_type; }; @@ -54,7 +59,7 @@ namespace OpenVulkano::Scene { // vertical difference between baselines double lineHeight = 0; - int16_t atlasType = FontAtlasType::UNKNOWN; + FontAtlasType atlasType = FontAtlasType::UNKNOWN; }; struct AtlasData diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 48b03ab..5e5b0c1 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -74,10 +74,9 @@ namespace OpenVulkano::Scene TextDrawable& textDrawable = m_texts.emplace_back(m_atlasData, config); // do not render glyph's background textDrawable.GetConfig().backgroundColor.a = 0; - textDrawable.SetShader(&m_textShader); double lineHeight = m_atlasData->meta.lineHeight; - textDrawable.GenerateText(text, m_position); + textDrawable.SetShader(&m_textShader); m_bbox.Grow(textDrawable.GetBoundingBox()); // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; From 94025c79c674aa9a9249c391641eedf1da0bdf0e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 02:46:24 +0100 Subject: [PATCH 13/36] Unify text shader handling --- examples/ExampleApps/TextExampleApp.cpp | 16 +++------- openVulkanoCpp/Scene/TextDrawable.cpp | 20 +++++++++--- openVulkanoCpp/Scene/TextDrawable.hpp | 9 ------ openVulkanoCpp/Shader/msdfText.frag | 9 ++---- openVulkanoCpp/Shader/sdfText.frag | 20 +++--------- openVulkanoCpp/Shader/sdfTextWithBorder.frag | 32 ++++++++++++++++++++ openVulkanoCpp/Shader/text.frag | 5 +-- 7 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 openVulkanoCpp/Shader/sdfTextWithBorder.frag diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 9ed0549..0ed5ca5 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -62,7 +62,6 @@ namespace OpenVulkano texts.push_back(std::make_pair("\u0410\u0411\u0412\u041F", TextConfig())); texts.push_back(std::make_pair("Unsupported glyphs \u1E30\u1E31 are coming", TextConfig())); texts.push_back(std::make_pair("This is first line\nSecond gg line\nThird G line", TextConfig())); - texts[0].second.applyBorder = true; texts[1].second.backgroundColor.a = 1; const int N = texts.size(); @@ -98,32 +97,27 @@ namespace OpenVulkano #if defined(MSDFGEN_AVAILABLE) && CREATE_NEW_ATLAS if (i < texts.size()) { - t = new TextDrawable(m_atlasGenerator.GetAtlasData(), texts[textIdx].second); - t->SetShader(&TextDrawable::GetSdfDefaultShader()); + t = new TextDrawable(m_atlasGenerator.GetAtlasData(), texts[textIdx].second); } else { - t = new TextDrawable(m_msdfAtlasGenerator.GetAtlasData(), texts[textIdx].second); - t->SetShader(&TextDrawable::GetMsdfDefaultShader()); + t = new TextDrawable(m_msdfAtlasGenerator.GetAtlasData(), texts[textIdx].second); } #else int xOffset = 0; if (i < N) { - t = new TextDrawable(sdfMetadataInfo, texts[textIdx].second); - t->SetShader(&TextDrawable::GetSdfDefaultShader()); + t = new TextDrawable(sdfMetadataInfo, texts[textIdx].second); xOffset = -5; } else if (i >= N && i < N * 2) { - t = new TextDrawable(msdfMetadataInfo, texts[textIdx].second); - t->SetShader(&TextDrawable::GetMsdfDefaultShader()); + t = new TextDrawable(msdfMetadataInfo, texts[textIdx].second); xOffset = 15; } else { - t = new TextDrawable(bitmapMetadataInfo, texts[textIdx].second); - t->SetShader(&TextDrawable::GetBitmapDefaultShader()); + t = new TextDrawable(bitmapMetadataInfo, texts[textIdx].second); xOffset = 35; } // OR use separate texture + metadata file diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index bbe5c1e..362f2c7 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -38,11 +38,11 @@ namespace OpenVulkano::Scene shader.cullMode = CullMode::NONE; return shader; } - } - Shader TextDrawable::DEFAULT_SHADER_BITMAP = MakeDefaultShader(FontAtlasType::BITMAP); - Shader TextDrawable::DEFAULT_SHADER_SDF = MakeDefaultShader(FontAtlasType::SDF); - Shader TextDrawable::DEFAULT_SHADER_MSDF = MakeDefaultShader(FontAtlasType::MSDF); + Shader DEFAULT_SHADER_BITMAP = MakeDefaultShader(FontAtlasType::BITMAP); + Shader DEFAULT_SHADER_SDF = MakeDefaultShader(FontAtlasType::SDF); + Shader DEFAULT_SHADER_MSDF = MakeDefaultShader(FontAtlasType::MSDF); + } TextDrawable::TextDrawable(const TextConfig& config) : m_cfg(config) { @@ -215,7 +215,17 @@ namespace OpenVulkano::Scene ++i; } m_bbox.Init(bmin, bmax); - SimpleDrawable::Init(nullptr, &m_geometry, &m_material, &m_uniBuffer); + + Shader* shader = nullptr; + switch (m_atlasData->meta.atlasType) + { + case FontAtlasType::SDF: shader = &DEFAULT_SHADER_SDF; break; + case FontAtlasType::MSDF: shader = &DEFAULT_SHADER_MSDF; break; + default: Logger::RENDER->warn("No default shader for atlas type: {}", m_atlasData->meta.atlasType.GetName()); + case FontAtlasType::BITMAP: shader = &DEFAULT_SHADER_BITMAP; break; + } + + SimpleDrawable::Init(shader, &m_geometry, &m_material, &m_uniBuffer); } void TextDrawable::SetAtlasData(const std::shared_ptr& atlasData) diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 2554899..6e01092 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -21,19 +21,13 @@ namespace OpenVulkano::Scene struct TextConfig { Math::Vector4f textColor = { 1, 1, 1, 1 }; - Math::Vector4f borderColor = { 1, 0, 0, 1 }; Math::Vector4f backgroundColor = { 0, 1, 0, 0 }; float threshold = 0.4f; - float borderSize = 0.05f; float smoothing = 1.f/32.f; - uint32_t applyBorder = false; - //bool sdfMultiChannel = false; }; class TextDrawable : public SimpleDrawable { - static Shader DEFAULT_SHADER_BITMAP, DEFAULT_SHADER_SDF, DEFAULT_SHADER_MSDF; - Geometry m_geometry; Material m_material; UniformBuffer m_uniBuffer; @@ -45,9 +39,6 @@ namespace OpenVulkano::Scene uint32_t GetFallbackGlyph() const; public: - [[nodiscard]] static Shader& GetSdfDefaultShader() { return DEFAULT_SHADER_SDF; } - [[nodiscard]] static Shader& GetMsdfDefaultShader() { return DEFAULT_SHADER_MSDF; } - [[nodiscard]] static Shader& GetBitmapDefaultShader() { return DEFAULT_SHADER_BITMAP; } TextDrawable(const TextConfig& config = TextConfig()); TextDrawable(const Array& atlasMetadata, const TextConfig& config = TextConfig()); TextDrawable(const std::string& atlasMetadataFile, const TextConfig& config = TextConfig()); diff --git a/openVulkanoCpp/Shader/msdfText.frag b/openVulkanoCpp/Shader/msdfText.frag index 2878e2e..5bb8fd3 100644 --- a/openVulkanoCpp/Shader/msdfText.frag +++ b/openVulkanoCpp/Shader/msdfText.frag @@ -8,13 +8,10 @@ layout(set = 2, binding = 0) uniform sampler2D texSampler; layout(set = 3, binding = 0) uniform TextConfig { - vec4 textColor; - vec4 borderColor; - vec4 backgroundColor; - float threshold; - float borderSize; + vec4 textColor; + vec4 backgroundColor; + float threshold; float smoothing; - bool applyBorder; } textConfig; float median(float r, float g, float b) { diff --git a/openVulkanoCpp/Shader/sdfText.frag b/openVulkanoCpp/Shader/sdfText.frag index 579d9c7..49cc3ab 100644 --- a/openVulkanoCpp/Shader/sdfText.frag +++ b/openVulkanoCpp/Shader/sdfText.frag @@ -8,29 +8,17 @@ layout(set = 2, binding = 0) uniform sampler2D texSampler; layout(set = 3, binding = 0) uniform TextConfig { - vec4 textColor; - vec4 borderColor; - vec4 backgroundColor; - float threshold; - float borderSize; + vec4 textColor; + vec4 backgroundColor; + float threshold; float smoothing; - bool applyBorder; } textConfig; void main() { float distance = texture(texSampler, texCoord).r; float alpha = smoothstep(textConfig.threshold - textConfig.smoothing, textConfig.threshold + textConfig.smoothing, distance); - if (textConfig.applyBorder) - { - float border = smoothstep(textConfig.threshold + textConfig.borderSize - textConfig.smoothing, - textConfig.threshold + textConfig.borderSize + textConfig.smoothing, distance); - outColor = mix(textConfig.borderColor, textConfig.textColor, border) * alpha; - } - else - { - outColor = vec4(textConfig.textColor) * alpha; - } + outColor = vec4(textConfig.textColor) * alpha; if (textConfig.backgroundColor.a != 0) { diff --git a/openVulkanoCpp/Shader/sdfTextWithBorder.frag b/openVulkanoCpp/Shader/sdfTextWithBorder.frag new file mode 100644 index 0000000..6960a33 --- /dev/null +++ b/openVulkanoCpp/Shader/sdfTextWithBorder.frag @@ -0,0 +1,32 @@ +#version 450 + +layout(location = 1) in vec2 texCoord; + +layout(location = 0) out vec4 outColor; + +layout(set = 2, binding = 0) uniform sampler2D texSampler; + +layout(set = 3, binding = 0) uniform TextConfig +{ + vec4 textColor; + vec4 borderColor; + vec4 backgroundColor; + float threshold; + float borderSize; + float smoothing; +} textConfig; + +void main() +{ + float distance = texture(texSampler, texCoord).r; + float alpha = smoothstep(textConfig.threshold - textConfig.smoothing, textConfig.threshold + textConfig.smoothing, distance); + + float border = smoothstep(textConfig.threshold + textConfig.borderSize - textConfig.smoothing, + textConfig.threshold + textConfig.borderSize + textConfig.smoothing, distance); + outColor = mix(textConfig.borderColor, textConfig.textColor, border) * alpha; + + if (textConfig.backgroundColor.a != 0) + { + outColor = mix(textConfig.backgroundColor, outColor, alpha); + } +} diff --git a/openVulkanoCpp/Shader/text.frag b/openVulkanoCpp/Shader/text.frag index b906e40..460a50d 100644 --- a/openVulkanoCpp/Shader/text.frag +++ b/openVulkanoCpp/Shader/text.frag @@ -1,6 +1,6 @@ #version 450 -layout(location = 0) in vec4 color; +//layout(location = 0) in vec4 color; layout(location = 1) in vec2 texCoord; layout(location = 0) out vec4 outColor; @@ -10,12 +10,9 @@ layout(set = 2, binding = 0) uniform sampler2D texSampler; layout(set = 3, binding = 0) uniform TextConfig { vec4 textColor; - vec4 borderColor; vec4 backgroundColor; float threshold; - float borderSize; float smoothing; - bool applyBorder; } textConfig; void main() From ca93036f31bb8ac5ae8c9620d97ab7c19df8eecc Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 03:08:06 +0100 Subject: [PATCH 14/36] Change TextDrawable base class --- examples/ExampleApps/TextExampleApp.cpp | 4 +- openVulkanoCpp/Scene/TextDrawable.cpp | 36 ++++++------ openVulkanoCpp/Scene/TextDrawable.hpp | 10 ++-- .../Scene/LabelDrawableVulkanEncoder.cpp | 38 ++++++------ .../Scene/TextDrawableVulkanEncoder.cpp | 58 +++++++++++++++++++ 5 files changed, 101 insertions(+), 45 deletions(-) create mode 100644 openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 0ed5ca5..26538d2 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -158,7 +158,7 @@ namespace OpenVulkano void Close() override { - for (SimpleDrawable* d: m_drawablesPool) + for (Drawable* d: m_drawablesPool) { d->Close(); delete d; @@ -173,7 +173,7 @@ namespace OpenVulkano SdfFontAtlasGenerator m_atlasGenerator; MsdfFontAtlasGenerator m_msdfAtlasGenerator; #endif - std::vector m_drawablesPool; + std::vector m_drawablesPool; std::vector m_nodesPool; Vector3f_SIMD m_position = { 0, 0, -10 }; OpenVulkano::Scene::UI::SimpleUi m_ui; diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 362f2c7..bb6fd43 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -44,7 +44,8 @@ namespace OpenVulkano::Scene Shader DEFAULT_SHADER_MSDF = MakeDefaultShader(FontAtlasType::MSDF); } - TextDrawable::TextDrawable(const TextConfig& config) : m_cfg(config) + TextDrawable::TextDrawable(const TextConfig& config) + : Drawable(DrawEncoder::GetDrawEncoder()), m_cfg(config) { m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; @@ -63,7 +64,7 @@ namespace OpenVulkano::Scene {} TextDrawable::TextDrawable(const Array& atlasMetadata, Texture* atlasTex, const TextConfig& config) - : m_cfg(config) + : Drawable(DrawEncoder::GetDrawEncoder()), m_cfg(config) { uint32_t isPacked; std::memcpy(&isPacked, atlasMetadata.Data() + (atlasMetadata.Size() - sizeof(uint32_t)), sizeof(uint32_t)); @@ -74,18 +75,17 @@ namespace OpenVulkano::Scene m_atlasData = std::make_shared(); if (isPacked) { - m_material.texture = &m_atlasData->texture; + Texture* texture = &m_atlasData->texture; m_atlasData->img = Image::IImageLoader::loadData(reinterpret_cast(atlasMetadata.Data()), offsetToMetadata); - m_material.texture->format = m_atlasData->img->dataFormat; - m_material.texture->resolution = m_atlasData->img->resolution; - m_material.texture->size = m_atlasData->img->data.Size(); - m_material.texture->textureBuffer = m_atlasData->img->data.Data(); + texture->format = m_atlasData->img->dataFormat; + texture->resolution = m_atlasData->img->resolution; + texture->size = m_atlasData->img->data.Size(); + texture->textureBuffer = m_atlasData->img->data.Data(); } else { if (atlasTex == nullptr) { throw std::runtime_error("Atlas texture cannot be null with non-packed atlas metadata"); } m_atlasData->texture = *atlasTex; - m_material.texture = atlasTex; } // metadata info @@ -110,12 +110,12 @@ namespace OpenVulkano::Scene m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; if (m_atlasData->meta.atlasType == FontAtlasType::BITMAP) { - m_material.texture->m_samplerConfig = &SamplerConfig::NEAREST; + m_atlasData->texture.m_samplerConfig = &SamplerConfig::NEAREST; } } TextDrawable::TextDrawable(const std::shared_ptr& atlasData, const TextConfig& config) - : m_atlasData(atlasData), m_cfg(config) + : Drawable(DrawEncoder::GetDrawEncoder()), m_atlasData(atlasData), m_cfg(config) { if (!atlasData || !*atlasData) throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); @@ -216,16 +216,16 @@ namespace OpenVulkano::Scene } m_bbox.Init(bmin, bmax); - Shader* shader = nullptr; - switch (m_atlasData->meta.atlasType) + if (!GetShader()) { - case FontAtlasType::SDF: shader = &DEFAULT_SHADER_SDF; break; - case FontAtlasType::MSDF: shader = &DEFAULT_SHADER_MSDF; break; - default: Logger::RENDER->warn("No default shader for atlas type: {}", m_atlasData->meta.atlasType.GetName()); - case FontAtlasType::BITMAP: shader = &DEFAULT_SHADER_BITMAP; break; + switch (m_atlasData->meta.atlasType) + { + case FontAtlasType::SDF: SetShader(&DEFAULT_SHADER_SDF); break; + case FontAtlasType::MSDF: SetShader(&DEFAULT_SHADER_MSDF); break; + default: Logger::RENDER->warn("No default shader for atlas type: {}", m_atlasData->meta.atlasType.GetName()); + case FontAtlasType::BITMAP: SetShader(&DEFAULT_SHADER_BITMAP); break; + } } - - SimpleDrawable::Init(shader, &m_geometry, &m_material, &m_uniBuffer); } void TextDrawable::SetAtlasData(const std::shared_ptr& atlasData) diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 6e01092..4547464 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -6,9 +6,8 @@ #pragma once -#include "SimpleDrawable.hpp" +#include "Drawable.hpp" #include "Texture.hpp" -#include "Material.hpp" #include "Geometry.hpp" #include "UniformBuffer.hpp" #include "AtlasData.hpp" @@ -26,10 +25,9 @@ namespace OpenVulkano::Scene float smoothing = 1.f/32.f; }; - class TextDrawable : public SimpleDrawable + class TextDrawable : public Drawable { Geometry m_geometry; - Material m_material; UniformBuffer m_uniBuffer; std::shared_ptr m_atlasData; Math::AABB m_bbox; @@ -52,5 +50,9 @@ namespace OpenVulkano::Scene [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } [[nodiscard]] const std::shared_ptr GetAtlasData() { return m_atlasData; } + + [[nodiscard]] Geometry* GetGeometry() { return &m_geometry; } + [[nodiscard]] Texture* GetTexture() { return &m_atlasData->texture; } + [[nodiscard]] UniformBuffer* GetUniformBuffer() { return &m_uniBuffer; } }; } diff --git a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp index 7371174..eeac1f7 100644 --- a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp @@ -18,11 +18,11 @@ using namespace OpenVulkano::Scene; namespace OpenVulkano::Vulkan { - void EncodeBackground(LabelDrawable* labelDrawable, Vulkan::VulkanDrawContext* drawContext) + void EncodeBackground(LabelDrawable* labelDrawable, VulkanDrawContext* drawContext) { if (labelDrawable->IsBillboard()) { - OpenVulkano::Scene::UniformBuffer* buffer = labelDrawable->GetBillboardBuffer(); + Scene::UniformBuffer* buffer = labelDrawable->GetBillboardBuffer(); VulkanUniformBuffer* vkBuffer = buffer->GetRenderResource(); if (!vkBuffer) { @@ -31,7 +31,7 @@ namespace OpenVulkano::Vulkan vkBuffer->Record(drawContext); } - OpenVulkano::Scene::UniformBuffer* labelBuffer = labelDrawable->GetLabelBuffer(); + Scene::UniformBuffer* labelBuffer = labelDrawable->GetLabelBuffer(); VulkanUniformBuffer* vkBuffer = labelBuffer->GetRenderResource(); if (!vkBuffer) { @@ -50,13 +50,13 @@ namespace OpenVulkano::Vulkan drawContext->commandBuffer.draw(4, 1, 0, 0); } - void EncodeTextDrawable(LabelDrawable* labelDrawable, Vulkan::VulkanDrawContext* drawContext) + void EncodeTextDrawable(LabelDrawable* labelDrawable, VulkanDrawContext* drawContext) { for (TextDrawable& entry : labelDrawable->GetTexts()) { - OpenVulkano::Scene::Shader* shader = entry.GetShader(); + Shader* shader = entry.GetShader(); drawContext->EncodeShader(shader); - Geometry* mesh = entry.GetMesh(); + Geometry* mesh = entry.GetGeometry(); VulkanGeometry* renderGeo = mesh->GetRenderResource(); if (!renderGeo) { @@ -64,16 +64,16 @@ namespace OpenVulkano::Vulkan } renderGeo->RecordBind(drawContext->commandBuffer); - std::array uniforms = { nullptr, nullptr }; + std::array uniforms = { nullptr, nullptr }; // fragment shader buffer - uniforms[0] = entry.GetBuffer(); + uniforms[0] = entry.GetUniformBuffer(); if (labelDrawable->IsBillboard()) { // vertex shader buffer uniforms[1] = labelDrawable->GetBillboardBuffer(); } - for (OpenVulkano::Scene::UniformBuffer* buffer : uniforms) + for (Scene::UniformBuffer* buffer : uniforms) { if (buffer) { @@ -85,19 +85,15 @@ namespace OpenVulkano::Vulkan vkBuffer->Record(drawContext); } } - - if (Material* material = entry.GetMaterial()) + + if (Texture* texture = entry.GetTexture()) { - if (Texture* texture = material->texture) + VulkanTexture* renderTexture = texture->GetRenderResource(); + if (!renderTexture) { - VulkanTexture* renderTexture = texture->GetRenderResource(); - if (!renderTexture) - { - drawContext->renderer->GetResourceManager().PrepareMaterial(entry.GetMaterial()); - renderTexture = texture->GetRenderResource(); - } - renderTexture->Record(drawContext); + renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(entry.GetTexture()); } + renderTexture->Record(drawContext); } for (Node* node: labelDrawable->GetNodes()) @@ -112,7 +108,7 @@ namespace OpenVulkano::Vulkan } } - void EncodeLabelDrawable(Drawable* instance, Vulkan::VulkanDrawContext* drawContext) + void EncodeLabelDrawable(Drawable* instance, VulkanDrawContext* drawContext) { LabelDrawable* labelDrawable = static_cast(instance); EncodeBackground(labelDrawable, drawContext); @@ -122,5 +118,5 @@ namespace OpenVulkano::Vulkan namespace { - void* labelDrawableVulkanEncoderReg = DrawEncoder::RegisterVulkanEncodeFunction(&OpenVulkano::Vulkan::EncodeLabelDrawable); + [[maybe_unused]] void* labelDrawableVulkanEncoderReg = DrawEncoder::RegisterVulkanEncodeFunction(&OpenVulkano::Vulkan::EncodeLabelDrawable); } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp new file mode 100644 index 0000000..9589ba4 --- /dev/null +++ b/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp @@ -0,0 +1,58 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "Scene/TextDrawable.hpp" +#include "VulkanGeometry.hpp" +#include "VulkanNode.hpp" +#include "Vulkan/VulkanDrawContext.hpp" +#include "Vulkan/Scene/VulkanUniformBuffer.hpp" +#include "VulkanTexture.hpp" + +using namespace OpenVulkano::Scene; + +namespace OpenVulkano::Vulkan +{ + void EncodeTextDrawable(Drawable* instance, Vulkan::VulkanDrawContext* drawContext) + { + TextDrawable* drawable = static_cast(instance); + Geometry* mesh = drawable->GetGeometry(); + VulkanGeometry* renderGeo = mesh->GetRenderResource(); + if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh); + renderGeo->RecordBind(drawContext->commandBuffer); + + if (drawable->GetUniformBuffer()) + { + VulkanUniformBuffer* vkBuffer = drawable->GetUniformBuffer()->GetRenderResource(); + if (!vkBuffer) + { + vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(drawable->GetUniformBuffer()); + } + vkBuffer->Record(drawContext); + } + + if (Texture* texture = drawable->GetTexture()) + { + VulkanTexture* renderTexture = texture->GetRenderResource(); + if (!renderTexture) + { + renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(drawable->GetTexture()); + } + renderTexture->Record(drawContext); + } + + for(Node* node : instance->GetNodes()) + { + if (!node->IsEnabled()) [[unlikely]] continue; + drawContext->EncodeNode(node); + renderGeo->RecordDraw(drawContext->commandBuffer); + } + } +} + +namespace +{ + [[maybe_unused]] void* textDrawableVulkanEncoderReg = DrawEncoder::RegisterVulkanEncodeFunction(&OpenVulkano::Vulkan::EncodeTextDrawable); +} \ No newline at end of file From 450f1170b48b51d622a7ef003caa28bb3cadd520 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 03:21:55 +0100 Subject: [PATCH 15/36] Remove redundancies --- examples/ExampleApps/BillboardExampleApp.cpp | 31 +++++++++-------- examples/ExampleApps/CubesExampleApp.cpp | 20 +++++------ .../ExampleApps/LabelDrawableExampleApp.cpp | 28 +++++----------- examples/ExampleApps/MovingCubeApp.cpp | 4 --- examples/ExampleApps/TextExampleApp.cpp | 33 +++++++------------ .../ExampleApps/TexturedCubeExampleApp.cpp | 21 ++++++------ examples/main.cpp | 21 ++---------- 7 files changed, 58 insertions(+), 100 deletions(-) diff --git a/examples/ExampleApps/BillboardExampleApp.cpp b/examples/ExampleApps/BillboardExampleApp.cpp index 068f812..dd7088f 100644 --- a/examples/ExampleApps/BillboardExampleApp.cpp +++ b/examples/ExampleApps/BillboardExampleApp.cpp @@ -31,10 +31,9 @@ namespace OpenVulkano class BillboardExampleAppImpl final : public BillboardExampleApp { public: - void Init() override { - auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); + auto engineConfig = EngineConfiguration::GetEngineConfiguration(); engineConfig->SetPreferFramebufferFormatSRGB(false); engineConfig->SetFpsCap(0); // monitor's refresh rate engineConfig->SetVSync(true); @@ -44,17 +43,17 @@ namespace OpenVulkano m_cam.Init(70, 16, 9, 0.1f, 100); m_scene.SetCamera(&m_cam); - m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboardFromSinglePoint"); - m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::GEOMETRY, "Shader/billboardFromSinglePoint"); - m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basic"); - m_quadBillboardShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + m_quadBillboardShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/billboardFromSinglePoint"); + m_quadBillboardShader.AddShaderProgram(ShaderProgramType::GEOMETRY, "Shader/billboardFromSinglePoint"); + m_quadBillboardShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basic"); + m_quadBillboardShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); m_quadBillboardShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); m_quadBillboardShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 4); m_quadBillboardShader.topology = Topology::POINT_LIST; - m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboard"); - m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basic"); - m_shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/billboard"); + m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basic"); + m_shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); m_shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); m_shader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 4); m_shader.cullMode = CullMode::NONE; @@ -85,13 +84,13 @@ namespace OpenVulkano geo->vertices[0].color = glm::vec4(1, 1, 1, 1); else geo->vertices[0].color = glm::vec4(1, 0, 0, 1); - m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, std::rand() % 5))); + m_nodesPool[i].SetMatrix(translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, std::rand() % 5))); m_drawablesPool[i].Init(&m_quadBillboardShader, geo, &m_texturedMat, &m_uniBuffer); } else { *geo = GeometryFactory::MakePyramid(1, 1, glm::vec4(0, 1, 0, 1)); - m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, -std::rand() % 10))); + m_nodesPool[i].SetMatrix(translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, -std::rand() % 10))); m_drawablesPool[i].Init(&m_shader, geo, &m_mat, &m_uniBuffer); } m_scene.GetRoot()->AddChild(&m_nodesPool[i]); @@ -105,8 +104,8 @@ namespace OpenVulkano m_camController.SetPosition({ 0, 0, 5 }); m_camController.SetBoostFactor(5); - std::shared_ptr m_perfInfo = - std::make_shared(); + std::shared_ptr m_perfInfo = + std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } @@ -125,7 +124,7 @@ namespace OpenVulkano BillboardControlBlock m_bbContolBlock; PerspectiveCamera m_cam; UniformBuffer m_uniBuffer; - OpenVulkano::FreeCamCameraController m_camController; + FreeCamCameraController m_camController; Material m_mat; Material m_texturedMat; Shader m_shader; @@ -133,9 +132,9 @@ namespace OpenVulkano std::vector m_drawablesPool; std::vector m_nodesPool; Vector3f_SIMD m_position = { 0, 0, -10 }; - OpenVulkano::Scene::UI::SimpleUi m_ui; + UI::SimpleUi m_ui; std::vector m_geo; - std::shared_ptr m_perfInfo; + std::shared_ptr m_perfInfo; }; IGraphicsApp* BillboardExampleApp::Create() { return new BillboardExampleAppImpl(); } diff --git a/examples/ExampleApps/CubesExampleApp.cpp b/examples/ExampleApps/CubesExampleApp.cpp index 391f548..d77ad3e 100644 --- a/examples/ExampleApps/CubesExampleApp.cpp +++ b/examples/ExampleApps/CubesExampleApp.cpp @@ -36,7 +36,7 @@ namespace OpenVulkano { OpenVulkano::Scene::Scene scene; PerspectiveCamera cam; - OpenVulkano::FreeCamCameraController camController; + FreeCamCameraController camController; Material mat; Shader shader; std::vector drawablesPool; @@ -44,13 +44,13 @@ namespace OpenVulkano Vector3f_SIMD position = {0, 0, -10}; std::vector m_geos; - OpenVulkano::Scene::UI::SimpleUi m_ui; - std::shared_ptr m_perfInfo; + UI::SimpleUi m_ui; + std::shared_ptr m_perfInfo; public: void Init() override { - auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); + auto engineConfig = EngineConfiguration::GetEngineConfiguration(); //engineConfig->SetNumThreads(4); engineConfig->SetPreferFramebufferFormatSRGB(false); @@ -58,9 +58,9 @@ namespace OpenVulkano scene.Init(); cam.Init(70, 16, 9, 0.1f, 100); scene.SetCamera(&cam); - shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/basic"); - shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basic"); - shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/basic"); + shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basic"); + shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); drawablesPool.resize(GEOS); m_geos.reserve(GEOS); for (uint32_t i = 0; i < GEOS; i++) @@ -78,7 +78,7 @@ namespace OpenVulkano scene.GetRoot()->AddChild(&nodesPool[i]); if (i < DYNAMIC) nodesPool[i].SetUpdateFrequency(UpdateFrequency::Always); nodesPool[i].AddDrawable(&drawablesPool[std::rand() % GEOS]); - nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1), Vector3f((std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5))); + nodesPool[i].SetMatrix(translate(glm::mat4x4(1), Vector3f((std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5))); } GetGraphicsAppManager()->GetRenderer()->SetScene(&scene); @@ -87,7 +87,7 @@ namespace OpenVulkano camController.SetDefaultKeybindings(); camController.SetPosition({0, 0, 10}); - std::shared_ptr m_perfInfo = std::make_shared(); + std::shared_ptr m_perfInfo = std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } @@ -96,7 +96,7 @@ namespace OpenVulkano { for (uint32_t i = 0; i < DYNAMIC; i++) { - nodesPool[i].SetMatrix(glm::translate(glm::mat4x4(1), glm::vec3((std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5))); + nodesPool[i].SetMatrix(translate(glm::mat4x4(1), glm::vec3((std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5, (std::rand() % 10000) / 1000.0f - 5))); } camController.Tick(); diff --git a/examples/ExampleApps/LabelDrawableExampleApp.cpp b/examples/ExampleApps/LabelDrawableExampleApp.cpp index a076eaf..ab899e6 100644 --- a/examples/ExampleApps/LabelDrawableExampleApp.cpp +++ b/examples/ExampleApps/LabelDrawableExampleApp.cpp @@ -7,14 +7,8 @@ #include "LabelDrawableExampleApp.hpp" #include "Scene/Scene.hpp" #include "Scene/Shader/Shader.hpp" -#include "Scene/Geometry.hpp" #include "Scene/TextDrawable.hpp" -#include "Scene/GeometryFactory.hpp" -#include "Scene/Material.hpp" -#include "Scene/Vertex.hpp" -#include "Scene/SimpleDrawable.hpp" #include "Scene/UI/PerformanceInfo.hpp" -#include "Scene/UniformBuffer.hpp" #include "Scene/Prefabs/LabelDrawable.hpp" #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" @@ -23,9 +17,7 @@ #include "Math/Math.hpp" #include "Base/EngineConfiguration.hpp" #include "Controller/FreeCamCameraController.hpp" -#include "Image/ImageLoaderPng.hpp" #include "Scene/SdfFontAtlasGenerator.hpp" -#include "Scene/IFontAtlasGenerator.hpp" #include #ifdef _WIN32 @@ -45,9 +37,7 @@ namespace OpenVulkano void Init() override { - auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); - engineConfig->SetNumThreads(1); - engineConfig->SetPreferFramebufferFormatSRGB(false); + EngineConfiguration::GetEngineConfiguration()->SetPreferFramebufferFormatSRGB(false); std::srand(1); // Fix seed for random numbers m_scene.Init(); @@ -74,10 +64,10 @@ namespace OpenVulkano } else { - labelSettings.hasRoundedCorners = (i % 2 == 0 ? 0 : 1); - labelSettings.hasArrow = (i % 2 == 0 ? 1 : 0); + labelSettings.hasRoundedCorners = i % 2 == 0 ? 0 : 1; + labelSettings.hasArrow = i % 2 == 0 ? 1 : 0; } - bool isBillboard = (i % 2 == 0 ? 1 : 0); + bool isBillboard = i % 2 == 0 ? 1 : 0; LabelDrawable& label = m_drawablesPool.emplace_back(textDrawable.GetAtlasData(), labelSettings, isBillboard); label.SetBillboardSettings(billboardSettings); label.AddText(texts[i]); @@ -100,8 +90,8 @@ namespace OpenVulkano m_camController.SetPosition({ 0, 0, 10 }); m_camController.SetBoostFactor(5); - std::shared_ptr m_perfInfo = - std::make_shared(); + std::shared_ptr m_perfInfo = + std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } @@ -116,12 +106,12 @@ namespace OpenVulkano private: OpenVulkano::Scene::Scene m_scene; PerspectiveCamera m_cam; - OpenVulkano::FreeCamCameraController m_camController; + FreeCamCameraController m_camController; std::vector m_drawablesPool; std::vector m_nodesPool; Vector3f_SIMD m_position = { 0, 0, -10 }; - OpenVulkano::Scene::UI::SimpleUi m_ui; - std::shared_ptr m_perfInfo; + UI::SimpleUi m_ui; + std::shared_ptr m_perfInfo; }; IGraphicsApp* LabelDrawableExampleApp::Create() { return new LabelDrawableExampleAppImpl(); } diff --git a/examples/ExampleApps/MovingCubeApp.cpp b/examples/ExampleApps/MovingCubeApp.cpp index d33dcd8..2fa39e3 100644 --- a/examples/ExampleApps/MovingCubeApp.cpp +++ b/examples/ExampleApps/MovingCubeApp.cpp @@ -17,16 +17,12 @@ #include "Scene/SimpleAnimationController.hpp" #include "Scene/SequenceAnimationController.hpp" #include "Scene/MorphableCameraController.hpp" -#include "Scene/PlaneCameraController.hpp" #include "Scene/UI/PerformanceInfo.hpp" #include "Scene/SceneIntersectionTestController.hpp" -#include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" -#include "Base/EngineConfiguration.hpp" #include "Base/Logger.hpp" #include "Controller/FreeCamCameraController.hpp" #include "Scene/Prefabs/LabelDrawable.hpp" -#include "Scene/SimpleDrawable.hpp" #include "Scene/Ray.hpp" #define USE_PLANE_CAM_CONTROL 0 diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 26538d2..11be545 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -9,12 +9,8 @@ #include "Scene/Shader/Shader.hpp" #include "Scene/Geometry.hpp" #include "Scene/TextDrawable.hpp" -#include "Scene/GeometryFactory.hpp" -#include "Scene/Material.hpp" #include "Scene/Vertex.hpp" -#include "Scene/SimpleDrawable.hpp" #include "Scene/UI/PerformanceInfo.hpp" -#include "Scene/UniformBuffer.hpp" #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" #include "Host/GLFW/WindowGLFW.hpp" @@ -22,9 +18,7 @@ #include "Math/Math.hpp" #include "Base/EngineConfiguration.hpp" #include "Controller/FreeCamCameraController.hpp" -#include "Image/ImageLoaderPng.hpp" #include "Scene/SdfFontAtlasGenerator.hpp" -#include "Scene/IFontAtlasGenerator.hpp" #include "Scene/BitmapFontAtlasGenerator.hpp" #include @@ -45,11 +39,9 @@ namespace OpenVulkano class TextExampleAppImpl final : public TextExampleApp { public: - void Init() override { - auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); - engineConfig->SetPreferFramebufferFormatSRGB(false); + EngineConfiguration::GetEngineConfiguration()->SetPreferFramebufferFormatSRGB(false); std::srand(1); // Fix seed for random numbers m_scene.Init(); @@ -72,6 +64,7 @@ namespace OpenVulkano if constexpr (CREATE_BITMAP_ATLAS) { + // ReSharper disable once CppDFAUnreachableCode std::set s = BitmapFontAtlasGenerator::LoadAllGlyphs(fontPath); BitmapFontAtlasGenerator generator; generator.GenerateAtlas(fontPath, s); @@ -133,10 +126,10 @@ namespace OpenVulkano //TextDrawable* t = new TextDrawable(metadataInfo, &tex, texts[i].second); #endif // MSDFGEN_AVAILABLE t->GenerateText(texts[textIdx].first); - m_drawablesPool[i] = t; + m_drawablesPool[i].reset(t); m_nodesPool[i].Init(); m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(xOffset, 2 - textIdx * 2, 0))); - m_nodesPool[i].AddDrawable(m_drawablesPool[i]); + m_nodesPool[i].AddDrawable(m_drawablesPool[i].get()); m_scene.GetRoot()->AddChild(&m_nodesPool[i]); } GetGraphicsAppManager()->GetRenderer()->SetScene(&m_scene); @@ -145,8 +138,8 @@ namespace OpenVulkano m_camController.SetPosition({ 10, 0, 15 }); m_camController.SetBoostFactor(5); - std::shared_ptr m_perfInfo = - std::make_shared(); + std::shared_ptr m_perfInfo = + std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } @@ -158,26 +151,22 @@ namespace OpenVulkano void Close() override { - for (Drawable* d: m_drawablesPool) - { - d->Close(); - delete d; - } + m_drawablesPool.clear(); } private: OpenVulkano::Scene::Scene m_scene; PerspectiveCamera m_cam; - OpenVulkano::FreeCamCameraController m_camController; + FreeCamCameraController m_camController; #ifdef MSDFGEN_AVAILABLE SdfFontAtlasGenerator m_atlasGenerator; MsdfFontAtlasGenerator m_msdfAtlasGenerator; #endif - std::vector m_drawablesPool; + std::vector> m_drawablesPool; std::vector m_nodesPool; Vector3f_SIMD m_position = { 0, 0, -10 }; - OpenVulkano::Scene::UI::SimpleUi m_ui; - std::shared_ptr m_perfInfo; + UI::SimpleUi m_ui; + std::shared_ptr m_perfInfo; }; IGraphicsApp* TextExampleApp::Create() { return new TextExampleAppImpl(); } diff --git a/examples/ExampleApps/TexturedCubeExampleApp.cpp b/examples/ExampleApps/TexturedCubeExampleApp.cpp index af3ba7d..396b49f 100644 --- a/examples/ExampleApps/TexturedCubeExampleApp.cpp +++ b/examples/ExampleApps/TexturedCubeExampleApp.cpp @@ -16,7 +16,6 @@ #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" #include "Math/Math.hpp" -#include "Base/EngineConfiguration.hpp" #include "Controller/FreeCamCameraController.hpp" #include "Base/FrameMetadata.hpp" @@ -30,14 +29,14 @@ namespace OpenVulkano { OpenVulkano::Scene::Scene scene; PerspectiveCamera cam; - OpenVulkano::FreeCamCameraController camController; + FreeCamCameraController camController; Material mat; Shader shader; SimpleDrawable drawable; Node node; - OpenVulkano::Scene::UI::SimpleUi m_ui; - std::shared_ptr m_perfInfo; + UI::SimpleUi m_ui; + std::shared_ptr m_perfInfo; public: void Init() override @@ -45,9 +44,9 @@ namespace OpenVulkano scene.Init(); cam.Init(70, 16, 9, 0.1f, 100); scene.SetCamera(&cam); - shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/basic"); - shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basicTexture"); - shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/basic"); + shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basicTexture"); + shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); static Geometry geo = GeometryFactory::MakeCube(); mat.texture = &Texture::PLACEHOLDER; @@ -63,7 +62,7 @@ namespace OpenVulkano //camController.SetDefaultKeybindings(); camController.SetPosition({0, 0, 2}); - m_perfInfo = std::make_shared(); + m_perfInfo = std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } @@ -73,9 +72,9 @@ namespace OpenVulkano { t += CURRENT_FRAME.frameTime * 0.25; - Math::Matrix4f rotation = Math::Utils::rotate(t, Math::Vector3f_SIMD{1.0f, 0.0f, 0.0f}); - rotation *= Math::Utils::rotate(t, Math::Vector3f_SIMD{0.0f, 1.0f, 0.0f}); - rotation *= Math::Utils::rotate(t, Math::Vector3f_SIMD{0.0f, 0.0f, 1.0f}); + Matrix4f rotation = Math::Utils::rotate(t, Vector3f_SIMD{1.0f, 0.0f, 0.0f}); + rotation *= Math::Utils::rotate(t, Vector3f_SIMD{0.0f, 1.0f, 0.0f}); + rotation *= Math::Utils::rotate(t, Vector3f_SIMD{0.0f, 0.0f, 1.0f}); node.SetMatrix(rotation); camController.Tick(); diff --git a/examples/main.cpp b/examples/main.cpp index f10b998..51a3807 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -29,27 +29,12 @@ int main(int argc, char** argv) int selectedExample = 0; ftxui::MenuOption option; auto screen = ftxui::ScreenInteractive::TerminalOutput(); - screen.ForceHandleCtrlC(true); - //screen.ForceHandleCtrlZ(true); - option.on_enter = screen.ExitLoopClosure(); auto menu = ftxui::Menu(&examples, &selectedExample, option); - bool shouldExit = false; - menu |= ftxui::CatchEvent( - [&](ftxui::Event event) - { - if (event == ftxui::Event::CtrlC || event == ftxui::Event::CtrlZ) - { - screen.ExitLoopClosure()(); - shouldExit = true; - } - return false; - }); + bool shouldExit = true; + option.on_enter = [&] { shouldExit = false; screen.ExitLoopClosure(); }; screen.Loop(menu); - if (shouldExit) - { - return 0; - } + if (shouldExit) return 0; if (selectedExample >= examples.size()) { From 994ae12b80d5cb1e51305bcec77217c2992e00f7 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 11:42:09 +0100 Subject: [PATCH 16/36] Remove branching --- openVulkanoCpp/Scene/TextDrawable.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index bb6fd43..5c8446e 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -145,7 +145,6 @@ namespace OpenVulkano::Scene m_geometry.Init(len * 4, len * 6); AtlasMetadata* meta; std::map* symbols; - m_material.texture = &m_atlasData->texture; symbols = &m_atlasData->glyphs; meta = &m_atlasData->meta; @@ -156,7 +155,6 @@ namespace OpenVulkano::Scene double posY = pos.y; int i = 0; Math::Vector3f bmin(pos), bmax(pos); - bool firstGlyph = true; while (begin != end) { uint32_t c = utf8::next(begin, end); @@ -204,16 +202,13 @@ namespace OpenVulkano::Scene // TODO: change to lower value(or ideally remove completely) to avoid overlapping and make less space between symbols // when setting for depth comparison operator will be available( <= ) cursorX += info.advance + 0.08; - if (firstGlyph) - { - bmin.x = m_geometry.vertices[vIdx].position.x; - firstGlyph = false; - } + bmax.x = std::max(bmax.x, m_geometry.vertices[vIdx + 1].position.x); bmax.y = std::max(bmax.y, m_geometry.vertices[vIdx + 2].position.y); bmin.y = std::min(bmin.y, m_geometry.vertices[vIdx + 1].position.y); ++i; } + bmin.x = m_geometry.vertices[0].position.x; m_bbox.Init(bmin, bmax); if (!GetShader()) From fad309d96d9dafc0b68f1b80ccba275303260e17 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 11:59:13 +0100 Subject: [PATCH 17/36] Move FreetypeHelper and cleanup glyph creation --- .../{Scene => Extensions}/FreetypeHelper.hpp | 2 +- openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp | 2 +- openVulkanoCpp/Scene/TextDrawable.cpp | 16 ++++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) rename openVulkanoCpp/{Scene => Extensions}/FreetypeHelper.hpp (85%) diff --git a/openVulkanoCpp/Scene/FreetypeHelper.hpp b/openVulkanoCpp/Extensions/FreetypeHelper.hpp similarity index 85% rename from openVulkanoCpp/Scene/FreetypeHelper.hpp rename to openVulkanoCpp/Extensions/FreetypeHelper.hpp index 7860f50..3f05c93 100644 --- a/openVulkanoCpp/Scene/FreetypeHelper.hpp +++ b/openVulkanoCpp/Extensions/FreetypeHelper.hpp @@ -6,7 +6,7 @@ #pragma once -#include +#include <../../../cmake-build/debug/_deps/freetype-src/freetype-install/include/freetype2/ft2build.h> #include FT_FREETYPE_H #include diff --git a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp index c4eae22..5561309 100644 --- a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp +++ b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp @@ -8,7 +8,7 @@ #include "IFontAtlasGenerator.hpp" #include "Math/AABB.hpp" -#include "FreetypeHelper.hpp" +#include "Extensions/FreetypeHelper.hpp" #include #include diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 5c8446e..1dba011 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -140,22 +140,18 @@ namespace OpenVulkano::Scene m_text = text; - size_t len = utf8::distance(text.begin(), text.end()); + const size_t len = utf8::distance(text.begin(), text.end()); m_geometry.Close(); m_geometry.Init(len * 4, len * 6); - AtlasMetadata* meta; - std::map* symbols; - symbols = &m_atlasData->glyphs; - meta = &m_atlasData->meta; + std::map* symbols = &m_atlasData->glyphs; + AtlasMetadata* meta = &m_atlasData->meta; double cursorX = pos.x; - auto begin = text.begin(); - auto end = text.end(); const double lineHeight = meta->lineHeight; double posY = pos.y; - int i = 0; Math::Vector3f bmin(pos), bmax(pos); - while (begin != end) + int i = 0; + for (auto begin = text.begin(), end = text.end(); begin != end;) { uint32_t c = utf8::next(begin, end); if (c == '\n') @@ -165,7 +161,7 @@ namespace OpenVulkano::Scene continue; } - if (symbols->find(c) == symbols->end()) + if (!symbols->contains(c)) { Logger::RENDER->warn("Could not find glyph for character {}, using fallback", c); c = fallbackGlyph; From 8250b2a3969c89fc3c8213057d9d5657842de39a Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 20:33:38 +0100 Subject: [PATCH 18/36] Add app id as first cli parameter --- examples/main.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/examples/main.cpp b/examples/main.cpp index 51a3807..263c96f 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -20,25 +20,32 @@ using namespace OpenVulkano; int main(int argc, char** argv) { - std::vector examples; - for (const auto& e : EXAMPLE_APPS) + int selectedExample = -1; + if (argc == 2) { - examples.emplace_back(e.first); + selectedExample = strtol(argv[1], nullptr, 10); } - - int selectedExample = 0; - ftxui::MenuOption option; - auto screen = ftxui::ScreenInteractive::TerminalOutput(); - auto menu = ftxui::Menu(&examples, &selectedExample, option); - bool shouldExit = true; - option.on_enter = [&] { shouldExit = false; screen.ExitLoopClosure(); }; - screen.Loop(menu); - - if (shouldExit) return 0; - - if (selectedExample >= examples.size()) + if (selectedExample < 0) { - throw std::runtime_error("Invalid menu selection!"); + std::vector examples; + for (const auto& e : EXAMPLE_APPS) + { + examples.emplace_back(e.first); + } + + ftxui::MenuOption option; + auto screen = ftxui::ScreenInteractive::TerminalOutput(); + bool shouldExit = true; + option.on_enter = [&]() { shouldExit = false; screen.ExitLoopClosure()(); }; + auto menu = ftxui::Menu(&examples, &selectedExample, option); + screen.Loop(menu); + + if (shouldExit) return 0; + + if (selectedExample >= examples.size()) + { + throw std::runtime_error("Invalid menu selection!"); + } } std::unique_ptr app(EXAMPLE_APPS[selectedExample].second()); From 6ccef62ad350aea40c170e5e942cc9553df8d3c1 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 20:56:53 +0100 Subject: [PATCH 19/36] Add VertexBuffer class --- openVulkanoCpp/Scene/VertexBuffer.hpp | 54 +++++++++++++++++++ .../Vulkan/Resources/ResourceManager.cpp | 19 +++++++ .../Vulkan/Resources/ResourceManager.hpp | 7 ++- .../Vulkan/Scene/VulkanVertexBuffer.hpp | 43 +++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 openVulkanoCpp/Scene/VertexBuffer.hpp create mode 100644 openVulkanoCpp/Vulkan/Scene/VulkanVertexBuffer.hpp diff --git a/openVulkanoCpp/Scene/VertexBuffer.hpp b/openVulkanoCpp/Scene/VertexBuffer.hpp new file mode 100644 index 0000000..3655881 --- /dev/null +++ b/openVulkanoCpp/Scene/VertexBuffer.hpp @@ -0,0 +1,54 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Base/Render/RenderResource.hpp" +#include "Scene/UpdateFrequency.hpp" + +namespace OpenVulkano::Scene +{ + class VertexBuffer final : public RenderResourceHolder + { + public: + size_t size = 0; + const void* data = nullptr; + UpdateFrequency updateFrequency = UpdateFrequency::Never; + bool updated = true; + bool ownsMemory = true; + + ~VertexBuffer() { Close(); } + + void Init(size_t size, const void* data) + { + this->size = size; + this->data = data; + this->ownsMemory = false; + } + + void Init(size_t size) + { + this->size = size; + this->data = malloc(size); + this->ownsMemory = true; + } + + template + T* Init(size_t count) + { + Init(count * sizeof(T)); + return static_cast(const_cast(data)); + } + + void Close() + { + if (ownsMemory && data) free(const_cast(data)); + data = nullptr; + } + + UpdateFrequency GetUpdateFrequency() const { return updateFrequency; } + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 452e907..bd88819 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -5,6 +5,9 @@ */ #include "ResourceManager.hpp" + +#include + #include "ManagedBuffer.hpp" #include "MemoryAllocation.hpp" #include "Scene/Vertex.hpp" @@ -21,6 +24,7 @@ #include "Vulkan/Scene/VulkanTexture.hpp" #include "Vulkan/Scene/VulkanCamera.hpp" #include "Vulkan/Scene/VulkanUniformBuffer.hpp" +#include "Vulkan/Scene/VulkanVertexBuffer.hpp" namespace OpenVulkano::Vulkan { @@ -173,6 +177,21 @@ namespace OpenVulkano::Vulkan return geometry->GetRenderResource(); } + VulkanVertexBuffer* ResourceManager::PrepareVertexBuffer(Scene::VertexBuffer* vbo) + { + const std::unique_lock lock(mutex); + if(!vbo->HasRenderResource()) + { + ManagedBuffer::Ptr vertexBuffer = + CreateDeviceOnlyBufferWithData(vbo->size, vk::BufferUsageFlagBits::eVertexBuffer, vbo->data); + ManagedBuffer::Ptr indexBuffer; + VulkanVertexBuffer* vkVbo = new VulkanVertexBuffer(vbo, vertexBuffer); + vertexBuffers.emplace_back(vkVbo); + return vkVbo; + } + return vbo->GetRenderResource(); + } + void ResourceManager::PrepareMaterial(Scene::Material* material) { if (material->texture && !material->texture->HasRenderResource()) diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index 9274a32..100c767 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -34,6 +34,7 @@ namespace OpenVulkano class Shader; class Camera; class UniformBuffer; + class VertexBuffer; } namespace Vulkan @@ -45,11 +46,12 @@ namespace OpenVulkano class VulkanNode; class VulkanShader; class VulkanUniformBuffer; + class VulkanVertexBuffer; class UniformBuffer; class ManagedBuffer; class MemoryAllocation; - class ResourceManager : public IShaderOwner, public IResourceManager + class ResourceManager final : public IShaderOwner, public IResourceManager { friend UniformBuffer; friend VulkanTexture; @@ -63,6 +65,7 @@ namespace OpenVulkano MemoryPool memPool; std::vector> shaders; std::vector> geometries; + std::vector> vertexBuffers; std::vector> nodes; std::vector> textures; std::vector> cameras; @@ -100,6 +103,8 @@ namespace OpenVulkano VulkanUniformBuffer* PrepareUniformBuffer(Scene::UniformBuffer* buffer); + VulkanVertexBuffer* PrepareVertexBuffer(Scene::VertexBuffer* vbo); + VulkanNode* PrepareNode(Scene::Node* node); VulkanTexture* PrepareTexture(Scene::Texture* texture); diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanVertexBuffer.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanVertexBuffer.hpp new file mode 100644 index 0000000..f774ab9 --- /dev/null +++ b/openVulkanoCpp/Vulkan/Scene/VulkanVertexBuffer.hpp @@ -0,0 +1,43 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "IRecordable.hpp" +#include "Scene/Scene.hpp" +#include "Scene/VertexBuffer.hpp" +#include "Vulkan/Resources/ManagedBuffer.hpp" + +namespace OpenVulkano::Vulkan +{ + class VulkanVertexBuffer final : public IRenderResource + { + ManagedBuffer::Ptr m_vertexBuffer; + + public: + VulkanVertexBuffer(Scene::VertexBuffer* vbo, ManagedBuffer::Ptr& vertexBuffer) + : IRenderResource(vbo) , m_vertexBuffer(std::move(vertexBuffer)) + {} + + ~VulkanVertexBuffer() override = default; + + void RecordBind(vk::CommandBuffer& cmdBuffer) + { + const vk::DeviceSize m_offsets = 0; + cmdBuffer.bindVertexBuffers(0, 1, &m_vertexBuffer->buffer, &m_offsets); + } + + void RecordDraw(vk::CommandBuffer& cmdBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex = 0, uint32_t firstInstance = 0) + { + cmdBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance); + } + + void Release() override + { + //TODO + } + }; +} From c0e85d4fba4b8d5bbcb8aa813cd34c2c980ca518 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 20:58:49 +0100 Subject: [PATCH 20/36] Add vertex buffer step mode config --- openVulkanoCpp/Scene/Shader/VertexInputDescription.hpp | 7 ++++++- openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Scene/Shader/VertexInputDescription.hpp b/openVulkanoCpp/Scene/Shader/VertexInputDescription.hpp index 03cb00f..1908ce7 100644 --- a/openVulkanoCpp/Scene/Shader/VertexInputDescription.hpp +++ b/openVulkanoCpp/Scene/Shader/VertexInputDescription.hpp @@ -12,6 +12,8 @@ namespace OpenVulkano { + enum class VertexStepMode : uint32_t { VERTEX = 0, INSTANCE }; + struct VertexInputParameter { uint32_t location; @@ -32,13 +34,16 @@ namespace OpenVulkano { uint32_t bindingId; uint32_t vertexSize; + VertexStepMode stepMode = VertexStepMode::VERTEX; std::vector inputParameters; VertexInputDescription(uint32_t bindingId, uint32_t vertexSize) : bindingId(bindingId), vertexSize(vertexSize) {} VertexInputDescription(uint32_t bindingId, const VertexInputDescription& vertexDescription) - : bindingId(bindingId), vertexSize(vertexDescription.vertexSize), inputParameters(vertexDescription.inputParameters) + : bindingId(bindingId), vertexSize(vertexDescription.vertexSize) + , stepMode(vertexDescription.stepMode) + , inputParameters(vertexDescription.inputParameters) { for (auto& param : inputParameters) { diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index e7bc334..c1046ce 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -54,7 +54,7 @@ namespace OpenVulkano::Vulkan for(const auto& description : shader->vertexInputDescriptions) { - vertexBindDesc.emplace_back(description.bindingId, description.vertexSize, vk::VertexInputRate::eVertex); + vertexBindDesc.emplace_back(description.bindingId, description.vertexSize, static_cast(description.stepMode)); if (shader->vertexInputDescriptions.size() > 1) { for(const auto& param : description.inputParameters) From 47a904f572795a15cec7bd803ec037b88ebb803e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 4 Jan 2025 21:16:08 +0100 Subject: [PATCH 21/36] Move GetDefaultShader logic into function --- openVulkanoCpp/Scene/TextDrawable.cpp | 22 ++++++++++++---------- openVulkanoCpp/Scene/TextDrawable.hpp | 4 +++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index 1dba011..b127b1d 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -207,16 +207,7 @@ namespace OpenVulkano::Scene bmin.x = m_geometry.vertices[0].position.x; m_bbox.Init(bmin, bmax); - if (!GetShader()) - { - switch (m_atlasData->meta.atlasType) - { - case FontAtlasType::SDF: SetShader(&DEFAULT_SHADER_SDF); break; - case FontAtlasType::MSDF: SetShader(&DEFAULT_SHADER_MSDF); break; - default: Logger::RENDER->warn("No default shader for atlas type: {}", m_atlasData->meta.atlasType.GetName()); - case FontAtlasType::BITMAP: SetShader(&DEFAULT_SHADER_BITMAP); break; - } - } + if (!GetShader()) SetShader(GetDefaultShader(m_atlasData->meta.atlasType)); } void TextDrawable::SetAtlasData(const std::shared_ptr& atlasData) @@ -224,4 +215,15 @@ namespace OpenVulkano::Scene if (!atlasData || !*atlasData) throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); m_atlasData = atlasData; } + + Shader* TextDrawable::GetDefaultShader(const FontAtlasType type) + { + switch (type) + { + case FontAtlasType::SDF: return &DEFAULT_SHADER_SDF; + case FontAtlasType::MSDF: return &DEFAULT_SHADER_MSDF; + default: Logger::RENDER->warn("No default shader for atlas type: {}", type.GetName()); + case FontAtlasType::BITMAP: return &DEFAULT_SHADER_BITMAP; + } + } } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 4547464..c4eb502 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -49,10 +49,12 @@ namespace OpenVulkano::Scene [[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; } [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } - [[nodiscard]] const std::shared_ptr GetAtlasData() { return m_atlasData; } + [[nodiscard]] const std::shared_ptr& GetAtlasData() { return m_atlasData; } [[nodiscard]] Geometry* GetGeometry() { return &m_geometry; } [[nodiscard]] Texture* GetTexture() { return &m_atlasData->texture; } [[nodiscard]] UniformBuffer* GetUniformBuffer() { return &m_uniBuffer; } + + [[nodiscard]] static Shader* GetDefaultShader(FontAtlasType type); }; } From e9a1c629d9e134716c0d1dca9097d4001b6b3b2f Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 00:02:01 +0100 Subject: [PATCH 22/36] Switch to more compact TextGlyph vertex format --- examples/ExampleApps/TextExampleApp.cpp | 2 +- openVulkanoCpp/Extensions/FreetypeHelper.hpp | 2 +- .../Scene/Prefabs/LabelDrawable.cpp | 80 ++++++------ .../Scene/Prefabs/LabelDrawable.hpp | 9 +- openVulkanoCpp/Scene/TextDrawable.cpp | 116 ++++++++---------- openVulkanoCpp/Scene/TextDrawable.hpp | 28 +++-- openVulkanoCpp/Shader/msdfText.frag | 30 ++--- openVulkanoCpp/Shader/sdfText.frag | 21 ++-- openVulkanoCpp/Shader/text.frag | 15 +-- openVulkanoCpp/Shader/text.vert | 26 ++-- openVulkanoCpp/Shader/textBillboard.vert | 64 ++++++++++ .../Scene/LabelDrawableVulkanEncoder.cpp | 69 ++++------- .../Scene/TextDrawableVulkanEncoder.cpp | 35 ++---- 13 files changed, 249 insertions(+), 248 deletions(-) create mode 100644 openVulkanoCpp/Shader/textBillboard.vert diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 11be545..f5b11ee 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -54,7 +54,7 @@ namespace OpenVulkano texts.push_back(std::make_pair("\u0410\u0411\u0412\u041F", TextConfig())); texts.push_back(std::make_pair("Unsupported glyphs \u1E30\u1E31 are coming", TextConfig())); texts.push_back(std::make_pair("This is first line\nSecond gg line\nThird G line", TextConfig())); - texts[1].second.backgroundColor.a = 1; + texts[1].second.backgroundColor.a = 255; const int N = texts.size(); auto& resourceLoader = ResourceLoader::GetInstance(); diff --git a/openVulkanoCpp/Extensions/FreetypeHelper.hpp b/openVulkanoCpp/Extensions/FreetypeHelper.hpp index 3f05c93..7860f50 100644 --- a/openVulkanoCpp/Extensions/FreetypeHelper.hpp +++ b/openVulkanoCpp/Extensions/FreetypeHelper.hpp @@ -6,7 +6,7 @@ #pragma once -#include <../../../cmake-build/debug/_deps/freetype-src/freetype-install/include/freetype2/ft2build.h> +#include #include FT_FREETYPE_H #include diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 5e5b0c1..89926ad 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -7,6 +7,8 @@ #include "LabelDrawable.hpp" #include "Scene/TextDrawable.hpp" #include "Scene/DrawEncoder.hpp" +#include "Scene/Vertex.hpp" +#include "Scene/Shader/Shader.hpp" #include "Scene/IFontAtlasGenerator.hpp" #include "Base/Logger.hpp" #include @@ -39,10 +41,45 @@ namespace OpenVulkano::Scene backgroundShader.cullMode = CullMode::NONE; return backgroundShader; } - } - Shader LabelDrawable::BACKGROUND_SHADER = MakeLabelBgShader(false); - Shader LabelDrawable::BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true); + Shader MakeLabelTextShader(const FontAtlasType type, const bool billboard) + { + Shader shader = TextDrawable::MakeDefaultShader(type); + shader.depthTest = false; + shader.depthCompareOp = CompareOp::LESS_OR_EQUAL; + if (billboard) + { + for (auto& program : shader.shaderPrograms) + { + if (program.type == ShaderProgramType::VERTEX) + { + program.name = "Shader/textBillboard"; + break; + } + } + DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; + billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX; + shader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4); + } + return shader; + } + + Shader BACKGROUND_SHADER = MakeLabelBgShader(false); + Shader BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true); + std::array TEXT_SHADERS = { + MakeLabelTextShader(FontAtlasType::SDF, false), + MakeLabelTextShader(FontAtlasType::SDF, true), + MakeLabelTextShader(FontAtlasType::MSDF, false), + MakeLabelTextShader(FontAtlasType::MSDF, true), + MakeLabelTextShader(FontAtlasType::BITMAP, false), + MakeLabelTextShader(FontAtlasType::BITMAP, true), + }; + + Shader* GetTextShader(const FontAtlasType type, const bool billboard) + { + return &TEXT_SHADERS[static_cast(type) << 1 | billboard]; + } + } LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, const bool isBillboard) : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard) @@ -52,7 +89,7 @@ namespace OpenVulkano::Scene throw std::runtime_error("Can't create label drawable. Either glyphs or texture is empty"); } SetLabelSettings(settings); - SetupShaders(); + SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER); SetupBuffers(); } @@ -72,11 +109,10 @@ namespace OpenVulkano::Scene if (text.empty()) return; TextDrawable& textDrawable = m_texts.emplace_back(m_atlasData, config); - // do not render glyph's background - textDrawable.GetConfig().backgroundColor.a = 0; + textDrawable.GetConfig().backgroundColor.a = 0; // do not render glyph's background double lineHeight = m_atlasData->meta.lineHeight; textDrawable.GenerateText(text, m_position); - textDrawable.SetShader(&m_textShader); + textDrawable.SetShader(GetTextShader(m_atlasData->meta.atlasType, m_isBillboard)); m_bbox.Grow(textDrawable.GetBoundingBox()); // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; @@ -107,36 +143,6 @@ namespace OpenVulkano::Scene return ray.IntersectAABB(m_bbox); } - void LabelDrawable::SetupShaders() - { - SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER); - - FontAtlasType fontAtlasType(static_cast(m_atlasData->meta.atlasType)); - if (!m_isBillboard) - { - m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); - } - else - { - m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/billboard"); - DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX; - m_textShader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4); - } - - DescriptorSetLayoutBinding textUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - textUniformBinding.stageFlags = ShaderProgramType::FRAGMENT; - m_textShader.AddDescriptorSetLayoutBinding(textUniformBinding, 3); - m_textShader.AddShaderProgram(ShaderProgramType::FRAGMENT, - std::string(fontAtlasType.GetDefaultFragmentShader())); - m_textShader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); - m_textShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2); - m_textShader.alphaBlend = true; - m_textShader.cullMode = CullMode::NONE; - m_textShader.depthWrite = false; - m_textShader.depthCompareOp = CompareOp::LESS_OR_EQUAL; - } - void LabelDrawable::SetupBuffers() { m_billboardBuffer.size = sizeof(BillboardControlBlock); diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index cb406d9..4357b42 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -6,12 +6,9 @@ #pragma once -#include "Base/Wrapper.hpp" #include "Scene/Drawable.hpp" -#include "Scene/Shader/Shader.hpp" #include "Scene/Texture.hpp" #include "Scene/UniformBuffer.hpp" -#include "Scene/Vertex.hpp" #include "Scene/BillboardControlBlock.hpp" #include "Math/AABB.hpp" #include "Scene/TextDrawable.hpp" @@ -19,6 +16,8 @@ namespace OpenVulkano::Scene { + class Shader; + struct LabelDrawableSettings { Math::Vector4f backgroundColor = { 1, 0, 0, 1 }; @@ -45,8 +44,6 @@ namespace OpenVulkano::Scene class LabelDrawable final : public Drawable { - static Shader BACKGROUND_SHADER, BACKGROUND_BILLBOARD_SHADER; - public: LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings = LabelDrawableSettings(), bool isBillboard = false); @@ -65,13 +62,11 @@ namespace OpenVulkano::Scene std::optional Intersect(const Ray& ray) const override; private: - void SetupShaders(); void SetupBuffers(); UniformBuffer m_billboardBuffer; UniformBuffer m_labelBuffer; std::list m_texts; // Using list instead of vector for stable iterators - Shader m_textShader; LabelDrawableSettings m_settings; LabelUniformData m_labelData; std::shared_ptr m_atlasData; diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index b127b1d..88acca2 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -6,9 +6,7 @@ #include "TextDrawable.hpp" #include "Scene/Geometry.hpp" -#include "Scene/Material.hpp" -#include "Scene/Vertex.hpp" -#include "Scene/UniformBuffer.hpp" +#include "Shader/Shader.hpp" #include "Scene/IFontAtlasGenerator.hpp" #include "Base/Logger.hpp" #include "Host/ResourceLoader.hpp" @@ -24,32 +22,39 @@ namespace OpenVulkano::Scene { constexpr uint32_t MISSING_GLYPH_SYMBOL = '?'; - Shader MakeDefaultShader(FontAtlasType type) - { - Shader shader; - shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); - shader.AddShaderProgram(ShaderProgramType::FRAGMENT, std::string(type.GetDefaultFragmentShader())); - shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); - shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); - DescriptorSetLayoutBinding desc = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - desc.stageFlags = ShaderProgramType::FRAGMENT; - shader.AddDescriptorSetLayoutBinding(desc); - shader.alphaBlend = true; - shader.cullMode = CullMode::NONE; - return shader; - } + Shader DEFAULT_SHADER_BITMAP = TextDrawable::MakeDefaultShader(FontAtlasType::BITMAP); + Shader DEFAULT_SHADER_SDF = TextDrawable::MakeDefaultShader(FontAtlasType::SDF); + Shader DEFAULT_SHADER_MSDF = TextDrawable::MakeDefaultShader(FontAtlasType::MSDF); + } - Shader DEFAULT_SHADER_BITMAP = MakeDefaultShader(FontAtlasType::BITMAP); - Shader DEFAULT_SHADER_SDF = MakeDefaultShader(FontAtlasType::SDF); - Shader DEFAULT_SHADER_MSDF = MakeDefaultShader(FontAtlasType::MSDF); + Shader TextDrawable::MakeDefaultShader(const FontAtlasType type) + { + Shader shader; + shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text"); + shader.AddShaderProgram(ShaderProgramType::FRAGMENT, std::string(type.GetDefaultFragmentShader())); + VertexInputDescription inputDesc(0, sizeof(TextGlyphVertex)); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, position)); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, position)+8); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, position)+16); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, position)+24); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, uv)); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, uv)+8); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, uv)+16); + inputDesc.AddInputParameter(DataFormat::R32G32_SFLOAT, offsetof(TextGlyphVertex, uv)+24); + inputDesc.AddInputParameter(DataFormat::R8G8B8A8_UNORM, offsetof(TextGlyphVertex, color)); + inputDesc.AddInputParameter(DataFormat::R8G8B8A8_UNORM, offsetof(TextGlyphVertex, background)); + inputDesc.stepMode = VertexStepMode::INSTANCE; + shader.AddVertexInputDescription(inputDesc); + shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING); + shader.alphaBlend = true; + shader.cullMode = CullMode::NONE; + shader.topology = Topology::TRIANGLE_FAN; + return shader; } TextDrawable::TextDrawable(const TextConfig& config) : Drawable(DrawEncoder::GetDrawEncoder()), m_cfg(config) - { - m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); - m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; - } + {} TextDrawable::TextDrawable(const Array& atlasMetadata, const TextConfig& config) : TextDrawable(atlasMetadata, nullptr, config) @@ -106,8 +111,6 @@ namespace OpenVulkano::Scene read_bytes += sizeof(GlyphInfo); readMetadataBytes += sizeof(GlyphInfo); } - m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); - m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; if (m_atlasData->meta.atlasType == FontAtlasType::BITMAP) { m_atlasData->texture.m_samplerConfig = &SamplerConfig::NEAREST; @@ -118,8 +121,6 @@ namespace OpenVulkano::Scene : Drawable(DrawEncoder::GetDrawEncoder()), m_atlasData(atlasData), m_cfg(config) { if (!atlasData || !*atlasData) throw std::runtime_error("Cannot initialize text drawable with empty atlas data"); - m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3); - m_uniBuffer.binding.stageFlags = ShaderProgramType::FRAGMENT; } uint32_t TextDrawable::GetFallbackGlyph() const @@ -132,25 +133,24 @@ namespace OpenVulkano::Scene return m_atlasData->glyphs.begin()->first; } - - void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos) + void TextDrawable::GenerateText(const std::string& text, const Math::Vector2f& pos) { if (text.empty()) return; + if (m_vertexBuffer.data) throw std::runtime_error("Text has already been initialized"); const uint32_t fallbackGlyph = GetFallbackGlyph(); m_text = text; - + m_symbolCount = 0; const size_t len = utf8::distance(text.begin(), text.end()); - m_geometry.Close(); - m_geometry.Init(len * 4, len * 6); + m_vertexBuffer.Close(); + TextGlyphVertex* vertices = m_vertexBuffer.Init(len); std::map* symbols = &m_atlasData->glyphs; AtlasMetadata* meta = &m_atlasData->meta; double cursorX = pos.x; const double lineHeight = meta->lineHeight; double posY = pos.y; - Math::Vector3f bmin(pos), bmax(pos); - int i = 0; + Math::Vector3f bmin(pos, 0), bmax(pos, 0); for (auto begin = text.begin(), end = text.end(); begin != end;) { uint32_t c = utf8::next(begin, end); @@ -160,6 +160,7 @@ namespace OpenVulkano::Scene cursorX = pos.x; continue; } + // TODO handle special chars if (!symbols->contains(c)) { @@ -167,44 +168,29 @@ namespace OpenVulkano::Scene c = fallbackGlyph; } - uint32_t vIdx = i * 4; - uint32_t indices[] = { 1 + vIdx, 2 + vIdx, 3 + vIdx, 1 + vIdx, 3 + vIdx, 0 + vIdx }; GlyphInfo& info = symbols->at(c); - // left bottom - m_geometry.vertices[vIdx].position.x = info.xyz[0].x + cursorX; - m_geometry.vertices[vIdx].position.y = posY - info.xyz[0].y; - m_geometry.vertices[vIdx].position.z = info.xyz[0].z; - m_geometry.vertices[vIdx].textureCoordinates = Math::Vector3f(info.uv[0], 0); + for (int i = 0; i < 4; i++) + { + vertices->position[i].x = info.xyz[i].x + cursorX; + vertices->uv[i] = info.uv[i]; + if (i < 2) vertices->position[i].y = posY - info.xyz[i].y; + else vertices->position[i].y = posY + info.xyz[i].y; + vertices->color = m_cfg.textColor; + vertices->background = m_cfg.backgroundColor; + } - // right bottom - m_geometry.vertices[vIdx + 1].position.x = info.xyz[1].x + cursorX; - m_geometry.vertices[vIdx + 1].position.y = posY - info.xyz[1].y; - m_geometry.vertices[vIdx + 1].position.z = info.xyz[1].z; - m_geometry.vertices[vIdx + 1].textureCoordinates = Math::Vector3f(info.uv[1], 0); - - // top right - m_geometry.vertices[vIdx + 2].position.x = info.xyz[2].x + cursorX; - m_geometry.vertices[vIdx + 2].position.y = posY + info.xyz[2].y; - m_geometry.vertices[vIdx + 2].position.z = info.xyz[2].z; - m_geometry.vertices[vIdx + 2].textureCoordinates = Math::Vector3f(info.uv[2], 0); - - // top left - m_geometry.vertices[vIdx + 3].position.x = info.xyz[3].x + cursorX; - m_geometry.vertices[vIdx + 3].position.y = posY + info.xyz[3].y; - m_geometry.vertices[vIdx + 3].position.z = info.xyz[3].z; - m_geometry.vertices[vIdx + 3].textureCoordinates = Math::Vector3f(info.uv[3], 0); - m_geometry.SetIndices(indices, 6, 6 * i); // TODO: change to lower value(or ideally remove completely) to avoid overlapping and make less space between symbols // when setting for depth comparison operator will be available( <= ) cursorX += info.advance + 0.08; - bmax.x = std::max(bmax.x, m_geometry.vertices[vIdx + 1].position.x); - bmax.y = std::max(bmax.y, m_geometry.vertices[vIdx + 2].position.y); - bmin.y = std::min(bmin.y, m_geometry.vertices[vIdx + 1].position.y); - ++i; + bmax.x = std::max(bmax.x, vertices->position[1].x); + bmax.y = std::max(bmax.y, vertices->position[2].y); + bmin.y = std::min(bmin.y, vertices->position[1].y); + vertices++; + m_symbolCount++; } - bmin.x = m_geometry.vertices[0].position.x; + bmin.x = vertices->position[0].x; m_bbox.Init(bmin, bmax); if (!GetShader()) SetShader(GetDefaultShader(m_atlasData->meta.atlasType)); diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index c4eb502..0af8ed4 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -8,8 +8,7 @@ #include "Drawable.hpp" #include "Texture.hpp" -#include "Geometry.hpp" -#include "UniformBuffer.hpp" +#include "VertexBuffer.hpp" #include "AtlasData.hpp" #include "Image/Image.hpp" @@ -19,19 +18,25 @@ namespace OpenVulkano::Scene struct TextConfig { - Math::Vector4f textColor = { 1, 1, 1, 1 }; - Math::Vector4f backgroundColor = { 0, 1, 0, 0 }; - float threshold = 0.4f; - float smoothing = 1.f/32.f; + Math::Vector4uc textColor = { 255, 255, 255, 255 }; + Math::Vector4uc backgroundColor = { 0, 255, 0, 0 }; + }; + + struct TextGlyphVertex + { + std::array position; + std::array uv; + Math::Vector4uc color = { 255, 255, 255, 255 }; + Math::Vector4uc background = {}; }; class TextDrawable : public Drawable { - Geometry m_geometry; - UniformBuffer m_uniBuffer; + VertexBuffer m_vertexBuffer; std::shared_ptr m_atlasData; Math::AABB m_bbox; std::string m_text; + size_t m_symbolCount = 0; TextConfig m_cfg; uint32_t GetFallbackGlyph() const; @@ -43,7 +48,7 @@ namespace OpenVulkano::Scene TextDrawable(const std::string& atlasMetadataFile, Texture* atlasTex, const TextConfig& config = TextConfig()); TextDrawable(const Array& atlasMetadata, Texture* atlasTex, const TextConfig& config = TextConfig()); TextDrawable(const std::shared_ptr& atlasData, const TextConfig& config = TextConfig()); - void GenerateText(const std::string& text, const Math::Vector3f& pos = Math::Vector3f(0.f)); + void GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } void SetAtlasData(const std::shared_ptr& atlasData); [[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; } @@ -51,10 +56,11 @@ namespace OpenVulkano::Scene [[nodiscard]] const std::string& GetText() const { return m_text; } [[nodiscard]] const std::shared_ptr& GetAtlasData() { return m_atlasData; } - [[nodiscard]] Geometry* GetGeometry() { return &m_geometry; } + [[nodiscard]] VertexBuffer* GetVertexBuffer() { return &m_vertexBuffer; } [[nodiscard]] Texture* GetTexture() { return &m_atlasData->texture; } - [[nodiscard]] UniformBuffer* GetUniformBuffer() { return &m_uniBuffer; } + [[nodiscard]] size_t GetSymbolCount() const { return m_symbolCount; } + [[nodiscard]] static Shader MakeDefaultShader(FontAtlasType type); [[nodiscard]] static Shader* GetDefaultShader(FontAtlasType type); }; } diff --git a/openVulkanoCpp/Shader/msdfText.frag b/openVulkanoCpp/Shader/msdfText.frag index 5bb8fd3..ad08fbd 100644 --- a/openVulkanoCpp/Shader/msdfText.frag +++ b/openVulkanoCpp/Shader/msdfText.frag @@ -1,44 +1,40 @@ #version 450 -layout(location = 1) in vec2 texCoord; +layout(location = 0) in vec4 color; +layout(location = 1) in vec4 bgColor; +layout(location = 2) in vec2 texCoord; layout(location = 0) out vec4 outColor; layout(set = 2, binding = 0) uniform sampler2D texSampler; -layout(set = 3, binding = 0) uniform TextConfig +float median(float r, float g, float b) { - vec4 textColor; - vec4 backgroundColor; - float threshold; - float smoothing; -} textConfig; - -float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } // this parameter should be same as FontAtlasGeneratorConfig::pixelRange const float pxRange = 3; -float screenPxRange() { - vec2 unitRange = vec2(pxRange)/vec2(textureSize(texSampler, 0)); - vec2 screenTexSize = vec2(1.0)/fwidth(texCoord); - return max(0.5*dot(unitRange, screenTexSize), 1.0); +float screenPxRange() +{ + vec2 unitRange = vec2(pxRange) / vec2(textureSize(texSampler, 0)); + vec2 screenTexSize = vec2(1.0) / fwidth(texCoord); + return max(0.5 * dot(unitRange, screenTexSize), 1.0); } void main() { vec3 msd = texture(texSampler, texCoord).rgb; float sd = median(msd.r, msd.g, msd.b); - float screenPxDistance = screenPxRange()*(sd - 0.5); + float screenPxDistance = screenPxRange() * (sd - 0.5); float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); - if (textConfig.backgroundColor.a != 0) + if (bgColor.a != 0) { - outColor = mix(textConfig.backgroundColor, textConfig.textColor, opacity); + outColor = mix(bgColor, color, opacity); } else { - outColor = vec4(vec3(textConfig.textColor), opacity); + outColor = vec4(vec3(color), opacity); } } diff --git a/openVulkanoCpp/Shader/sdfText.frag b/openVulkanoCpp/Shader/sdfText.frag index 49cc3ab..c5e17fa 100644 --- a/openVulkanoCpp/Shader/sdfText.frag +++ b/openVulkanoCpp/Shader/sdfText.frag @@ -1,27 +1,24 @@ #version 450 -layout(location = 1) in vec2 texCoord; +layout(location = 0) in vec4 color; +layout(location = 1) in vec4 bgColor; +layout(location = 2) in vec2 texCoord; layout(location = 0) out vec4 outColor; layout(set = 2, binding = 0) uniform sampler2D texSampler; -layout(set = 3, binding = 0) uniform TextConfig -{ - vec4 textColor; - vec4 backgroundColor; - float threshold; - float smoothing; -} textConfig; +const float threshold = 0.4f; +const float smoothing = 1.f/32.f; void main() { float distance = texture(texSampler, texCoord).r; - float alpha = smoothstep(textConfig.threshold - textConfig.smoothing, textConfig.threshold + textConfig.smoothing, distance); - outColor = vec4(textConfig.textColor) * alpha; + float alpha = smoothstep(threshold - smoothing, threshold + smoothing, distance); + outColor = vec4(color) * alpha; - if (textConfig.backgroundColor.a != 0) + if (bgColor.a != 0) { - outColor = mix(textConfig.backgroundColor, outColor, alpha); + outColor = mix(bgColor, outColor, alpha); } } diff --git a/openVulkanoCpp/Shader/text.frag b/openVulkanoCpp/Shader/text.frag index 460a50d..47a7164 100644 --- a/openVulkanoCpp/Shader/text.frag +++ b/openVulkanoCpp/Shader/text.frag @@ -1,22 +1,15 @@ #version 450 -//layout(location = 0) in vec4 color; -layout(location = 1) in vec2 texCoord; +layout(location = 0) in vec4 color; +layout(location = 1) in vec4 bgColor; +layout(location = 2) in vec2 texCoord; layout(location = 0) out vec4 outColor; layout(set = 2, binding = 0) uniform sampler2D texSampler; -layout(set = 3, binding = 0) uniform TextConfig -{ - vec4 textColor; - vec4 backgroundColor; - float threshold; - float smoothing; -} textConfig; - void main() { vec4 sampled = vec4(1.0, 1.0, 1.0, texture(texSampler, texCoord).r); - outColor = vec4(textConfig.textColor) * sampled; + outColor = vec4(color) * sampled; } diff --git a/openVulkanoCpp/Shader/text.vert b/openVulkanoCpp/Shader/text.vert index 47f4b61..7d0f209 100644 --- a/openVulkanoCpp/Shader/text.vert +++ b/openVulkanoCpp/Shader/text.vert @@ -1,13 +1,13 @@ #version 450 -layout(location = 0) in vec3 position; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec3 tangent; -layout(location = 3) in vec3 biTangent; -layout(location = 4) in vec3 textureCoordinates; -layout(location = 5) in vec4 color; + +layout(location = 0) in vec2 position[4]; +layout(location = 4) in vec2 textureCoordinates[4]; +layout(location = 8) in vec4 color; +layout(location = 9) in vec4 bgColor; layout(location = 0) out vec4 outColor; -layout(location = 1) out vec2 fragTextureCoordinates; +layout(location = 1) out vec4 outBgColor; +layout(location = 2) out vec2 fragTextureCoordinates; layout(set = 0, binding = 0) uniform NodeData { @@ -16,14 +16,12 @@ layout(set = 0, binding = 0) uniform NodeData layout(set = 1, binding = 0) uniform CameraData { - mat4 viewProjection; - mat4 view; - mat4 projection; - vec4 camPos; + mat4 viewProjection; } cam; void main() { - gl_Position = cam.viewProjection * node.world * vec4(position, 1.0); - fragTextureCoordinates.xy = textureCoordinates.xy; - outColor = color; + gl_Position = cam.viewProjection * node.world * vec4(position[gl_VertexIndex], 1.0, 1.0); + fragTextureCoordinates = textureCoordinates[gl_VertexIndex]; + outColor = color; + outBgColor = bgColor; } diff --git a/openVulkanoCpp/Shader/textBillboard.vert b/openVulkanoCpp/Shader/textBillboard.vert new file mode 100644 index 0000000..0326fce --- /dev/null +++ b/openVulkanoCpp/Shader/textBillboard.vert @@ -0,0 +1,64 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec2 position[4]; +layout(location = 4) in vec2 textureCoordinates[4]; +layout(location = 8) in vec4 color; +layout(location = 9) in vec4 bgColor; + +layout(location = 0) out vec4 outColor; +layout(location = 1) out vec4 outBgColor; +layout(location = 2) out vec2 outTexture; + +layout(set = 0, binding = 0) uniform NodeData +{ + mat4 world; +} node; + +layout(set = 1, binding = 0) uniform CameraData +{ + mat4 viewProjection; + mat4 view; + mat4 projection; + vec4 camPos; +} cam; + +layout(set = 4, binding = 0) uniform BillboardData +{ + vec2 size; + bool isFixedSize; +} billboardInfo; + +void main() +{ + vec4 pos = vec4(position[gl_VertexIndex], 0, 1); + if (!billboardInfo.isFixedSize) + { + mat4 mv = cam.view * node.world; + + mv[0][0] = 1; + mv[0][1] = 0; + mv[0][2] = 0; + + mv[1][0] = 0; + mv[1][1] = 1; + mv[1][2] = 0; + + mv[2][0] = 0; + mv[2][1] = 0; + mv[2][2] = 1; + + gl_Position = cam.projection * mv * pos; + } + else + { + vec4 billboardPos = vec4(0.5, 0.5, 0.5, 1); + vec4 viewPos = cam.view * node.world * billboardPos; + float dist = -viewPos.z; + gl_Position = cam.projection * (viewPos + vec4(pos.xy * dist * 0.2, 0, 0)); + } + outTexture = textureCoordinates[gl_VertexIndex]; + outColor = color; + outBgColor = bgColor; +} diff --git a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp index eeac1f7..5241cc7 100644 --- a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp @@ -12,6 +12,7 @@ #include "Vulkan/VulkanDrawContext.hpp" #include "Vulkan/Scene/VulkanTexture.hpp" #include "Vulkan/Scene/VulkanUniformBuffer.hpp" +#include "Vulkan/Scene/VulkanVertexBuffer.hpp" using namespace OpenVulkano::Scene; @@ -33,18 +34,12 @@ namespace OpenVulkano::Vulkan Scene::UniformBuffer* labelBuffer = labelDrawable->GetLabelBuffer(); VulkanUniformBuffer* vkBuffer = labelBuffer->GetRenderResource(); - if (!vkBuffer) - { - vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelBuffer); - } + if (!vkBuffer) vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelBuffer); vkBuffer->Record(drawContext); for (Node* node: labelDrawable->GetNodes()) { - if (!node->IsEnabled()) [[unlikely]] - { - continue; - } + if (!node->IsEnabled()) [[unlikely]] continue; drawContext->EncodeNode(node); } drawContext->commandBuffer.draw(4, 1, 0, 0); @@ -54,56 +49,34 @@ namespace OpenVulkano::Vulkan { for (TextDrawable& entry : labelDrawable->GetTexts()) { - Shader* shader = entry.GetShader(); - drawContext->EncodeShader(shader); - Geometry* mesh = entry.GetGeometry(); - VulkanGeometry* renderGeo = mesh->GetRenderResource(); - if (!renderGeo) - { - renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh); - } - renderGeo->RecordBind(drawContext->commandBuffer); - - std::array uniforms = { nullptr, nullptr }; - // fragment shader buffer - uniforms[0] = entry.GetUniformBuffer(); + drawContext->EncodeShader(entry.GetShader()); + VertexBuffer* vbo = entry.GetVertexBuffer(); + VulkanVertexBuffer* renderVbo = vbo->GetRenderResource(); + if (!renderVbo) renderVbo = drawContext->renderer->GetResourceManager().PrepareVertexBuffer(vbo); + renderVbo->RecordBind(drawContext->commandBuffer); + if (labelDrawable->IsBillboard()) { - // vertex shader buffer - uniforms[1] = labelDrawable->GetBillboardBuffer(); + VulkanUniformBuffer* vkBuffer = labelDrawable->GetBillboardBuffer()->GetRenderResource(); + if (!vkBuffer) + { + vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelDrawable->GetBillboardBuffer()); + } + vkBuffer->Record(drawContext); } - for (Scene::UniformBuffer* buffer : uniforms) + VulkanTexture* renderTexture = entry.GetTexture()->GetRenderResource(); + if (!renderTexture) { - if (buffer) - { - VulkanUniformBuffer* vkBuffer = buffer->GetRenderResource(); - if (!vkBuffer) - { - vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(buffer); - } - vkBuffer->Record(drawContext); - } - } - - if (Texture* texture = entry.GetTexture()) - { - VulkanTexture* renderTexture = texture->GetRenderResource(); - if (!renderTexture) - { - renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(entry.GetTexture()); - } - renderTexture->Record(drawContext); + renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(entry.GetTexture()); } + renderTexture->Record(drawContext); for (Node* node: labelDrawable->GetNodes()) { - if (!node->IsEnabled()) [[unlikely]] - { - continue; - } + if (!node->IsEnabled()) [[unlikely]] continue; drawContext->EncodeNode(node); - renderGeo->RecordDraw(drawContext->commandBuffer); + drawContext->commandBuffer.draw(4, entry.GetSymbolCount(), 0, 0); } } } diff --git a/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp index 9589ba4..445a4c6 100644 --- a/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/TextDrawableVulkanEncoder.cpp @@ -5,49 +5,36 @@ */ #include "Scene/TextDrawable.hpp" -#include "VulkanGeometry.hpp" #include "VulkanNode.hpp" #include "Vulkan/VulkanDrawContext.hpp" #include "Vulkan/Scene/VulkanUniformBuffer.hpp" +#include "Vulkan/Scene/VulkanVertexBuffer.hpp" #include "VulkanTexture.hpp" using namespace OpenVulkano::Scene; namespace OpenVulkano::Vulkan { - void EncodeTextDrawable(Drawable* instance, Vulkan::VulkanDrawContext* drawContext) + void EncodeTextDrawable(Drawable* instance, VulkanDrawContext* drawContext) { TextDrawable* drawable = static_cast(instance); - Geometry* mesh = drawable->GetGeometry(); - VulkanGeometry* renderGeo = mesh->GetRenderResource(); - if (!renderGeo) renderGeo = drawContext->renderer->GetResourceManager().PrepareGeometry(mesh); - renderGeo->RecordBind(drawContext->commandBuffer); + VertexBuffer* vbo = drawable->GetVertexBuffer(); + VulkanVertexBuffer* renderVbo = vbo->GetRenderResource(); + if (!renderVbo) renderVbo = drawContext->renderer->GetResourceManager().PrepareVertexBuffer(vbo); + renderVbo->RecordBind(drawContext->commandBuffer); - if (drawable->GetUniformBuffer()) + VulkanTexture* renderTexture = drawable->GetTexture()->GetRenderResource(); + if (!renderTexture) { - VulkanUniformBuffer* vkBuffer = drawable->GetUniformBuffer()->GetRenderResource(); - if (!vkBuffer) - { - vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(drawable->GetUniformBuffer()); - } - vkBuffer->Record(drawContext); - } - - if (Texture* texture = drawable->GetTexture()) - { - VulkanTexture* renderTexture = texture->GetRenderResource(); - if (!renderTexture) - { - renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(drawable->GetTexture()); - } - renderTexture->Record(drawContext); + renderTexture = drawContext->renderer->GetResourceManager().PrepareTexture(drawable->GetTexture()); } + renderTexture->Record(drawContext); for(Node* node : instance->GetNodes()) { if (!node->IsEnabled()) [[unlikely]] continue; drawContext->EncodeNode(node); - renderGeo->RecordDraw(drawContext->commandBuffer); + drawContext->commandBuffer.draw(4, drawable->GetSymbolCount(), 0, 0); } } } From aca64c57b7e1435223acbd2a02f7b57e30c47f7a Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 16:31:04 +0100 Subject: [PATCH 23/36] Optimize label size calculation --- openVulkanoCpp/Math/Math.hpp | 12 ++ .../Scene/Prefabs/LabelDrawable.cpp | 21 +-- .../Scene/Prefabs/LabelDrawable.hpp | 7 +- openVulkanoCpp/Shader/label.frag | 120 +++++++++--------- openVulkanoCpp/Shader/label.vert | 34 ++--- openVulkanoCpp/Shader/labelBillboard.vert | 11 +- 6 files changed, 102 insertions(+), 103 deletions(-) diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index a6f0f03..9852a03 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -177,3 +177,15 @@ glm::vec operator / (const float lhs, const glm::vec& rhs) { return lhs / glm::vec(rhs); } + +template>> +glm::vec operator * (const float lhs, const glm::vec& rhs) +{ + return lhs * glm::vec(rhs); +} + +template>> +glm::vec operator * (const glm::vec& lhs, const T rhs) +{ + return lhs * static_cast(rhs); +} diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 89926ad..48fdf08 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -15,8 +15,6 @@ namespace OpenVulkano::Scene { - using namespace Math; - namespace { Shader MakeLabelBgShader(const bool billboard) @@ -45,7 +43,6 @@ namespace OpenVulkano::Scene Shader MakeLabelTextShader(const FontAtlasType type, const bool billboard) { Shader shader = TextDrawable::MakeDefaultShader(type); - shader.depthTest = false; shader.depthCompareOp = CompareOp::LESS_OR_EQUAL; if (billboard) { @@ -117,20 +114,12 @@ namespace OpenVulkano::Scene // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; - const auto& min = m_bbox.GetMin(); - const auto& max = m_bbox.GetMax(); - Vertex v, v2, v3, v4; - const float offset = 0.001; - const float yOffset = m_settings.hasArrow ? m_settings.arrowLength : 0; - v.position = Vector3f(min.x - m_settings.horizontalOffset, min.y - m_settings.verticalOffset - yOffset, min.z - offset); - v2.position = Vector3f(max.x + m_settings.horizontalOffset, min.y - m_settings.verticalOffset - yOffset, min.z - offset); - v3.position = Vector3f(max.x + m_settings.horizontalOffset, max.y + m_settings.verticalOffset, min.z - offset); - v4.position = Vector3f(min.x - m_settings.horizontalOffset, max.y + m_settings.verticalOffset, min.z - offset); + Math::Vector2f padding = m_settings.padding * 2; + if (m_settings.hasArrow) padding.y += m_settings.arrowLength; - m_labelData.textSize.x = v2.position.x - v.position.x; - m_labelData.textSize.y = v3.position.y - v.position.y; - m_labelData.bboxCenter.x = (v2.position.x + v.position.x) / 2; - m_labelData.bboxCenter.y = (v3.position.y + v.position.y) / 2; + m_labelData.textSize = Math::Vector2f(m_bbox.GetSize()) + padding * 2; + m_labelData.bboxCenter = { m_bbox.GetCenter() }; + if (m_settings.hasArrow) m_labelData.bboxCenter.y -= m_settings.arrowLength; } void LabelDrawable::SetBillboardSettings(const BillboardControlBlock& settings) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 4357b42..8bc64bc 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -21,8 +21,7 @@ namespace OpenVulkano::Scene struct LabelDrawableSettings { Math::Vector4f backgroundColor = { 1, 0, 0, 1 }; - float horizontalOffset = 0.05f; - float verticalOffset = 0.05f; + Math::Vector2f padding = { 0.2f, 0.2f }; float cornerRadius = 0.05f; float arrowLength = 0.5f; float arrowWidth = 0.2f; @@ -32,9 +31,9 @@ namespace OpenVulkano::Scene struct LabelUniformData { - Math::Vector4f textSize = { 0, 0, 0, 0 }; Math::Vector4f color = { 0, 0, 0, 0 }; - Math::Vector4f bboxCenter = { 0, 0, 0, 0 }; + Math::Vector2f textSize = {}; + Math::Vector2f bboxCenter = {}; float cornerRadius = 0.f; float arrowLength = 0.f; float arrowWidth = 0.f; diff --git a/openVulkanoCpp/Shader/label.frag b/openVulkanoCpp/Shader/label.frag index 33c8fc5..aec26b0 100644 --- a/openVulkanoCpp/Shader/label.frag +++ b/openVulkanoCpp/Shader/label.frag @@ -5,69 +5,69 @@ layout(location = 0) out vec4 outColor; layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; - vec4 color; - vec4 bboxCenter; - float radius; - float arrowLength; - float arrowWidth; - bool hasRoundedCorners; - bool hasArrow; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + float arrowWidth; + bool hasRoundedCorners; + bool hasArrow; } labelInfo; void main() -{ - if (labelInfo.hasRoundedCorners || labelInfo.hasArrow) - { - vec2 bbox = vec2(labelInfo.textSize); - const float arrowLength = int(labelInfo.hasArrow) * labelInfo.arrowLength; - float arrowWidth = labelInfo.arrowWidth; - vec2 uvScaled = texCoord; +{ + if (labelInfo.hasRoundedCorners || labelInfo.hasArrow) + { + vec2 bbox = vec2(labelInfo.textSize); + const float arrowLength = int(labelInfo.hasArrow) * labelInfo.arrowLength; + float arrowWidth = labelInfo.arrowWidth; + vec2 uvScaled = texCoord; - float distX = min(uvScaled.x, bbox.x - uvScaled.x); - float distY = min(uvScaled.y - arrowLength, bbox.y - uvScaled.y); - float distanceFromCorner = distX * distY; + float distX = min(uvScaled.x, bbox.x - uvScaled.x); + float distY = min(uvScaled.y - arrowLength, bbox.y - uvScaled.y); + float distanceFromCorner = distX * distY; - if (distanceFromCorner < labelInfo.radius) - { - // plain arrow - if (labelInfo.hasArrow && !labelInfo.hasRoundedCorners) - { - // Some bias to prevent line between arrow and label + - // check that we are dealing with lower parts of the label where arrow should be drawn, - // to prevent discarding fragments from upper corners - if (distY <= 0.01 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) - { - arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); - if (distX < (bbox.x - arrowWidth) * 0.5) - { - discard; - } - } - } - // TODO: rounded corners + rounded arrow. - // now renders rounded corners and sharp arrow - else if (labelInfo.hasArrow && labelInfo.hasRoundedCorners) - { - if (distY <= 0.05 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) - { - arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); - if (distX < (bbox.x - arrowWidth) * 0.5) - { - discard; - } - } - else - { - discard; - } - } - // no arrow, rounded corners - else - { - discard; - } - } - } - outColor = labelInfo.color; + if (distanceFromCorner < labelInfo.radius) + { + // plain arrow + if (labelInfo.hasArrow && !labelInfo.hasRoundedCorners) + { + // Some bias to prevent line between arrow and label + + // check that we are dealing with lower parts of the label where arrow should be drawn, + // to prevent discarding fragments from upper corners + if (distY <= 0.01 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) + { + arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); + if (distX < (bbox.x - arrowWidth) * 0.5) + { + discard; + } + } + } + // TODO: rounded corners + rounded arrow. + // now renders rounded corners and sharp arrow + else if (labelInfo.hasArrow && labelInfo.hasRoundedCorners) + { + if (distY <= 0.05 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) + { + arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); + if (distX < (bbox.x - arrowWidth) * 0.5) + { + discard; + } + } + else + { + discard; + } + } + // no arrow, rounded corners + else + { + discard; + } + } + } + outColor = labelInfo.color; } \ No newline at end of file diff --git a/openVulkanoCpp/Shader/label.vert b/openVulkanoCpp/Shader/label.vert index ca0380d..fab71cd 100644 --- a/openVulkanoCpp/Shader/label.vert +++ b/openVulkanoCpp/Shader/label.vert @@ -8,18 +8,18 @@ layout(set = 0, binding = 0) uniform NodeData layout(set = 1, binding = 0) uniform CameraData { - mat4 viewProjection; + mat4 viewProjection; } cam; layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; - vec4 color; - vec4 bboxCenter; - float radius; - float arrowLength; - bool hasRoundedCorners; - bool hasArrow; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + bool hasRoundedCorners; + bool hasArrow; } labelInfo; layout(location = 0) out vec4 color; @@ -28,18 +28,18 @@ layout(location = 1) out vec2 textureCoordinates; // Background plane positions are in clipped space const vec4 PLANE[4] = vec4[]( vec4(-0.5, -0.5, 0, 1), vec4(0.5, -0.5, 0, 1), vec4(-0.5, 0.5, 0, 1), vec4(0.5, 0.5, 0, 1) - ); + const vec2 TEX_COORDS[4] = vec2[]( vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) ); -void main() { - vec4 position = PLANE[gl_VertexIndex]; - vec2 bbox = labelInfo.textSize.xy; - position.xy *= bbox; - position.xy += vec2(labelInfo.bboxCenter); - position.z = -0.001; - gl_Position = cam.viewProjection * node.world * position; - textureCoordinates = TEX_COORDS[gl_VertexIndex] * bbox; +void main() +{ + vec4 position = PLANE[gl_VertexIndex]; + position.xy *= labelInfo.textSize; + position.xy += labelInfo.bboxCenter; + //position.z = -0.001; + gl_Position = cam.viewProjection * node.world * position; + textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; } diff --git a/openVulkanoCpp/Shader/labelBillboard.vert b/openVulkanoCpp/Shader/labelBillboard.vert index 00e1d02..c528d0a 100644 --- a/openVulkanoCpp/Shader/labelBillboard.vert +++ b/openVulkanoCpp/Shader/labelBillboard.vert @@ -30,9 +30,9 @@ layout(set = 4, binding = 0) uniform BillboardData layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; vec4 color; - vec4 bboxCenter; + vec2 textSize; + vec2 bboxCenter; float radius; float arrowLength; bool hasRoundedCorners; @@ -53,11 +53,10 @@ const vec2 TEX_COORDS[4] = vec2[]( void main() { vec4 position = PLANE[gl_VertexIndex]; - vec2 bbox = labelInfo.textSize.xy; - position.xy *= bbox; - position.xy += vec2(labelInfo.bboxCenter); + position.xy *= labelInfo.textSize; + position.xy += labelInfo.bboxCenter; position.z = -0.001; - textureCoordinates = TEX_COORDS[gl_VertexIndex] * bbox; + textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; if (!billboardInfo.isFixedSize) { From 56cb5080029d1b31e77f689567f28173bcdcfa2e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 17:15:18 +0100 Subject: [PATCH 24/36] Fix text position --- .../Scene/FontAtlasGeneratorBase.hpp | 21 ++++++++++--------- openVulkanoCpp/Scene/IFontAtlasGenerator.hpp | 9 ++++---- .../Scene/Prefabs/LabelDrawable.hpp | 1 - openVulkanoCpp/Shader/text.vert | 2 +- openVulkanoCpp/Shader/textBillboard.vert | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp index 5561309..0c4ff78 100644 --- a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp +++ b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.hpp @@ -7,30 +7,31 @@ #pragma once #include "IFontAtlasGenerator.hpp" +#include "AtlasData.hpp" #include "Math/AABB.hpp" #include "Extensions/FreetypeHelper.hpp" #include -#include namespace OpenVulkano::Scene { class FontAtlasGeneratorBase : public IFontAtlasGenerator { + protected: + int m_channelsCount; + std::shared_ptr m_atlasData; + public: - FontAtlasGeneratorBase(int channelsCount) : m_channelsCount(channelsCount) {} + FontAtlasGeneratorBase(const int channelsCount) : m_channelsCount(channelsCount) {} void SaveAtlasMetadataInfo(const std::string& outputFile, bool packIntoSingleFile = true) const override; - std::shared_ptr GetAtlasData() const { return m_atlasData; } - int GetAtlasChannelsCount() const { return m_channelsCount; } - static std::set LoadAllGlyphs(const std::variant>& data); + [[nodiscard]] const std::shared_ptr& GetAtlasData() const override { return m_atlasData; } + [[nodiscard]] int GetAtlasChannelsCount() const { return m_channelsCount; } + [[nodiscard]] static std::set LoadAllGlyphs(const std::variant>& data); protected: void SavePng(std::string output) const; void SetupAtlasData(Math::Vector2ui textureResolution, double lineHeight, FontAtlasType::Type atlasType); void SetGlyphData(GlyphInfo& info, Math::Vector2d bearing, Math::Vector2d size, const Math::AABB& aabb, double advance); - static std::string GetFreetypeErrorDescription(FT_Error error); - static std::pair InitFreetype(const std::variant>& source); - protected: - int m_channelsCount; - std::shared_ptr m_atlasData; + [[nodiscard]] static std::string GetFreetypeErrorDescription(FT_Error error); + [[nodiscard]] static std::pair InitFreetype(const std::variant>& source); }; } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/IFontAtlasGenerator.hpp b/openVulkanoCpp/Scene/IFontAtlasGenerator.hpp index cdb4094..979f723 100644 --- a/openVulkanoCpp/Scene/IFontAtlasGenerator.hpp +++ b/openVulkanoCpp/Scene/IFontAtlasGenerator.hpp @@ -6,24 +6,25 @@ #pragma once -#include "Scene/AtlasData.hpp" +#include #include #include -#include -#include #include #include namespace OpenVulkano::Scene { + struct AtlasData; + class IFontAtlasGenerator { public: + virtual ~IFontAtlasGenerator() = default; virtual void GenerateAtlas(const std::string& fontFile, const std::set& charset, const std::optional& pngOutput = std::nullopt) = 0; virtual void GenerateAtlas(const Array& fontData, const std::set& charset, const std::optional& pngOutput = std::nullopt) = 0; virtual void SaveAtlasMetadataInfo(const std::string& outputFile, bool packIntoSingleFile = true) const = 0; - virtual std::shared_ptr GetAtlasData() const = 0; + virtual const std::shared_ptr& GetAtlasData() const = 0; }; } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 8bc64bc..3f898bc 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -7,7 +7,6 @@ #pragma once #include "Scene/Drawable.hpp" -#include "Scene/Texture.hpp" #include "Scene/UniformBuffer.hpp" #include "Scene/BillboardControlBlock.hpp" #include "Math/AABB.hpp" diff --git a/openVulkanoCpp/Shader/text.vert b/openVulkanoCpp/Shader/text.vert index 7d0f209..bc4012c 100644 --- a/openVulkanoCpp/Shader/text.vert +++ b/openVulkanoCpp/Shader/text.vert @@ -20,7 +20,7 @@ layout(set = 1, binding = 0) uniform CameraData } cam; void main() { - gl_Position = cam.viewProjection * node.world * vec4(position[gl_VertexIndex], 1.0, 1.0); + gl_Position = cam.viewProjection * node.world * vec4(position[gl_VertexIndex], 0.0, 1.0); fragTextureCoordinates = textureCoordinates[gl_VertexIndex]; outColor = color; outBgColor = bgColor; diff --git a/openVulkanoCpp/Shader/textBillboard.vert b/openVulkanoCpp/Shader/textBillboard.vert index 0326fce..3bdbfa5 100644 --- a/openVulkanoCpp/Shader/textBillboard.vert +++ b/openVulkanoCpp/Shader/textBillboard.vert @@ -53,7 +53,7 @@ void main() } else { - vec4 billboardPos = vec4(0.5, 0.5, 0.5, 1); + vec4 billboardPos = vec4(0.5, 0.5, 0, 1); vec4 viewPos = cam.view * node.world * billboardPos; float dist = -viewPos.z; gl_Position = cam.projection * (viewPos + vec4(pos.xy * dist * 0.2, 0, 0)); From 4f1d730e30b33ab15792094aac0fd15375cd8c44 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 17:36:19 +0100 Subject: [PATCH 25/36] Add depth bias config to shader --- .../Scene/Prefabs/LabelDrawable.cpp | 1 + openVulkanoCpp/Scene/Shader/Shader.hpp | 12 ++++- openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp | 7 +++ openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp | 47 +++++++++---------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 48fdf08..001dec1 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -58,6 +58,7 @@ namespace OpenVulkano::Scene billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX; shader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4); } + shader.EnableDepthBias(); return shader; } diff --git a/openVulkanoCpp/Scene/Shader/Shader.hpp b/openVulkanoCpp/Scene/Shader/Shader.hpp index 1ff0a54..aec8bc9 100644 --- a/openVulkanoCpp/Scene/Shader/Shader.hpp +++ b/openVulkanoCpp/Scene/Shader/Shader.hpp @@ -81,7 +81,6 @@ namespace OpenVulkano::Scene }; - class Shader final : public RenderResourceHolder, public ICloseable { public: @@ -96,6 +95,8 @@ namespace OpenVulkano::Scene bool depthTest = true; bool depthWrite = true; bool dynamicViewport = true; // If disabled the swapchains fullscreen viewport will always be used, regardless of framebuffer or viewport + bool depthBias = false; + float depthBiasClamp = 0.0f, depthBiasSlope = 0.0f, depthBiasConstant = 0.0f; Shader() = default; ~Shader() override { Shader::Close(); } @@ -128,6 +129,7 @@ namespace OpenVulkano::Scene { CheckShaderInitState(); if (bindingId < 0) bindingId = static_cast(vertexInputDescriptions.size()); + // ReSharper disable once CppDFALoopConditionNotUpdated while (bindingId > static_cast(vertexInputDescriptions.size())) { vertexInputDescriptions.emplace_back(0, 0); @@ -149,6 +151,7 @@ namespace OpenVulkano::Scene if (setId < 0) setId = static_cast(descriptorSets.size() + 2); if (setId < 2) throw std::runtime_error("Cant bind set id 0 or 1! They are used for node and camera!"); setId -= 2; + // ReSharper disable once CppDFALoopConditionNotUpdated while (setId >= static_cast(descriptorSets.size())) { descriptorSets.emplace_back(); @@ -163,6 +166,13 @@ namespace OpenVulkano::Scene pushConstantRanges.push_back(pushConstantRange); } + void EnableDepthBias(const float slope = -1.0, const float constant = 0.001f) + { + depthBias = true; + depthBiasSlope = slope; + depthBiasConstant = constant; + } + void Close() override { if (HasRenderResource()) diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index c1046ce..db0542b 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -84,6 +84,13 @@ namespace OpenVulkano::Vulkan vk::PipelineInputAssemblyStateCreateInfo inputAssembly = { {}, static_cast(shader->topology), 0 }; vk::PipelineRasterizationStateCreateInfo rasterizer = {}; rasterizer.cullMode = static_cast(shader->cullMode); + if (shader->depthBias) + { + rasterizer.depthBiasEnable = VK_TRUE; + rasterizer.depthBiasClamp = shader->depthBiasClamp; + rasterizer.depthBiasConstantFactor = shader->depthBiasConstant; + rasterizer.depthBiasSlopeFactor = shader->depthBiasSlope; + } vk::PipelineMultisampleStateCreateInfo msaa = {}; vk::PipelineDepthStencilStateCreateInfo depth = { {}, shader->depthTest, shader->depthWrite, static_cast(shader->depthCompareOp) }; depth.maxDepthBounds = 1; diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp index 738e0c2..8ece2c3 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp @@ -11,39 +11,36 @@ #include #include -namespace OpenVulkano +namespace OpenVulkano::Vulkan { - namespace Vulkan - { - class Context; - class IShaderOwner; + class Context; + class IShaderOwner; class VulkanShader final : public IRenderResource, public IRecordable - { - public: - vk::Device device; - std::vector shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs - std::vector shaderStageCreateInfo; - vk::Pipeline pipeline; // TODO pipeline and shader config should be split - std::vector descriptorSetLayouts; - vk::PipelineLayout pipelineLayout; - IShaderOwner* owner = nullptr; - Context* context = nullptr; + { + public: + vk::Device device; + std::vector shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs + std::vector shaderStageCreateInfo; + vk::Pipeline pipeline; // TODO pipeline and shader config should be split + std::vector descriptorSetLayouts; + vk::PipelineLayout pipelineLayout; + IShaderOwner* owner = nullptr; + Context* context = nullptr; - VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner); + VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner); - ~VulkanShader() override; + ~VulkanShader() override; - void Resize(); + void Resize(); - void Record(VulkanDrawContext* context) override; + void Record(VulkanDrawContext* context) override; - void Release() override; + void Release() override; - private: - void BuildPipeline(); + private: + void BuildPipeline(); - void CreatePipelineLayout(); - }; - } + void CreatePipelineLayout(); + }; } \ No newline at end of file From 92b9fb597fa25adb67c13897d316c4873ca7fb3d Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 23:31:42 +0100 Subject: [PATCH 26/36] Remove unnecessary buffer --- .../ExampleApps/LabelDrawableExampleApp.cpp | 4 +- .../Scene/Prefabs/LabelDrawable.cpp | 33 +---- .../Scene/Prefabs/LabelDrawable.hpp | 7 +- openVulkanoCpp/Shader/label.frag | 2 +- openVulkanoCpp/Shader/label.vert | 3 +- openVulkanoCpp/Shader/labelBillboard.vert | 115 +++++++++--------- openVulkanoCpp/Shader/textBillboard.vert | 13 +- .../Scene/LabelDrawableVulkanEncoder.cpp | 23 +--- 8 files changed, 79 insertions(+), 121 deletions(-) diff --git a/examples/ExampleApps/LabelDrawableExampleApp.cpp b/examples/ExampleApps/LabelDrawableExampleApp.cpp index ab899e6..89373c8 100644 --- a/examples/ExampleApps/LabelDrawableExampleApp.cpp +++ b/examples/ExampleApps/LabelDrawableExampleApp.cpp @@ -53,7 +53,6 @@ namespace OpenVulkano m_nodesPool.resize(N); m_drawablesPool.reserve(N); - BillboardControlBlock billboardSettings; LabelDrawableSettings labelSettings; for (int i = 0; i < N; i++) @@ -69,7 +68,6 @@ namespace OpenVulkano } bool isBillboard = i % 2 == 0 ? 1 : 0; LabelDrawable& label = m_drawablesPool.emplace_back(textDrawable.GetAtlasData(), labelSettings, isBillboard); - label.SetBillboardSettings(billboardSettings); label.AddText(texts[i]); if (i == 2) { @@ -80,7 +78,7 @@ namespace OpenVulkano } m_drawablesPool[i].SetIsHittable(true); m_scene.GetRoot()->AddChild(&m_nodesPool[i]); - m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, -std::rand() % 10))); + m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(5 - std::rand() % 10, 5 - std::rand() % 10, 5 - std::rand() % 10))); m_nodesPool[i].AddDrawable(&m_drawablesPool[i]); } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 001dec1..a631f17 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -20,21 +20,10 @@ namespace OpenVulkano::Scene Shader MakeLabelBgShader(const bool billboard) { Shader backgroundShader; - if (!billboard) - { - backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/label"); - } - else - { - backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/labelBillboard"); - // binding for billboard's buffer - DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - binding.stageFlags = ShaderProgramType::Type::VERTEX; - backgroundShader.AddDescriptorSetLayoutBinding(binding, 4); - } + backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, billboard ? "Shader/labelBillboard" : "Shader/label"); backgroundShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/label"); backgroundShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2); - backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 5); + backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 4); backgroundShader.topology = Topology::TRIANGLE_STRIP; backgroundShader.cullMode = CullMode::NONE; return backgroundShader; @@ -44,6 +33,7 @@ namespace OpenVulkano::Scene { Shader shader = TextDrawable::MakeDefaultShader(type); shader.depthCompareOp = CompareOp::LESS_OR_EQUAL; + shader.EnableDepthBias(); if (billboard) { for (auto& program : shader.shaderPrograms) @@ -55,10 +45,9 @@ namespace OpenVulkano::Scene } } DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX; shader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4); + shader.depthBiasConstant = 0.01f; } - shader.EnableDepthBias(); return shader; } @@ -123,11 +112,6 @@ namespace OpenVulkano::Scene if (m_settings.hasArrow) m_labelData.bboxCenter.y -= m_settings.arrowLength; } - void LabelDrawable::SetBillboardSettings(const BillboardControlBlock& settings) - { - m_billboardSettings = settings; - } - std::optional LabelDrawable::Intersect(const Ray& ray) const { return ray.IntersectAABB(m_bbox); @@ -135,16 +119,9 @@ namespace OpenVulkano::Scene void LabelDrawable::SetupBuffers() { - m_billboardBuffer.size = sizeof(BillboardControlBlock); - m_billboardBuffer.data = &m_billboardSettings; - m_billboardBuffer.setId = 4; - DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - binding.stageFlags = ShaderProgramType::Type::VERTEX; - m_billboardBuffer.binding = binding; - m_labelBuffer.size = sizeof(LabelUniformData); m_labelBuffer.data = &m_labelData; - m_labelBuffer.setId = 5; + m_labelBuffer.setId = 4; m_labelBuffer.binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; } } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 3f898bc..ac2b23a 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -8,7 +8,6 @@ #include "Scene/Drawable.hpp" #include "Scene/UniformBuffer.hpp" -#include "Scene/BillboardControlBlock.hpp" #include "Math/AABB.hpp" #include "Scene/TextDrawable.hpp" #include @@ -38,6 +37,7 @@ namespace OpenVulkano::Scene float arrowWidth = 0.f; int32_t hasRoundedCorners = false; int32_t hasArrow = false; + int32_t isBillboardFixedSize = false; }; class LabelDrawable final : public Drawable @@ -47,13 +47,10 @@ namespace OpenVulkano::Scene const LabelDrawableSettings& settings = LabelDrawableSettings(), bool isBillboard = false); void AddText(const std::string& text, const TextConfig& config = TextConfig()); void SetLabelSettings(const LabelDrawableSettings& settings); - void SetBillboardSettings(const BillboardControlBlock& settings); void SetPosition(const Math::Vector3f& pos) { m_position = pos; } [[nodiscard]] std::list& GetTexts() { return m_texts; } [[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; } - [[nodiscard]] UniformBuffer* GetBillboardBuffer() { return &m_billboardBuffer; } [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } - [[nodiscard]] BillboardControlBlock& GetBillboardSettings() { return m_billboardSettings; } [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } [[nodiscard]] bool IsBillboard() const { return m_isBillboard; } [[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; } @@ -62,13 +59,11 @@ namespace OpenVulkano::Scene private: void SetupBuffers(); - UniformBuffer m_billboardBuffer; UniformBuffer m_labelBuffer; std::list m_texts; // Using list instead of vector for stable iterators LabelDrawableSettings m_settings; LabelUniformData m_labelData; std::shared_ptr m_atlasData; - BillboardControlBlock m_billboardSettings; Math::Vector3f m_position = { 0, 0, 0 }; Math::AABB m_bbox; bool m_isBillboard; diff --git a/openVulkanoCpp/Shader/label.frag b/openVulkanoCpp/Shader/label.frag index aec26b0..2d702d5 100644 --- a/openVulkanoCpp/Shader/label.frag +++ b/openVulkanoCpp/Shader/label.frag @@ -3,7 +3,7 @@ layout(location = 1) in vec2 texCoord; layout(location = 0) out vec4 outColor; -layout(set = 5, binding = 0) uniform LabelData +layout(set = 4, binding = 0) uniform LabelData { vec4 color; vec2 textSize; diff --git a/openVulkanoCpp/Shader/label.vert b/openVulkanoCpp/Shader/label.vert index fab71cd..2d23910 100644 --- a/openVulkanoCpp/Shader/label.vert +++ b/openVulkanoCpp/Shader/label.vert @@ -11,13 +11,14 @@ layout(set = 1, binding = 0) uniform CameraData mat4 viewProjection; } cam; -layout(set = 5, binding = 0) uniform LabelData +layout(set = 4, binding = 0) uniform LabelData { vec4 color; vec2 textSize; vec2 bboxCenter; float radius; float arrowLength; + float arrowWidth; bool hasRoundedCorners; bool hasArrow; } labelInfo; diff --git a/openVulkanoCpp/Shader/labelBillboard.vert b/openVulkanoCpp/Shader/labelBillboard.vert index c528d0a..ab4e610 100644 --- a/openVulkanoCpp/Shader/labelBillboard.vert +++ b/openVulkanoCpp/Shader/labelBillboard.vert @@ -8,35 +8,31 @@ layout(set = 0, binding = 0) uniform NodeData layout(set = 1, binding = 0) uniform CameraData { - mat4 viewProjection; - mat4 view; - mat4 projection; - vec4 camPos; - float nearPlane; - float farPlane; - float width; - float height; - float fov; - float aspect; - float scaleFactor; - float pixelScaleFactor; + mat4 viewProjection; + mat4 view; + mat4 projection; + vec4 camPos; + float nearPlane; + float farPlane; + float width; + float height; + float fov; + float aspect; + float scaleFactor; + float pixelScaleFactor; } cam; -layout(set = 4, binding = 0) uniform BillboardData +layout(set = 4, binding = 0) uniform LabelData { - vec2 size; - bool isFixedSize; -} billboardInfo; - -layout(set = 5, binding = 0) uniform LabelData -{ - vec4 color; - vec2 textSize; - vec2 bboxCenter; - float radius; - float arrowLength; - bool hasRoundedCorners; - bool hasArrow; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + float arrowWidth; + bool hasRoundedCorners; + bool hasArrow; + bool isBillboardFixedSize; } labelInfo; layout(location = 0) out vec4 color; @@ -45,42 +41,41 @@ layout(location = 1) out vec2 textureCoordinates; // Background plane positions are in clipped space const vec4 PLANE[4] = vec4[]( vec4(-0.5, -0.5, 0, 1), vec4(0.5, -0.5, 0, 1), vec4(-0.5, 0.5, 0, 1), vec4(0.5, 0.5, 0, 1) - - ); -const vec2 TEX_COORDS[4] = vec2[]( - vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) ); -void main() { - vec4 position = PLANE[gl_VertexIndex]; - position.xy *= labelInfo.textSize; - position.xy += labelInfo.bboxCenter; - position.z = -0.001; - textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; +const vec2 TEX_COORDS[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1)); - if (!billboardInfo.isFixedSize) - { - mat4 mv = cam.view * node.world; +void main() +{ + vec4 position = PLANE[gl_VertexIndex]; + position.xy *= labelInfo.textSize; + position.xy += labelInfo.bboxCenter; + position.z = - 0.001; + textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; - mv[0][0] = 1; - mv[0][1] = 0; - mv[0][2] = 0; - - mv[1][0] = 0; - mv[1][1] = 1; - mv[1][2] = 0; - - mv[2][0] = 0; - mv[2][1] = 0; - mv[2][2] = 1; - - gl_Position = cam.projection * mv * vec4(position.xyz, 1); - } - else - { - vec4 billboardPos = vec4(0.5, 0.5, 0.5, 1); - vec4 viewPos = cam.view * node.world * billboardPos; - float dist = -viewPos.z; - gl_Position = cam.projection * (viewPos + vec4(position.xy*dist*0.2,0,0)); - } + if (!labelInfo.isBillboardFixedSize) + { + mat4 mv = cam.view * node.world; + + mv[0][0] = 1; + mv[0][1] = 0; + mv[0][2] = 0; + + mv[1][0] = 0; + mv[1][1] = 1; + mv[1][2] = 0; + + mv[2][0] = 0; + mv[2][1] = 0; + mv[2][2] = 1; + + gl_Position = cam.projection * mv * vec4(position.xyz, 1); + } + else + { + vec4 billboardPos = vec4(0.5, 0.5, 0, 1); + vec4 viewPos = cam.view * node.world * billboardPos; + float dist = - viewPos.z; + gl_Position = cam.projection * (viewPos + vec4(position.xy *dist * 0.2, 0, 0)); + } } diff --git a/openVulkanoCpp/Shader/textBillboard.vert b/openVulkanoCpp/Shader/textBillboard.vert index 3bdbfa5..dfe9de1 100644 --- a/openVulkanoCpp/Shader/textBillboard.vert +++ b/openVulkanoCpp/Shader/textBillboard.vert @@ -26,14 +26,21 @@ layout(set = 1, binding = 0) uniform CameraData layout(set = 4, binding = 0) uniform BillboardData { - vec2 size; - bool isFixedSize; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + float arrowWidth; + bool hasRoundedCorners; + bool hasArrow; + bool isBillboardFixedSize; } billboardInfo; void main() { vec4 pos = vec4(position[gl_VertexIndex], 0, 1); - if (!billboardInfo.isFixedSize) + if (!billboardInfo.isBillboardFixedSize) { mat4 mv = cam.view * node.world; diff --git a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp index 5241cc7..2dd0ef4 100644 --- a/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp +++ b/openVulkanoCpp/Vulkan/Scene/LabelDrawableVulkanEncoder.cpp @@ -21,20 +21,8 @@ namespace OpenVulkano::Vulkan void EncodeBackground(LabelDrawable* labelDrawable, VulkanDrawContext* drawContext) { - if (labelDrawable->IsBillboard()) - { - Scene::UniformBuffer* buffer = labelDrawable->GetBillboardBuffer(); - VulkanUniformBuffer* vkBuffer = buffer->GetRenderResource(); - if (!vkBuffer) - { - vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(buffer); - } - vkBuffer->Record(drawContext); - } - - Scene::UniformBuffer* labelBuffer = labelDrawable->GetLabelBuffer(); - VulkanUniformBuffer* vkBuffer = labelBuffer->GetRenderResource(); - if (!vkBuffer) vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelBuffer); + VulkanUniformBuffer* vkBuffer = labelDrawable->GetLabelBuffer()->GetRenderResource(); + if (!vkBuffer) vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelDrawable->GetLabelBuffer()); vkBuffer->Record(drawContext); for (Node* node: labelDrawable->GetNodes()) @@ -57,11 +45,8 @@ namespace OpenVulkano::Vulkan if (labelDrawable->IsBillboard()) { - VulkanUniformBuffer* vkBuffer = labelDrawable->GetBillboardBuffer()->GetRenderResource(); - if (!vkBuffer) - { - vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelDrawable->GetBillboardBuffer()); - } + VulkanUniformBuffer* vkBuffer = labelDrawable->GetLabelBuffer()->GetRenderResource(); + if (!vkBuffer) vkBuffer = drawContext->renderer->GetResourceManager().PrepareUniformBuffer(labelDrawable->GetLabelBuffer()); vkBuffer->Record(drawContext); } From 6cfd760034e6394ee4118acd20a7db9f86c25b42 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 23:44:01 +0100 Subject: [PATCH 27/36] Move billboard state into LabelDrawableSettings --- examples/ExampleApps/LabelDrawableExampleApp.cpp | 11 +++++------ openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp | 6 +++--- openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp | 11 +++++------ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/ExampleApps/LabelDrawableExampleApp.cpp b/examples/ExampleApps/LabelDrawableExampleApp.cpp index 89373c8..cfe0566 100644 --- a/examples/ExampleApps/LabelDrawableExampleApp.cpp +++ b/examples/ExampleApps/LabelDrawableExampleApp.cpp @@ -63,11 +63,11 @@ namespace OpenVulkano } else { - labelSettings.hasRoundedCorners = i % 2 == 0 ? 0 : 1; - labelSettings.hasArrow = i % 2 == 0 ? 1 : 0; + labelSettings.hasRoundedCorners = i & 1; + labelSettings.hasArrow = i % 2 == 0; } - bool isBillboard = i % 2 == 0 ? 1 : 0; - LabelDrawable& label = m_drawablesPool.emplace_back(textDrawable.GetAtlasData(), labelSettings, isBillboard); + labelSettings.isBillboard = i % 2 == 0; + LabelDrawable& label = m_drawablesPool.emplace_back(textDrawable.GetAtlasData(), labelSettings); label.AddText(texts[i]); if (i == 2) { @@ -88,8 +88,7 @@ namespace OpenVulkano m_camController.SetPosition({ 0, 0, 10 }); m_camController.SetBoostFactor(5); - std::shared_ptr m_perfInfo = - std::make_shared(); + std::shared_ptr m_perfInfo = std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index a631f17..1e26cc8 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -68,8 +68,8 @@ namespace OpenVulkano::Scene } } - LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings, const bool isBillboard) - : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard) + LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings) + : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData) { if (atlasData->glyphs.empty() || !atlasData->texture.size) { @@ -99,7 +99,7 @@ namespace OpenVulkano::Scene textDrawable.GetConfig().backgroundColor.a = 0; // do not render glyph's background double lineHeight = m_atlasData->meta.lineHeight; textDrawable.GenerateText(text, m_position); - textDrawable.SetShader(GetTextShader(m_atlasData->meta.atlasType, m_isBillboard)); + textDrawable.SetShader(GetTextShader(m_atlasData->meta.atlasType, IsBillboard())); m_bbox.Grow(textDrawable.GetBoundingBox()); // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index ac2b23a..1e4b68a 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -23,8 +23,9 @@ namespace OpenVulkano::Scene float cornerRadius = 0.05f; float arrowLength = 0.5f; float arrowWidth = 0.2f; - int32_t hasRoundedCorners = false; - int32_t hasArrow = false; + bool hasRoundedCorners = false; + bool hasArrow = false; + bool isBillboard = false; }; struct LabelUniformData @@ -43,8 +44,7 @@ namespace OpenVulkano::Scene class LabelDrawable final : public Drawable { public: - LabelDrawable(const std::shared_ptr& atlasData, - const LabelDrawableSettings& settings = LabelDrawableSettings(), bool isBillboard = false); + LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings = LabelDrawableSettings()); void AddText(const std::string& text, const TextConfig& config = TextConfig()); void SetLabelSettings(const LabelDrawableSettings& settings); void SetPosition(const Math::Vector3f& pos) { m_position = pos; } @@ -52,7 +52,7 @@ namespace OpenVulkano::Scene [[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; } [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } - [[nodiscard]] bool IsBillboard() const { return m_isBillboard; } + [[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; } [[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; } std::optional Intersect(const Ray& ray) const override; @@ -66,6 +66,5 @@ namespace OpenVulkano::Scene std::shared_ptr m_atlasData; Math::Vector3f m_position = { 0, 0, 0 }; Math::AABB m_bbox; - bool m_isBillboard; }; } From ceee3ef12e9abf8fbbb4e643d4541790299025b5 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 5 Jan 2025 23:54:42 +0100 Subject: [PATCH 28/36] Add Constructor for UniformBuffer --- openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp | 10 +--------- openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp | 4 +--- openVulkanoCpp/Scene/UniformBuffer.hpp | 8 ++++++-- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 1e26cc8..16040bd 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -70,6 +70,7 @@ namespace OpenVulkano::Scene LabelDrawable::LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings) : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::MAIN), m_atlasData(atlasData) + , m_labelBuffer(sizeof(LabelUniformData), &m_labelData, 4) { if (atlasData->glyphs.empty() || !atlasData->texture.size) { @@ -77,7 +78,6 @@ namespace OpenVulkano::Scene } SetLabelSettings(settings); SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER); - SetupBuffers(); } void LabelDrawable::SetLabelSettings(const LabelDrawableSettings& settings) @@ -116,12 +116,4 @@ namespace OpenVulkano::Scene { return ray.IntersectAABB(m_bbox); } - - void LabelDrawable::SetupBuffers() - { - m_labelBuffer.size = sizeof(LabelUniformData); - m_labelBuffer.data = &m_labelData; - m_labelBuffer.setId = 4; - m_labelBuffer.binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING; - } } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 1e4b68a..7458d00 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -57,13 +57,11 @@ namespace OpenVulkano::Scene std::optional Intersect(const Ray& ray) const override; private: - void SetupBuffers(); - + std::shared_ptr m_atlasData; UniformBuffer m_labelBuffer; std::list m_texts; // Using list instead of vector for stable iterators LabelDrawableSettings m_settings; LabelUniformData m_labelData; - std::shared_ptr m_atlasData; Math::Vector3f m_position = { 0, 0, 0 }; Math::AABB m_bbox; }; diff --git a/openVulkanoCpp/Scene/UniformBuffer.hpp b/openVulkanoCpp/Scene/UniformBuffer.hpp index ec6370a..f975e53 100644 --- a/openVulkanoCpp/Scene/UniformBuffer.hpp +++ b/openVulkanoCpp/Scene/UniformBuffer.hpp @@ -19,11 +19,15 @@ namespace OpenVulkano::Scene DescriptorSetLayoutBinding binding; uint32_t setId; - size_t size = 0; - const void* data = nullptr; + size_t size; + const void* data; UpdateFrequency updateFrequency = UpdateFrequency::Never; bool updated = true; + UniformBuffer(size_t size = 0, const void* data = nullptr, uint32_t setId = 2, const DescriptorSetLayoutBinding& binding = DESCRIPTOR_SET_LAYOUT_BINDING) + : binding(binding), setId(setId), size(size), data(data) + {} + void Init(size_t size, const void* data, uint32_t setId = 2, const DescriptorSetLayoutBinding& binding = DESCRIPTOR_SET_LAYOUT_BINDING) { this->size = size; From 7ef6503a78e830c42ef00c4bef7453fd51769dbf Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 00:28:10 +0100 Subject: [PATCH 29/36] Add 2d variant of bounding box --- openVulkanoCpp/Math/AABB.hpp | 79 ++++++++++--------- .../Scene/Prefabs/LabelDrawable.hpp | 4 +- openVulkanoCpp/Scene/Ray.cpp | 64 +++++++-------- openVulkanoCpp/Scene/Ray.hpp | 20 ++++- openVulkanoCpp/Scene/TextDrawable.hpp | 4 +- 5 files changed, 92 insertions(+), 79 deletions(-) diff --git a/openVulkanoCpp/Math/AABB.hpp b/openVulkanoCpp/Math/AABB.hpp index 5c0039b..d0b8b3b 100644 --- a/openVulkanoCpp/Math/AABB.hpp +++ b/openVulkanoCpp/Math/AABB.hpp @@ -14,101 +14,103 @@ namespace OpenVulkano::Math /** * \brief A class that represents an axis aligned bounding box */ - class AABB final : public Range + template + class AABB_T final : public Range { public: - AABB() : Range(Vector3f(INFINITY), Vector3f(-INFINITY)) {} + AABB_T() : Range(T(INFINITY), T(-INFINITY)) {} - AABB(const Vector3f& min, const Vector3f& max) : Range(min, max) {} + AABB_T(const T& min, const T& max) : Range(min, max) {} - AABB(const Vector3f& point) : Range(point, point) + AABB_T(const T& point) : Range(point, point) {} - AABB(const Vector3f& point, float radius) : Range(point - radius, point + radius) + AABB_T(const T& point, float radius) : Range(point - radius, point + radius) {} /** * \brief Initiates the AABB to a single point (min=max=point) * \param point The point that should be used as min and max of the AABB */ - void Init(const Vector3f& point) + void Init(const T& point) { - min = max = point; + Range::min = Range::max = point; } - void Init(const Vector3f& min, const Vector3f& max) + void Init(const T& min, const T& max) { this->min = min; this->max = max; } - void Init(const Vector3f& point, float radius) + void Init(const T& point, float radius) { - min = point - radius; - max = point + radius; + Range::min = point - radius; + Range::max = point + radius; } /** * \brief Initiates the AABB from some other AABB * \param other The other AABB that should be copied */ - void Init(const AABB& other) + void Init(const AABB_T& other) { - min = other.GetMin(); - max = other.GetMax(); + Range::min = other.GetMin(); + Range::max = other.GetMax(); } - void Grow(const Vector3f& point) + void Grow(const T& point) { - min = Math::Utils::min(min, point); - max = Math::Utils::max(max, point); + Range::min = Math::Utils::min(Range::min, point); + Range::max = Math::Utils::max(Range::max, point); } - void Grow(const AABB& otherAABB) + void Grow(const AABB_T& otherAABB) { - min = Math::Utils::min(min, otherAABB.GetMin()); - max = Math::Utils::max(max, otherAABB.GetMax()); + Range::min = Math::Utils::min(Range::min, otherAABB.GetMin()); + Range::max = Math::Utils::max(Range::max, otherAABB.GetMax()); } - void Grow(const AABB& otherAABB, Math::Matrix4f transformation) + void Grow(const AABB_T& otherAABB, Math::Matrix4f transformation) { //TODO } - [[nodiscard]] Vector3f GetDiagonal() const + [[nodiscard]] T GetDiagonal() const { - return GetSize(); + return Range::GetSize(); } - [[nodiscard]] Vector3f GetCenter() const + [[nodiscard]] T GetCenter() const { - return min + (GetDiagonal() * 0.5f); + return Range::min + (GetDiagonal() * 0.5f); } /** - * \brief Checks if the AABB overlaps with an other AABB + * \brief Checks if the AABB overlaps with another AABB * \param other The other AABB that should be checked * \return true if the AABB overlaps with the other, false if not */ - [[nodiscard]] bool IsOverlapping(const AABB& other) const + [[nodiscard]] bool IsOverlapping(const AABB_T& other) const { - return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || - other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); + //return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || + // other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); + return Math::Utils::any(Math::Utils::greaterThan(Range::min, other.GetMin())) || Math::Utils::any(Math::Utils::lessThan(other.GetMax(), Range::max)); } - [[nodiscard]] bool InBounds(const Vector3f& position) const + [[nodiscard]] bool InBounds(const T& position) const { - return Math::Utils::all(Math::Utils::lessThanEqual(min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, max)); + return Math::Utils::all(Math::Utils::lessThanEqual(Range::min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, Range::max)); } - [[nodiscard]] bool Inside(const Math::Vector3f& position) const + [[nodiscard]] bool Inside(const T& position) const { - return Math::Utils::all(Math::Utils::lessThan(min, position)) && Math::Utils::all(Math::Utils::lessThan(position, max)); + return Math::Utils::all(Math::Utils::lessThan(Range::min, position)) && Math::Utils::all(Math::Utils::lessThan(position, Range::max)); } [[nodiscard]] bool IsEmpty() const { - return min == Math::Vector3f(INFINITY) && max == Math::Vector3f(-INFINITY); + return Range::min == T(INFINITY) && Range::max == T(-INFINITY); } /** @@ -116,10 +118,13 @@ namespace OpenVulkano::Math */ void Reset() { - min = Vector3f(INFINITY); - max = Vector3f(-INFINITY); + Range::min = T(INFINITY); + Range::max = T(-INFINITY); } - AABB& operator +=(const AABB& other) { Grow(other); return *this; } + AABB_T& operator +=(const AABB_T& other) { Grow(other); return *this; } }; + + typedef AABB_T AABB; + typedef AABB_T AABB2f; } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 7458d00..e50ec50 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -53,7 +53,7 @@ namespace OpenVulkano::Scene [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } [[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; } - [[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; } + [[nodiscard]] const Math::AABB2f& GetBoundingBox() const { return m_bbox; } std::optional Intersect(const Ray& ray) const override; private: @@ -63,6 +63,6 @@ namespace OpenVulkano::Scene LabelDrawableSettings m_settings; LabelUniformData m_labelData; Math::Vector3f m_position = { 0, 0, 0 }; - Math::AABB m_bbox; + Math::AABB2f m_bbox; }; } diff --git a/openVulkanoCpp/Scene/Ray.cpp b/openVulkanoCpp/Scene/Ray.cpp index 7e2a30c..ec09810 100644 --- a/openVulkanoCpp/Scene/Ray.cpp +++ b/openVulkanoCpp/Scene/Ray.cpp @@ -92,6 +92,12 @@ namespace OpenVulkano::Scene return {}; } + std::optional Ray::IntersectAABB(const Math::AABB2f& bbox) const + { + //TODO impl that skips z checks + return IntersectAABB(Math::AABB({bbox.GetMin(), 0}, {bbox.GetMax(), 0})); + } + std::optional Ray::IntersectAABB(const Math::AABB& bbox) const { RayHit h1, h2; @@ -108,69 +114,63 @@ namespace OpenVulkano::Scene int Ray::IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const { - const auto tmin = (bbox.min - m_origin) / m_dir; - const auto tmax = (bbox.max - m_origin) / m_dir; - float txmin = tmin.x; - float txmax = tmax.x; - float tymin = tmin.y; - float tymax = tmax.y; - float tzmin = tmin.z; - float tzmax = tmax.z; + auto tmin = (bbox.min - m_origin) / m_dir; + auto tmax = (bbox.max - m_origin) / m_dir; - if (txmin > txmax) + if (tmin.x > tmax.x) { - std::swap(txmin, txmax); + std::swap(tmin.x, tmax.x); } - if (tymin > tymax) + if (tmin.y > tmax.y) { - std::swap(tymin, tymax); + std::swap(tmin.y, tmax.y); } - if ((txmin > tymax) || (tymin > txmax)) + if ((tmin.x > tmax.y) || (tmin.y > tmax.x)) { return 0; } - if (tymin > txmin) + if (tmin.y > tmin.x) { - txmin = tymin; + tmin.x = tmin.y; } - if (tymax < txmax) + if (tmax.y < tmax.x) { - txmax = tymax; + tmax.x = tmax.y; } - if (tzmin > tzmax) + if (tmin.z > tmax.z) { - std::swap(tzmin, tzmax); + std::swap(tmin.z, tmax.z); } - if ((txmin > tzmax) || (tzmin > txmax)) + if ((tmin.x > tmax.z) || (tmin.z > tmax.x)) { return 0; } - if (tzmin > txmin) + if (tmin.z > tmin.x) { - txmin = tzmin; + tmin.x = tmin.z; } - if (tzmax < txmax) + if (tmax.z < tmax.x) { - txmax = tzmax; + tmax.x = tmax.z; } int intersections = 2; - if (txmin < 0) + if (tmin.x < 0) { - if (txmax < 0) + if (tmax.x < 0) { return 0; } intersections--; - txmin = txmax; + tmin.x = tmax.x; } - p1.point = m_origin + txmin * m_dir; - p2.point = m_origin + txmax * m_dir; + p1.point = m_origin + tmin.x * m_dir; + p2.point = m_origin + tmax.x * m_dir; p1.distance2 = distance2(m_origin, p1.point); p2.distance2 = distance2(m_origin, p2.point); p1.normal = p2.normal = Math::Vector3f(0); @@ -179,15 +179,11 @@ namespace OpenVulkano::Scene std::optional Ray::IntersectPlane(const Math::Vector3f& pOrigin, const Math::Vector3f& pNorm) const { - RayHit hit; Math::Vector3f norm = normalize(pNorm); float d; if (intersectRayPlane(m_origin, m_dir, pOrigin, pNorm, d)) { - hit.SetDistance(d); - hit.point = m_origin + m_dir * d; - hit.normal = norm; - return hit; + return {{ m_origin + m_dir * d, norm, d, d * d }}; } return {}; } diff --git a/openVulkanoCpp/Scene/Ray.hpp b/openVulkanoCpp/Scene/Ray.hpp index 999888b..38b1f32 100644 --- a/openVulkanoCpp/Scene/Ray.hpp +++ b/openVulkanoCpp/Scene/Ray.hpp @@ -20,21 +20,32 @@ namespace OpenVulkano::Scene Math::Vector3f point; Math::Vector3f normal; float distance2; + + RayHit() : distance2(0), distance(-1) {} + + RayHit(Math::Vector3f point, Math::Vector3f normal, float distance2) + : point(point), normal(normal), distance2(distance2) + {} + + RayHit(Math::Vector3f point, Math::Vector3f normal, float distance, float distance2) + : point(point), normal(normal), distance2(distance2), distance(distance) + {} + [[nodiscard]] float GetDistance() const { - if (distance == -1) - { - distance = std::sqrt(distance2); - } + if (distance == -1) distance = std::sqrt(distance2); return distance; } + void SetDistance(float d) { this->distance = d; this->distance2 = d * d; } + bool operator==(const RayHit& other) const; bool operator!=(const RayHit& other) const; + private: mutable float distance = -1; }; @@ -66,6 +77,7 @@ namespace OpenVulkano::Scene const Math::Vector3f& n1, const Math::Vector3f& n2) const; [[nodiscard]] std::optional IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1, const Math::Vector3f& v2, const Math::Vector3f& v3) const; + [[nodiscard]] std::optional IntersectAABB(const Math::AABB2f& bbox) const; [[nodiscard]] std::optional IntersectAABB(const Math::AABB& bbox) const; int IntersectAABB(const Math::AABB& bbox, RayHit& p1, RayHit& p2) const; [[nodiscard]] std::optional IntersectPlane(const Math::Vector3f& pOrigin, diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 0af8ed4..60f2a6b 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -34,7 +34,7 @@ namespace OpenVulkano::Scene { VertexBuffer m_vertexBuffer; std::shared_ptr m_atlasData; - Math::AABB m_bbox; + Math::AABB2f m_bbox; std::string m_text; size_t m_symbolCount = 0; TextConfig m_cfg; @@ -51,7 +51,7 @@ namespace OpenVulkano::Scene void GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } void SetAtlasData(const std::shared_ptr& atlasData); - [[nodiscard]] Math::AABB& GetBoundingBox() { return m_bbox; } + [[nodiscard]] Math::AABB2f& GetBoundingBox() { return m_bbox; } [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } [[nodiscard]] const std::shared_ptr& GetAtlasData() { return m_atlasData; } From 6407f40f940073699abe1d369ce491e52a41a109 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 00:52:13 +0100 Subject: [PATCH 30/36] Deduplicate code --- openVulkanoCpp/Math/Math.hpp | 6 +++ openVulkanoCpp/Scene/Ray.cpp | 102 +++++++++-------------------------- 2 files changed, 31 insertions(+), 77 deletions(-) diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index 9852a03..7f0f9ce 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -52,6 +52,12 @@ namespace OpenVulkano::Math } return angle; } + + template + constexpr void SortPair(T& e1, T& e2) + { + if (e1 > e2) std::swap(e1, e2); + } } template using Matrix2_SIMD = glm::tmat2x2; diff --git a/openVulkanoCpp/Scene/Ray.cpp b/openVulkanoCpp/Scene/Ray.cpp index ec09810..29f6308 100644 --- a/openVulkanoCpp/Scene/Ray.cpp +++ b/openVulkanoCpp/Scene/Ray.cpp @@ -10,12 +10,9 @@ namespace { int SolveQuadraticEquation(float a, float b, float c, float& x0, float& x1) - { - float discr = b * b - 4 * a * c; - if (discr < 0) - { - return 0; - } + { + const float discr = b * b - 4 * a * c; + if (discr < 0) return 0; if (discr == 0) { x0 = x1 = (-b) / (2 * a); @@ -24,10 +21,7 @@ namespace float q = (b > 0) ? -0.5 * (b + std::sqrt(discr)) : -0.5 * (b - std::sqrt(discr)); x0 = q / a; x1 = c / q; - if (x0 > x1) - { - std::swap(x0, x1); - } + OpenVulkano::Math::Utils::SortPair(x0, x1); return 2; } }; @@ -50,10 +44,10 @@ namespace OpenVulkano::Scene std::optional Ray::IntersectTriangle(const Math::Vector3f& v0, const Math::Vector3f& v1, const Math::Vector3f& v2) const { - RayHit hitRes; float d; if (intersectRayTriangle(m_origin, m_dir, v0, v1, v2, m_baryPos, d) && d >= 0) { + RayHit hitRes; hitRes.point = (1.f - m_baryPos.x - m_baryPos.y) * v0 + m_baryPos.x * v1 + m_baryPos.y * v2; Math::Vector3f e = v1 - v0; Math::Vector3f e2 = v2 - v0; @@ -81,11 +75,11 @@ namespace OpenVulkano::Scene std::optional Ray::IntersectQuad(const Math::Vector3f& v0, const Math::Vector3f& v1, const Math::Vector3f& v2, const Math::Vector3f& v3) const { - if (auto hitRes = IntersectTriangle(v0, v1, v2)) + if (const auto hitRes = IntersectTriangle(v0, v1, v2)) { return hitRes; } - if (auto hitRes = IntersectTriangle(v0, v2, v3)) + if (const auto hitRes = IntersectTriangle(v0, v2, v3)) { return hitRes; } @@ -102,13 +96,8 @@ namespace OpenVulkano::Scene { RayHit h1, h2; const int intersections = this->IntersectAABB(bbox, h1, h2); - switch (intersections) - { - case 1: - return h1; - case 2: - return (h1.distance2 < h2.distance2) ? h1 : h2; - } + if (intersections == 1) return h1; + if (intersections == 2) return (h1.distance2 < h2.distance2) ? h1 : h2; return {}; } @@ -117,18 +106,11 @@ namespace OpenVulkano::Scene auto tmin = (bbox.min - m_origin) / m_dir; auto tmax = (bbox.max - m_origin) / m_dir; - if (tmin.x > tmax.x) - { - std::swap(tmin.x, tmax.x); - } - if (tmin.y > tmax.y) - { - std::swap(tmin.y, tmax.y); - } - if ((tmin.x > tmax.y) || (tmin.y > tmax.x)) - { - return 0; - } + SortPair(tmin.x, tmax.x); + SortPair(tmin.y, tmax.y); + SortPair(tmin.z, tmax.z); + + if ((tmin.x > tmax.y) || (tmin.y > tmax.x)) return 0; if (tmin.y > tmin.x) { @@ -138,16 +120,8 @@ namespace OpenVulkano::Scene { tmax.x = tmax.y; } - - if (tmin.z > tmax.z) - { - std::swap(tmin.z, tmax.z); - } - if ((tmin.x > tmax.z) || (tmin.z > tmax.x)) - { - return 0; - } + if ((tmin.x > tmax.z) || (tmin.z > tmax.x)) return 0; if (tmin.z > tmin.x) { @@ -161,10 +135,7 @@ namespace OpenVulkano::Scene int intersections = 2; if (tmin.x < 0) { - if (tmax.x < 0) - { - return 0; - } + if (tmax.x < 0) return 0; intersections--; tmin.x = tmax.x; } @@ -197,39 +168,19 @@ namespace OpenVulkano::Scene float x1, x2; int roots = ::SolveQuadraticEquation(a, b, c, x1, x2); - if (roots == 0) - { - return 0; - } - if (x1 > x2) - { - std::swap(x1, x2); - } + if (roots == 0) return 0; + SortPair(x1, x2); if (roots == 1) { - // ray intersects sphere behind the origin - if (x1 < 0) - { - return 0; - } - p1.point = m_origin + x1 * m_dir; - p1.distance2 = distance2(m_origin, p1.point); - p1.normal = normalize(p1.point - center); + if (x1 < 0) return 0; // ray intersects sphere behind the origin p2 = p1; } - else if (roots == 2) + else { - // ray intersects sphere behind the origin - if (x1 < 0 && x2 < 0) - { - return 0; - } + if (x1 < 0 && x2 < 0) return 0; // ray intersects sphere behind the origin if (x1 >= 0 && x2 >= 0) { - p1.point = m_origin + x1 * m_dir; - p1.distance2 = distance2(m_origin, p1.point); - p1.normal = normalize(p1.point - center); p2.point = m_origin + x2 * m_dir; p2.distance2 = distance2(m_origin, p2.point); p2.normal = normalize(p2.point - center); @@ -237,16 +188,13 @@ namespace OpenVulkano::Scene else { --roots; - if (x1 < 0) - { - x1 = x2; - } - p1.point = m_origin + x1 * m_dir; - p1.distance2 = distance2(m_origin, p1.point); - p1.normal = normalize(p1.point - center); + if (x1 < 0) x1 = x2; p2 = p1; } } + p1.point = m_origin + x1 * m_dir; + p1.distance2 = distance2(m_origin, p1.point); + p1.normal = normalize(p1.point - center); return roots; } From 91cf59648dc324e5825e2878fc97620369124beb Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 00:57:41 +0100 Subject: [PATCH 31/36] Formatting --- openVulkanoCpp/Scene/IRayIntersectable.hpp | 1 + openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp | 5 ++++- openVulkanoCpp/Scene/TextDrawable.hpp | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Scene/IRayIntersectable.hpp b/openVulkanoCpp/Scene/IRayIntersectable.hpp index 0deaf91..1e4d741 100644 --- a/openVulkanoCpp/Scene/IRayIntersectable.hpp +++ b/openVulkanoCpp/Scene/IRayIntersectable.hpp @@ -13,6 +13,7 @@ namespace OpenVulkano::Scene class IRayIntersectable { public: + virtual ~IRayIntersectable() = default; virtual std::optional Intersect(const Ray& ray) const = 0; }; } diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index e50ec50..fe0e747 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -45,16 +45,19 @@ namespace OpenVulkano::Scene { public: LabelDrawable(const std::shared_ptr& atlasData, const LabelDrawableSettings& settings = LabelDrawableSettings()); + void AddText(const std::string& text, const TextConfig& config = TextConfig()); void SetLabelSettings(const LabelDrawableSettings& settings); void SetPosition(const Math::Vector3f& pos) { m_position = pos; } + [[nodiscard]] std::list& GetTexts() { return m_texts; } [[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; } [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } [[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; } [[nodiscard]] const Math::AABB2f& GetBoundingBox() const { return m_bbox; } - std::optional Intersect(const Ray& ray) const override; + + [[nodiscard]] std::optional Intersect(const Ray& ray) const override; private: std::shared_ptr m_atlasData; diff --git a/openVulkanoCpp/Scene/TextDrawable.hpp b/openVulkanoCpp/Scene/TextDrawable.hpp index 60f2a6b..2dac8d8 100644 --- a/openVulkanoCpp/Scene/TextDrawable.hpp +++ b/openVulkanoCpp/Scene/TextDrawable.hpp @@ -48,9 +48,11 @@ namespace OpenVulkano::Scene TextDrawable(const std::string& atlasMetadataFile, Texture* atlasTex, const TextConfig& config = TextConfig()); TextDrawable(const Array& atlasMetadata, Texture* atlasTex, const TextConfig& config = TextConfig()); TextDrawable(const std::shared_ptr& atlasData, const TextConfig& config = TextConfig()); + void GenerateText(const std::string& text, const Math::Vector2f& pos = Math::Vector2f(0.f)); void SetConfig(const TextConfig& cfg) { m_cfg = cfg; } void SetAtlasData(const std::shared_ptr& atlasData); + [[nodiscard]] Math::AABB2f& GetBoundingBox() { return m_bbox; } [[nodiscard]] TextConfig& GetConfig() { return m_cfg; } [[nodiscard]] const std::string& GetText() const { return m_text; } From 8caf546cad6442e467e9df36b7926bbf4ba6b40c Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 14:07:16 +0100 Subject: [PATCH 32/36] Remove closeable handler from renderer --- openVulkanoCpp/Vulkan/Renderer.cpp | 6 ------ openVulkanoCpp/Vulkan/Renderer.hpp | 5 ----- 2 files changed, 11 deletions(-) diff --git a/openVulkanoCpp/Vulkan/Renderer.cpp b/openVulkanoCpp/Vulkan/Renderer.cpp index 30390b8..d3b9a5b 100644 --- a/openVulkanoCpp/Vulkan/Renderer.cpp +++ b/openVulkanoCpp/Vulkan/Renderer.cpp @@ -89,12 +89,6 @@ namespace OpenVulkano::Vulkan { context.device->device.destroySemaphore(sema); } - while (!closeables.empty()) - { - ICloseable* closeable = closeables.back(); - closeables.pop_back(); - closeable->Close(); - } depthBufferQuery.Close(); uiRenderer.Close(); resourceManager.Close(); diff --git a/openVulkanoCpp/Vulkan/Renderer.hpp b/openVulkanoCpp/Vulkan/Renderer.hpp index 567e3ea..5ab6c3a 100644 --- a/openVulkanoCpp/Vulkan/Renderer.hpp +++ b/openVulkanoCpp/Vulkan/Renderer.hpp @@ -40,7 +40,6 @@ namespace OpenVulkano::Vulkan std::vector> commands; std::vector> submitBuffers; UiRenderer uiRenderer; - std::vector closeables; DepthBufferQuery depthBufferQuery; public: @@ -83,10 +82,6 @@ namespace OpenVulkano::Vulkan Context& GetContext() { return context; } - void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); } - - void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); } - IResourceManager* GetIResourceManager() override { return &resourceManager; } From 46c1d1f18f543b75b9eecfb8e9cef6541d7dd1d3 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 15:27:42 +0100 Subject: [PATCH 33/36] Bugfix --- openVulkanoCpp/Math/AABB.hpp | 14 +++++++++++--- openVulkanoCpp/Scene/Ray.cpp | 15 +++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/openVulkanoCpp/Math/AABB.hpp b/openVulkanoCpp/Math/AABB.hpp index d0b8b3b..9c68237 100644 --- a/openVulkanoCpp/Math/AABB.hpp +++ b/openVulkanoCpp/Math/AABB.hpp @@ -86,6 +86,16 @@ namespace OpenVulkano::Math return Range::min + (GetDiagonal() * 0.5f); } + [[nodiscard]] bool Covers(const AABB_T& other) const + { + return other.IsCovered(*this); + } + + [[nodiscard]] bool IsCovered(const AABB_T& other) const + { + return Math::Utils::all(Math::Utils::greaterThanEqual(other.GetMax(), Range::max)) && Math::Utils::all(Math::Utils::greaterThanEqual(Range::min, other.GetMin())); + } + /** * \brief Checks if the AABB overlaps with another AABB * \param other The other AABB that should be checked @@ -93,9 +103,7 @@ namespace OpenVulkano::Math */ [[nodiscard]] bool IsOverlapping(const AABB_T& other) const { - //return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || - // other.max.y < min.y || other.min.z > max.z || other.max.z < min.z); - return Math::Utils::any(Math::Utils::greaterThan(Range::min, other.GetMin())) || Math::Utils::any(Math::Utils::lessThan(other.GetMax(), Range::max)); + return Math::Utils::all(Math::Utils::lessThanEqual(Range::min, other.GetMax())) && Math::Utils::all(Math::Utils::greaterThanEqual(Range::max, other.GetMin())); } [[nodiscard]] bool InBounds(const T& position) const diff --git a/openVulkanoCpp/Scene/Ray.cpp b/openVulkanoCpp/Scene/Ray.cpp index 29f6308..49d9679 100644 --- a/openVulkanoCpp/Scene/Ray.cpp +++ b/openVulkanoCpp/Scene/Ray.cpp @@ -170,31 +170,34 @@ namespace OpenVulkano::Scene if (roots == 0) return 0; SortPair(x1, x2); - + bool calcP2 = false; if (roots == 1) { if (x1 < 0) return 0; // ray intersects sphere behind the origin - p2 = p1; } else { if (x1 < 0 && x2 < 0) return 0; // ray intersects sphere behind the origin if (x1 >= 0 && x2 >= 0) { - p2.point = m_origin + x2 * m_dir; - p2.distance2 = distance2(m_origin, p2.point); - p2.normal = normalize(p2.point - center); + calcP2 = true; } else { --roots; if (x1 < 0) x1 = x2; - p2 = p1; } } p1.point = m_origin + x1 * m_dir; p1.distance2 = distance2(m_origin, p1.point); p1.normal = normalize(p1.point - center); + if (calcP2) + { + p2.point = m_origin + x2 * m_dir; + p2.distance2 = distance2(m_origin, p2.point); + p2.normal = normalize(p2.point - center); + } + else p2 = p1; return roots; } From ac0a0e84b47f3fe58d70e34e01d41075e3fc600e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 16:28:27 +0100 Subject: [PATCH 34/36] Remove ICloseable --- openVulkanoCpp/Base/ICloseable.hpp | 12 ------------ openVulkanoCpp/Base/IGraphicsApp.hpp | 4 ++-- openVulkanoCpp/Base/IPlatform.hpp | 5 ++--- openVulkanoCpp/Base/Render/IRenderer.hpp | 4 ++-- openVulkanoCpp/Base/UI/IWindow.hpp | 6 +++--- openVulkanoCpp/Controller/CameraController.hpp | 5 ++--- openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp | 5 ++--- openVulkanoCpp/Input/InputDevice.hpp | 7 +++---- openVulkanoCpp/Scene/Drawable.hpp | 5 ++--- openVulkanoCpp/Scene/Geometry.hpp | 5 ++--- openVulkanoCpp/Scene/Node.hpp | 7 +++---- openVulkanoCpp/Scene/Scene.hpp | 4 ++-- openVulkanoCpp/Scene/Shader/Shader.hpp | 7 +++---- openVulkanoCpp/Vulkan/Buffer.hpp | 6 +++--- openVulkanoCpp/Vulkan/CommandHelper.hpp | 5 ++--- openVulkanoCpp/Vulkan/Context.hpp | 6 +++--- openVulkanoCpp/Vulkan/Device.hpp | 5 ++--- openVulkanoCpp/Vulkan/FrameBuffer.hpp | 5 ++--- openVulkanoCpp/Vulkan/Image.hpp | 2 +- openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h | 5 ++--- openVulkanoCpp/Vulkan/RenderPass.hpp | 6 +++--- openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp | 5 ++--- 22 files changed, 48 insertions(+), 73 deletions(-) delete mode 100644 openVulkanoCpp/Base/ICloseable.hpp diff --git a/openVulkanoCpp/Base/ICloseable.hpp b/openVulkanoCpp/Base/ICloseable.hpp deleted file mode 100644 index 07f143a..0000000 --- a/openVulkanoCpp/Base/ICloseable.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace OpenVulkano -{ - class ICloseable - { - public: - virtual ~ICloseable() = default; - - virtual void Close() = 0; - }; -} \ No newline at end of file diff --git a/openVulkanoCpp/Base/IGraphicsApp.hpp b/openVulkanoCpp/Base/IGraphicsApp.hpp index c282416..4055b5e 100644 --- a/openVulkanoCpp/Base/IGraphicsApp.hpp +++ b/openVulkanoCpp/Base/IGraphicsApp.hpp @@ -7,7 +7,6 @@ #pragma once #include "ITickable.hpp" -#include "ICloseable.hpp" #include "Version.hpp" #include @@ -15,7 +14,7 @@ namespace OpenVulkano { class IGraphicsAppManager; - class IGraphicsApp : public ITickable, public ICloseable + class IGraphicsApp : public ITickable { private: IGraphicsAppManager* m_manager = nullptr; @@ -25,6 +24,7 @@ namespace OpenVulkano virtual void Init() = 0; virtual void InitPostGraphics() {} + virtual void Close() {} virtual void CloseFinalize() {} [[nodiscard]] IGraphicsAppManager* GetGraphicsAppManager() const { return m_manager; } void SetGraphicsAppManager(IGraphicsAppManager* manager) { m_manager = manager; } diff --git a/openVulkanoCpp/Base/IPlatform.hpp b/openVulkanoCpp/Base/IPlatform.hpp index d6c99d4..65fc847 100644 --- a/openVulkanoCpp/Base/IPlatform.hpp +++ b/openVulkanoCpp/Base/IPlatform.hpp @@ -1,7 +1,6 @@ #pragma once #include "ITickable.hpp" -#include "ICloseable.hpp" #include "UI/IWindow.hpp" namespace OpenVulkano @@ -12,11 +11,11 @@ namespace OpenVulkano PlatformInitFailedException(char const* const message) : runtime_error(message) {} }; - class IPlatform : public ITickable, public ICloseable + class IPlatform : public ITickable { public: virtual void Init() = 0; - + virtual void Close() = 0; virtual IWindow* MakeWindow() = 0; }; } diff --git a/openVulkanoCpp/Base/Render/IRenderer.hpp b/openVulkanoCpp/Base/Render/IRenderer.hpp index 59d8dd7..63cce17 100644 --- a/openVulkanoCpp/Base/Render/IRenderer.hpp +++ b/openVulkanoCpp/Base/Render/IRenderer.hpp @@ -8,7 +8,6 @@ #include "IResourceManager.hpp" #include "Base/ITickable.hpp" -#include "Base/ICloseable.hpp" #include "Scene/Scene.hpp" #include "Scene/UI/UI.hpp" #include @@ -18,12 +17,13 @@ namespace OpenVulkano class IWindow; class IGraphicsAppManager; - class IRenderer : public ITickable, public ICloseable + class IRenderer : public ITickable { public: virtual ~IRenderer() = default; virtual void Init(IGraphicsAppManager* graphicsAppManager, IWindow* window) = 0; + virtual void Close() = 0; virtual std::string GetMainRenderDeviceName() = 0; virtual void Resize(uint32_t newWidth, uint32_t newHeight) = 0; diff --git a/openVulkanoCpp/Base/UI/IWindow.hpp b/openVulkanoCpp/Base/UI/IWindow.hpp index 876cd19..4b7c868 100644 --- a/openVulkanoCpp/Base/UI/IWindow.hpp +++ b/openVulkanoCpp/Base/UI/IWindow.hpp @@ -8,7 +8,6 @@ #include "Math/Math.hpp" #include "Base/PlatformEnums.hpp" -#include "Base/ICloseable.hpp" #include #include @@ -36,12 +35,13 @@ namespace OpenVulkano bool resizeable = true; }; - class IWindow : public ICloseable + class IWindow { public: - ~IWindow() override = default; + virtual ~IWindow() = default; virtual void Init(RenderAPI::RenderApi renderApi) = 0; + virtual void Close() = 0; virtual bool WindowHasBeenDestroyed() const = 0; virtual void SetWindowHasBeenDestroyed() = 0; diff --git a/openVulkanoCpp/Controller/CameraController.hpp b/openVulkanoCpp/Controller/CameraController.hpp index 80bfa2d..171e140 100644 --- a/openVulkanoCpp/Controller/CameraController.hpp +++ b/openVulkanoCpp/Controller/CameraController.hpp @@ -7,7 +7,6 @@ #pragma once #include "Base/ITickable.hpp" -#include "Base/ICloseable.hpp" namespace OpenVulkano { @@ -16,7 +15,7 @@ namespace OpenVulkano class Camera; } - class CameraController : public ITickable, ICloseable + class CameraController : public ITickable { Scene::Camera* m_camera; @@ -30,7 +29,7 @@ namespace OpenVulkano virtual void Init(Scene::Camera* camera) { m_camera = camera; } - void Close() override { m_camera = nullptr; } + virtual void Close() { m_camera = nullptr; } void SetCamera(Scene::Camera* camera) { m_camera = camera; } diff --git a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp index 2e9a2b9..3ca8fe2 100644 --- a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp @@ -7,7 +7,6 @@ #pragma once #include "Base/ITickable.hpp" -#include "Base/ICloseable.hpp" #include "Base/IPlatform.hpp" #include "InputDeviceGLFW.hpp" #include @@ -18,7 +17,7 @@ namespace OpenVulkano { class WindowGLFW; - class InputProviderGLFW final : public ITickable, public ICloseable + class InputProviderGLFW final : public ITickable { friend WindowGLFW; static InputProviderGLFW* INSTANCE; @@ -32,7 +31,7 @@ namespace OpenVulkano public: void Init(); - void Close() override; + virtual void Close(); void PreTick(); diff --git a/openVulkanoCpp/Input/InputDevice.hpp b/openVulkanoCpp/Input/InputDevice.hpp index 9649a67..ff50491 100644 --- a/openVulkanoCpp/Input/InputDevice.hpp +++ b/openVulkanoCpp/Input/InputDevice.hpp @@ -6,12 +6,11 @@ #pragma once -#include "Base/ICloseable.hpp" #include "InputKey.hpp" namespace OpenVulkano::Input { - class InputDevice : public ICloseable + class InputDevice { InputDeviceType deviceType = InputDeviceType::UNKNOWN; int index = -1; @@ -38,11 +37,11 @@ namespace OpenVulkano::Input [[nodiscard]] virtual bool ReadButtonDown(int16_t key) const = 0; public: - ~InputDevice() override = default; + virtual ~InputDevice() = default; virtual void Tick() {} - void Close() override + virtual void Close() { this->deviceType = InputDeviceType::UNKNOWN; this->index = -1; diff --git a/openVulkanoCpp/Scene/Drawable.hpp b/openVulkanoCpp/Scene/Drawable.hpp index 2c24b0d..42c9bdb 100644 --- a/openVulkanoCpp/Scene/Drawable.hpp +++ b/openVulkanoCpp/Scene/Drawable.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Scene/IRayIntersectable.hpp" #include "DrawEncoder.hpp" #include @@ -27,7 +26,7 @@ namespace OpenVulkano::Scene BACKGROUND = 0, MAIN, TRANSPARENT, POST }; - class Drawable : public ICloseable, public IRayIntersectable + class Drawable : public IRayIntersectable { std::vector m_nodes; Scene* m_scene = nullptr; @@ -43,7 +42,7 @@ namespace OpenVulkano::Scene ~Drawable() override {/* if (m_scene) Drawable::Close();*/ } - void Close() override; + virtual void Close(); void SetShader(Shader* shader) { m_shader = shader; } diff --git a/openVulkanoCpp/Scene/Geometry.hpp b/openVulkanoCpp/Scene/Geometry.hpp index 5522ac5..cd62b18 100644 --- a/openVulkanoCpp/Scene/Geometry.hpp +++ b/openVulkanoCpp/Scene/Geometry.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Base/Render/RenderResource.hpp" #include "Math/AABB.hpp" #include "Base/Utils.hpp" @@ -22,7 +21,7 @@ namespace OpenVulkano UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t) }; - class Geometry : public RenderResourceHolder, public ICloseable + class Geometry : public RenderResourceHolder { friend class MeshLoader; public: @@ -51,7 +50,7 @@ namespace OpenVulkano void SetIndices(const uint32_t* data, uint32_t size, uint32_t dstOffset = 0) const; - void Close() override; + virtual void Close(); void Free(); diff --git a/openVulkanoCpp/Scene/Node.hpp b/openVulkanoCpp/Scene/Node.hpp index abcdcff..fb0886d 100644 --- a/openVulkanoCpp/Scene/Node.hpp +++ b/openVulkanoCpp/Scene/Node.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Base/Render/RenderResource.hpp" #include "Math/Math.hpp" #include "Math/Pose.hpp" @@ -20,7 +19,7 @@ namespace OpenVulkano::Scene { class Scene; - class Node : public RenderResourceHolder, public ICloseable + class Node : public RenderResourceHolder { friend Scene; @@ -41,11 +40,11 @@ namespace OpenVulkano::Scene Node(const Math::Matrix4f& pose); - ~Node() noexcept override; + virtual ~Node() noexcept; void Init(); - void Close() override; + virtual void Close(); void AddChild(Node* node); diff --git a/openVulkanoCpp/Scene/Scene.hpp b/openVulkanoCpp/Scene/Scene.hpp index a3dc720..e83e910 100644 --- a/openVulkanoCpp/Scene/Scene.hpp +++ b/openVulkanoCpp/Scene/Scene.hpp @@ -15,7 +15,7 @@ namespace OpenVulkano { namespace Scene { - class Scene : public ICloseable + class Scene { public: Node* root; @@ -46,7 +46,7 @@ namespace OpenVulkano this->root = root; } - void Close() override + virtual void Close() { //TODO } diff --git a/openVulkanoCpp/Scene/Shader/Shader.hpp b/openVulkanoCpp/Scene/Shader/Shader.hpp index aec8bc9..53c2594 100644 --- a/openVulkanoCpp/Scene/Shader/Shader.hpp +++ b/openVulkanoCpp/Scene/Shader/Shader.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Base/Utils.hpp" #include "Base/Render/RenderResource.hpp" #include "VertexInputDescription.hpp" @@ -81,7 +80,7 @@ namespace OpenVulkano::Scene }; - class Shader final : public RenderResourceHolder, public ICloseable + class Shader final : public RenderResourceHolder { public: std::vector shaderPrograms{}; @@ -99,7 +98,7 @@ namespace OpenVulkano::Scene float depthBiasClamp = 0.0f, depthBiasSlope = 0.0f, depthBiasConstant = 0.0f; Shader() = default; - ~Shader() override { Shader::Close(); } + ~Shader() { Shader::Close(); } Shader& AddShaderProgram(const ShaderProgram& shaderProgram) { @@ -173,7 +172,7 @@ namespace OpenVulkano::Scene depthBiasConstant = constant; } - void Close() override + void Close() { if (HasRenderResource()) GetRenderResource().Release(); diff --git a/openVulkanoCpp/Vulkan/Buffer.hpp b/openVulkanoCpp/Vulkan/Buffer.hpp index 373497c..e737f23 100644 --- a/openVulkanoCpp/Vulkan/Buffer.hpp +++ b/openVulkanoCpp/Vulkan/Buffer.hpp @@ -1,5 +1,5 @@ #pragma once -#include "Base/ICloseable.hpp" + #include "Device.hpp" namespace OpenVulkano @@ -9,7 +9,7 @@ namespace OpenVulkano /** * \brief A not managed buffer. This should be used rarely. */ - struct Buffer : public ICloseable + struct Buffer { vk::Device device; vk::DeviceMemory memory; @@ -94,7 +94,7 @@ namespace OpenVulkano device.invalidateMappedMemoryRanges(vk::MappedMemoryRange(memory, offset, size)); } - void Close() override + void Close() { if (mapped) UnMap(); if(memory) diff --git a/openVulkanoCpp/Vulkan/CommandHelper.hpp b/openVulkanoCpp/Vulkan/CommandHelper.hpp index f109db3..2dcaf78 100644 --- a/openVulkanoCpp/Vulkan/CommandHelper.hpp +++ b/openVulkanoCpp/Vulkan/CommandHelper.hpp @@ -6,14 +6,13 @@ #pragma once -#include "Base/ICloseable.hpp" #include namespace OpenVulkano { namespace Vulkan { - struct CommandHelper : virtual ICloseable + struct CommandHelper final { vk::Device device; vk::CommandPool cmdPool; @@ -42,7 +41,7 @@ namespace OpenVulkano return level; } - void Close() override + void Close() { device.freeCommandBuffers(cmdPool, 1, &cmdBuffer); device.destroyCommandPool(cmdPool); diff --git a/openVulkanoCpp/Vulkan/Context.hpp b/openVulkanoCpp/Vulkan/Context.hpp index 18d4765..644b2cb 100644 --- a/openVulkanoCpp/Vulkan/Context.hpp +++ b/openVulkanoCpp/Vulkan/Context.hpp @@ -21,7 +21,7 @@ namespace OpenVulkano { class Device; - class Context final : public ICloseable + class Context final { bool enableValidationLayer, initialized; std::set requiredExtensions; @@ -45,14 +45,14 @@ namespace OpenVulkano #endif } - ~Context() override + ~Context() { if (initialized) Close(); } void Init(IGraphicsAppManager* graphicsAppManager, IVulkanWindow* window); - void Close() override; + void Close(); void Resize(uint32_t newWidth, uint32_t newHeight); diff --git a/openVulkanoCpp/Vulkan/Device.hpp b/openVulkanoCpp/Vulkan/Device.hpp index 6a26226..a6c99b0 100644 --- a/openVulkanoCpp/Vulkan/Device.hpp +++ b/openVulkanoCpp/Vulkan/Device.hpp @@ -10,13 +10,12 @@ #include #include #include -#include "Base/ICloseable.hpp" namespace OpenVulkano { namespace Vulkan { - class Device : public ICloseable + class Device final { public: vk::PhysicalDevice physicalDevice; @@ -106,7 +105,7 @@ namespace OpenVulkano return memoryProperties.memoryTypes[memoryType].propertyFlags; } - void Close() override; + void Close(); }; } } diff --git a/openVulkanoCpp/Vulkan/FrameBuffer.hpp b/openVulkanoCpp/Vulkan/FrameBuffer.hpp index e9d68ca..757d9f9 100644 --- a/openVulkanoCpp/Vulkan/FrameBuffer.hpp +++ b/openVulkanoCpp/Vulkan/FrameBuffer.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Image.hpp" #include "Device.hpp" #include @@ -17,7 +16,7 @@ namespace OpenVulkano::Vulkan { class RenderPass; - class FrameBuffer : ICloseable + class FrameBuffer { Image depthBuffer; std::vector frameBuffers; @@ -50,7 +49,7 @@ namespace OpenVulkano::Vulkan protected: void Resize(vk::Extent3D size); - void Close() override + virtual void Close() { DestroyFrameBuffer(); if(depthBuffer) depthBuffer.Close(); diff --git a/openVulkanoCpp/Vulkan/Image.hpp b/openVulkanoCpp/Vulkan/Image.hpp index 40d8ad1..7b820b4 100644 --- a/openVulkanoCpp/Vulkan/Image.hpp +++ b/openVulkanoCpp/Vulkan/Image.hpp @@ -47,7 +47,7 @@ namespace OpenVulkano::Vulkan SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout); } - void Close() override; + virtual void Close(); operator bool() const { return image.operator bool(); } diff --git a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h index 7a4c226..e1f98cd 100644 --- a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h +++ b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "MetalBackedTexture.h" #import @@ -16,7 +15,7 @@ namespace OpenVulkano::Vulkan { class Renderer; - class MetalTextureCache : public ICloseable + class MetalTextureCache final { CVMetalTextureCacheRef m_textureCache = nullptr; Vulkan::ResourceManager* m_resourceManager = nullptr; @@ -28,7 +27,7 @@ namespace OpenVulkano::Vulkan void Init(IRenderer* renderer); - void Close() override; + void Close(); Scene::Texture* Get(CVPixelBufferRef pixelBuffer, MTLPixelFormat pixelFormat); diff --git a/openVulkanoCpp/Vulkan/RenderPass.hpp b/openVulkanoCpp/Vulkan/RenderPass.hpp index 71a7f3f..fbedfab 100644 --- a/openVulkanoCpp/Vulkan/RenderPass.hpp +++ b/openVulkanoCpp/Vulkan/RenderPass.hpp @@ -13,7 +13,7 @@ namespace OpenVulkano::Vulkan { class FrameBuffer; - class RenderPass : public ICloseable + class RenderPass { //TODO allow to control the render rect size protected: vk::Device m_device; @@ -27,14 +27,14 @@ namespace OpenVulkano::Vulkan RenderPass() = default; - ~RenderPass() override + virtual ~RenderPass() { if (m_frameBuffer) RenderPass::Close(); } void Init(Device* device, FrameBuffer* frameBuffer, bool clearColor = false, bool clearDepth = false); - void Close() override; + virtual void Close(); void SetClearColor(vk::ClearColorValue clearColor = vk::ClearColorValue(std::array{ 0.39f, 0.58f, 0.93f, 1.0f })) { diff --git a/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp b/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp index 656ae61..a9feeb9 100644 --- a/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp +++ b/openVulkanoCpp/Vulkan/Resources/UniformBuffer.hpp @@ -6,7 +6,6 @@ #pragma once -#include "Base/ICloseable.hpp" #include "Vulkan/Resources/ManagedBuffer.hpp" #include "Vulkan/Scene/IRecordable.hpp" @@ -14,7 +13,7 @@ namespace OpenVulkano::Vulkan { class ManagedBuffer; - class UniformBuffer final : public IRecordable, public ICloseable + class UniformBuffer final : public IRecordable { ManagedBuffer::Ptr m_buffer = nullptr; vk::DescriptorSet m_descriptorSet; @@ -30,7 +29,7 @@ namespace OpenVulkano::Vulkan void Init(ManagedBuffer::Ptr buffer, uint32_t frameOffset, uint32_t frameSize, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding, uint32_t setId); - void Close() override; + virtual void Close(); void Record(VulkanDrawContext* drawContext) override; From 89d732d5701e6557c1d6d028fdee7bc4ba8278a1 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 16:52:36 +0100 Subject: [PATCH 35/36] Update MetalTextureCache close handling --- openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h | 1 + openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm | 4 ++-- openVulkanoCpp/Vulkan/Renderer.cpp | 1 + openVulkanoCpp/Vulkan/Renderer.hpp | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h index e1f98cd..14dbc9c 100644 --- a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h +++ b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.h @@ -21,6 +21,7 @@ namespace OpenVulkano::Vulkan Vulkan::ResourceManager* m_resourceManager = nullptr; std::map m_mtlToVkTextureMap; Renderer* m_renderer; + IEventHandler* m_eventHandler = nullptr; public: ~MetalTextureCache() { if (m_resourceManager) Close(); } diff --git a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm index 29a68d8..46b36cc 100644 --- a/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm +++ b/openVulkanoCpp/Vulkan/Metal/MetalTextureCache.mm @@ -28,7 +28,7 @@ namespace OpenVulkano::Vulkan Logger::AR->error("Failed to create metal texture cache! Status code: {}", result); } m_resourceManager = &m_renderer->GetResourceManager(); - m_renderer->RegisterCloseable(this); + m_renderer->OnClose += EventHandler(this, &MetalTextureCache::Close); } Scene::Texture* MetalTextureCache::Get(CVPixelBufferRef pixelBuffer, MTLPixelFormat pixelFormat) @@ -57,7 +57,7 @@ namespace OpenVulkano::Vulkan void MetalTextureCache::Close() { m_mtlToVkTextureMap.clear(); - m_renderer->UnregisterCloseable(this); + m_eventHandler->SetInvalid(); m_renderer = nullptr; m_resourceManager = nullptr; //TODO delete the texture cache object? diff --git a/openVulkanoCpp/Vulkan/Renderer.cpp b/openVulkanoCpp/Vulkan/Renderer.cpp index d3b9a5b..4aa56f1 100644 --- a/openVulkanoCpp/Vulkan/Renderer.cpp +++ b/openVulkanoCpp/Vulkan/Renderer.cpp @@ -89,6 +89,7 @@ namespace OpenVulkano::Vulkan { context.device->device.destroySemaphore(sema); } + OnClose(); depthBufferQuery.Close(); uiRenderer.Close(); resourceManager.Close(); diff --git a/openVulkanoCpp/Vulkan/Renderer.hpp b/openVulkanoCpp/Vulkan/Renderer.hpp index 5ab6c3a..fb7ccc3 100644 --- a/openVulkanoCpp/Vulkan/Renderer.hpp +++ b/openVulkanoCpp/Vulkan/Renderer.hpp @@ -87,5 +87,7 @@ namespace OpenVulkano::Vulkan float GetLastQueriedDepthValue() override { return depthBufferQuery.GetQueriedValue(); } void SetQueryDepthValue(const Math::Vector2f& depthCoordinates) override { depthBufferQuery.SetQueryCoordinates(depthCoordinates); } + + Event<> OnClose; }; } From 129d83374fe606a50b6af5d9622359dfd932fe1f Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 6 Jan 2025 17:09:18 +0100 Subject: [PATCH 36/36] Relayout file to reduce memory footprint --- openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index fe0e747..03eff25 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -48,24 +48,24 @@ namespace OpenVulkano::Scene void AddText(const std::string& text, const TextConfig& config = TextConfig()); void SetLabelSettings(const LabelDrawableSettings& settings); - void SetPosition(const Math::Vector3f& pos) { m_position = pos; } + void SetPosition(const Math::Vector2f& pos) { m_position = pos; } [[nodiscard]] std::list& GetTexts() { return m_texts; } [[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; } [[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; } - [[nodiscard]] Math::Vector3f& GetPosition() { return m_position; } + [[nodiscard]] Math::Vector2f& GetPosition() { return m_position; } [[nodiscard]] bool IsBillboard() const { return m_settings.isBillboard; } [[nodiscard]] const Math::AABB2f& GetBoundingBox() const { return m_bbox; } [[nodiscard]] std::optional Intersect(const Ray& ray) const override; private: + LabelDrawableSettings m_settings; std::shared_ptr m_atlasData; UniformBuffer m_labelBuffer; - std::list m_texts; // Using list instead of vector for stable iterators - LabelDrawableSettings m_settings; LabelUniformData m_labelData; - Math::Vector3f m_position = { 0, 0, 0 }; + std::list m_texts; // Using list instead of vector for stable iterators + Math::Vector2f m_position = { 0, 0 }; Math::AABB2f m_bbox; }; }