From 1bb9c33699ff6d929348a18ab116b8b582513f9e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Wed, 17 Jul 2024 16:15:42 +0200 Subject: [PATCH 01/25] Fix crash when using ArBackgroundDrawable without setting an ar session --- openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp index 6268abc..7772469 100644 --- a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp @@ -46,7 +46,8 @@ namespace OpenVulkano::Scene void ArBackgroundDrawable::Close() { - m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); + if (m_arSession) m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); + m_arSession = nullptr; m_nextFrame = nullptr; Drawable::Close(); } @@ -70,4 +71,4 @@ namespace OpenVulkano::Scene } if (!m_texture) m_texture = &Texture::PLACEHOLDER; } -} \ No newline at end of file +} From ab38e03ba19dcae82467fbb9b538d5594bfd13e8 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Thu, 18 Jul 2024 22:04:28 +0200 Subject: [PATCH 02/25] Delay start of playback --- openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp b/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp index 7278cac..47fd852 100644 --- a/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp +++ b/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp @@ -10,6 +10,8 @@ #include "Scene/Texture.hpp" #include +using namespace std::chrono_literals; + namespace OpenVulkano::AR::Playback { ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance) @@ -60,6 +62,7 @@ namespace OpenVulkano::AR::Playback void ArSessionPlayback::ReadWorker() { + std::this_thread::sleep_for(128ms); // Delay startup of playback while (playbackReader.HasNext() && IsRunning()) { while (!m_frameConsumed) { std::this_thread::yield(); } From 22d6ea9d2ea335d4ad9f3e0db44c6eda1176702f Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 20 Jul 2024 19:12:34 +0200 Subject: [PATCH 03/25] Add second constructor to node --- openVulkanoCpp/Scene/Node.cpp | 4 ++++ openVulkanoCpp/Scene/Node.hpp | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Scene/Node.cpp b/openVulkanoCpp/Scene/Node.cpp index 1ceebf1..604cc45 100644 --- a/openVulkanoCpp/Scene/Node.cpp +++ b/openVulkanoCpp/Scene/Node.cpp @@ -14,6 +14,10 @@ namespace OpenVulkano::Scene Node::Node() : localMat(1), worldMat(1), enabled(true) {} + + Node::Node(const Math::Matrix4f& pose) + : localMat(pose), worldMat(pose), enabled(true) + {} Node::~Node() noexcept { diff --git a/openVulkanoCpp/Scene/Node.hpp b/openVulkanoCpp/Scene/Node.hpp index 784bf17..89be67c 100644 --- a/openVulkanoCpp/Scene/Node.hpp +++ b/openVulkanoCpp/Scene/Node.hpp @@ -28,16 +28,18 @@ namespace OpenVulkano::Scene static constexpr DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS }; Math::Matrix4f localMat, worldMat; - bool enabled = true; Node* parent = nullptr; Scene* scene = nullptr; std::vector children; std::vector drawables; UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never; ICloseable* renderNode = nullptr; + bool enabled = true; public: Node(); + + Node(const Math::Matrix4f& pose); ~Node() noexcept override; @@ -80,6 +82,8 @@ namespace OpenVulkano::Scene void Enable() { enabled = true; } void Disable() { enabled = false; } + + void SetEnabled(bool enable) { enabled = enable; } [[nodiscard]] Node* GetParent() const { return parent; } From bcad0116d4e400880d2b38d4f778a741080b8d6e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sat, 20 Jul 2024 19:30:28 +0200 Subject: [PATCH 04/25] Update camera projection matrix handling --- openVulkanoCpp/Scene/Camera.hpp | 19 +++++++++++-------- openVulkanoCpp/Scene/MorphableCamera.cpp | 12 ++++++------ openVulkanoCpp/Scene/MorphableCamera.hpp | 3 +-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/openVulkanoCpp/Scene/Camera.hpp b/openVulkanoCpp/Scene/Camera.hpp index 478176b..229f48c 100644 --- a/openVulkanoCpp/Scene/Camera.hpp +++ b/openVulkanoCpp/Scene/Camera.hpp @@ -97,9 +97,7 @@ namespace OpenVulkano::Scene void UpdateViewProjectionMatrix() { - //TODO this should be done based on the clipspace used by the rendering api - // In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped - m_viewProjection = m_projection * Math::Matrix4f(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) * m_view; + m_viewProjection = m_projection * m_view; } void UpdateWorldMatrix(const Math::Matrix4f& parentWorldMat) override @@ -115,6 +113,14 @@ namespace OpenVulkano::Scene SetMatrix(Math::Utils::inverse(view)); } + void SetProjectionMatrix(const Math::Matrix4f& projection) + { + //TODO this should be done based on the clipspace used by the rendering api + // In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped + m_projection = projection * Math::Matrix4f(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + UpdateViewProjectionMatrix(); + } + [[nodiscard]] const Math::Matrix4f& GetViewProjectionMatrix() const { return m_viewProjection; @@ -251,8 +257,7 @@ namespace OpenVulkano::Scene void UpdateProjectionMatrix() override { - m_projection = Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane); - UpdateViewProjectionMatrix(); + SetProjectionMatrix(Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane)); } [[nodiscard]] bool IsPerspective() const override { return true; } @@ -265,11 +270,9 @@ namespace OpenVulkano::Scene { const float scale = 0.5f * m_contentScaleFactor * m_zoom; const float widthHalf = m_width * scale, heightHalf = m_height * scale; - m_projection = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane); - UpdateViewProjectionMatrix(); + SetProjectionMatrix(Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane)); } [[nodiscard]] bool IsOrtho() const override { return true; } }; } - diff --git a/openVulkanoCpp/Scene/MorphableCamera.cpp b/openVulkanoCpp/Scene/MorphableCamera.cpp index b7275b3..f47a52d 100644 --- a/openVulkanoCpp/Scene/MorphableCamera.cpp +++ b/openVulkanoCpp/Scene/MorphableCamera.cpp @@ -22,21 +22,21 @@ namespace OpenVulkano::Scene } void MorphableCamera::UpdateProjectionMatrix() { - PerspectiveCamera::UpdateProjectionMatrix(); + if (m_morphState == 0) PerspectiveCamera::UpdateProjectionMatrix(); if (m_morphState != 0) { const float scale = 0.5f * m_contentScaleFactor * m_zoom; const float widthHalf = m_width * scale, heightHalf = m_height * scale; - m_orthoMatrix = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane); + Math::Matrix4f orthoMatrix = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane); if (m_morphState == 1) { - m_projection = m_orthoMatrix; + SetProjectionMatrix(orthoMatrix); } else { - m_projection = BlendMatrices(m_projection, m_orthoMatrix, m_morphState); + Math::Matrix4f projection = Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane); + SetProjectionMatrix(BlendMatrices(projection, orthoMatrix, m_morphState)); } - UpdateViewProjectionMatrix(); } } -} \ No newline at end of file +} diff --git a/openVulkanoCpp/Scene/MorphableCamera.hpp b/openVulkanoCpp/Scene/MorphableCamera.hpp index 8c1cb3c..caedb91 100644 --- a/openVulkanoCpp/Scene/MorphableCamera.hpp +++ b/openVulkanoCpp/Scene/MorphableCamera.hpp @@ -13,7 +13,6 @@ namespace OpenVulkano::Scene class MorphableCamera : public PerspectiveCamera { float m_morphState; - Math::Matrix4f m_orthoMatrix; public: MorphableCamera(float fovDegrees, float nearPlane = 0.1f, float farPlane = 1000.0f, float width = 16, float height = 9) @@ -33,4 +32,4 @@ namespace OpenVulkano::Scene [[nodiscard]] bool IsPerspective() const override { return m_morphState == 0; } [[nodiscard]] bool IsOrtho() const override { return m_morphState == 1; } }; -} \ No newline at end of file +} From 4e445495e4bc636c22297248430971e522237f68 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 01:24:51 +0200 Subject: [PATCH 05/25] Add push constants handling for shaders --- openVulkanoCpp/Scene/Shader/PushConstant.hpp | 31 ++++++++++++++++++++ openVulkanoCpp/Scene/Shader/Shader.hpp | 7 +++++ openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp | 6 ++-- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 openVulkanoCpp/Scene/Shader/PushConstant.hpp diff --git a/openVulkanoCpp/Scene/Shader/PushConstant.hpp b/openVulkanoCpp/Scene/Shader/PushConstant.hpp new file mode 100644 index 0000000..dcb90bc --- /dev/null +++ b/openVulkanoCpp/Scene/Shader/PushConstant.hpp @@ -0,0 +1,31 @@ +/* + * 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 "ShaderProgramType.hpp" + +namespace OpenVulkano +{ + struct PushConstantRange + { + ShaderProgramType::Type stageFlags; + uint32_t offset, size; + }; + + struct PushConstant : PushConstantRange + { + const void* data; + + PushConstant(ShaderProgramType::Type stages, uint32_t offset, uint32_t size, const void* data) + : PushConstantRange(stages, offset, size), data(data) + {} + + PushConstant(const void* data, uint32_t size, uint32_t offset = 0, ShaderProgramType::Type stages = ShaderProgramType::ALL_GRAPHICS) + : PushConstantRange(stages, offset, size), data(data) + {} + }; +} diff --git a/openVulkanoCpp/Scene/Shader/Shader.hpp b/openVulkanoCpp/Scene/Shader/Shader.hpp index c138a03..4bc87b3 100644 --- a/openVulkanoCpp/Scene/Shader/Shader.hpp +++ b/openVulkanoCpp/Scene/Shader/Shader.hpp @@ -11,6 +11,7 @@ #include "VertexInputDescription.hpp" #include "ShaderProgramType.hpp" #include "DescriptorInputDescription.hpp" +#include "PushConstant.hpp" #include #include @@ -72,6 +73,7 @@ namespace OpenVulkano::Scene std::vector shaderPrograms{}; std::vector vertexInputDescriptions{}; std::vector> descriptorSets; + std::vector pushConstantRanges; Topology topology = Topology::TRIANGLE_LIST; CullMode cullMode = CullMode::BACK; ICloseable* renderShader = nullptr; @@ -138,6 +140,11 @@ namespace OpenVulkano::Scene } #pragma clang diagnostic pop + void AddPushConstantRange(const PushConstantRange& pushConstantRange) + { + pushConstantRanges.push_back(pushConstantRange); + } + void Close() override { renderShader->Close(); diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index 6187934..5ad6966 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -13,6 +13,7 @@ namespace OpenVulkano::Vulkan { static_assert(sizeof(vk::DescriptorSetLayoutBinding) == sizeof(DescriptorSetLayoutBinding)); + static_assert(sizeof(vk::PushConstantRange) == sizeof(PushConstantRange)); VulkanShader::~VulkanShader() { @@ -148,9 +149,8 @@ namespace OpenVulkano::Vulkan vk::DescriptorSetLayoutCreateInfo createInfo { {}, static_cast(set.size()), reinterpret_cast(set.data()) }; descriptorSetLayouts.push_back(device.createDescriptorSetLayout(createInfo)); } - - - vk::PipelineLayoutCreateInfo plci = { {}, static_cast(descriptorSetLayouts.size()), descriptorSetLayouts.data(), 0, nullptr }; + vk::PushConstantRange* pcRanges = reinterpret_cast(shader->pushConstantRanges.data()); + vk::PipelineLayoutCreateInfo plci = {{}, static_cast(descriptorSetLayouts.size()), descriptorSetLayouts.data(), static_cast(shader->pushConstantRanges.size()), pcRanges }; pipelineLayout = this->device.createPipelineLayout(plci); } } From 7a376ea8fb46d328d8822e204b6b03b421f828bd Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 12:37:25 +0200 Subject: [PATCH 06/25] Add units library --- .gitea/workflows/DependencyMirrors.txt | 4 +++- 3rdParty/units/CMakeLists.txt | 15 +++++++++++++++ CMakeLists.txt | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 3rdParty/units/CMakeLists.txt diff --git a/.gitea/workflows/DependencyMirrors.txt b/.gitea/workflows/DependencyMirrors.txt index 215e5a5..1b1164c 100644 --- a/.gitea/workflows/DependencyMirrors.txt +++ b/.gitea/workflows/DependencyMirrors.txt @@ -19,4 +19,6 @@ PUGIXML_REPO=https://git.madvoxel.net/Mirrors/pugixml.git YAMLCPP_REPO=https://git.madvoxel.net/Mirrors/yaml-cpp.git UTFCPP_REPO=https://git.madvoxel.net/Mirrors/utfcpp.git TRACY_REPO=https://git.madvoxel.net/Mirrors/tracy.git -STB_REPO=https://git.madvoxel.net/Mirrors/stb.git \ No newline at end of file +STB_REPO=https://git.madvoxel.net/Mirrors/stb.git +UNITS_REPO=https://git.madvoxel.net/Mirrors/units.git +ANKERLUD_REPO=https://git.madvoxel.net/Mirrors/ankerl_unordered_dense.git \ No newline at end of file diff --git a/3rdParty/units/CMakeLists.txt b/3rdParty/units/CMakeLists.txt new file mode 100644 index 0000000..6448fee --- /dev/null +++ b/3rdParty/units/CMakeLists.txt @@ -0,0 +1,15 @@ +include(FetchContent) + +if(NOT DEFINED UNITS_REPO) + set(UNITS_REPO https://github.com/nholthaus/units.git) +endif () + +FetchContent_Declare( + units + EXCLUDE_FROM_ALL + GIT_REPOSITORY ${UNITS_REPO} + GIT_TAG v2.3.3 + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(units) + diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cf720b..267085a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,7 @@ endif() list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/deps/INSTALL) -target_link_libraries(openVulkanoCpp PRIVATE magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense Boost::regex) +target_link_libraries(openVulkanoCpp PRIVATE magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense Boost::regex units) LinkCurl(openVulkanoCpp) add_compile_definitions(LIBARCHIVE_STATIC) From 1e400a4030ff659583d25323430cded0c7dfa30e Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 12:48:20 +0200 Subject: [PATCH 07/25] Fix some warnings --- openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp | 2 +- openVulkanoCpp/Scene/PlaneCameraController.hpp | 1 + openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp | 8 +++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp b/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp index 09d2a65..0d514d0 100644 --- a/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp @@ -30,7 +30,7 @@ namespace OpenVulkano [[nodiscard]] bool IsInitialized() const { return initialized; } - void Init(); + void Init() override; void Tick() override; diff --git a/openVulkanoCpp/Scene/PlaneCameraController.hpp b/openVulkanoCpp/Scene/PlaneCameraController.hpp index c1bdfac..ef9eb0c 100644 --- a/openVulkanoCpp/Scene/PlaneCameraController.hpp +++ b/openVulkanoCpp/Scene/PlaneCameraController.hpp @@ -34,6 +34,7 @@ namespace OpenVulkano::Scene PlaneCameraController(Camera* camera = nullptr); + void Init(Camera* camera) override { Init(camera, DefaultAxis::OXZ); } void Init(Camera* camera, const Math::Vector3f& planeNormal); void Init(Camera* camera, DefaultAxis axis); void Tick() override; diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index c49030a..88ac114 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -133,7 +133,11 @@ namespace OpenVulkano::Vulkan { GetCmdBuffer().end(); vk::SubmitInfo si = { 0, nullptr, nullptr, 1, &frameResources[currentBuffer].cmdBuffer, 1, &frameResources[currentBuffer].semaphore }; - transferQueue.submit(1, &si, vk::Fence()); + vk::Result result = transferQueue.submit(1, &si, vk::Fence()); + if (result != vk::Result::eSuccess) [[unlikely]] + { + Logger::RENDER->error("Failed to submit resource manager transfer queue"); + } return frameResources[currentBuffer].semaphore; } @@ -321,10 +325,8 @@ namespace OpenVulkano::Vulkan VulkanUniformBuffer* vkBuffer; ManagedBuffer::Ptr mBuffer; const vk::DeviceSize allocSize = Utils::Align(buffer->size, uniformBufferAlignment); - vk::DeviceSize frameSize = 0; if (buffer->GetUpdateFrequency() != Scene::UpdateFrequency::Never) { - frameSize = allocSize; vkBuffer = new VulkanUniformBufferDynamic(); const uint32_t imgs = context->swapChain.GetImageCount(); mBuffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible); From 1993495dbc988c90b968e7fc87548c341f9c05e3 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 13:42:51 +0200 Subject: [PATCH 08/25] Add option to link vulkan without shaderc --- 3rdParty/imgui/CMakeLists.txt | 1 + cmake/SetupVulkan.cmake | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/3rdParty/imgui/CMakeLists.txt b/3rdParty/imgui/CMakeLists.txt index 5f0ae37..832dd6d 100644 --- a/3rdParty/imgui/CMakeLists.txt +++ b/3rdParty/imgui/CMakeLists.txt @@ -29,6 +29,7 @@ if (glfw_FOUND) target_link_libraries(imgui_internal PUBLIC glfw) endif () +set(NO_SHADERC ON) SetupVulkan(imgui_internal) target_include_directories(imgui_internal PUBLIC ${Vulkan_INCLUDE_DIR}) diff --git a/cmake/SetupVulkan.cmake b/cmake/SetupVulkan.cmake index 24ed595..3a14b93 100644 --- a/cmake/SetupVulkan.cmake +++ b/cmake/SetupVulkan.cmake @@ -5,10 +5,14 @@ function(SetupVulkan TARGET) else () find_package(Vulkan REQUIRED) target_link_libraries(${TARGET} PRIVATE Vulkan::Vulkan) - find_package(Vulkan OPTIONAL_COMPONENTS shaderc_combined) - if (Vulkan_shaderc_combined_FOUND) - target_link_libraries(${TARGET} PRIVATE Vulkan::shaderc_combined) - target_compile_definitions(${TARGET} PRIVATE HAS_SHADERC) + if (NO_SHADERC) + message("Disable shaderc linking") + else() + find_package(Vulkan OPTIONAL_COMPONENTS shaderc_combined) + if (Vulkan_shaderc_combined_FOUND) + target_link_libraries(${TARGET} PRIVATE Vulkan::shaderc_combined) + target_compile_definitions(${TARGET} PRIVATE HAS_SHADERC) + endif () endif () endif () target_include_directories(${TARGET} PUBLIC ${Vulkan_INCLUDE_DIR}) From f97f3206561f8674ddc24ee21fe9997d9d154195 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 13:51:28 +0200 Subject: [PATCH 09/25] Don't build libjpeg turbo on ios (it's not working correctly --- 3rdParty/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index c11e651..d345507 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -20,8 +20,9 @@ add_subdirectory(tracy) add_subdirectory(libstud-uuid) add_subdirectory(rapidyaml) add_subdirectory(libarchive) -add_subdirectory(libjpeg-turbo) add_subdirectory(boost) +add_subdirectory(units) if (NOT IOS) + add_subdirectory(libjpeg-turbo) add_subdirectory(curl) endif() From 23df2966104f58d76b68c9fd52b8dbe83270f238 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 17:34:43 +0200 Subject: [PATCH 10/25] Update formatting --- openVulkanoCpp/Shader/background.frag | 9 ++-- openVulkanoCpp/Shader/background.vert | 74 ++++++++++++++------------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/openVulkanoCpp/Shader/background.frag b/openVulkanoCpp/Shader/background.frag index a1025c7..c05c432 100644 --- a/openVulkanoCpp/Shader/background.frag +++ b/openVulkanoCpp/Shader/background.frag @@ -1,13 +1,14 @@ #version 450 -layout (set = 3, binding = 0) uniform sampler2D camTexture; +layout(set = 3, binding = 0) uniform sampler2D camTexture; #ifdef ENABLE_DEPTH_WRITE -layout (set = 2, binding = 1) uniform sampler2D depthMap; +layout(set = 2, binding = 1) uniform sampler2D depthMap; #endif -layout (location = 0) in vec2 texCoords; -layout (location = 0) out vec4 fragColor; +layout(location = 0) in vec2 texCoords; +layout(location = 1) in float scale; +layout(location = 0) out vec4 fragColor; layout(set = 1, binding = 0) uniform CameraData { diff --git a/openVulkanoCpp/Shader/background.vert b/openVulkanoCpp/Shader/background.vert index 7d5b677..f6a52ae 100644 --- a/openVulkanoCpp/Shader/background.vert +++ b/openVulkanoCpp/Shader/background.vert @@ -3,56 +3,58 @@ 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 = 2, binding = 0) uniform RealCameraData { - mat3 intrinsic; - int width; - int height; + mat3 intrinsic; + int width; + int height; } realCam; layout(location = 0) out vec2 textureCoordinates; +layout(location = 1) out float scaleOut; const float FLOAT_MAX_LESS_THAN_1 = 0.999999940395355224609; // Background plane positions are in clipped space -const vec4 PLANE[4] = vec4[] ( - vec4(1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(1, 1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, 1, FLOAT_MAX_LESS_THAN_1, 1) -); -const vec2 TEX_COORDS[4] = vec2[] ( - vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1) -); +const vec4 PLANE[4] = vec4[]( + vec4(1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(1, 1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, 1, FLOAT_MAX_LESS_THAN_1, 1) + ); +const vec2 TEX_COORDS[4] = vec2[]( + vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1) + ); void main() { - vec4 position = PLANE[gl_VertexIndex]; + vec4 position = PLANE[gl_VertexIndex]; - // Calculate the scaling factors for width and height - float height = realCam.height; - float realScale = realCam.intrinsic[1][1] / height; - float realAspect = height / realCam.width; - float scaleY = realScale / cam.scaleFactor; - float scaleX = scaleY / (cam.aspect * realAspect); + // Calculate the scaling factors for width and height + float height = realCam.height; + float realScale = realCam.intrinsic[1][1] / height; + float realAspect = height / realCam.width; + float scaleY = realScale / cam.scaleFactor; + float scaleX = scaleY / (cam.aspect * realAspect); - // Scale the quad's position - position.xy *= vec2(scaleX, scaleY); + // Handle center + vec2 centerOffset = realCam.intrinsic[2].xy / vec2(realCam.width, realCam.height); + centerOffset -= 0.5; + position.xy -= centerOffset * vec2(2, 2); - // Handle center - vec2 centerOffset = realCam.intrinsic[2].xy / vec2(realCam.width, realCam.height); - centerOffset -= 0.5; - position.xy -= centerOffset; + // Scale the quad's position + position.xy *= vec2(scaleX, scaleY); - gl_Position = position; - textureCoordinates = TEX_COORDS[gl_VertexIndex]; + scaleOut = 1 / scaleY; + gl_Position = position; + textureCoordinates = TEX_COORDS[gl_VertexIndex]; } From 01c273d2fe05eed07e28b610fb84d5d20b3698c2 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 21 Jul 2024 21:49:24 +0200 Subject: [PATCH 11/25] Fix window resizing issue --- openVulkanoCpp/Host/GLFW/WindowGLFW.cpp | 14 +++++++++----- openVulkanoCpp/Host/GLFW/WindowGLFW.hpp | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp index 6525988..aa61f02 100644 --- a/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp @@ -149,8 +149,7 @@ namespace OpenVulkano::GLFW void WindowGLFW::SetSize(uint32_t width, uint32_t height) { - windowConfig.size.x = width; - windowConfig.size.y = height; + currentSize = { width, height }; if (window) { glfwSetWindowSize(window, width, height); @@ -169,9 +168,9 @@ namespace OpenVulkano::GLFW Math::Vector2ui WindowGLFW::GetSize() { - Math::Vector2i size; - glfwGetWindowSize(window, &size.x, &size.y); - return size; + if (currentSize.x == 0 || currentSize.y == 0) + glfwGetWindowSize(window, reinterpret_cast(¤tSize.x), reinterpret_cast(¤tSize.y)); + return currentSize; } Math::Vector2i WindowGLFW::GetPosition() @@ -269,6 +268,11 @@ namespace OpenVulkano::GLFW void WindowGLFW::OnResize(const uint32_t newWidth, const uint32_t newHeight) { Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight); + currentSize = { newWidth, newHeight }; + if (GetWindowMode() == WINDOWED || GetWindowMode() == BORDERLESS) + { + windowConfig.size = currentSize; + } handler->OnWindowResize(this, newWidth, newHeight); } diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp index 709468a..fc6844f 100644 --- a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp @@ -23,6 +23,7 @@ namespace OpenVulkano::GLFW InputProviderGLFW& inputProvider; GLFWwindow* window = nullptr; IWindowHandler* handler = nullptr; + Math::Vector2ui currentSize = {}; public: WindowGLFW(InputProviderGLFW& inputProvider); From f92cc09853ea9995919cfa07e203e6620e520716 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 00:37:04 +0200 Subject: [PATCH 12/25] Add getter for format size --- openVulkanoCpp/Scene/DataFormat.cpp | 58 +++++++++++++++++++++++++++++ openVulkanoCpp/Scene/DataFormat.hpp | 3 ++ 2 files changed, 61 insertions(+) diff --git a/openVulkanoCpp/Scene/DataFormat.cpp b/openVulkanoCpp/Scene/DataFormat.cpp index f0efca7..5f46d8b 100644 --- a/openVulkanoCpp/Scene/DataFormat.cpp +++ b/openVulkanoCpp/Scene/DataFormat.cpp @@ -5,10 +5,50 @@ */ #include "DataFormat.hpp" +#include "Base/Logger.hpp" #include namespace OpenVulkano { + namespace + { + std::unordered_map MakeFormatSizeMap() + { + std::unordered_map map; + for (auto format : magic_enum::enum_values()) + { + uint32_t size = 0; + if (format == DataFormat::R4G4_UNORM_PACK8 || format == DataFormat::S8_UINT) size = 1; + else if (format >= DataFormat::R4G4B4A4_UNORM_PACK16 && format <= DataFormat::A1R5G5B5_UNORM_PACK16) size = 2; + else if (format >= DataFormat::R8_UNORM && format <= DataFormat::R8_SRGB) size = 1; + else if (format >= DataFormat::R8G8_UNORM && format <= DataFormat::R8G8_SRGB) size = 2; + else if (format >= DataFormat::R8G8B8_UNORM && format <= DataFormat::B8G8R8_SRGB) size = 3; + else if (format >= DataFormat::R8G8B8A8_UNORM && format <= DataFormat::A2B10G10R10_SINT_PACK32) size = 4; + else if (format >= DataFormat::R16_UNORM && format <= DataFormat::R16_SFLOAT) size = 2; + else if (format >= DataFormat::R16G16_UNORM && format <= DataFormat::R16G16_SFLOAT) size = 4; + else if (format >= DataFormat::R16G16B16_UNORM && format <= DataFormat::R16G16B16_SFLOAT) size = 6; + else if (format >= DataFormat::R16G16B16A16_UNORM && format <= DataFormat::R16G16B16A16_SFLOAT) size = 8; + else if (format >= DataFormat::R32_UINT && format <= DataFormat::R32_SFLOAT) size = 4; + else if (format >= DataFormat::R32G32_UINT && format <= DataFormat::R32G32_SFLOAT) size = 8; + else if (format >= DataFormat::R32G32B32_UINT && format <= DataFormat::R32G32B32_SFLOAT) size = 12; + else if (format >= DataFormat::R32G32B32A32_UINT && format <= DataFormat::R32G32B32A32_SFLOAT) size = 16; + else if (format >= DataFormat::R64_UINT && format <= DataFormat::R64_SFLOAT) size = 8; + else if (format >= DataFormat::R64G64_UINT && format <= DataFormat::R64G64_SFLOAT) size = 16; + else if (format >= DataFormat::R64G64B64_UINT && format <= DataFormat::R64G64B64_SFLOAT) size = 24; + else if (format >= DataFormat::R64G64B64A64_UINT && format <= DataFormat::R64G64B64A64_SFLOAT) size = 32; + else if (format == DataFormat::B10G11R11_UFLOAT_PACK32 || format == DataFormat::E5B9G9R9_UFLOAT_PACK32 || + format == DataFormat::X8_D24_UNORM_PACK32 || format == DataFormat::D32_SFLOAT || format == DataFormat::D24_UNORM_S8_UINT) size = 4; + else if (format == DataFormat::D16_UNORM) size = 2; + else if (format == DataFormat::D16_UNORM_S8_UINT) size = 3; + else if (format == DataFormat::D32_SFLOAT_S8_UINT) size = 5; + map[format] = size; + } + return map; + } + + const std::unordered_map FORMAT_SIZE_MAP = MakeFormatSizeMap(); + } + std::string_view DataFormat::GetName() const { return magic_enum::enum_name(m_format); @@ -20,4 +60,22 @@ namespace OpenVulkano if (result.has_value()) return { result.value() }; return { UNDEFINED }; } + + uint32_t DataFormat::GetBytesPerPixel() + { + auto size = FORMAT_SIZE_MAP.find(m_format); + if (size == FORMAT_SIZE_MAP.end() || size->second == 0) [[unlikely]] + { + Logger::RENDER->warn("Failed to get pixel size for format: {}", GetName()); + return 0; + } + return size->second; + } + +#ifndef __APPLE__ + DataFormat DataFormat::GetFromMetalPixelFormat(int formatId) + { + return UNDEFINED; + } +#endif } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/DataFormat.hpp b/openVulkanoCpp/Scene/DataFormat.hpp index 67457a6..67c0f39 100644 --- a/openVulkanoCpp/Scene/DataFormat.hpp +++ b/openVulkanoCpp/Scene/DataFormat.hpp @@ -371,9 +371,12 @@ namespace OpenVulkano return reinterpret_cast(m_format); } + uint32_t GetBytesPerPixel(); + static DataFormat GetFromName(std::string_view name); static DataFormat GetFromMetalPixelFormat(int formatId); + private: Format m_format; }; From 00b200301c997a26bcfcbe07e8f5c1a58c45580b Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 09:09:05 +0200 Subject: [PATCH 13/25] Add constructor to make apple clang happy --- openVulkanoCpp/Scene/Shader/PushConstant.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openVulkanoCpp/Scene/Shader/PushConstant.hpp b/openVulkanoCpp/Scene/Shader/PushConstant.hpp index dcb90bc..9b59423 100644 --- a/openVulkanoCpp/Scene/Shader/PushConstant.hpp +++ b/openVulkanoCpp/Scene/Shader/PushConstant.hpp @@ -14,6 +14,14 @@ namespace OpenVulkano { ShaderProgramType::Type stageFlags; uint32_t offset, size; + + PushConstantRange(ShaderProgramType::Type stages, uint32_t offset, uint32_t size) + : stageFlags(stages), offset(offset), size(size) + {} + + PushConstantRange(uint32_t size, uint32_t offset = 0, ShaderProgramType::Type stages = ShaderProgramType::ALL_GRAPHICS) + : stageFlags(stages), offset(offset), size(size) + {} }; struct PushConstant : PushConstantRange From dd1d5fba4b3a9cae9e0c4012b70b92411b4e8cce Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 11:29:48 +0200 Subject: [PATCH 14/25] Update code style --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 88fb9e1..25bfd51 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 88fb9e13fc4e9f92ec6a9ad2f5005e142d5ae678 +Subproject commit 25bfd5114cf9872e2ba014ae853e1ef6e16a4448 From e68fe0613962d2370c60bdec944b0d9b3420e305 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 14:19:09 +0200 Subject: [PATCH 15/25] Allow to control depth test & write for shader --- openVulkanoCpp/Scene/Shader/Shader.hpp | 2 ++ openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Scene/Shader/Shader.hpp b/openVulkanoCpp/Scene/Shader/Shader.hpp index 4bc87b3..484165d 100644 --- a/openVulkanoCpp/Scene/Shader/Shader.hpp +++ b/openVulkanoCpp/Scene/Shader/Shader.hpp @@ -78,6 +78,8 @@ namespace OpenVulkano::Scene CullMode cullMode = CullMode::BACK; ICloseable* renderShader = nullptr; bool alphaBlend = false; // TODO allow fine control over blending + bool depthTest = true; + bool depthWrite = true; Shader() = default; ~Shader() override { /*if (renderShader) Shader::Close();*/ } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index 5ad6966..91fa821 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -80,7 +80,7 @@ namespace OpenVulkano::Vulkan vk::PipelineRasterizationStateCreateInfo rasterizer = {}; rasterizer.cullMode = static_cast(shader->cullMode); vk::PipelineMultisampleStateCreateInfo msaa = {}; - vk::PipelineDepthStencilStateCreateInfo depth = { {}, 1, 1, vk::CompareOp::eLess }; + vk::PipelineDepthStencilStateCreateInfo depth = { {}, shader->depthTest, shader->depthWrite, vk::CompareOp::eLess }; depth.maxDepthBounds = 1; vk::PipelineColorBlendAttachmentState colorBlendAttachment = {}; colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR; From 06e662305059fff8f8816aef6ee6bac9b8ca894b Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 14:19:53 +0200 Subject: [PATCH 16/25] Allow simple drawable to define its draw phase --- openVulkanoCpp/Scene/SimpleDrawable.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Scene/SimpleDrawable.hpp b/openVulkanoCpp/Scene/SimpleDrawable.hpp index 0f5aa13..41ba61b 100644 --- a/openVulkanoCpp/Scene/SimpleDrawable.hpp +++ b/openVulkanoCpp/Scene/SimpleDrawable.hpp @@ -21,10 +21,12 @@ namespace OpenVulkano::Scene UniformBuffer* m_uniBuffer = nullptr; public: - SimpleDrawable() : Drawable(DrawEncoder::GetDrawEncoder()) {} + SimpleDrawable(const DrawPhase phase = DrawPhase::MAIN) + : Drawable(DrawEncoder::GetDrawEncoder(), phase) + {} explicit SimpleDrawable(const SimpleDrawable* toCopy) - : Drawable(DrawEncoder::GetDrawEncoder()) + : Drawable(DrawEncoder::GetDrawEncoder(), toCopy->GetDrawPhase()) , m_mesh(toCopy->m_mesh) , m_material(toCopy->m_material) , m_uniBuffer(toCopy->m_uniBuffer) From 53410bb8dba2407a54741f59369ede0a1a3ea51c Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Mon, 22 Jul 2024 21:08:08 +0200 Subject: [PATCH 17/25] Allow shared memory uniform buffer creation --- openVulkanoCpp/Scene/UniformBuffer.hpp | 2 ++ .../Vulkan/Resources/ResourceManager.cpp | 14 ++++++++++++-- .../Vulkan/Resources/ResourceManager.hpp | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/openVulkanoCpp/Scene/UniformBuffer.hpp b/openVulkanoCpp/Scene/UniformBuffer.hpp index 1551d3f..f198c3e 100644 --- a/openVulkanoCpp/Scene/UniformBuffer.hpp +++ b/openVulkanoCpp/Scene/UniformBuffer.hpp @@ -7,6 +7,8 @@ #pragma once #include "Base/ICloseable.hpp" +#include "Scene/Shader/DescriptorInputDescription.hpp" +#include "Scene/UpdateFrequency.hpp" namespace OpenVulkano::Scene { diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 88ac114..2fc8b8d 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -225,12 +225,22 @@ namespace OpenVulkano::Vulkan return static_cast(camera->renderCamera); } - UniformBuffer* ResourceManager::CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId) + UniformBuffer* ResourceManager::CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId, bool hostVis) { const std::unique_lock lock(mutex); const vk::DeviceSize allocSize = Utils::Align(size, uniformBufferAlignment); - auto buffer = CreateDeviceOnlyBufferWithData(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, data); + MemoryPool::ManagedBufferPtr buffer; + if (hostVis) + { + buffer = memPool.CreateBuffer(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible); + buffer->Map(); + buffer->Copy(data, size, 0); + } + else + { + buffer = CreateDeviceOnlyBufferWithData(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, data); + } UniformBuffer* uBuffer = new UniformBuffer(); uBuffer->Init(std::move(buffer), 0, allocSize, GetDescriptorLayoutSet(binding), binding, setId); diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index fe75424..3910542 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -114,7 +114,7 @@ namespace OpenVulkano [[nodiscard]] vk::Device GetDevice() const { return device; } - UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2); + UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2, bool hostVis = false); vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig); From cd97052ec2367e4f90a3003c752ccd23f42fbe57 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 01:00:03 +0200 Subject: [PATCH 18/25] Add additional sampler --- openVulkanoCpp/AR/ArFrame.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openVulkanoCpp/AR/ArFrame.hpp b/openVulkanoCpp/AR/ArFrame.hpp index db0ce51..8909e8c 100644 --- a/openVulkanoCpp/AR/ArFrame.hpp +++ b/openVulkanoCpp/AR/ArFrame.hpp @@ -45,6 +45,11 @@ namespace OpenVulkano::AR Math::CameraIntrinsic intrinsic; Format format = Format::NV12; + [[nodiscard]] Math::Vector4uc Sample(float nx, float ny, bool asRgb = true) const + { + return Sample(static_cast(nx * luminescenceOrColor.resolution.x), static_cast(nx * luminescenceOrColor.resolution.y), asRgb); + } + [[nodiscard]] Math::Vector4uc Sample(uint32_t x, uint32_t y, bool asRgb = true) const { const uint8_t* lumColBuffer = static_cast(luminescenceOrColor.data); From d64bb7a530b8bb417ea5367eb71e3453816c4572 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 01:20:07 +0200 Subject: [PATCH 19/25] Update AR background --- openVulkanoCpp/Shader/background.frag | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Shader/background.frag b/openVulkanoCpp/Shader/background.frag index c05c432..8e38811 100644 --- a/openVulkanoCpp/Shader/background.frag +++ b/openVulkanoCpp/Shader/background.frag @@ -22,8 +22,14 @@ layout(set = 1, binding = 0) uniform CameraData void main() { + vec2 rm = (texCoords - 0.5) * 2; + float intensity = rm.x * rm.x + rm.y * rm.y; + intensity = (intensity / 1.4) * scale / 2; + fragColor = texture(camTexture, texCoords); + fragColor.rgb = fragColor.rgb - intensity; + #ifdef ENABLE_DEPTH_WRITE gl_FragDepth = (texture(depthMap, texCoords).r - cam.near) / (cam.far - cam.near); #endif -} \ No newline at end of file +} From 75aa36c0249c0236c5e1bbad90df1eea659c9cf6 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 01:21:27 +0200 Subject: [PATCH 20/25] Experimental shared memory texture handling --- openVulkanoCpp/Base/Render/IRenderer.hpp | 3 +++ .../Base/Render/IResourceManager.hpp | 25 +++++++++++++++++++ openVulkanoCpp/Vulkan/Device.cpp | 2 +- openVulkanoCpp/Vulkan/Image.cpp | 16 +++++++++--- openVulkanoCpp/Vulkan/Image.hpp | 2 +- openVulkanoCpp/Vulkan/Renderer.hpp | 2 ++ .../Vulkan/Resources/ResourceManager.cpp | 15 +++++++++++ .../Vulkan/Resources/ResourceManager.hpp | 5 +++- openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp | 13 ++++++++++ 9 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 openVulkanoCpp/Base/Render/IResourceManager.hpp diff --git a/openVulkanoCpp/Base/Render/IRenderer.hpp b/openVulkanoCpp/Base/Render/IRenderer.hpp index de12732..3c01ef3 100644 --- a/openVulkanoCpp/Base/Render/IRenderer.hpp +++ b/openVulkanoCpp/Base/Render/IRenderer.hpp @@ -6,6 +6,7 @@ #pragma once +#include "IResourceManager.hpp" #include "Base/ITickable.hpp" #include "Base/ICloseable.hpp" #include "Scene/Scene.hpp" @@ -32,5 +33,7 @@ namespace OpenVulkano virtual void SetActiveUi(Scene::UI::Ui* ui) = 0; virtual Scene::UI::Ui* GetActiveUi() = 0; + + virtual IResourceManager* GetIResourceManager() = 0; }; } diff --git a/openVulkanoCpp/Base/Render/IResourceManager.hpp b/openVulkanoCpp/Base/Render/IResourceManager.hpp new file mode 100644 index 0000000..afecdb2 --- /dev/null +++ b/openVulkanoCpp/Base/Render/IResourceManager.hpp @@ -0,0 +1,25 @@ +/* + * 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/Wrapper.hpp" +#include "Math/Math.hpp" +#include "Scene/DataFormat.hpp" + +namespace OpenVulkano +{ + namespace Scene + { + class Texture; + } + + class IResourceManager + { + public: + [[nodiscard]] virtual Unique CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) = 0; + }; +} diff --git a/openVulkanoCpp/Vulkan/Device.cpp b/openVulkanoCpp/Vulkan/Device.cpp index deb58a1..76d22d4 100644 --- a/openVulkanoCpp/Vulkan/Device.cpp +++ b/openVulkanoCpp/Vulkan/Device.cpp @@ -202,7 +202,7 @@ namespace OpenVulkano::Vulkan bool Device::GetMemoryType(uint32_t typeBits, const vk::MemoryPropertyFlags& properties, uint32_t* typeIndex) const { - for (uint32_t i = 0; i < 32; i++) + for (uint32_t i = 0; i < 32 && typeBits; i++) { if ((typeBits & 1) == 1) { diff --git a/openVulkanoCpp/Vulkan/Image.cpp b/openVulkanoCpp/Vulkan/Image.cpp index 21e738f..26b94e8 100644 --- a/openVulkanoCpp/Vulkan/Image.cpp +++ b/openVulkanoCpp/Vulkan/Image.cpp @@ -35,14 +35,22 @@ namespace OpenVulkano::Vulkan cmdBuffer.pipelineBarrier(/*VulkanUtils::GetPipelineStageForLayout(oldLayout)*/vk::PipelineStageFlagBits::eTopOfPipe, /*VulkanUtils::GetPipelineStageForLayout(newLayout)*/ vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, imgMemBarrier); } - void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution) + void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags) { vk::ImageCreateInfo imgCreateInfo { {}, vk::ImageType::e2D, format, resolution, 1, 1 }; imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled; - imgCreateInfo.tiling = vk::ImageTiling::eOptimal; + if (memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible) + { + imgCreateInfo.tiling = vk::ImageTiling::eLinear; + imgCreateInfo.initialLayout = vk::ImageLayout::ePreinitialized; + } + else + { + imgCreateInfo.tiling = vk::ImageTiling::eOptimal; + imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined; + } imgCreateInfo.sharingMode = vk::SharingMode::eExclusive; - imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined; vk::ImageViewCreateInfo imgViewCreateInfo { {}, image, vk::ImageViewType::e2D, imgCreateInfo.format }; imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; @@ -51,7 +59,7 @@ namespace OpenVulkano::Vulkan imgViewCreateInfo.subresourceRange.baseArrayLayer = 0; imgViewCreateInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; - Init(device, imgCreateInfo, imgViewCreateInfo); + Init(device, imgCreateInfo, imgViewCreateInfo, true, memoryPropertyFlags); } void Image::Close() diff --git a/openVulkanoCpp/Vulkan/Image.hpp b/openVulkanoCpp/Vulkan/Image.hpp index ee684bb..40d8ad1 100644 --- a/openVulkanoCpp/Vulkan/Image.hpp +++ b/openVulkanoCpp/Vulkan/Image.hpp @@ -38,7 +38,7 @@ namespace OpenVulkano::Vulkan */ void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal); - void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution); + void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal); void SetLayout(vk::CommandBuffer& cmdBuffer, const vk::ImageSubresourceRange& subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const; diff --git a/openVulkanoCpp/Vulkan/Renderer.hpp b/openVulkanoCpp/Vulkan/Renderer.hpp index 2ff4d36..5740256 100644 --- a/openVulkanoCpp/Vulkan/Renderer.hpp +++ b/openVulkanoCpp/Vulkan/Renderer.hpp @@ -84,5 +84,7 @@ namespace OpenVulkano::Vulkan void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); } void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); } + + IResourceManager* GetIResourceManager() override { return &resourceManager; } }; } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index 2fc8b8d..47a9d9e 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -365,4 +365,19 @@ namespace OpenVulkano::Vulkan if (!sampler) sampler = device.createSampler(samplerConfig); return sampler; } + + Unique ResourceManager::CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) + { + const std::unique_lock lock(mutex); + Unique texture = std::make_unique(); + texture->resolution = resolution; + texture->format = format; + texture->size = resolution.x * resolution.y * resolution.z * format.GetBytesPerPixel(); + + VulkanTexture* vkTexture = new VulkanTexture(); + vkTexture->InitSharedMem(this, texture.get(), GetDescriptorLayoutSet(Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING); + textures.emplace_back(vkTexture); + + return texture; + } } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp index 3910542..b347f73 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.hpp @@ -14,6 +14,7 @@ #include "IShaderOwner.hpp" #include "MemoryPool.hpp" #include "Base/Wrapper.hpp" +#include "Base/Render/IResourceManager.hpp" #include "Vulkan/Image.hpp" #include "Scene/Shader/DescriptorInputDescription.hpp" #include @@ -47,7 +48,7 @@ namespace OpenVulkano class ManagedBuffer; class MemoryAllocation; - class ResourceManager : public IShaderOwner + class ResourceManager : public IShaderOwner, public IResourceManager { friend UniformBuffer; friend VulkanTexture; @@ -118,6 +119,8 @@ namespace OpenVulkano vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig); + [[nodiscard]] Unique CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) override; + protected: // Allocation management MemoryPool::ManagedBufferPtr CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data); diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index 1442434..c47f37e 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -37,6 +37,19 @@ namespace OpenVulkano::Vulkan texture->renderTexture = this; } + void InitSharedMem(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding) + { + m_texture = texture; + Image::Init(resManager->GetContext()->device.get(), texture->format, { texture->resolution.x, texture->resolution.y, texture->resolution.z }, vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible); + texture->updated = false; + texture->textureBuffer = Map(); + + m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG); + SetDescriptorSet(resManager, descriptorSetLayout, binding); + + texture->renderTexture = this; + } + virtual ~VulkanTexture() override { if (m_texture) Close(); From 545f24843622b13adb7922bbfd39de449b9cbfc9 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 02:10:42 +0200 Subject: [PATCH 21/25] Fix issue with sampler --- openVulkanoCpp/AR/ArFrame.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openVulkanoCpp/AR/ArFrame.hpp b/openVulkanoCpp/AR/ArFrame.hpp index 8909e8c..b0678ce 100644 --- a/openVulkanoCpp/AR/ArFrame.hpp +++ b/openVulkanoCpp/AR/ArFrame.hpp @@ -47,7 +47,7 @@ namespace OpenVulkano::AR [[nodiscard]] Math::Vector4uc Sample(float nx, float ny, bool asRgb = true) const { - return Sample(static_cast(nx * luminescenceOrColor.resolution.x), static_cast(nx * luminescenceOrColor.resolution.y), asRgb); + return Sample(static_cast(nx * luminescenceOrColor.resolution.x), static_cast(ny * luminescenceOrColor.resolution.y), asRgb); } [[nodiscard]] Math::Vector4uc Sample(uint32_t x, uint32_t y, bool asRgb = true) const From d262daa66f6f047160e21479489add9a2df785af Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 02:27:29 +0200 Subject: [PATCH 22/25] Add RGB565 class --- openVulkanoCpp/Math/RGB565.hpp | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 openVulkanoCpp/Math/RGB565.hpp diff --git a/openVulkanoCpp/Math/RGB565.hpp b/openVulkanoCpp/Math/RGB565.hpp new file mode 100644 index 0000000..1600b5a --- /dev/null +++ b/openVulkanoCpp/Math/RGB565.hpp @@ -0,0 +1,46 @@ +/* + * 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 "Math/Math.hpp" + +namespace OpenVulkano::Math +{ + class RGB565 + { + uint16_t Make5(uint8_t val) + { + return val * 31.0f / 255.0f; + } + + uint16_t Make6(uint8_t val) + { + return val * 63.0f / 255.0f; + } + + public: + union + { + uint16_t value; + struct + { + uint16_t b : 5; + uint16_t g : 6; + uint16_t r : 5; + }; + }; + + RGB565(Math::Vector4uc color = {0, 0, 0, 1}) + : b(Make5(color.b)) + , g(Make6(color.g)) + , r(Make5(color.r)) + { + } + }; + + static_assert(sizeof(RGB565) == 2); +} From 02ff22d1933522057bb31ec427d0ad4db4342698 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 22:01:07 +0200 Subject: [PATCH 23/25] Fix some issue with deinitializing textures --- openVulkanoCpp/Scene/Texture.hpp | 24 +++++++++++++++---- .../Vulkan/Metal/MetalBackedTexture.mm | 2 +- openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp | 7 +++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/openVulkanoCpp/Scene/Texture.hpp b/openVulkanoCpp/Scene/Texture.hpp index f05dfef..ab3d30c 100644 --- a/openVulkanoCpp/Scene/Texture.hpp +++ b/openVulkanoCpp/Scene/Texture.hpp @@ -14,22 +14,36 @@ namespace OpenVulkano::Scene { + class Texture; + + struct RenderTexture + { + Texture* m_texture = nullptr; + }; + class Texture { public: static Texture PLACEHOLDER; static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_COMBINED_IMAGE_SAMPLER, 1, ShaderProgramType::ALL_GRAPHICS }; - Texture(bool placeholder = false) { if (placeholder) MakePlaceholder(); } - - ICloseable* renderTexture = nullptr; + RenderTexture* renderTexture = nullptr; void* textureBuffer = nullptr; - Math::Vector3ui resolution = {0,0,0}; size_t size = 0; + Math::Vector3ui resolution = {0,0,0}; DataFormat format = DataFormat::B8G8R8A8_UNORM; bool updated = true; UpdateFrequency updateFrequency = UpdateFrequency::Never; + Texture(bool placeholder = false) { if (placeholder) MakePlaceholder(); } + + ~Texture() + { + if (renderTexture) + { + renderTexture->m_texture = nullptr; + } + } void MakePlaceholder(uint32_t width = 32, uint32_t height = 32, Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255}); @@ -43,4 +57,4 @@ namespace OpenVulkano::Scene operator bool() const { return setId >= 0 && texture; } }; -} \ No newline at end of file +} diff --git a/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm b/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm index 91be222..75995a4 100644 --- a/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm +++ b/openVulkanoCpp/Vulkan/Metal/MetalBackedTexture.mm @@ -64,7 +64,7 @@ namespace OpenVulkano::Vulkan void MetalBackedTexture::Close() { - m_vulkanTexture.Close(); + if (m_vulkanTexture) m_vulkanTexture.Close(); if (m_metalTexture) { [m_metalTexture release]; diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index c47f37e..a7c50c4 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -16,11 +16,10 @@ namespace OpenVulkano::Vulkan { - class VulkanTexture : public IRecordable, public Image + class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image { public: static inline vk::SamplerCreateInfo DEFAULT_SAMPLER_CONFIG {}; - Scene::Texture* m_texture = nullptr; vk::Sampler m_sampler; vk::DescriptorSet m_descriptorSet; @@ -52,7 +51,7 @@ namespace OpenVulkano::Vulkan virtual ~VulkanTexture() override { - if (m_texture) Close(); + if (m_sampler) Close(); } void Close() override @@ -138,4 +137,4 @@ namespace OpenVulkano::Vulkan VulkanTexture::Record(context, setId); } }; -} \ No newline at end of file +} From 2e514576025107b2e74e17f825949c1488e57df9 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 22:10:33 +0200 Subject: [PATCH 24/25] Silence some warnings --- openVulkanoCpp/Base/Version.hpp | 2 +- openVulkanoCpp/Vulkan/SwapChain.cpp | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/openVulkanoCpp/Base/Version.hpp b/openVulkanoCpp/Base/Version.hpp index 36e4fb4..cfca78b 100644 --- a/openVulkanoCpp/Base/Version.hpp +++ b/openVulkanoCpp/Base/Version.hpp @@ -37,7 +37,7 @@ namespace OpenVulkano [[nodiscard]] uint32_t Patch() const { return GetComponent(2); } - [[nodiscard]] uint32_t Build() const { return m_buildNumber; } + [[nodiscard]] uint64_t Build() const { return m_buildNumber; } [[nodiscard]] bool IsPreRelease() const { return m_preRelease; } diff --git a/openVulkanoCpp/Vulkan/SwapChain.cpp b/openVulkanoCpp/Vulkan/SwapChain.cpp index eca6a43..72605f3 100644 --- a/openVulkanoCpp/Vulkan/SwapChain.cpp +++ b/openVulkanoCpp/Vulkan/SwapChain.cpp @@ -50,13 +50,25 @@ namespace OpenVulkano::Vulkan { currentSemaphoreId = (currentSemaphoreId + 1) % imageAvailableSemaphores.size(); const auto resultValue = device->device.acquireNextImageKHR(swapChain, UINT64_MAX, imageAvailableSemaphores[currentSemaphoreId], fence); - const vk::Result result = resultValue.result; - if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR) throw std::error_code(result); + vk::Result result = resultValue.result; + if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR) [[unlikely]] + { + Logger::RENDER->error("Failed to acquire next swapchain image: {}", vk::to_string(result)); + throw std::error_code(result); + } SetCurrentFrameId(resultValue.value); vk::Fence submitFence = GetCurrentSubmitFence(); - device->device.waitForFences(1, &submitFence, true, -1); - device->device.resetFences(1, &submitFence); + result = device->device.waitForFences(1, &submitFence, true, -1); + if (result != vk::Result::eSuccess) [[unlikely]] + { + Logger::RENDER->error("Failed to wait for fence: {}", vk::to_string(result)); + } + result = device->device.resetFences(1, &submitFence); + if (result != vk::Result::eSuccess) [[unlikely]] + { + Logger::RENDER->error("Failed to reset fence: {}", vk::to_string(result)); + } return currentFrameBufferId; } From a578be93ec8087a632bed1c273e1f0a738bb3e44 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Tue, 23 Jul 2024 23:02:22 +0200 Subject: [PATCH 25/25] Add some functions --- openVulkanoCpp/Math/Math.hpp | 6 ++++++ openVulkanoCpp/Vulkan/Scene/VulkanCamera.hpp | 5 ++++- openVulkanoCpp/Vulkan/VulkanDrawContext.hpp | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index ac06bca..4dc74ec 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -29,6 +29,12 @@ namespace OpenVulkano::Math constexpr T CONVERSION = std::numbers::pi_v / 180.0; return degree * CONVERSION; } + + template + constexpr T Square(T val) + { + return val * val; + } } template using Matrix2_SIMD = glm::tmat2x2; diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanCamera.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanCamera.hpp index 7996b4a..1832fec 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanCamera.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanCamera.hpp @@ -7,6 +7,7 @@ #pragma once #include "Base/ICloseable.hpp" +#include "Scene/Camera.hpp" #include "IRecordable.hpp" #include "Vulkan/Resources/UniformBuffer.hpp" @@ -39,5 +40,7 @@ namespace OpenVulkano::Vulkan m_camera = nullptr; delete m_buffer; } + + [[nodiscard]] Scene::Camera* GetCamera() const { return m_camera; } }; -} \ No newline at end of file +} diff --git a/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp b/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp index 87723d8..169858e 100644 --- a/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp +++ b/openVulkanoCpp/Vulkan/VulkanDrawContext.hpp @@ -35,6 +35,8 @@ namespace OpenVulkano::Vulkan void SetCamera(Scene::Camera* camera); - VulkanShader* GetShader() const { return m_lastShader; } + [[nodiscard]] VulkanShader* GetShader() const { return m_lastShader; } + + [[nodiscard]] VulkanCamera* GetCamera() const { return m_lastCamera; } }; }