From aee79133ec0a95368732298707fc050ecb5db9a3 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 22 Sep 2025 15:16:55 -0600 Subject: [PATCH 01/19] Allow context to recreate doodad pipeline when we should be switching polygon modes --- src/quartz/rendering/context/CMakeLists.txt | 9 ++++-- src/quartz/rendering/context/Context.cpp | 32 +++++++++++++++++---- src/quartz/rendering/context/Context.hpp | 5 +++- src/quartz/rendering/device/Device.cpp | 1 + src/quartz/rendering/pipeline/Pipeline.cpp | 8 +++++- src/quartz/rendering/pipeline/Pipeline.hpp | 9 ++++++ 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/quartz/rendering/context/CMakeLists.txt b/src/quartz/rendering/context/CMakeLists.txt index f3f9d3d6..9e0fd737 100644 --- a/src/quartz/rendering/context/CMakeLists.txt +++ b/src/quartz/rendering/context/CMakeLists.txt @@ -21,12 +21,14 @@ target_compile_options( target_compile_definitions( QUARTZ_RENDERING_Context - PUBLIC ${QUARTZ_COMPILE_DEFINITIONS} + PUBLIC + ${QUARTZ_COMPILE_DEFINITIONS} ) target_compile_definitions( - QUARTZ_RENDERING_Context - PUBLIC ${QUARTZ_COMPILE_DEFINITIONS} + QUARTZ_RENDERING_Context + PUBLIC + ${QUARTZ_COMPILE_DEFINITIONS} ) target_link_libraries( @@ -57,3 +59,4 @@ target_link_libraries( QUARTZ_SCENE_Light QUARTZ_SCENE_Scene ) + diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 4ba51400..8b2fcd74 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -1,8 +1,12 @@ #include #include +#include +#include + #include "math/transform/Mat4.hpp" +#include "util/logger/Logger.hpp" #include "util/file_system/FileSystem.hpp" #include "quartz/rendering/Loggers.hpp" @@ -19,7 +23,6 @@ #include "quartz/scene/light/DirectionalLight.hpp" #include "quartz/scene/light/PointLight.hpp" #include "quartz/scene/light/SpotLight.hpp" -#include "util/logger/Logger.hpp" quartz::rendering::Pipeline quartz::rendering::Context::createSkyBoxRenderingPipeline( @@ -60,6 +63,7 @@ quartz::rendering::Context::createSkyBoxRenderingPipeline( maxNumFramesInFlight, quartz::rendering::CubeMap::getVulkanVertexInputBindingDescription(), quartz::rendering::CubeMap::getVulkanVertexInputAttributeDescriptions(), + vk::PolygonMode::eFill, vk::CullModeFlagBits::eFront, false, {}, @@ -204,6 +208,7 @@ quartz::rendering::Context::createDoodadRenderingPipeline( maxNumFramesInFlight, quartz::rendering::Vertex::getVulkanVertexInputBindingDescription(), quartz::rendering::Vertex::getVulkanVertexInputAttributeDescriptions(), + vk::PolygonMode::eFill, vk::CullModeFlagBits::eBack, true, pushConstantInfos, @@ -308,8 +313,15 @@ quartz::rendering::Context::draw( m_currentInFlightFrameIndex ); - if (m_renderingSwapchain.getShouldRecreate() || m_renderingWindow.getWasResized()) { - recreateSwapchain(); + const bool shouldRecreateDoodadPipeline = (m_doodadRenderingPipeline.getPolygonMode() == vk::PolygonMode::eFill) ? + wireframeDoodadMode : + !wireframeDoodadMode; + if ( + m_renderingSwapchain.getShouldRecreate() || + m_renderingWindow.getWasResized() || + shouldRecreateDoodadPipeline + ) { + recreateSwapchain(wireframeDoodadMode, wireframeColliderMode); return; } @@ -332,7 +344,7 @@ quartz::rendering::Context::draw( // housekeeping if (m_renderingSwapchain.getShouldRecreate() || m_renderingWindow.getWasResized()) { - recreateSwapchain(); + recreateSwapchain(wireframeDoodadMode, wireframeColliderMode); return; } @@ -340,7 +352,10 @@ quartz::rendering::Context::draw( } void -quartz::rendering::Context::recreateSwapchain() { +quartz::rendering::Context::recreateSwapchain( + const bool wireframeDoodadMode, + UNUSED const bool wireframeColliderMode +) { LOG_FUNCTION_SCOPE_INFOthis(""); m_renderingDevice.waitIdle(); @@ -353,18 +368,25 @@ quartz::rendering::Context::recreateSwapchain() { m_renderingInstance, m_renderingDevice ); + m_renderingRenderPass.recreate( m_renderingDevice, m_renderingWindow ); + m_skyBoxRenderingPipeline.recreate( m_renderingDevice, m_renderingRenderPass ); + + LOG_INFOthis("Setting doodad pipeline polygon mode to: {}", wireframeDoodadMode ? "line" : "fill"); + const vk::PolygonMode polygonMode = wireframeDoodadMode ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; + m_doodadRenderingPipeline.setPolygonMode(polygonMode); m_doodadRenderingPipeline.recreate( m_renderingDevice, m_renderingRenderPass ); + m_renderingSwapchain.recreate( m_renderingDevice, m_renderingWindow, diff --git a/src/quartz/rendering/context/Context.hpp b/src/quartz/rendering/context/Context.hpp index 3d50b5a1..6ce8df9e 100644 --- a/src/quartz/rendering/context/Context.hpp +++ b/src/quartz/rendering/context/Context.hpp @@ -66,7 +66,10 @@ class quartz::rendering::Context { ); private: // member functions - void recreateSwapchain(); + void recreateSwapchain( + const bool wireframeDoodadMode, + const bool wireframeColliderMode + ); void waitForImage(); void updateSkyBoxPipeline( const quartz::scene::Camera::UniformBufferObject& cameraUBO); void updateDoodadPipeline( diff --git a/src/quartz/rendering/device/Device.cpp b/src/quartz/rendering/device/Device.cpp index 19589eb4..6ad4e207 100644 --- a/src/quartz/rendering/device/Device.cpp +++ b/src/quartz/rendering/device/Device.cpp @@ -161,6 +161,7 @@ quartz::rendering::Device::createVulkanLogicalDevicePtr( vk::PhysicalDeviceFeatures requestedPhysicalDeviceFeatures; requestedPhysicalDeviceFeatures.samplerAnisotropy = true; + requestedPhysicalDeviceFeatures.fillModeNonSolid = true; /// @todo 2023/11/01 enable requestedPhysicalDeviceFeatures.depthBounds vk::DeviceCreateInfo logicalDeviceCreateInfo( diff --git a/src/quartz/rendering/pipeline/Pipeline.cpp b/src/quartz/rendering/pipeline/Pipeline.cpp index feb037d8..294a1790 100644 --- a/src/quartz/rendering/pipeline/Pipeline.cpp +++ b/src/quartz/rendering/pipeline/Pipeline.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "util/macros.hpp" #include "util/errors/RichException.hpp" @@ -526,6 +527,7 @@ quartz::rendering::Pipeline::createVulkanGraphicsPipelinePtr( const std::vector vertexInputAttributeDescriptions, const std::vector viewports, const std::vector scissorRectangles, + const vk::PolygonMode polygonMode, const vk::CullModeFlags cullModeFlags, const bool shouldDepthTest, const std::vector colorBlendAttachmentStates, @@ -598,7 +600,7 @@ quartz::rendering::Pipeline::createVulkanGraphicsPipelinePtr( {}, false, false, - vk::PolygonMode::eFill, + polygonMode, cullModeFlags, vk::FrontFace::eCounterClockwise, false, @@ -699,6 +701,7 @@ quartz::rendering::Pipeline::Pipeline( const uint32_t maxNumFramesInFlight, const vk::VertexInputBindingDescription& vertexInputBindingDescription, const std::vector& vertexInputAttributeDescriptions, + const vk::PolygonMode polygonMode, const vk::CullModeFlags cullModeFlags, const bool shouldDepthTest, const std::vector& pushConstantInfos, @@ -725,6 +728,7 @@ quartz::rendering::Pipeline::Pipeline( renderingWindow.getVulkanExtent() ) }), + m_polygonMode(polygonMode), m_vulkanCullModeFlags(cullModeFlags), m_shouldDepthTest(shouldDepthTest), m_vulkanColorBlendAttachmentStates({ @@ -813,6 +817,7 @@ quartz::rendering::Pipeline::Pipeline( m_vulkanVertexInputAttributeDescriptions, m_vulkanViewports, m_vulkanScissorRectangles, + m_polygonMode, m_vulkanCullModeFlags, m_shouldDepthTest, m_vulkanColorBlendAttachmentStates, @@ -857,6 +862,7 @@ quartz::rendering::Pipeline::recreate( m_vulkanVertexInputAttributeDescriptions, m_vulkanViewports, m_vulkanScissorRectangles, + m_polygonMode, m_vulkanCullModeFlags, m_shouldDepthTest, m_vulkanColorBlendAttachmentStates, diff --git a/src/quartz/rendering/pipeline/Pipeline.hpp b/src/quartz/rendering/pipeline/Pipeline.hpp index 75a4410b..4d521b1e 100644 --- a/src/quartz/rendering/pipeline/Pipeline.hpp +++ b/src/quartz/rendering/pipeline/Pipeline.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "quartz/rendering/Loggers.hpp" #include "quartz/rendering/buffer/LocallyMappedBuffer.hpp" @@ -42,6 +43,7 @@ class quartz::rendering::Pipeline { const uint32_t maxNumFramesInFlight, const vk::VertexInputBindingDescription& vertexInputBindingDescription, const std::vector& vertexInputAttributeDescriptions, + const vk::PolygonMode polygonMode, const vk::CullModeFlags cullModeFlags, const bool shouldDepthTest, const std::vector& pushConstantInfos, @@ -75,6 +77,8 @@ class quartz::rendering::Pipeline { const std::vector>& texturePtrs ); + void setPolygonMode(const vk::PolygonMode polygonMode) { m_polygonMode = polygonMode; } + USE_LOGGER(PIPELINE); const std::vector& getPushConstantInfos() const { return m_pushConstantInfos; } @@ -83,6 +87,9 @@ class quartz::rendering::Pipeline { const std::vector& getVulkanViewports() const { return m_vulkanViewports; } const std::vector& getVulkanScissorRectangles() const { return m_vulkanScissorRectangles; } + + vk::PolygonMode getPolygonMode() const { return m_polygonMode; } + const std::vector& getVulkanDescriptorSets() const { return m_vulkanDescriptorSets; } const vk::UniquePipelineLayout& getVulkanPipelineLayoutPtr() const { return mp_vulkanPipelineLayout; } const vk::UniquePipeline& getVulkanGraphicsPipelinePtr() const { return mp_vulkanGraphicsPipeline; } @@ -160,6 +167,7 @@ class quartz::rendering::Pipeline { const std::vector vertexInputAttributeDescriptions, const std::vector viewports, const std::vector scissorRectangles, + const vk::PolygonMode polygonMode, const vk::CullModeFlags cullModeFlags, const bool shouldDepthTest, const std::vector colorBlendAttachmentStates, @@ -175,6 +183,7 @@ class quartz::rendering::Pipeline { std::vector m_vulkanVertexInputAttributeDescriptions; std::vector m_vulkanViewports; std::vector m_vulkanScissorRectangles; + vk::PolygonMode m_polygonMode; vk::CullModeFlags m_vulkanCullModeFlags; bool m_shouldDepthTest; std::vector m_vulkanColorBlendAttachmentStates; From f95b82aaa6e1507a470f07840c36f0fe40a941f2 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 22 Sep 2025 15:19:43 -0600 Subject: [PATCH 02/19] Increment quartz version --- cmake/QuartzVersion.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/QuartzVersion.cmake b/cmake/QuartzVersion.cmake index f6930e7c..f700c9e0 100644 --- a/cmake/QuartzVersion.cmake +++ b/cmake/QuartzVersion.cmake @@ -47,9 +47,10 @@ endfunction() # set_quartz_major_minor_patch_versions(0 2 11) # scene libarary fixes # set_quartz_major_minor_patch_versions(0 2 12) # fixes for linux # set_quartz_major_minor_patch_versions(0 2 13) # RichException implementation and usage -# set_quartz_major_minor_patch_versions(0 2 14) # Custom source_location and mocked stacktrace for Mac so we can still use rich exceptions +# set_quartz_major_minor_patch_versions(0 2 14) # custom source_location and mocked stacktrace for Mac so we can still use rich exceptions # Minor Version 3 - Scene Debugging Capabilities -set_quartz_major_minor_patch_versions(0 3 0) # Enable Quartz to enter a debugging mode +# set_quartz_major_minor_patch_versions(0 3 0) # enable Quartz to enter a debugging mode +set_quartz_major_minor_patch_versions(0 3 1) # allow for wireframe display of doodads when in scene debugging mode From c3b75fb5b497072f1ae1870ba30f1028c12e6390 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Tue, 23 Sep 2025 23:25:07 -0600 Subject: [PATCH 03/19] Inspect some of the behavior of the UBO info's stride calculation - it makes no sense --- src/quartz/rendering/context/Context.cpp | 3 +- src/quartz/rendering/pipeline/Pipeline.hpp | 1 + .../rendering/pipeline/UniformBufferInfo.cpp | 6 +- .../rendering/pipeline/UniformBufferInfo.hpp | 4 +- test/scratch/CMakeLists.txt | 1 + test/scratch/StridePlayground.cpp | 64 +++++++++++++++++++ test/unit/CMakeLists.txt | 1 + .../quartz/rendering/pipeline/CMakeLists.txt | 6 ++ .../pipeline/test_UniformBufferInfo.cpp | 52 +++++++++++++++ 9 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 test/scratch/StridePlayground.cpp create mode 100644 test/unit/quartz/rendering/pipeline/CMakeLists.txt create mode 100644 test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 8b2fcd74..b44a002c 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -98,7 +98,8 @@ quartz::rendering::Context::createDoodadRenderingPipeline( } }; - const uint32_t materialByteStride = quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride(renderingDevice, sizeof(quartz::rendering::Material::UniformBufferObject)); + const uint32_t minUniformBufferOffsetAlignment = renderingDevice.getVulkanPhysicalDevice().getProperties().limits.minUniformBufferOffsetAlignment; + const uint32_t materialByteStride = quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride(minUniformBufferOffsetAlignment, sizeof(quartz::rendering::Material::UniformBufferObject)); std::vector uniformBufferInfos = { // the camera { diff --git a/src/quartz/rendering/pipeline/Pipeline.hpp b/src/quartz/rendering/pipeline/Pipeline.hpp index 4d521b1e..5563d69c 100644 --- a/src/quartz/rendering/pipeline/Pipeline.hpp +++ b/src/quartz/rendering/pipeline/Pipeline.hpp @@ -206,3 +206,4 @@ class quartz::rendering::Pipeline { vk::UniquePipelineLayout mp_vulkanPipelineLayout; vk::UniquePipeline mp_vulkanGraphicsPipeline; }; + diff --git a/src/quartz/rendering/pipeline/UniformBufferInfo.cpp b/src/quartz/rendering/pipeline/UniformBufferInfo.cpp index c677267b..4aa6b11e 100644 --- a/src/quartz/rendering/pipeline/UniformBufferInfo.cpp +++ b/src/quartz/rendering/pipeline/UniformBufferInfo.cpp @@ -5,11 +5,9 @@ uint32_t quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride( - const quartz::rendering::Device& renderingDevice, + const uint32_t minUniformBufferOffsetAlignment, const uint32_t uniformBufferObjectSizeBytes ) { - const uint32_t minUniformBufferOffsetAlignment = renderingDevice.getVulkanPhysicalDevice().getProperties().limits.minUniformBufferOffsetAlignment; - const uint32_t byteStride = minUniformBufferOffsetAlignment > 0 ? (uniformBufferObjectSizeBytes + minUniformBufferOffsetAlignment - 1) & ~(minUniformBufferOffsetAlignment - 1) : uniformBufferObjectSizeBytes; @@ -102,4 +100,4 @@ quartz::rendering::UniformBufferInfo::operator=( m_vulkanShaderStageFlags = other.m_vulkanShaderStageFlags; return *this; -} \ No newline at end of file +} diff --git a/src/quartz/rendering/pipeline/UniformBufferInfo.hpp b/src/quartz/rendering/pipeline/UniformBufferInfo.hpp index c640a5e9..7619e621 100644 --- a/src/quartz/rendering/pipeline/UniformBufferInfo.hpp +++ b/src/quartz/rendering/pipeline/UniformBufferInfo.hpp @@ -42,7 +42,7 @@ class quartz::rendering::UniformBufferInfo { public: // static functions static uint32_t calculateDynamicUniformBufferByteStride( - const quartz::rendering::Device& renderingDevice, + const uint32_t minUniformBufferOffsetAlignment, const uint32_t uniformBufferObjectSizeBytes ); @@ -56,4 +56,4 @@ class quartz::rendering::UniformBufferInfo { uint32_t m_objectStrideBytes; vk::DescriptorType m_vulkanDescriptorType; vk::ShaderStageFlags m_vulkanShaderStageFlags; -}; \ No newline at end of file +}; diff --git a/test/scratch/CMakeLists.txt b/test/scratch/CMakeLists.txt index 88a7c895..e1b9e32e 100644 --- a/test/scratch/CMakeLists.txt +++ b/test/scratch/CMakeLists.txt @@ -4,4 +4,5 @@ create_scratch_executable(QuaternionEulerAngleExploration.cpp MATH_Transform) create_scratch_executable(RichExceptionExample.cpp UTIL_Errors) +create_scratch_executable(StridePlayground.cpp QUARTZ_RENDERING_Pipeline) create_scratch_executable(SuccessiveWindows.cpp QUARTZ_RENDERING_Window) diff --git a/test/scratch/StridePlayground.cpp b/test/scratch/StridePlayground.cpp new file mode 100644 index 00000000..af3856c2 --- /dev/null +++ b/test/scratch/StridePlayground.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "quartz/rendering/pipeline/UniformBufferInfo.hpp" + +void +inspectStride( + const uint32_t minAlignmentBytes, + const uint32_t uboSizeBytes +) { +#if true + const uint32_t resultBytes = quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride( + minAlignmentBytes, + uboSizeBytes + ); + std::cout << std::setw(3) << uboSizeBytes << std::setw(0) << " , "; + std::cout << std::setw(3) << minAlignmentBytes << std::setw(0) << " -> "; + std::cout << std::setw(4) << resultBytes << std::setw(0); + std::cout << std::endl; + return; +#else + const uint32_t addedBytes = uboSizeBytes + minAlignmentBytes - 1; + const uint32_t negatedMinAlignmentBytes = ~(minAlignmentBytes - 1); + const uint32_t resultBytes = addedBytes & negatedMinAlignmentBytes; + + std::cout << std::endl; + std::cout << "====================================================" << std::endl; + std::cout << "{" << std::endl; + + std::cout << " UBO size bytes : " << std::bitset<32>(uboSizeBytes) << " = " << uboSizeBytes << std::endl; + std::cout << " Min alignment : " << std::bitset<32>(minAlignmentBytes) << " = " << minAlignmentBytes << std::endl; + std::cout << std::endl; + + std::cout << " added with offset : " << std::bitset<32>(addedBytes) << " = " << addedBytes << std::endl; + std::cout << std::endl; + std::cout << " negated min alignment: " << std::bitset<32>(negatedMinAlignmentBytes) << " = " << negatedMinAlignmentBytes << std::endl; + std::cout << std::endl; + std::cout << " result : " << std::bitset<32>(resultBytes) << " = " << resultBytes << std::endl; + + std::cout << "}" << std::endl; + std::cout << "====================================================" << std::endl; + std::cout << std::endl; +#endif +} + +int +main() { + const std::vector alignments = { + 1, 2, 3, 4, 5, 7, 10, 11 + }; + + const double iterations = 2.5; + for (const uint32_t alignment : alignments) { + std::cout << std::endl; + std::cout << "Alignment: " << alignment << std::endl; + for (uint32_t uboSize = 1; uboSize < (alignment * iterations + 1); ++uboSize) { + inspectStride(alignment, uboSize); + } + } + + return 0; +} diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 5b2e3fe1..c6c0dc54 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -29,6 +29,7 @@ add_subdirectory("quartz/physics/field") add_subdirectory("quartz/physics/rigid_body") add_subdirectory("quartz/rendering/material") +add_subdirectory("quartz/rendering/pipeline") add_subdirectory("quartz/scene/camera") add_subdirectory("quartz/scene/doodad") diff --git a/test/unit/quartz/rendering/pipeline/CMakeLists.txt b/test/unit/quartz/rendering/pipeline/CMakeLists.txt new file mode 100644 index 00000000..c634bd1a --- /dev/null +++ b/test/unit/quartz/rendering/pipeline/CMakeLists.txt @@ -0,0 +1,6 @@ +#==================================================================== +# Quartz Rendering Pipeline Unit Tests +#==================================================================== + +create_unit_test(test_UniformBufferInfo.cpp QUARTZ_RENDERING_Pipeline) + diff --git a/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp new file mode 100644 index 00000000..f7906874 --- /dev/null +++ b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp @@ -0,0 +1,52 @@ +#include + +#include "util/unit_test/UnitTest.hpp" + +#include "quartz/rendering/pipeline/UniformBufferInfo.hpp" + +uint32_t manualStride( + const uint32_t minAlignment, + const uint32_t uboSizeBytes +) { + if (minAlignment == 0) { + return uboSizeBytes; + } + + // TODO - what the fuck is our stride function actually doing? I don't get it ... + return minAlignment + uboSizeBytes; +} + +UT_FUNCTION(test_calculateDynamicUniformBufferByteStride) { + struct TestInfo { + uint32_t minAlignment; + uint32_t uboSizeBytes; + }; + + std::vector testInfos; + const std::vector alignments = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 23, 37, 50, 199, 55555, 6666 }; + const double iterations = 10; + for (const uint32_t alignment : alignments) { + for (uint32_t uboSize = 1; uboSize < (alignment * iterations + 1); uboSize++) { + testInfos.push_back({alignment, uboSize}); + } + } + + for (const TestInfo& testInfo : testInfos) { + UT_CHECK_NOT_EQUAL( + quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride( + testInfo.minAlignment, + testInfo.uboSizeBytes + ), + manualStride( + testInfo.minAlignment, + testInfo.uboSizeBytes + ) + ); + } +} + +UT_MAIN() { + REGISTER_UT_FUNCTION(test_calculateDynamicUniformBufferByteStride); + UT_RUN_TESTS(); +} + From 534184027ba330a644fee9e63eb90488783d412a Mon Sep 17 00:00:00 2001 From: Kejoko Date: Wed, 24 Sep 2025 10:58:06 -0600 Subject: [PATCH 04/19] Unit test for validating UBO info stride calc (using vulkan spec power of 2 alignment) --- test/scratch/StridePlayground.cpp | 31 ++----------------- .../pipeline/test_UniformBufferInfo.cpp | 31 ++++++++++++++++--- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/test/scratch/StridePlayground.cpp b/test/scratch/StridePlayground.cpp index af3856c2..3f7bfda7 100644 --- a/test/scratch/StridePlayground.cpp +++ b/test/scratch/StridePlayground.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -10,45 +9,21 @@ inspectStride( const uint32_t minAlignmentBytes, const uint32_t uboSizeBytes ) { -#if true const uint32_t resultBytes = quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride( minAlignmentBytes, uboSizeBytes ); - std::cout << std::setw(3) << uboSizeBytes << std::setw(0) << " , "; - std::cout << std::setw(3) << minAlignmentBytes << std::setw(0) << " -> "; + std::cout << std::setw(3) << uboSizeBytes << std::setw(0) << " -> "; std::cout << std::setw(4) << resultBytes << std::setw(0); std::cout << std::endl; return; -#else - const uint32_t addedBytes = uboSizeBytes + minAlignmentBytes - 1; - const uint32_t negatedMinAlignmentBytes = ~(minAlignmentBytes - 1); - const uint32_t resultBytes = addedBytes & negatedMinAlignmentBytes; - - std::cout << std::endl; - std::cout << "====================================================" << std::endl; - std::cout << "{" << std::endl; - - std::cout << " UBO size bytes : " << std::bitset<32>(uboSizeBytes) << " = " << uboSizeBytes << std::endl; - std::cout << " Min alignment : " << std::bitset<32>(minAlignmentBytes) << " = " << minAlignmentBytes << std::endl; - std::cout << std::endl; - - std::cout << " added with offset : " << std::bitset<32>(addedBytes) << " = " << addedBytes << std::endl; - std::cout << std::endl; - std::cout << " negated min alignment: " << std::bitset<32>(negatedMinAlignmentBytes) << " = " << negatedMinAlignmentBytes << std::endl; - std::cout << std::endl; - std::cout << " result : " << std::bitset<32>(resultBytes) << " = " << resultBytes << std::endl; - - std::cout << "}" << std::endl; - std::cout << "====================================================" << std::endl; - std::cout << std::endl; -#endif } int main() { + // must be a multiple of 2 according to vulkan spec const std::vector alignments = { - 1, 2, 3, 4, 5, 7, 10, 11 + 1, 2, 4, 8, 16, 32 }; const double iterations = 2.5; diff --git a/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp index f7906874..23c9184f 100644 --- a/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp +++ b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp @@ -1,5 +1,7 @@ +#include #include +#include "util/logger/Logger.hpp" #include "util/unit_test/UnitTest.hpp" #include "quartz/rendering/pipeline/UniformBufferInfo.hpp" @@ -12,18 +14,39 @@ uint32_t manualStride( return uboSizeBytes; } - // TODO - what the fuck is our stride function actually doing? I don't get it ... - return minAlignment + uboSizeBytes; + // Take our uboSize and round up to the next multiple of our alignment size + + const double fitment = static_cast(uboSizeBytes) / static_cast(minAlignment); + const uint32_t alignmentMultiples = std::ceil(fitment); + return alignmentMultiples * minAlignment; } +/** + * @brief From the vulkan spec: + * """ + * `minUniformBufferOffsetAlignment` is the minimum __required__ alignment, in bytes, for the + * `offset` member of the `VkDescriptorBufferInfo` structure for uniform buffers. + * When a descriptor of type `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` + * is updated, the `offset` __must__ be an integer multiple of this limit. + * Similarly, dynamic offsets for uniform buffers __must__ be multiples of this limit. + * The value __must__ be a power of two. + * """ + */ UT_FUNCTION(test_calculateDynamicUniformBufferByteStride) { struct TestInfo { uint32_t minAlignment; uint32_t uboSizeBytes; }; + // Create the list of testing information + // We do this by creating a list of alignments (each of which is a power of 2), + // then creating a set of uboSizes to test each alignment std::vector testInfos; - const std::vector alignments = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 23, 37, 50, 199, 55555, 6666 }; + std::vector alignments; + const uint32_t maxPower = 8; + for (uint32_t power = 0; power <= maxPower; ++power) { + alignments.push_back(std::pow(2, power)); + } const double iterations = 10; for (const uint32_t alignment : alignments) { for (uint32_t uboSize = 1; uboSize < (alignment * iterations + 1); uboSize++) { @@ -32,7 +55,7 @@ UT_FUNCTION(test_calculateDynamicUniformBufferByteStride) { } for (const TestInfo& testInfo : testInfos) { - UT_CHECK_NOT_EQUAL( + UT_CHECK_EQUAL( quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride( testInfo.minAlignment, testInfo.uboSizeBytes From 4f2f6dde344156abc22be20a4117e7849e192692 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 2 Oct 2025 15:14:12 -0600 Subject: [PATCH 05/19] Test UBO construction, vulkan printing utility --- .../rendering/buffer/LocallyMappedBuffer.hpp | 3 +- .../rendering/vulkan_util/VulkanUtil.cpp | 207 ++++++++++++++++-- .../rendering/vulkan_util/VulkanUtil.hpp | 15 +- test/unit/CMakeLists.txt | 1 + .../quartz/rendering/buffer/CMakeLists.txt | 6 + .../buffer/test_LocallyMappedBuffer.cpp | 19 ++ .../pipeline/test_UniformBufferInfo.cpp | 71 ++++++ 7 files changed, 299 insertions(+), 23 deletions(-) create mode 100644 test/unit/quartz/rendering/buffer/CMakeLists.txt create mode 100644 test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp diff --git a/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp b/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp index 25f68f5a..a01276f8 100644 --- a/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp +++ b/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp @@ -45,4 +45,5 @@ class quartz::rendering::LocallyMappedBuffer { vk::UniqueBuffer mp_vulkanLogicalBuffer; vk::UniqueDeviceMemory mp_vulkanPhysicalDeviceMemory; void* mp_mappedLocalMemory; -}; \ No newline at end of file +}; + diff --git a/src/quartz/rendering/vulkan_util/VulkanUtil.cpp b/src/quartz/rendering/vulkan_util/VulkanUtil.cpp index 617c7073..5a7c321a 100644 --- a/src/quartz/rendering/vulkan_util/VulkanUtil.cpp +++ b/src/quartz/rendering/vulkan_util/VulkanUtil.cpp @@ -1,4 +1,7 @@ +#include #include +#include +#include #include #include "util/errors/RichException.hpp" @@ -9,9 +12,9 @@ std::string quartz::rendering::VulkanUtil::toString( - const vk::DescriptorType descriptorType + const vk::DescriptorType type ) { - switch (descriptorType) { + switch (type) { case vk::DescriptorType::eSampler: return "eSampler"; case vk::DescriptorType::eCombinedImageSampler: @@ -45,6 +48,30 @@ quartz::rendering::VulkanUtil::toString( } } +std::string +quartz::rendering::VulkanUtil::toString( + const vk::ImageViewType type +) { + switch (type) { + case vk::ImageViewType::e1D: + return "1D"; + case vk::ImageViewType::e2D: + return "2D"; + case vk::ImageViewType::e3D: + return "3D"; + case vk::ImageViewType::eCube: + return "Cube"; + case vk::ImageViewType::e1DArray: + return "1D Array"; + case vk::ImageViewType::e2DArray: + return "2D Array"; + case vk::ImageViewType::eCubeArray: + return "Cube Array"; + default: + return "Unknown vk::ImageViewType"; + } +} + std::string quartz::rendering::VulkanUtil::toString( const vk::ImageCreateFlags flags @@ -86,26 +113,130 @@ quartz::rendering::VulkanUtil::toString( std::string quartz::rendering::VulkanUtil::toString( - const vk::ImageViewType type + const vk::BufferUsageFlags flags ) { - switch (type) { - case vk::ImageViewType::e1D: - return "1D"; - case vk::ImageViewType::e2D: - return "2D"; - case vk::ImageViewType::e3D: - return "3D"; - case vk::ImageViewType::eCube: - return "Cube"; - case vk::ImageViewType::e1DArray: - return "1D Array"; - case vk::ImageViewType::e2DArray: - return "2D Array"; - case vk::ImageViewType::eCubeArray: - return "Cube Array"; - default: - return "Unknown vk::ImageViewType"; + std::vector flagStrings; + + if (flags & vk::BufferUsageFlagBits::eUniformBuffer) { flagStrings.push_back("UniformBuffer"); } + if (flags & vk::BufferUsageFlagBits::eIndexBuffer) { flagStrings.push_back("IndexBuffer"); } + if (flags & vk::BufferUsageFlagBits::eVertexBuffer) { flagStrings.push_back("VertexBuffer"); } + if (flags & vk::BufferUsageFlagBits::eStorageBuffer) { flagStrings.push_back("StorageBuffer"); } + if (flags & vk::BufferUsageFlagBits::eIndirectBuffer) { flagStrings.push_back("IndirectBuffer"); } + if (flags & vk::BufferUsageFlagBits::eStorageTexelBuffer) { flagStrings.push_back("StorageTexelBuffer"); } + if (flags & vk::BufferUsageFlagBits::eUniformTexelBuffer) { flagStrings.push_back("UniformTexelBuffer"); } + + if (flags & vk::BufferUsageFlagBits::eTransferDst) { flagStrings.push_back("TransferDst"); } + if (flags & vk::BufferUsageFlagBits::eTransferSrc) { flagStrings.push_back("TransferSrc"); } + + if (flags & vk::BufferUsageFlagBits::eRayTracingNV) { flagStrings.push_back("RayTracingNV"); } + + if (flags & vk::BufferUsageFlagBits::eShaderDeviceAddress) { flagStrings.push_back("ShaderDeviceAddress"); } + + if (flags & vk::BufferUsageFlagBits::eShaderDeviceAddressEXT) { flagStrings.push_back("ShaderDeviceAddressEXT"); } + if (flags & vk::BufferUsageFlagBits::eConditionalRenderingEXT) { flagStrings.push_back("ConditionalRenderingEXT"); } + if (flags & vk::BufferUsageFlagBits::eTransformFeedbackBufferEXT) { flagStrings.push_back("TransformFeedbackBufferEXT"); } + if (flags & vk::BufferUsageFlagBits::eTransformFeedbackCounterBufferEXT) { flagStrings.push_back("TransformFeedbackCounterBufferEXT"); } + + if (flags & vk::BufferUsageFlagBits::eShaderDeviceAddressKHR) { flagStrings.push_back("ShaderDeviceAddressKHR"); } + if (flags & vk::BufferUsageFlagBits::eShaderBindingTableKHR) { flagStrings.push_back("ShaderBindingTableKHR"); } + if (flags & vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR) { flagStrings.push_back("AccelerationStructureStorageKHR"); } + if (flags & vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR) { flagStrings.push_back("AccelerationStructureBuildInputReadOnlyKHR"); } + + if (flagStrings.empty()) { + return "[ None ]"; + } + + // Join the flag strings with a separator + std::string result = "[ "; + for (const std::string& flagString : flagStrings) { + if (!result.empty()) { + result += " | "; + } + result += flagString; } + result += " ]"; + + return result; +} + +std::string +quartz::rendering::VulkanUtil::toString( + const vk::MemoryPropertyFlags flags +) { + std::vector flagStrings; + + if (flags & vk::MemoryPropertyFlagBits::eProtected) { flagStrings.push_back("Protected"); } + if (flags & vk::MemoryPropertyFlagBits::eHostCached) { flagStrings.push_back("HostCached"); } + if (flags & vk::MemoryPropertyFlagBits::eHostVisible) { flagStrings.push_back("HostVisible"); } + if (flags & vk::MemoryPropertyFlagBits::eDeviceLocal) { flagStrings.push_back("DeviceLocal"); } + if (flags & vk::MemoryPropertyFlagBits::eHostCoherent) { flagStrings.push_back("HostCoherent"); } + if (flags & vk::MemoryPropertyFlagBits::eRdmaCapableNV) { flagStrings.push_back("RdmaCapableNV"); } + if (flags & vk::MemoryPropertyFlagBits::eLazilyAllocated) { flagStrings.push_back("LazilyAllocated"); } + if (flags & vk::MemoryPropertyFlagBits::eDeviceCoherentAMD) { flagStrings.push_back("DeviceCoherentAMD"); } + if (flags & vk::MemoryPropertyFlagBits::eDeviceUncachedAMD) { flagStrings.push_back("DeviceUncachedAMD"); } + + if (flagStrings.empty()) { + return "[ None ]"; + } + + // Join the flag strings with a separator + std::string result = "[ "; + for (const std::string& flagString : flagStrings) { + if (!result.empty()) { + result += " | "; + } + result += flagString; + } + result += " ]"; + + return result; +} + +std::string +quartz::rendering::VulkanUtil::toString( + const vk::ShaderStageFlags flags +) { + std::vector flagStrings; + + if (flags & vk::ShaderStageFlagBits::eAll) { flagStrings.push_back("All"); } + if (flags & vk::ShaderStageFlagBits::eMeshNV) { flagStrings.push_back("MeshNV"); } + if (flags & vk::ShaderStageFlagBits::eMissNV) { flagStrings.push_back("MissNV"); } + if (flags & vk::ShaderStageFlagBits::eTaskNV) { flagStrings.push_back("TaskNV"); } + if (flags & vk::ShaderStageFlagBits::eVertex) { flagStrings.push_back("Vertex"); } + if (flags & vk::ShaderStageFlagBits::eCompute) { flagStrings.push_back("Compute"); } + if (flags & vk::ShaderStageFlagBits::eMissKHR) { flagStrings.push_back("MissKHR"); } + if (flags & vk::ShaderStageFlagBits::eAnyHitNV) { flagStrings.push_back("AnyHitNV"); } + if (flags & vk::ShaderStageFlagBits::eFragment) { flagStrings.push_back("Fragment"); } + if (flags & vk::ShaderStageFlagBits::eGeometry) { flagStrings.push_back("Geometry"); } + if (flags & vk::ShaderStageFlagBits::eRaygenNV) { flagStrings.push_back("RaygenNV"); } + if (flags & vk::ShaderStageFlagBits::eRaygenKHR) { flagStrings.push_back("RaygenKHR"); } + if (flags & vk::ShaderStageFlagBits::eAnyHitKHR) { flagStrings.push_back("AnyHitKHR"); } + if (flags & vk::ShaderStageFlagBits::eCallableNV) { flagStrings.push_back("CallableNV"); } + if (flags & vk::ShaderStageFlagBits::eCallableKHR) { flagStrings.push_back("CallableKHR"); } + if (flags & vk::ShaderStageFlagBits::eAllGraphics) { flagStrings.push_back("AllGraphics"); } + if (flags & vk::ShaderStageFlagBits::eClosestHitNV) { flagStrings.push_back("ClosestHitNV"); } + if (flags & vk::ShaderStageFlagBits::eClosestHitKHR) { flagStrings.push_back("ClosestHitKHR"); } + if (flags & vk::ShaderStageFlagBits::eIntersectionNV) { flagStrings.push_back("IntersectionNV"); } + if (flags & vk::ShaderStageFlagBits::eIntersectionKHR) { flagStrings.push_back("IntersectionKHR"); } + if (flags & vk::ShaderStageFlagBits::eTessellationControl) { flagStrings.push_back("TessellationControl"); } + if (flags & vk::ShaderStageFlagBits::eSubpassShadingHUAWEI) { flagStrings.push_back("SubpassShadingHUAWEI"); } + if (flags & vk::ShaderStageFlagBits::eTessellationEvaluation) { flagStrings.push_back("TessellationEvaluation"); } + + if (flagStrings.empty()) { + return "[ None ]"; + } + + // Join the flag strings with a separator + std::string result = "[ "; + for (const std::string& flagString : flagStrings) { + if (!result.empty()) { + result += " | "; + } + result += flagString; + } + result += " ]"; + + return result; } vk::UniqueImageView @@ -245,3 +376,39 @@ quartz::rendering::VulkanUtil::allocateVulkanCommandBufferPtr( return commandBufferPtrs; } +std::ostream& +operator<<( + std::ostream& os, + const vk::DescriptorType type +) { + os << quartz::rendering::VulkanUtil::toString(type); + return os; +} + +std::ostream& +operator<<( + std::ostream& os, + const vk::BufferUsageFlags flags +) { + os << quartz::rendering::VulkanUtil::toString(flags); + return os; +} + +std::ostream& +operator<<( + std::ostream& os, + const vk::MemoryPropertyFlags flags +) { + os << quartz::rendering::VulkanUtil::toString(flags); + return os; +} + +std::ostream& +operator<<( + std::ostream& os, + const vk::ShaderStageFlags flags +) { + os << quartz::rendering::VulkanUtil::toString(flags); + return os; +} + diff --git a/src/quartz/rendering/vulkan_util/VulkanUtil.hpp b/src/quartz/rendering/vulkan_util/VulkanUtil.hpp index 8318b284..98001412 100644 --- a/src/quartz/rendering/vulkan_util/VulkanUtil.hpp +++ b/src/quartz/rendering/vulkan_util/VulkanUtil.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include +#include namespace quartz { namespace rendering { @@ -19,9 +21,12 @@ class quartz::rendering::VulkanUtil { // ----- stringifying things ----- // - static std::string toString(const vk::DescriptorType descriptorType); - static std::string toString(const vk::ImageCreateFlags flags); + static std::string toString(const vk::DescriptorType type); static std::string toString(const vk::ImageViewType type); + static std::string toString(const vk::ImageCreateFlags flags); + static std::string toString(const vk::BufferUsageFlags flags); + static std::string toString(const vk::MemoryPropertyFlags flags); + static std::string toString(const vk::ShaderStageFlags flags); // ----- image, image view, smapler things ----- // @@ -57,3 +62,9 @@ class quartz::rendering::VulkanUtil { const uint32_t desiredCommandBufferCount ); }; + +std::ostream& operator<<(std::ostream& os, const vk::DescriptorType flags); +std::ostream& operator<<(std::ostream& os, const vk::BufferUsageFlags flags); +std::ostream& operator<<(std::ostream& os, const vk::MemoryPropertyFlags flags); +std::ostream& operator<<(std::ostream& os, const vk::ShaderStageFlags flags); + diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index c6c0dc54..b365e073 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -28,6 +28,7 @@ add_subdirectory("quartz/physics/collider") add_subdirectory("quartz/physics/field") add_subdirectory("quartz/physics/rigid_body") +add_subdirectory("quartz/rendering/buffer") add_subdirectory("quartz/rendering/material") add_subdirectory("quartz/rendering/pipeline") diff --git a/test/unit/quartz/rendering/buffer/CMakeLists.txt b/test/unit/quartz/rendering/buffer/CMakeLists.txt new file mode 100644 index 00000000..00485b8e --- /dev/null +++ b/test/unit/quartz/rendering/buffer/CMakeLists.txt @@ -0,0 +1,6 @@ +#==================================================================== +# Quartz Rendering Buffer Unit Tests +#==================================================================== + +create_unit_test(test_LocallyMappedBuffer.cpp QUARTZ_RENDERING_Buffer) + diff --git a/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp b/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp new file mode 100644 index 00000000..3dac2d7c --- /dev/null +++ b/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp @@ -0,0 +1,19 @@ +#include "util/unit_test/UnitTest.hpp" + +#include "quartz/rendering/buffer/LocallyMappedBuffer.hpp" + +UT_FUNCTION(test_mapVulkanPhysicalDeviceMemoryToLocalMemory) { + // Create physical device + quartz::rendering::Instance renderingInstance("DOODAD_UT", 9, 9, 9, true); + quartz::rendering::Device renderingDevice(renderingInstance); + + // Create uniform buffer info + // Create locally mapped buffer + // Ensure that the locally mapped buffer contains the correct data (UBO info data) +} + +UT_MAIN() { + REGISTER_UT_FUNCTION(test_mapVulkanPhysicalDeviceMemoryToLocalMemory); + UT_RUN_TESTS(); +} + diff --git a/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp index 23c9184f..30ea056d 100644 --- a/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp +++ b/test/unit/quartz/rendering/pipeline/test_UniformBufferInfo.cpp @@ -4,8 +4,11 @@ #include "util/logger/Logger.hpp" #include "util/unit_test/UnitTest.hpp" +#include "quartz/rendering/vulkan_util/VulkanUtil.hpp" #include "quartz/rendering/pipeline/UniformBufferInfo.hpp" +#include // so linting stops complaining - and to prevent this from being auto included at the beginning + uint32_t manualStride( const uint32_t minAlignment, const uint32_t uboSizeBytes @@ -68,8 +71,76 @@ UT_FUNCTION(test_calculateDynamicUniformBufferByteStride) { } } +UT_FUNCTION(test_construction) { + struct UBOInfoParameters { + uint32_t locallyMappedBufferSizeBytes; + vk::MemoryPropertyFlags locallyMappedBufferPropertyFlags; + uint32_t bindingLocation; + uint32_t descriptorCount; + uint32_t objectStrideBytes; + bool isDynamic; + vk::ShaderStageFlags shaderStageFlags; + }; + + std::vector allParameters = { + UBOInfoParameters( + 99, + vk::MemoryPropertyFlagBits::eHostCoherent, + 42, + 102, + 88, + true, + vk::ShaderStageFlagBits::eMeshNV + ), + + UBOInfoParameters( + 233, + vk::MemoryPropertyFlagBits::eDeviceCoherentAMD | vk::MemoryPropertyFlagBits::eHostVisible, + 4, + 12, + 8, + false, + vk::ShaderStageFlagBits::eClosestHitNV | vk::ShaderStageFlagBits::eAnyHitKHR + ) + }; + + for (uint32_t iParameter = 0; iParameter < allParameters.size(); ++iParameter) { + LOG_SCOPE_CHANGE_TRACE(UT); + LOG_TRACE(UT, "UBO Info {}", iParameter); + + const UBOInfoParameters& parameters = allParameters[iParameter]; + + const quartz::rendering::UniformBufferInfo uboInfo( + parameters.locallyMappedBufferSizeBytes, + parameters.locallyMappedBufferPropertyFlags, + parameters.bindingLocation, + parameters.descriptorCount, + parameters.objectStrideBytes, + parameters.isDynamic, + parameters.shaderStageFlags + ); + + UT_CHECK_EQUAL(uboInfo.getLocallyMappedBufferSize(), parameters.locallyMappedBufferSizeBytes); + UT_CHECK_EQUAL(uboInfo.getLocallyMappedBufferVulkanUsageFlags(), vk::BufferUsageFlagBits::eUniformBuffer); + UT_CHECK_EQUAL(uboInfo.getLocallyMappedBufferVulkanPropertyFlags(), parameters.locallyMappedBufferPropertyFlags); + + UT_CHECK_EQUAL(uboInfo.getBindingLocation(), parameters.bindingLocation); + UT_CHECK_EQUAL(uboInfo.getDescriptorCount(), parameters.descriptorCount); + UT_CHECK_EQUAL(uboInfo.getObjectStrideBytes(), parameters.objectStrideBytes); + + if (parameters.isDynamic) { + UT_CHECK_EQUAL(uboInfo.getVulkanDescriptorType(), vk::DescriptorType::eUniformBufferDynamic); + } else { + UT_CHECK_EQUAL(uboInfo.getVulkanDescriptorType(), vk::DescriptorType::eUniformBuffer); + } + + UT_CHECK_EQUAL(uboInfo.getVulkanShaderStageFlags(), parameters.shaderStageFlags); + } +} + UT_MAIN() { REGISTER_UT_FUNCTION(test_calculateDynamicUniformBufferByteStride); + REGISTER_UT_FUNCTION(test_construction); UT_RUN_TESTS(); } From 8de39ea1304139c8da2d47132d88eb136593dad5 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 2 Oct 2025 17:16:32 -0600 Subject: [PATCH 06/19] Test the locally mapped buffer (kinda) --- .../rendering/buffer/LocallyMappedBuffer.hpp | 1 + src/quartz/rendering/pipeline/Pipeline.cpp | 1 + .../quartz/rendering/buffer/CMakeLists.txt | 2 +- .../buffer/test_LocallyMappedBuffer.cpp | 65 ++++++++++++++++++- test/unit/quartz/scene/scene/test_Scene.cpp | 2 +- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp b/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp index a01276f8..76c7f3b9 100644 --- a/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp +++ b/src/quartz/rendering/buffer/LocallyMappedBuffer.hpp @@ -28,6 +28,7 @@ class quartz::rendering::LocallyMappedBuffer { USE_LOGGER(BUFFER_MAPPED); const vk::UniqueBuffer& getVulkanLogicalBufferPtr() const { return mp_vulkanLogicalBuffer; } + const vk::UniqueDeviceMemory& getVulkanPhysicalDeviceMemoryPtr() const { return mp_vulkanPhysicalDeviceMemory; } void* getMappedLocalMemoryPtr() { return mp_mappedLocalMemory; } private: // static functions diff --git a/src/quartz/rendering/pipeline/Pipeline.cpp b/src/quartz/rendering/pipeline/Pipeline.cpp index 294a1790..cebe82f3 100644 --- a/src/quartz/rendering/pipeline/Pipeline.cpp +++ b/src/quartz/rendering/pipeline/Pipeline.cpp @@ -943,3 +943,4 @@ quartz::rendering::Pipeline::updateUniformBuffer( uniformBufferInfo.getLocallyMappedBufferSize() ); } + diff --git a/test/unit/quartz/rendering/buffer/CMakeLists.txt b/test/unit/quartz/rendering/buffer/CMakeLists.txt index 00485b8e..abd4072d 100644 --- a/test/unit/quartz/rendering/buffer/CMakeLists.txt +++ b/test/unit/quartz/rendering/buffer/CMakeLists.txt @@ -2,5 +2,5 @@ # Quartz Rendering Buffer Unit Tests #==================================================================== -create_unit_test(test_LocallyMappedBuffer.cpp QUARTZ_RENDERING_Buffer) +create_unit_test(test_LocallyMappedBuffer.cpp QUARTZ_RENDERING_Buffer QUARTZ_RENDERING_Pipeline) diff --git a/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp b/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp index 3dac2d7c..cd6f5451 100644 --- a/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp +++ b/test/unit/quartz/rendering/buffer/test_LocallyMappedBuffer.cpp @@ -1,15 +1,76 @@ +#include + +#include "util/logger/Logger.hpp" #include "util/unit_test/UnitTest.hpp" #include "quartz/rendering/buffer/LocallyMappedBuffer.hpp" +std::string +catsOfSkyrim() { + return + "I have been sent to this frigid wasteland to catalogue and study any of its indigenous cats, which has so far been uneventful. After months of wandering I have so far only encountered some variations of the same basic species." + "In my travels I have encountered several khajiit outcast from their clans that have taken up residence in Skyrim. They have been most unhelpful, probably for fear I’d expose their locations. I can’t say I’m surprised that there are few khajiit here, it’s cold and unwelcoming." + "Sabrecats are basic giant cats that have evolved two dangerously sharp front teeth." + "The average sabrecat has a reddish brown fur which it uses to blend into grassy regions, but I have observed them skulking and sleeping on rocks so I don’t believe the fur is for camouflage." + "The primary attacks of the sabrecat are its biting attack, but it can also briefly rear up to attack with its front claws. I have also seen it pounce forward on its prey in a particularly powerful attack." + "The snowy version of the sabrecat has spotted white fur which I believe it uses more for stalking more than its cousin in the plains." + "The tooth of the cat is rumored to be useful in potions that restore the imbibers stamina as well as a potion that will temporarily give a more keen eye for smithing." + "An skillful hunter can usually salvage the pelts and teeth of their kill, but report that the meat is tasteless and not fit to eat." + ; +} + + UT_FUNCTION(test_mapVulkanPhysicalDeviceMemoryToLocalMemory) { // Create physical device - quartz::rendering::Instance renderingInstance("DOODAD_UT", 9, 9, 9, true); + quartz::rendering::Instance renderingInstance("LMB_UT", 9, 9, 9, true); quartz::rendering::Device renderingDevice(renderingInstance); - // Create uniform buffer info + // Create the data which we are going to copy in + const std::string sourceData = catsOfSkyrim(); + // Create locally mapped buffer + quartz::rendering::LocallyMappedBuffer locallyMappedBuffer( + renderingDevice, + sourceData.size(), + vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst, + vk::MemoryPropertyFlagBits::eHostVisible + ); + // Ensure that the locally mapped buffer contains the correct data (UBO info data) + + // The vk::UniqueBuffer is a unique handle around a VkBuffer. + // A VkBuffer is used to "represent linear arrays of data which are used for various + // purposes by binding them to a graphics or compute pipeline via descriptor sets or + // certain commands, or by directly specifying them as parameters to certain commands." + + // We can use memcpy to get data into our buffer by utilizing the mapped local memory pointer + // but we need to figure out how to get data out of the vk::UniqueBuffer without having to + // unmap the buffer then remap it + + // Copy the data to the locally mapped buffer + LOG_TRACE(UT, "Copying {} bytes into mapped buffer at 0x{}", sourceData.size(), locallyMappedBuffer.getMappedLocalMemoryPtr()); + memcpy( + locallyMappedBuffer.getMappedLocalMemoryPtr(), + sourceData.data(), + sourceData.size() + ); + + LOG_TRACE(UT, "Comparing data at mapped memory location to source data"); + LOG_TRACE(UT, " 0x{}", locallyMappedBuffer.getMappedLocalMemoryPtr()); + uint32_t numMismatches = 0; + for (uint32_t iByte = 0; iByte < sourceData.size(); ++iByte) { + const char a = reinterpret_cast(locallyMappedBuffer.getMappedLocalMemoryPtr())[iByte]; + const char b = sourceData[iByte]; + if (a == b) { + continue; + } + + LOG_TRACE(UT, "Mismatch at index {} - {} != {}", iByte, a, b); + ++numMismatches; + } + LOG_TRACE(UT, "Total mismatches: {}", numMismatches); + + UT_CHECK_EQUAL(numMismatches, 0); } UT_MAIN() { diff --git a/test/unit/quartz/scene/scene/test_Scene.cpp b/test/unit/quartz/scene/scene/test_Scene.cpp index c06cce13..c4bc372b 100644 --- a/test/unit/quartz/scene/scene/test_Scene.cpp +++ b/test/unit/quartz/scene/scene/test_Scene.cpp @@ -56,7 +56,7 @@ UT_FUNCTION(test_construction) { } UT_FUNCTION(test_high_level) { - quartz::rendering::Instance renderingInstance("DOODAD_UT", 9, 9, 9, true); + quartz::rendering::Instance renderingInstance("SCENE_UT", 9, 9, 9, true); quartz::rendering::Device renderingDevice(renderingInstance); quartz::managers::PhysicsManager& physicsManager = quartz::unit_test::PhysicsManagerUnitTestClient::getInstance(); From d5e40a0bc8f64aa280d9cf273d3a360ad20acb49 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 6 Oct 2025 20:46:48 -0600 Subject: [PATCH 07/19] Create rendering pipeline for colliders using simple shaders --- src/quartz/rendering/context/Context.cpp | 193 ++++++++++++++++--- src/quartz/rendering/context/Context.hpp | 12 ++ src/quartz/rendering/shaders/CMakeLists.txt | 13 +- src/quartz/rendering/shaders/base.frag | 9 + src/quartz/rendering/shaders/base.vert | 10 + src/quartz/rendering/shaders/collider.frag | 16 ++ src/quartz/rendering/shaders/collider.vert | 57 ++++++ src/quartz/rendering/swapchain/Swapchain.cpp | 11 ++ src/quartz/rendering/swapchain/Swapchain.hpp | 10 +- 9 files changed, 303 insertions(+), 28 deletions(-) create mode 100644 src/quartz/rendering/shaders/base.frag create mode 100644 src/quartz/rendering/shaders/base.vert create mode 100644 src/quartz/rendering/shaders/collider.frag create mode 100644 src/quartz/rendering/shaders/collider.vert diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index b44a002c..6434383b 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -3,12 +3,17 @@ #include #include +#include #include "math/transform/Mat4.hpp" +#include "math/transform/Quaternion.hpp" +#include "math/transform/Vec3.hpp" #include "util/logger/Logger.hpp" #include "util/file_system/FileSystem.hpp" +#include "quartz/physics/collider/Collider.hpp" +#include "quartz/physics/rigid_body/RigidBody.hpp" #include "quartz/rendering/Loggers.hpp" #include "quartz/rendering/context/Context.hpp" #include "quartz/rendering/cube_map/CubeMap.hpp" @@ -35,7 +40,7 @@ quartz::rendering::Context::createSkyBoxRenderingPipeline( std::vector uniformBufferInfos = { // camera - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::Camera::UniformBufferObject), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 0, @@ -43,7 +48,7 @@ quartz::rendering::Context::createSkyBoxRenderingPipeline( sizeof(quartz::scene::Camera::UniformBufferObject), false, vk::ShaderStageFlagBits::eVertex - } + ) }; quartz::rendering::UniformSamplerCubeInfo uniformSamplerCubeInfo( @@ -85,24 +90,24 @@ quartz::rendering::Context::createDoodadRenderingPipeline( std::vector pushConstantInfos = { // perObjectVertexPushConstant (for model matrix) - { + quartz::rendering::PushConstantInfo( vk::ShaderStageFlagBits::eVertex, 0, sizeof(math::Mat4) - }, + ), // dummy - { + quartz::rendering::PushConstantInfo( vk::ShaderStageFlagBits::eFragment, sizeof(math::Mat4), sizeof(uint32_t) - } + ) }; const uint32_t minUniformBufferOffsetAlignment = renderingDevice.getVulkanPhysicalDevice().getProperties().limits.minUniformBufferOffsetAlignment; const uint32_t materialByteStride = quartz::rendering::UniformBufferInfo::calculateDynamicUniformBufferByteStride(minUniformBufferOffsetAlignment, sizeof(quartz::rendering::Material::UniformBufferObject)); std::vector uniformBufferInfos = { // the camera - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::Camera::UniformBufferObject), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 0, @@ -110,9 +115,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(quartz::scene::Camera::UniformBufferObject), false, vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment - }, + ), // the ambient light - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::AmbientLight), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 1, @@ -120,9 +125,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(quartz::scene::AmbientLight), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the directional light - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::DirectionalLight), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 2, @@ -130,9 +135,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(quartz::scene::DirectionalLight), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the number of point lights - { + quartz::rendering::UniformBufferInfo( sizeof(uint32_t), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 3, @@ -140,9 +145,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(uint32_t), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the point lights - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::PointLight) * QUARTZ_MAX_NUMBER_POINT_LIGHTS, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 4, @@ -150,9 +155,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(quartz::scene::PointLight), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the number of spot lights - { + quartz::rendering::UniformBufferInfo( sizeof(uint32_t), vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 5, @@ -160,9 +165,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(uint32_t), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the spot lights - { + quartz::rendering::UniformBufferInfo( sizeof(quartz::scene::SpotLight) * QUARTZ_MAX_NUMBER_SPOT_LIGHTS, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, 6, @@ -170,9 +175,9 @@ quartz::rendering::Context::createDoodadRenderingPipeline( sizeof(quartz::scene::SpotLight), false, vk::ShaderStageFlagBits::eFragment - }, + ), // the materials - { + quartz::rendering::UniformBufferInfo( materialByteStride * QUARTZ_MAX_NUMBER_MATERIALS, vk::MemoryPropertyFlagBits::eHostVisible, 9, @@ -180,7 +185,7 @@ quartz::rendering::Context::createDoodadRenderingPipeline( materialByteStride, true, vk::ShaderStageFlagBits::eFragment - }, + ) }; quartz::rendering::UniformSamplerInfo uniformSamplerInfo( @@ -220,6 +225,83 @@ quartz::rendering::Context::createDoodadRenderingPipeline( }; } +quartz::rendering::Pipeline +quartz::rendering::Context::createColliderRenderingPipeline( + const quartz::rendering::Device& renderingDevice, + const quartz::rendering::Window& renderingWindow, + const quartz::rendering::RenderPass& renderingRenderPass, + const uint32_t maxNumFramesInFlight +) { + LOG_FUNCTION_SCOPE_DEBUG(CONTEXT, ""); + + const vk::VertexInputBindingDescription vertexInputBindingDescription( + 0, + sizeof(math::Vec3), + vk::VertexInputRate::eVertex + ); + + const std::vector vertexInputAttributeDescription = { + vk::VertexInputAttributeDescription( + 0, + 0, + vk::Format::eR32G32B32Sfloat, + 0 + ), + vk::VertexInputAttributeDescription( + 1, + 0, + vk::Format::eR32Uint, + sizeof(math::Vec3) + ) + }; + + std::vector pushConstantInfos = { + // perObjectVertexPushConstant (for model matrix) + quartz::rendering::PushConstantInfo( + vk::ShaderStageFlagBits::eVertex, + 0, + sizeof(math::Mat4) + ) + }; + + std::vector uniformBufferInfos = { + // the camera + quartz::rendering::UniformBufferInfo( + sizeof(quartz::scene::Camera::UniformBufferObject), + vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, + 0, + 1, + sizeof(quartz::scene::Camera::UniformBufferObject), + false, + vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment + ) + }; + + LOG_DEBUG(PIPELINE, "Using {} push constants", pushConstantInfos.size()); + LOG_DEBUG(PIPELINE, "Using {} uniform buffers", uniformBufferInfos.size()); + LOG_DEBUG(PIPELINE, "Using a uniform sampler"); + LOG_DEBUG(PIPELINE, "Using a uniform texture array"); + + return { + renderingDevice, + renderingWindow, + renderingRenderPass, + util::FileSystem::getCompiledShaderAbsoluteFilepath("collider.vert"), + util::FileSystem::getCompiledShaderAbsoluteFilepath("collider.frag"), + maxNumFramesInFlight, + vertexInputBindingDescription, + vertexInputAttributeDescription, + vk::PolygonMode::eFill, + vk::CullModeFlagBits::eBack, + true, + pushConstantInfos, + uniformBufferInfos, + std::nullopt, + std::nullopt, + std::nullopt + }; +} + quartz::rendering::Context::Context( const std::string& applicationName, const uint32_t applicationMajorVersion, @@ -266,6 +348,14 @@ quartz::rendering::Context::Context( m_maxNumFramesInFlight ) ), + m_colliderRenderingPipeline( + quartz::rendering::Context::createColliderRenderingPipeline( + m_renderingDevice, + m_renderingWindow, + m_renderingRenderPass, + m_maxNumFramesInFlight + ) + ), m_renderingSwapchain( m_renderingDevice, m_renderingWindow, @@ -299,8 +389,8 @@ quartz::rendering::Context::loadScene(const quartz::scene::Scene& scene) { void quartz::rendering::Context::draw( const quartz::scene::Scene& scene, - UNUSED const bool wireframeDoodadMode, - UNUSED const bool wireframeColliderMode + const bool wireframeDoodadMode, + const bool wireframeColliderMode ) { // set up @@ -331,6 +421,9 @@ quartz::rendering::Context::draw( // update pipelines updateSkyBoxPipeline(cameraUBO); updateDoodadPipeline(scene, cameraUBO); + if (wireframeColliderMode) { + updateColliderPipeline(scene, cameraUBO); + } // reset resetSwapchain(availableSwapchainImageIndex); @@ -338,6 +431,9 @@ quartz::rendering::Context::draw( // record pipelines recordSkyBoxPipeline(scene); recordDoodadPipeline(scene); + if (wireframeColliderMode) { + recordColliderPipeline(scene); + } // submit submitImage(availableSwapchainImageIndex); @@ -388,6 +484,14 @@ quartz::rendering::Context::recreateSwapchain( m_renderingRenderPass ); + /** + * @todo 2025/10/02 If we are not in wireframeColliderMode, we do not need to recreate this pipeline. Disable it somehow?? + */ + m_colliderRenderingPipeline.recreate( + m_renderingDevice, + m_renderingRenderPass + ); + m_renderingSwapchain.recreate( m_renderingDevice, m_renderingWindow, @@ -442,6 +546,14 @@ quartz::rendering::Context::updateDoodadPipeline( m_doodadRenderingPipeline.updateUniformBuffer(m_currentInFlightFrameIndex, 7, alignedMaterialUBOBytes.data()); } +void +quartz::rendering::Context::updateColliderPipeline( + UNUSED const quartz::scene::Scene& scene, + const quartz::scene::Camera::UniformBufferObject& cameraUBO +) { + m_doodadRenderingPipeline.updateUniformBuffer(m_currentInFlightFrameIndex, 0, &cameraUBO); +} + void quartz::rendering::Context::resetSwapchain( const uint32_t availableSwapchainImageIndex @@ -496,6 +608,39 @@ quartz::rendering::Context::recordDoodadPipeline( } } +void +quartz::rendering::Context::recordColliderPipeline( + UNUSED const quartz::scene::Scene& scene +) { + m_renderingSwapchain.bindPipelineToDrawingCommandBuffer( + m_renderingWindow, + m_colliderRenderingPipeline, + m_currentInFlightFrameIndex + ); + + for (const quartz::scene::Doodad& doodad : scene.getDoodads()) { + const std::optional& o_rigidBody = doodad.getRigidBodyOptional(); + if (!o_rigidBody) { + continue; + } + + const std::optional& o_collider = o_rigidBody->getColliderOptional(); + if (!o_collider) { + continue; + } + + math::Vec3 colliderPosition = o_rigidBody->getPosition(); + math::Quaternion colliderRotation = o_rigidBody->getRotation(); + m_renderingSwapchain.recordColliderToDrawingCommandBuffer( + m_renderingDevice, + m_colliderRenderingPipeline, + *o_collider, + colliderPosition, + colliderRotation + ); + } +} + void quartz::rendering::Context::submitImage( const uint32_t availableSwapchainImageIndex diff --git a/src/quartz/rendering/context/Context.hpp b/src/quartz/rendering/context/Context.hpp index 6ce8df9e..f4000656 100644 --- a/src/quartz/rendering/context/Context.hpp +++ b/src/quartz/rendering/context/Context.hpp @@ -64,6 +64,12 @@ class quartz::rendering::Context { const quartz::rendering::RenderPass& renderingRenderPass, const uint32_t maxNumFramesInFlight ); + static quartz::rendering::Pipeline createColliderRenderingPipeline( + const quartz::rendering::Device& renderingDevice, + const quartz::rendering::Window& renderingWindow, + const quartz::rendering::RenderPass& renderingRenderPass, + const uint32_t maxNumFramesInFlight + ); private: // member functions void recreateSwapchain( @@ -76,9 +82,14 @@ class quartz::rendering::Context { const quartz::scene::Scene& scene, const quartz::scene::Camera::UniformBufferObject& cameraUBO ); + void updateColliderPipeline( + const quartz::scene::Scene& scene, + const quartz::scene::Camera::UniformBufferObject& cameraUBO + ); void resetSwapchain(const uint32_t availableSwapchainImageIndex); void recordSkyBoxPipeline(const quartz::scene::Scene& scene); void recordDoodadPipeline(const quartz::scene::Scene& scene); + void recordColliderPipeline(const quartz::scene::Scene& scene); void submitImage(const uint32_t availableSwapchainImageIndex); private: // member variables @@ -90,6 +101,7 @@ class quartz::rendering::Context { quartz::rendering::RenderPass m_renderingRenderPass; quartz::rendering::Pipeline m_skyBoxRenderingPipeline; quartz::rendering::Pipeline m_doodadRenderingPipeline; + quartz::rendering::Pipeline m_colliderRenderingPipeline; quartz::rendering::Swapchain m_renderingSwapchain; }; diff --git a/src/quartz/rendering/shaders/CMakeLists.txt b/src/quartz/rendering/shaders/CMakeLists.txt index 2e3b02e6..d53d702d 100644 --- a/src/quartz/rendering/shaders/CMakeLists.txt +++ b/src/quartz/rendering/shaders/CMakeLists.txt @@ -4,9 +4,16 @@ compile_shaders( QUARTZ_RENDERING_Shaders ${CMAKE_CURRENT_LIST_DIR} # directory containing input shaders - shader.vert - shader.frag + + base.vert + base.frag skybox.vert skybox.frag -) \ No newline at end of file + + shader.vert + shader.frag + + collider.vert + collider.frag +) diff --git a/src/quartz/rendering/shaders/base.frag b/src/quartz/rendering/shaders/base.frag new file mode 100644 index 00000000..58b0496b --- /dev/null +++ b/src/quartz/rendering/shaders/base.frag @@ -0,0 +1,9 @@ +#version 450 + +layout(location = 0) in vec3 in_fragmentPosition; + +layout(location = 0) out vec4 out_fragmentColor; + +void main() { + out_fragmentColor = vec4(1, 0, 0, 1); +} diff --git a/src/quartz/rendering/shaders/base.vert b/src/quartz/rendering/shaders/base.vert new file mode 100644 index 00000000..66f76d11 --- /dev/null +++ b/src/quartz/rendering/shaders/base.vert @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0) in vec3 in_vertexPosition; + +layout(location = 0) out vec3 out_fragmentPosition; + +void main() { + gl_Position = vec4(0, 0, 0, 0); + out_fragmentPosition = vec3(0, 0, 0); +} diff --git a/src/quartz/rendering/shaders/collider.frag b/src/quartz/rendering/shaders/collider.frag new file mode 100644 index 00000000..cb9cc934 --- /dev/null +++ b/src/quartz/rendering/shaders/collider.frag @@ -0,0 +1,16 @@ +#version 450 + +// --------------------====================================== Input from vertex shader =======================================-------------------- // + +layout(location = 0) in vec3 in_fragmentPosition; +layout(location = 1) flat in uint in_colliderInfoBits; + +// --------------------====================================== Output =======================================-------------------- // + +layout(location = 0) out vec4 out_fragmentColor; + +// --------------------====================================== Main logic =======================================-------------------- // + +void main() { + out_fragmentColor = vec4(1, 1, 1, 1); +} diff --git a/src/quartz/rendering/shaders/collider.vert b/src/quartz/rendering/shaders/collider.vert new file mode 100644 index 00000000..a11af5b8 --- /dev/null +++ b/src/quartz/rendering/shaders/collider.vert @@ -0,0 +1,57 @@ +#version 450 + +// -----==== Uniforms from the CPU =====----- // + +// ... world level things ... // + +layout(binding = 0) uniform CameraUniformBufferObject { + vec3 position; + mat4 viewMatrix; + mat4 projectionMatrix; +} camera; + +// ... mesh level things ... // + +layout(push_constant) uniform perObjectVertexPushConstant { + mat4 modelMatrix; +} pushConstant; + +// -----==== Inputs =====----- // + +/** + * @brief This stores information about the collider. We are packing many bits into + * this word so we can use this as the only input. + * + * @brief The information we need to transfer is: + * - collider type (box, sphere, capsule, custom, etc) + * - physics type (static, kinematic, dynamic) + */ + +layout(location = 0) in vec3 in_vertexPosition; +layout(location = 1) in uint in_colliderInfoBits; + +// -----==== Outputs to fragment shader =====----- // + +layout(location = 0) out vec3 out_fragmentPosition; +layout(location = 1) out uint out_colliderInfoBits; + +// -----==== Logic =====----- // + +void main() { + + // ----- Set the position of the vertex in clip space ----- // + + gl_Position = + camera.projectionMatrix * + camera.viewMatrix * + pushConstant.modelMatrix * + vec4(in_vertexPosition, 1.0); + + // ----- Calculate the position of the fragment ----- // + + out_fragmentPosition = vec3(pushConstant.modelMatrix * vec4(in_vertexPosition, 1.0)); + + // ----- set output for fragment shader to use as input ----- // + + out_colliderInfoBits = in_colliderInfoBits; +} diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index 12bef0d4..6eae882d 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -670,6 +670,17 @@ quartz::rendering::Swapchain::recordDoodadToDrawingCommandBuffer( } } +void +quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( + UNUSED const quartz::rendering::Device& renderingDevice, + UNUSED const quartz::rendering::Pipeline& colliderRenderingPipeline, + UNUSED const quartz::physics::Collider& collider, + UNUSED const math::Vec3& position, + UNUSED const math::Quaternion& rotation +) { + +} + void quartz::rendering::Swapchain::endAndSubmitDrawingCommandBuffer( const quartz::rendering::Device& renderingDevice, diff --git a/src/quartz/rendering/swapchain/Swapchain.hpp b/src/quartz/rendering/swapchain/Swapchain.hpp index e4a20a20..85e2ad7a 100644 --- a/src/quartz/rendering/swapchain/Swapchain.hpp +++ b/src/quartz/rendering/swapchain/Swapchain.hpp @@ -6,6 +6,7 @@ #include "math/transform/Vec3.hpp" +#include "quartz/physics/collider/Collider.hpp" #include "quartz/rendering/Loggers.hpp" #include "quartz/rendering/depth_buffer/DepthBuffer.hpp" #include "quartz/rendering/device/Device.hpp" @@ -79,6 +80,13 @@ class quartz::rendering::Swapchain { const quartz::scene::Doodad& doodad, const uint32_t inFlightFrameIndex ); + void recordColliderToDrawingCommandBuffer( + const quartz::rendering::Device& renderingDevice, + const quartz::rendering::Pipeline& colliderRenderingPipeline, + const quartz::physics::Collider& collider, + const math::Vec3& position, + const math::Quaternion& rotation + ); void endAndSubmitDrawingCommandBuffer( const quartz::rendering::Device& renderingDevice, const uint32_t inFlightFrameIndex @@ -137,4 +145,4 @@ class quartz::rendering::Swapchain { std::vector m_vulkanImageAvailableSemaphorePtrs; std::vector m_vulkanRenderFinishedSemaphorePtrs; std::vector m_vulkanInFlightFencePtrs; -}; \ No newline at end of file +}; From 5a13b87771eb90bed274f70712ecd1e1137b5f2e Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 6 Oct 2025 23:17:35 -0600 Subject: [PATCH 08/19] First pass at getting box colliders displayed on screen --- src/quartz/rendering/context/Context.cpp | 33 ++--- src/quartz/rendering/context/Context.hpp | 1 - src/quartz/rendering/cube_map/CubeMap.cpp | 4 +- src/quartz/rendering/shaders/collider.frag | 6 +- src/quartz/rendering/shaders/collider.vert | 12 +- src/quartz/rendering/swapchain/Swapchain.cpp | 127 ++++++++++++++++++- src/quartz/rendering/swapchain/Swapchain.hpp | 3 +- 7 files changed, 152 insertions(+), 34 deletions(-) diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 6434383b..9f01e8e5 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -236,7 +236,7 @@ quartz::rendering::Context::createColliderRenderingPipeline( const vk::VertexInputBindingDescription vertexInputBindingDescription( 0, - sizeof(math::Vec3), + sizeof(math::Vec3), // + sizeof(uint32_t), vk::VertexInputRate::eVertex ); @@ -246,13 +246,13 @@ quartz::rendering::Context::createColliderRenderingPipeline( 0, vk::Format::eR32G32B32Sfloat, 0 - ), - vk::VertexInputAttributeDescription( - 1, - 0, - vk::Format::eR32Uint, - sizeof(math::Vec3) - ) + ) //, + // vk::VertexInputAttributeDescription( + // 1, + // 0, + // vk::Format::eR32Uint, + // sizeof(math::Vec3) + // ) }; std::vector pushConstantInfos = { @@ -273,14 +273,12 @@ quartz::rendering::Context::createColliderRenderingPipeline( 1, sizeof(quartz::scene::Camera::UniformBufferObject), false, - vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment + vk::ShaderStageFlagBits::eVertex ) }; LOG_DEBUG(PIPELINE, "Using {} push constants", pushConstantInfos.size()); LOG_DEBUG(PIPELINE, "Using {} uniform buffers", uniformBufferInfos.size()); - LOG_DEBUG(PIPELINE, "Using a uniform sampler"); - LOG_DEBUG(PIPELINE, "Using a uniform texture array"); return { renderingDevice, @@ -383,6 +381,9 @@ quartz::rendering::Context::loadScene(const quartz::scene::Scene& scene) { m_doodadRenderingPipeline.updateSamplerDescriptorSets(m_renderingDevice, quartz::rendering::Texture::getDefaultVulkanSamplerPtr()); m_doodadRenderingPipeline.updateTextureArrayDescriptorSets(m_renderingDevice, quartz::rendering::Texture::getMasterTextureList()); + LOG_DEBUGthis("Updating collider rendering pipeline's descriptor sets"); + m_colliderRenderingPipeline.updateUniformBufferDescriptorSets(m_renderingDevice); + m_renderingSwapchain.setScreenClearColor(scene.getScreenClearColor()); } @@ -422,7 +423,7 @@ quartz::rendering::Context::draw( updateSkyBoxPipeline(cameraUBO); updateDoodadPipeline(scene, cameraUBO); if (wireframeColliderMode) { - updateColliderPipeline(scene, cameraUBO); + updateColliderPipeline(cameraUBO); } // reset @@ -548,10 +549,9 @@ quartz::rendering::Context::updateDoodadPipeline( void quartz::rendering::Context::updateColliderPipeline( - UNUSED const quartz::scene::Scene& scene, const quartz::scene::Camera::UniformBufferObject& cameraUBO ) { - m_doodadRenderingPipeline.updateUniformBuffer(m_currentInFlightFrameIndex, 0, &cameraUBO); + m_colliderRenderingPipeline.updateUniformBuffer(m_currentInFlightFrameIndex, 0, &cameraUBO); } void @@ -610,7 +610,7 @@ quartz::rendering::Context::recordDoodadPipeline( void quartz::rendering::Context::recordColliderPipeline( - UNUSED const quartz::scene::Scene& scene + const quartz::scene::Scene& scene ) { m_renderingSwapchain.bindPipelineToDrawingCommandBuffer( m_renderingWindow, @@ -636,7 +636,8 @@ quartz::rendering::Context::recordColliderPipeline( m_colliderRenderingPipeline, *o_collider, colliderPosition, - colliderRotation + colliderRotation, + m_currentInFlightFrameIndex ); } } diff --git a/src/quartz/rendering/context/Context.hpp b/src/quartz/rendering/context/Context.hpp index f4000656..bf61d827 100644 --- a/src/quartz/rendering/context/Context.hpp +++ b/src/quartz/rendering/context/Context.hpp @@ -83,7 +83,6 @@ class quartz::rendering::Context { const quartz::scene::Camera::UniformBufferObject& cameraUBO ); void updateColliderPipeline( - const quartz::scene::Scene& scene, const quartz::scene::Camera::UniformBufferObject& cameraUBO ); void resetSwapchain(const uint32_t availableSwapchainImageIndex); diff --git a/src/quartz/rendering/cube_map/CubeMap.cpp b/src/quartz/rendering/cube_map/CubeMap.cpp index 79d211e7..49d00aec 100644 --- a/src/quartz/rendering/cube_map/CubeMap.cpp +++ b/src/quartz/rendering/cube_map/CubeMap.cpp @@ -159,7 +159,7 @@ quartz::rendering::CubeMap::createStagedVertexBuffer( {1.0f , 1.0f , 1.0f}, {1.0f , 1.0f , 0.0f}, {0.0f , 0.0f , 1.0f}, - {0.0f , 0.0f , 0.0f}, + {0.0f , 0.0f , .0f}, {0.0f , 1.0f , 0.0f}, {0.0f , 1.0f , 1.0f}, {0.0f , 1.0f , 0.0f}, @@ -171,6 +171,8 @@ quartz::rendering::CubeMap::createStagedVertexBuffer( {1.0f , 0.0f , 0.0f}, {0.0f , 0.0f , 0.0f}, }; + + // Convert the vertices from [0,1] to [-1,1] for (uint32_t i = 0; i < vertices.size(); ++i) { vertices[i] = (2.0f * vertices[i]) - math::Vec3(1.0f, 1.0f, 1.0f); } diff --git a/src/quartz/rendering/shaders/collider.frag b/src/quartz/rendering/shaders/collider.frag index cb9cc934..50d005d4 100644 --- a/src/quartz/rendering/shaders/collider.frag +++ b/src/quartz/rendering/shaders/collider.frag @@ -2,8 +2,7 @@ // --------------------====================================== Input from vertex shader =======================================-------------------- // -layout(location = 0) in vec3 in_fragmentPosition; -layout(location = 1) flat in uint in_colliderInfoBits; +// layout(location = 0) flat in uint in_colliderInfoBits; // --------------------====================================== Output =======================================-------------------- // @@ -12,5 +11,6 @@ layout(location = 0) out vec4 out_fragmentColor; // --------------------====================================== Main logic =======================================-------------------- // void main() { - out_fragmentColor = vec4(1, 1, 1, 1); + out_fragmentColor = vec4(1.0, 0.0, 0.0, 1.0); } + diff --git a/src/quartz/rendering/shaders/collider.vert b/src/quartz/rendering/shaders/collider.vert index a11af5b8..057dee8d 100644 --- a/src/quartz/rendering/shaders/collider.vert +++ b/src/quartz/rendering/shaders/collider.vert @@ -28,12 +28,11 @@ layout(push_constant) uniform perObjectVertexPushConstant { */ layout(location = 0) in vec3 in_vertexPosition; -layout(location = 1) in uint in_colliderInfoBits; +// layout(location = 1) in uint in_colliderInfoBits; // -----==== Outputs to fragment shader =====----- // -layout(location = 0) out vec3 out_fragmentPosition; -layout(location = 1) out uint out_colliderInfoBits; +// layout(location = 1) out uint out_colliderInfoBits; // -----==== Logic =====----- // @@ -47,11 +46,8 @@ void main() { pushConstant.modelMatrix * vec4(in_vertexPosition, 1.0); - // ----- Calculate the position of the fragment ----- // - - out_fragmentPosition = vec3(pushConstant.modelMatrix * vec4(in_vertexPosition, 1.0)); - // ----- set output for fragment shader to use as input ----- // - out_colliderInfoBits = in_colliderInfoBits; + // out_colliderInfoBits = in_colliderInfoBits; } + diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index 6eae882d..bfb5f9c1 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -3,8 +3,10 @@ #include #include +#include #include +#include "quartz/rendering/pipeline/PushConstantInfo.hpp" #include "util/errors/RichException.hpp" #include "math/transform/Mat4.hpp" @@ -672,13 +674,130 @@ quartz::rendering::Swapchain::recordDoodadToDrawingCommandBuffer( void quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( - UNUSED const quartz::rendering::Device& renderingDevice, - UNUSED const quartz::rendering::Pipeline& colliderRenderingPipeline, + const quartz::rendering::Device& renderingDevice, + const quartz::rendering::Pipeline& colliderRenderingPipeline, UNUSED const quartz::physics::Collider& collider, - UNUSED const math::Vec3& position, - UNUSED const math::Quaternion& rotation + const math::Vec3& position, + const math::Quaternion& rotation, + const uint32_t inFlightFrameIndex ) { + uint32_t offset = 0; + + /** + * @todo 2025/10/06 Calculate the transformation matrix from the position, rotation, and scale of the collider. + * We will be getting the scale from the collider itself (extents for collider, radius for sphere) + */ + const math::Transform transform( + position, + rotation, + {2, 2, 2} + ); + math::Mat4 transformationMatrix = transform.calculateTransformationMatrix(); + // Model matrix push constant info + const quartz::rendering::PushConstantInfo& transformationmatrixPushConstantInfo = colliderRenderingPipeline.getPushConstantInfos()[0]; + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->pushConstants( + *colliderRenderingPipeline.getVulkanPipelineLayoutPtr(), + transformationmatrixPushConstantInfo.getVulkanShaderStageFlags(), + transformationmatrixPushConstantInfo.getOffset(), + transformationmatrixPushConstantInfo.getSize(), + reinterpret_cast(&transformationMatrix) + ); + + // Bind the descriptor set + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindDescriptorSets( + vk::PipelineBindPoint::eGraphics, + *colliderRenderingPipeline.getVulkanPipelineLayoutPtr(), + 0, + 1, + &(colliderRenderingPipeline.getVulkanDescriptorSets()[inFlightFrameIndex]), + 0, + &offset + ); + + // Vertex buffer + static std::vector vertices = { + {0.0f , 0.0f , 0.0f}, + {1.0f , 0.0f , 0.0f}, + {1.0f , 1.0f , 0.0f}, + {0.0f , 1.0f , 0.0f}, + {1.0f , 0.0f , 1.0f}, + {0.0f , 0.0f , 1.0f}, + {0.0f , 1.0f , 1.0f}, + {1.0f , 1.0f , 1.0f}, + {1.0f , 0.0f , 0.0f}, + {1.0f , 0.0f , 1.0f}, + {1.0f , 1.0f , 1.0f}, + {1.0f , 1.0f , 0.0f}, + {0.0f , 0.0f , 1.0f}, + {0.0f , 0.0f , .0f}, + {0.0f , 1.0f , 0.0f}, + {0.0f , 1.0f , 1.0f}, + {0.0f , 1.0f , 0.0f}, + {1.0f , 1.0f , 0.0f}, + {1.0f , 1.0f , 1.0f}, + {0.0f , 1.0f , 1.0f}, + {0.0f , 0.0f , 1.0f}, + {1.0f , 0.0f , 1.0f}, + {1.0f , 0.0f , 0.0f}, + {0.0f , 0.0f , 0.0f}, + }; + for (uint32_t i = 0; i < vertices.size(); ++i) { + vertices[i] = (2.0f * vertices[i]) - math::Vec3(1.0f, 1.0f, 1.0f); + } + static quartz::rendering::StagedBuffer stagedVertexBuffer( + renderingDevice, + sizeof(math::Vec3) * vertices.size(), + vk::BufferUsageFlagBits::eVertexBuffer, + vertices.data() + ); + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindVertexBuffers( + 0, + *(stagedVertexBuffer.getVulkanLogicalBufferPtr()), + offset + ); + + // Index buffer + static const std::vector indices = { + // tri 0 + 0, 2, 1, + 0, 3, 2, + // tri 1 + 4, 6, 5, + 4, 7, 6, + // tri 2 + 8, 10, 9, + 8, 11, 10, + // tri 3 + 12, 14, 13, + 12, 15, 14, + // tri 4 + 16, 18, 17, + 16, 19, 18, + // tri 5 + 20, 22, 21, + 20, 23, 22, + }; + static quartz::rendering::StagedBuffer indexBuffer( + renderingDevice, + sizeof(uint32_t) * indices.size(), + vk::BufferUsageFlagBits::eIndexBuffer, + indices.data() + ); + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindIndexBuffer( + *(indexBuffer.getVulkanLogicalBufferPtr()), + 0, + vk::IndexType::eUint32 + ); + + // Draw using vertex and index buffer + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->drawIndexed( + 36, /** @todo 2025/10/06 Needs to change based on the type of collider (type of model) */ + 1, + 0, + 0, + 0 + ); } void diff --git a/src/quartz/rendering/swapchain/Swapchain.hpp b/src/quartz/rendering/swapchain/Swapchain.hpp index 85e2ad7a..c5152e19 100644 --- a/src/quartz/rendering/swapchain/Swapchain.hpp +++ b/src/quartz/rendering/swapchain/Swapchain.hpp @@ -85,7 +85,8 @@ class quartz::rendering::Swapchain { const quartz::rendering::Pipeline& colliderRenderingPipeline, const quartz::physics::Collider& collider, const math::Vec3& position, - const math::Quaternion& rotation + const math::Quaternion& rotation, + const uint32_t inFlightFrameIndex ); void endAndSubmitDrawingCommandBuffer( const quartz::rendering::Device& renderingDevice, From 71b101fe2b37edb7941c6639cbc7f6e585a5eae8 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Sun, 19 Oct 2025 08:55:01 -0600 Subject: [PATCH 09/19] Create primitive constructor accepting vertices and indices --- src/quartz/rendering/context/Context.cpp | 2 +- src/quartz/rendering/model/Primitive.cpp | 22 ++++++++++++++ src/quartz/rendering/model/Primitive.hpp | 10 ++++++- src/quartz/rendering/swapchain/Swapchain.cpp | 30 ++++++++------------ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 9f01e8e5..31ad733e 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -466,7 +466,7 @@ quartz::rendering::Context::recreateSwapchain( m_renderingInstance, m_renderingDevice ); - + m_renderingRenderPass.recreate( m_renderingDevice, m_renderingWindow diff --git a/src/quartz/rendering/model/Primitive.cpp b/src/quartz/rendering/model/Primitive.cpp index 3ef0df6b..1deeb22c 100644 --- a/src/quartz/rendering/model/Primitive.cpp +++ b/src/quartz/rendering/model/Primitive.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -363,6 +364,27 @@ quartz::rendering::Primitive::createStagedVertexBuffer( return stagedVertexBuffer; } +quartz::rendering::Primitive::Primitive( + const quartz::rendering::Device& renderingDevice, + const std::vector& vertices, + const std::vector& indices +) : + m_materialMasterIndex(0), + m_indices(indices), + m_stagedVertexBuffer( + renderingDevice, + sizeof(math::Vec3) * vertices.size(), + vk::BufferUsageFlagBits::eVertexBuffer, + vertices.data() + ), + m_stagedIndexBuffer( + renderingDevice, + sizeof(uint32_t) * indices.size(), + vk::BufferUsageFlagBits::eIndexBuffer, + indices.data() + ) +{} + quartz::rendering::Primitive::Primitive( const quartz::rendering::Device& renderingDevice, const tinygltf::Model& gltfModel, diff --git a/src/quartz/rendering/model/Primitive.hpp b/src/quartz/rendering/model/Primitive.hpp index d06f4a6b..5318f8a4 100644 --- a/src/quartz/rendering/model/Primitive.hpp +++ b/src/quartz/rendering/model/Primitive.hpp @@ -2,6 +2,8 @@ #include +#include "math/transform/Vec3.hpp" + #include "quartz/rendering/Loggers.hpp" #include "quartz/rendering/buffer/StagedBuffer.hpp" #include "quartz/rendering/device/Device.hpp" @@ -16,6 +18,11 @@ namespace rendering { class quartz::rendering::Primitive { public: // member functions + Primitive( + const quartz::rendering::Device& renderingDevice, + const std::vector& vertices, + const std::vector& indices + ); Primitive( const quartz::rendering::Device& renderingDevice, const tinygltf::Model& gltfModel, @@ -82,4 +89,5 @@ class quartz::rendering::Primitive { std::vector m_indices; quartz::rendering::StagedBuffer m_stagedVertexBuffer; quartz::rendering::StagedBuffer m_stagedIndexBuffer; -}; \ No newline at end of file +}; + diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index bfb5f9c1..3e13b4ca 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -6,6 +6,7 @@ #include #include +#include "quartz/rendering/model/Primitive.hpp" #include "quartz/rendering/pipeline/PushConstantInfo.hpp" #include "util/errors/RichException.hpp" @@ -730,7 +731,7 @@ quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( {1.0f , 1.0f , 1.0f}, {1.0f , 1.0f , 0.0f}, {0.0f , 0.0f , 1.0f}, - {0.0f , 0.0f , .0f}, + {0.0f , 0.0f , 0.0f}, {0.0f , 1.0f , 0.0f}, {0.0f , 1.0f , 1.0f}, {0.0f , 1.0f , 0.0f}, @@ -745,18 +746,6 @@ quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( for (uint32_t i = 0; i < vertices.size(); ++i) { vertices[i] = (2.0f * vertices[i]) - math::Vec3(1.0f, 1.0f, 1.0f); } - static quartz::rendering::StagedBuffer stagedVertexBuffer( - renderingDevice, - sizeof(math::Vec3) * vertices.size(), - vk::BufferUsageFlagBits::eVertexBuffer, - vertices.data() - ); - m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindVertexBuffers( - 0, - *(stagedVertexBuffer.getVulkanLogicalBufferPtr()), - offset - ); - // Index buffer static const std::vector indices = { // tri 0 @@ -778,14 +767,19 @@ quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( 20, 22, 21, 20, 23, 22, }; - static quartz::rendering::StagedBuffer indexBuffer( + static quartz::rendering::Primitive colliderPrimitive( renderingDevice, - sizeof(uint32_t) * indices.size(), - vk::BufferUsageFlagBits::eIndexBuffer, - indices.data() + vertices, + indices + ); + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindVertexBuffers( + 0, + *(colliderPrimitive.getStagedVertexBuffer().getVulkanLogicalBufferPtr()), + offset ); + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindIndexBuffer( - *(indexBuffer.getVulkanLogicalBufferPtr()), + *(colliderPrimitive.getStagedIndexBuffer().getVulkanLogicalBufferPtr()), 0, vk::IndexType::eUint32 ); From 2b9fb65f6e26a6d1b6c2a319b5848631e555dad8 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Sun, 19 Oct 2025 09:10:02 -0600 Subject: [PATCH 10/19] Put box collider primitive in the swapchain class as a member variable --- src/quartz/rendering/swapchain/Swapchain.cpp | 113 +++++++++---------- src/quartz/rendering/swapchain/Swapchain.hpp | 7 ++ 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index 3e13b4ca..c09d224f 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -278,6 +278,55 @@ quartz::rendering::Swapchain::Swapchain( renderingDevice.getVulkanLogicalDevicePtr(), maxNumFramesInFlight ) + ), + m_boxColliderPrimitive( + renderingDevice, + { + {-1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + {-1.0f , -1.0f , -1.0f}, + }, + { + // tri 0 + 0, 2, 1, + 0, 3, 2, + // tri 1 + 4, 6, 5, + 4, 7, 6, + // tri 2 + 8, 10, 9, + 8, 11, 10, + // tri 3 + 12, 14, 13, + 12, 15, 14, + // tri 4 + 16, 18, 17, + 16, 19, 18, + // tri 5 + 20, 22, 21, + 20, 23, 22, + } ) { LOG_FUNCTION_CALL_TRACEthis(""); @@ -675,7 +724,7 @@ quartz::rendering::Swapchain::recordDoodadToDrawingCommandBuffer( void quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( - const quartz::rendering::Device& renderingDevice, + UNUSED const quartz::rendering::Device& renderingDevice, /** @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter?? */ const quartz::rendering::Pipeline& colliderRenderingPipeline, UNUSED const quartz::physics::Collider& collider, const math::Vec3& position, @@ -716,77 +765,21 @@ quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( &offset ); - // Vertex buffer - static std::vector vertices = { - {0.0f , 0.0f , 0.0f}, - {1.0f , 0.0f , 0.0f}, - {1.0f , 1.0f , 0.0f}, - {0.0f , 1.0f , 0.0f}, - {1.0f , 0.0f , 1.0f}, - {0.0f , 0.0f , 1.0f}, - {0.0f , 1.0f , 1.0f}, - {1.0f , 1.0f , 1.0f}, - {1.0f , 0.0f , 0.0f}, - {1.0f , 0.0f , 1.0f}, - {1.0f , 1.0f , 1.0f}, - {1.0f , 1.0f , 0.0f}, - {0.0f , 0.0f , 1.0f}, - {0.0f , 0.0f , 0.0f}, - {0.0f , 1.0f , 0.0f}, - {0.0f , 1.0f , 1.0f}, - {0.0f , 1.0f , 0.0f}, - {1.0f , 1.0f , 0.0f}, - {1.0f , 1.0f , 1.0f}, - {0.0f , 1.0f , 1.0f}, - {0.0f , 0.0f , 1.0f}, - {1.0f , 0.0f , 1.0f}, - {1.0f , 0.0f , 0.0f}, - {0.0f , 0.0f , 0.0f}, - }; - for (uint32_t i = 0; i < vertices.size(); ++i) { - vertices[i] = (2.0f * vertices[i]) - math::Vec3(1.0f, 1.0f, 1.0f); - } - // Index buffer - static const std::vector indices = { - // tri 0 - 0, 2, 1, - 0, 3, 2, - // tri 1 - 4, 6, 5, - 4, 7, 6, - // tri 2 - 8, 10, 9, - 8, 11, 10, - // tri 3 - 12, 14, 13, - 12, 15, 14, - // tri 4 - 16, 18, 17, - 16, 19, 18, - // tri 5 - 20, 22, 21, - 20, 23, 22, - }; - static quartz::rendering::Primitive colliderPrimitive( - renderingDevice, - vertices, - indices - ); m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindVertexBuffers( 0, - *(colliderPrimitive.getStagedVertexBuffer().getVulkanLogicalBufferPtr()), + *(m_boxColliderPrimitive.getStagedVertexBuffer().getVulkanLogicalBufferPtr()), offset ); m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindIndexBuffer( - *(colliderPrimitive.getStagedIndexBuffer().getVulkanLogicalBufferPtr()), + *(m_boxColliderPrimitive.getStagedIndexBuffer().getVulkanLogicalBufferPtr()), 0, vk::IndexType::eUint32 ); // Draw using vertex and index buffer m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->drawIndexed( - 36, /** @todo 2025/10/06 Needs to change based on the type of collider (type of model) */ + m_boxColliderPrimitive.getIndexCount(), 1, 0, 0, diff --git a/src/quartz/rendering/swapchain/Swapchain.hpp b/src/quartz/rendering/swapchain/Swapchain.hpp index c5152e19..9300ee22 100644 --- a/src/quartz/rendering/swapchain/Swapchain.hpp +++ b/src/quartz/rendering/swapchain/Swapchain.hpp @@ -146,4 +146,11 @@ class quartz::rendering::Swapchain { std::vector m_vulkanImageAvailableSemaphorePtrs; std::vector m_vulkanRenderFinishedSemaphorePtrs; std::vector m_vulkanInFlightFencePtrs; + + /** + * @brief 2025/10/19 I don't really think that these belong here, but I can't + * think of a better place to put them + */ + quartz::rendering::Primitive m_boxColliderPrimitive; }; + From 3c971799649995d956cb2d41585d74b5a53a100f Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 20 Oct 2025 16:03:10 -0600 Subject: [PATCH 11/19] Colliders use unique colors based on collider id, passed via push constant to fragment shader --- src/quartz/physics/collider/Collider.cpp | 7 +++- src/quartz/physics/collider/Collider.hpp | 4 ++ src/quartz/rendering/context/Context.cpp | 16 ++++---- src/quartz/rendering/model/Vertex.cpp | 2 +- src/quartz/rendering/shaders/collider.frag | 19 +++++++-- src/quartz/rendering/shaders/collider.vert | 29 ++++---------- src/quartz/rendering/swapchain/Swapchain.cpp | 41 +++++++++++++------- src/quartz/scene/doodad/Doodad.cpp | 9 ++++- src/quartz/scene/doodad/Doodad.hpp | 6 +++ 9 files changed, 81 insertions(+), 52 deletions(-) diff --git a/src/quartz/physics/collider/Collider.cpp b/src/quartz/physics/collider/Collider.cpp index 13ae5d6b..758a2db3 100644 --- a/src/quartz/physics/collider/Collider.cpp +++ b/src/quartz/physics/collider/Collider.cpp @@ -13,6 +13,7 @@ #include "quartz/physics/collider/SphereShape.hpp" #include "quartz/physics/collider/Collider.hpp" +uint32_t quartz::physics::Collider::colliderCount = 0; std::map quartz::physics::Collider::colliderMap; quartz::physics::Collider::CollisionType @@ -71,6 +72,7 @@ quartz::physics::Collider::Collider( const quartz::physics::Collider::CollisionCallback& collisionStayCallback, const quartz::physics::Collider::CollisionCallback& collisionEndCallback ) : + m_id(quartz::physics::Collider::colliderCount++), mo_boxShape( (std::holds_alternative(v_shape)) ? std::optional{std::get(std::move(v_shape))} : @@ -87,13 +89,14 @@ quartz::physics::Collider::Collider( m_collisionEndCallback(collisionEndCallback ? collisionEndCallback : quartz::physics::Collider::noopCollisionCallback) { LOG_FUNCTION_SCOPE_TRACEthis(""); - LOG_TRACEthis("Constructing Collider. Setting collider map rp3d pointer at {} to point to quartz pointer at {}", reinterpret_cast(mp_collider), reinterpret_cast(this)); + LOG_TRACEthis("Constructing Collider {}. Setting collider map rp3d pointer at {} to point to quartz pointer at {}", m_id, reinterpret_cast(mp_collider), reinterpret_cast(this)); quartz::physics::Collider::colliderMap[mp_collider] = this; } quartz::physics::Collider::Collider( quartz::physics::Collider&& other ) : + m_id(other.m_id), mo_boxShape(std::move(other.mo_boxShape)), mo_sphereShape(std::move(other.mo_sphereShape)), mp_collider(std::move(other.mp_collider)), @@ -102,7 +105,7 @@ quartz::physics::Collider::Collider( m_collisionEndCallback(std::move(other.m_collisionEndCallback)) { LOG_FUNCTION_SCOPE_TRACEthis(""); - LOG_TRACEthis("Move-constructing Collider. Setting collider map rp3d pointer at {} to point to quartz pointer at {}", reinterpret_cast(mp_collider), reinterpret_cast(this)); + LOG_TRACEthis("Move-constructing Collider {}. Setting collider map rp3d pointer at {} to point to quartz pointer at {}", m_id, reinterpret_cast(mp_collider), reinterpret_cast(this)); quartz::physics::Collider::colliderMap[mp_collider] = this; } diff --git a/src/quartz/physics/collider/Collider.hpp b/src/quartz/physics/collider/Collider.hpp index f7998827..2747f465 100644 --- a/src/quartz/physics/collider/Collider.hpp +++ b/src/quartz/physics/collider/Collider.hpp @@ -110,6 +110,7 @@ class quartz::physics::Collider { quartz::physics::Collider::CategoryProperties getCategoryProperties() const; + uint32_t getId() const { return m_id; } bool getIsTrigger() const; math::Vec3 getLocalPosition() const; math::Quaternion getLocalRotation() const; @@ -145,9 +146,12 @@ class quartz::physics::Collider { static void eraseCollider(reactphysics3d::Collider* const p_collider) { quartz::physics::Collider::colliderMap.erase(p_collider); } private: // static variables + static uint32_t colliderCount; static std::map colliderMap; private: // member variables + const uint32_t m_id; + std::optional mo_boxShape; std::optional mo_sphereShape; diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 31ad733e..3ed77ea5 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -236,7 +236,7 @@ quartz::rendering::Context::createColliderRenderingPipeline( const vk::VertexInputBindingDescription vertexInputBindingDescription( 0, - sizeof(math::Vec3), // + sizeof(uint32_t), + sizeof(math::Vec3), vk::VertexInputRate::eVertex ); @@ -246,13 +246,7 @@ quartz::rendering::Context::createColliderRenderingPipeline( 0, vk::Format::eR32G32B32Sfloat, 0 - ) //, - // vk::VertexInputAttributeDescription( - // 1, - // 0, - // vk::Format::eR32Uint, - // sizeof(math::Vec3) - // ) + ) }; std::vector pushConstantInfos = { @@ -261,6 +255,12 @@ quartz::rendering::Context::createColliderRenderingPipeline( vk::ShaderStageFlagBits::eVertex, 0, sizeof(math::Mat4) + ), + // perColliderVertexPushConstant (for collider id) + quartz::rendering::PushConstantInfo( + vk::ShaderStageFlagBits::eFragment, + sizeof(math::Mat4), + sizeof(uint32_t) ) }; diff --git a/src/quartz/rendering/model/Vertex.cpp b/src/quartz/rendering/model/Vertex.cpp index e2a42e85..e7149be5 100644 --- a/src/quartz/rendering/model/Vertex.cpp +++ b/src/quartz/rendering/model/Vertex.cpp @@ -186,4 +186,4 @@ quartz::rendering::Vertex::operator==( occlusionTextureCoordinate.x == other.occlusionTextureCoordinate.x && occlusionTextureCoordinate.y == other.occlusionTextureCoordinate.y ); -} \ No newline at end of file +} diff --git a/src/quartz/rendering/shaders/collider.frag b/src/quartz/rendering/shaders/collider.frag index 50d005d4..aadb6700 100644 --- a/src/quartz/rendering/shaders/collider.frag +++ b/src/quartz/rendering/shaders/collider.frag @@ -1,8 +1,14 @@ #version 450 -// --------------------====================================== Input from vertex shader =======================================-------------------- // +// ........ math constants ........ // -// layout(location = 0) flat in uint in_colliderInfoBits; +#define M_PI 3.1415926535897932384626433832795 + +// ........ object level things ........ // + +layout(push_constant) uniform perColliderFragmentPushConstant { + layout(offset = 64) uint colliderId; // offset of 64 because vertex shader uses mat4 push constant for model matrix +} pushConstant; // --------------------====================================== Output =======================================-------------------- // @@ -11,6 +17,11 @@ layout(location = 0) out vec4 out_fragmentColor; // --------------------====================================== Main logic =======================================-------------------- // void main() { - out_fragmentColor = vec4(1.0, 0.0, 0.0, 1.0); -} + // @todo 2025/10/20 We should initialize an array of colors as a uniform buffer and index into it + // using the id modulo the array size, instead of calculating colors every frame + float redValue = sin((pushConstant.colliderId * 1) + (M_PI / 3)); + float greenValue = sin((pushConstant.colliderId * 2) + (M_PI / 5)); + float blueValue = sin((pushConstant.colliderId * 4) + (M_PI / 7)); + out_fragmentColor = vec4(redValue, greenValue, blueValue, 0.750); +} diff --git a/src/quartz/rendering/shaders/collider.vert b/src/quartz/rendering/shaders/collider.vert index 057dee8d..7dd67e11 100644 --- a/src/quartz/rendering/shaders/collider.vert +++ b/src/quartz/rendering/shaders/collider.vert @@ -12,27 +12,21 @@ layout(binding = 0) uniform CameraUniformBufferObject { // ... mesh level things ... // -layout(push_constant) uniform perObjectVertexPushConstant { - mat4 modelMatrix; -} pushConstant; - -// -----==== Inputs =====----- // - /** * @brief This stores information about the collider. We are packing many bits into * this word so we can use this as the only input. - * + * * @brief The information we need to transfer is: * - collider type (box, sphere, capsule, custom, etc) * - physics type (static, kinematic, dynamic) */ +layout(push_constant) uniform perObjectVertexPushConstant { + mat4 modelMatrix; +} pushConstant; -layout(location = 0) in vec3 in_vertexPosition; -// layout(location = 1) in uint in_colliderInfoBits; - -// -----==== Outputs to fragment shader =====----- // +// -----==== Inputs =====----- // -// layout(location = 1) out uint out_colliderInfoBits; +layout(location = 0) in vec3 in_vertexPosition; // -----==== Logic =====----- // @@ -40,14 +34,5 @@ void main() { // ----- Set the position of the vertex in clip space ----- // - gl_Position = - camera.projectionMatrix * - camera.viewMatrix * - pushConstant.modelMatrix * - vec4(in_vertexPosition, 1.0); - - // ----- set output for fragment shader to use as input ----- // - - // out_colliderInfoBits = in_colliderInfoBits; + gl_Position = camera.projectionMatrix * camera.viewMatrix * pushConstant.modelMatrix * vec4(in_vertexPosition, 1.0); } - diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index c09d224f..0a21d86b 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -281,6 +281,10 @@ quartz::rendering::Swapchain::Swapchain( ), m_boxColliderPrimitive( renderingDevice, + /** + * @todo 2025/10/20 Move these anywhere else. Maybe these should be retrieved from a static variable or static + * function within the primitive class + */ { {-1.0f , -1.0f , -1.0f}, { 1.0f , -1.0f , -1.0f}, @@ -724,34 +728,45 @@ quartz::rendering::Swapchain::recordDoodadToDrawingCommandBuffer( void quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( - UNUSED const quartz::rendering::Device& renderingDevice, /** @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter @todo 2025/10/19 remove this parameter?? */ + UNUSED const quartz::rendering::Device& renderingDevice, /** @todo 2025/10/19 remove this parameter ?? */ const quartz::rendering::Pipeline& colliderRenderingPipeline, - UNUSED const quartz::physics::Collider& collider, + const quartz::physics::Collider& collider, const math::Vec3& position, const math::Quaternion& rotation, const uint32_t inFlightFrameIndex ) { + if (collider.getSphereShapeOptional()) { + return; + } + uint32_t offset = 0; - /** - * @todo 2025/10/06 Calculate the transformation matrix from the position, rotation, and scale of the collider. - * We will be getting the scale from the collider itself (extents for collider, radius for sphere) - */ const math::Transform transform( position, rotation, - {2, 2, 2} + collider.getBoxShapeOptional()->getHalfExtents_m() ); - math::Mat4 transformationMatrix = transform.calculateTransformationMatrix(); + const math::Mat4 transformationMatrix = transform.calculateTransformationMatrix(); // Model matrix push constant info - const quartz::rendering::PushConstantInfo& transformationmatrixPushConstantInfo = colliderRenderingPipeline.getPushConstantInfos()[0]; + const quartz::rendering::PushConstantInfo& transformationMatrixPushConstantInfo = colliderRenderingPipeline.getPushConstantInfos()[0]; + m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->pushConstants( + *colliderRenderingPipeline.getVulkanPipelineLayoutPtr(), + transformationMatrixPushConstantInfo.getVulkanShaderStageFlags(), + transformationMatrixPushConstantInfo.getOffset(), + transformationMatrixPushConstantInfo.getSize(), + reinterpret_cast(&transformationMatrix) + ); + + // Collider id push constant info + const uint32_t colliderId = collider.getId(); + const quartz::rendering::PushConstantInfo& colliderIdPushConstantInfo = colliderRenderingPipeline.getPushConstantInfos()[1]; m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->pushConstants( *colliderRenderingPipeline.getVulkanPipelineLayoutPtr(), - transformationmatrixPushConstantInfo.getVulkanShaderStageFlags(), - transformationmatrixPushConstantInfo.getOffset(), - transformationmatrixPushConstantInfo.getSize(), - reinterpret_cast(&transformationMatrix) + colliderIdPushConstantInfo.getVulkanShaderStageFlags(), + colliderIdPushConstantInfo.getOffset(), + colliderIdPushConstantInfo.getSize(), + reinterpret_cast(&colliderId) ); // Bind the descriptor set diff --git a/src/quartz/scene/doodad/Doodad.cpp b/src/quartz/scene/doodad/Doodad.cpp index cd1e7a62..833ed3d2 100644 --- a/src/quartz/scene/doodad/Doodad.cpp +++ b/src/quartz/scene/doodad/Doodad.cpp @@ -12,6 +12,8 @@ #include "quartz/physics/field/Field.hpp" #include "quartz/scene/doodad/Doodad.hpp" +uint32_t quartz::scene::Doodad::doodadCount = 0; + void quartz::scene::Doodad::noopAwakenCallback( UNUSED quartz::scene::Doodad::AwakenCallbackParameters parameters @@ -84,6 +86,7 @@ quartz::scene::Doodad::Doodad( const quartz::scene::Doodad::FixedUpdateCallback& fixedUpdateCallback, const quartz::scene::Doodad::UpdateCallback& updateCallback ) : + m_id(quartz::scene::Doodad::doodadCount++), mo_model( o_objectFilepath ? std::optional(quartz::rendering::Model(renderingDevice, *o_objectFilepath)) : @@ -101,7 +104,7 @@ quartz::scene::Doodad::Doodad( m_updateCallback(updateCallback ? updateCallback : quartz::scene::Doodad::noopUpdateCallback) { LOG_FUNCTION_CALL_TRACEthis(""); - LOG_TRACEthis("Constructing doodad with transform:"); + LOG_TRACEthis("Constructing doodad {} with transform:", m_id); LOG_TRACE(DOODAD, " position = {}", m_transform.position.toString()); LOG_TRACE(DOODAD, " rotation = {}", m_transform.rotation.toString()); LOG_TRACE(DOODAD, " scale = {}", m_transform.scale.toString()); @@ -113,6 +116,7 @@ quartz::scene::Doodad::Doodad( std::optional& o_field, const quartz::scene::Doodad::Parameters& doodadParameters ) : + m_id(quartz::scene::Doodad::doodadCount++), mo_model( doodadParameters.o_objectFilepath ? std::optional(quartz::rendering::Model(renderingDevice, *doodadParameters.o_objectFilepath)) : @@ -130,7 +134,7 @@ quartz::scene::Doodad::Doodad( m_updateCallback(doodadParameters.updateCallback ? doodadParameters.updateCallback : quartz::scene::Doodad::noopUpdateCallback) { LOG_FUNCTION_CALL_TRACEthis(""); - LOG_TRACEthis("Constructing doodad with transform:"); + LOG_TRACEthis("Constructing doodad {} with transform:", m_id); LOG_TRACE(DOODAD, " position = {}", m_transform.position.toString()); LOG_TRACE(DOODAD, " rotation = {}", m_transform.rotation.toString()); LOG_TRACE(DOODAD, " scale = {}", m_transform.scale.toString()); @@ -139,6 +143,7 @@ quartz::scene::Doodad::Doodad( quartz::scene::Doodad::Doodad( quartz::scene::Doodad&& other ) : + m_id(other.m_id), mo_model(std::move(other.mo_model)), m_transform(other.m_transform), m_transformationMatrix(other.m_transformationMatrix), diff --git a/src/quartz/scene/doodad/Doodad.hpp b/src/quartz/scene/doodad/Doodad.hpp index 4842202c..ff63f800 100644 --- a/src/quartz/scene/doodad/Doodad.hpp +++ b/src/quartz/scene/doodad/Doodad.hpp @@ -131,6 +131,7 @@ class quartz::scene::Doodad { USE_LOGGER(DOODAD); + uint32_t getId() const { return m_id; } const std::optional& getModelOptional() const { return mo_model; } const math::Transform& getTransform() const { return m_transform; } const math::Mat4& getTransformationMatrix() const { return m_transformationMatrix; } @@ -176,7 +177,12 @@ class quartz::scene::Doodad { static void noopFixedUpdateCallback(FixedUpdateCallbackParameters parameters); static void noopUpdateCallback(UpdateCallbackParameters parameters); +private: // static variables + static uint32_t doodadCount; + private: // member variables + const uint32_t m_id; + std::optional mo_model; math::Transform m_transform; From ee784b353c8e2ecc02d3fadc6bbbec11b75b1c6f Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 20 Oct 2025 17:35:52 -0600 Subject: [PATCH 12/19] Update oscillation rate for collider color choice, clamp value to [0,1] instead of [-1,1] --- src/quartz/rendering/shaders/collider.frag | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/quartz/rendering/shaders/collider.frag b/src/quartz/rendering/shaders/collider.frag index aadb6700..da014ddc 100644 --- a/src/quartz/rendering/shaders/collider.frag +++ b/src/quartz/rendering/shaders/collider.frag @@ -19,9 +19,13 @@ layout(location = 0) out vec4 out_fragmentColor; void main() { // @todo 2025/10/20 We should initialize an array of colors as a uniform buffer and index into it // using the id modulo the array size, instead of calculating colors every frame - float redValue = sin((pushConstant.colliderId * 1) + (M_PI / 3)); - float greenValue = sin((pushConstant.colliderId * 2) + (M_PI / 5)); - float blueValue = sin((pushConstant.colliderId * 4) + (M_PI / 7)); - - out_fragmentColor = vec4(redValue, greenValue, blueValue, 0.750); + // + // @brief Create a custom color based on the id of the current collider. This generates a value based on the sin function, + // but uses a different oscillation frequency and offset for each color channel, then it is converted from [-1, 1] to + // [0, 1] + float redValue = sin((pushConstant.colliderId * 5.4321) + (M_PI / 3.0)) * 0.5 + 0.5; + float greenValue = sin((pushConstant.colliderId * 3.4567) + (M_PI / 5.0)) * 0.5 + 0.5; + float blueValue = sin((pushConstant.colliderId * 2.2222) + (M_PI / 7.0)) * 0.5 + 0.5; + + out_fragmentColor = vec4(redValue, greenValue, blueValue, 0.50); } From 81a346dbeec47d0413aff9f67a76d7de3f7e4578 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 20 Oct 2025 17:42:20 -0600 Subject: [PATCH 13/19] Enter doodad wire frame mode upon collider display mode --- src/quartz/rendering/context/Context.cpp | 10 +++++----- src/quartz/rendering/shaders/collider.frag | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 3ed77ea5..2d87fb06 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -406,8 +406,8 @@ quartz::rendering::Context::draw( ); const bool shouldRecreateDoodadPipeline = (m_doodadRenderingPipeline.getPolygonMode() == vk::PolygonMode::eFill) ? - wireframeDoodadMode : - !wireframeDoodadMode; + wireframeDoodadMode || wireframeColliderMode: + !wireframeDoodadMode && !wireframeColliderMode; if ( m_renderingSwapchain.getShouldRecreate() || m_renderingWindow.getWasResized() || @@ -452,7 +452,7 @@ quartz::rendering::Context::draw( void quartz::rendering::Context::recreateSwapchain( const bool wireframeDoodadMode, - UNUSED const bool wireframeColliderMode + const bool wireframeColliderMode ) { LOG_FUNCTION_SCOPE_INFOthis(""); m_renderingDevice.waitIdle(); @@ -477,8 +477,8 @@ quartz::rendering::Context::recreateSwapchain( m_renderingRenderPass ); - LOG_INFOthis("Setting doodad pipeline polygon mode to: {}", wireframeDoodadMode ? "line" : "fill"); - const vk::PolygonMode polygonMode = wireframeDoodadMode ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; + LOG_INFOthis("Setting doodad pipeline polygon mode to: {}", wireframeDoodadMode || wireframeColliderMode ? "line" : "fill"); + const vk::PolygonMode polygonMode = wireframeDoodadMode || wireframeColliderMode ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; m_doodadRenderingPipeline.setPolygonMode(polygonMode); m_doodadRenderingPipeline.recreate( m_renderingDevice, diff --git a/src/quartz/rendering/shaders/collider.frag b/src/quartz/rendering/shaders/collider.frag index da014ddc..739edd72 100644 --- a/src/quartz/rendering/shaders/collider.frag +++ b/src/quartz/rendering/shaders/collider.frag @@ -27,5 +27,5 @@ void main() { float greenValue = sin((pushConstant.colliderId * 3.4567) + (M_PI / 5.0)) * 0.5 + 0.5; float blueValue = sin((pushConstant.colliderId * 2.2222) + (M_PI / 7.0)) * 0.5 + 0.5; - out_fragmentColor = vec4(redValue, greenValue, blueValue, 0.50); + out_fragmentColor = vec4(redValue, greenValue, blueValue, 0.650); } From 1c8c0b73f93cf925e733d0bb946c7205940d0fca Mon Sep 17 00:00:00 2001 From: Kejoko Date: Mon, 20 Oct 2025 17:45:10 -0600 Subject: [PATCH 14/19] rename wireframe collider mode to display collider mode --- src/quartz/application/Application.cpp | 10 +++++----- src/quartz/application/Application.hpp | 4 ++-- src/quartz/rendering/context/Context.cpp | 22 +++++++++++----------- src/quartz/rendering/context/Context.hpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/quartz/application/Application.cpp b/src/quartz/application/Application.cpp index ac1bd1c5..fcc23942 100644 --- a/src/quartz/application/Application.cpp +++ b/src/quartz/application/Application.cpp @@ -40,7 +40,7 @@ quartz::Application::Application( m_isPaused(false), m_sceneDebugMode(false), m_wireframeDoodadMode(false), - m_wireframeColliderMode(false) + m_displayColliderMode(false) { LOG_FUNCTION_CALL_TRACEthis(""); } @@ -103,7 +103,7 @@ void quartz::Application::run() { double frameInterpolationFactor = (frameTimeAccumulator + targetTickTimeDelta) / targetTickTimeDelta; currentScene.update(m_renderingContext.getRenderingWindow(), m_inputManager, totalElapsedTime, currentFrameTimeDelta, frameInterpolationFactor); - m_renderingContext.draw(currentScene, m_wireframeDoodadMode, m_wireframeColliderMode); + m_renderingContext.draw(currentScene, m_wireframeDoodadMode, m_displayColliderMode); } LOG_INFOthis("Unloading scene"); @@ -158,7 +158,7 @@ quartz::Application::determineSceneDebugMode( if (!m_sceneDebugMode) { m_wireframeDoodadMode = false; - m_wireframeColliderMode = false; + m_displayColliderMode = false; return; } @@ -168,7 +168,7 @@ quartz::Application::determineSceneDebugMode( } if (shouldToggleWireframeColliderMode) { - m_wireframeColliderMode = !m_wireframeColliderMode; - LOG_INFOthis("{} collider wireframe mode", (m_wireframeColliderMode ? "Entering" : "Exiting")); + m_displayColliderMode = !m_displayColliderMode; + LOG_INFOthis("{} collider wireframe mode", (m_displayColliderMode ? "Entering" : "Exiting")); } } diff --git a/src/quartz/application/Application.hpp b/src/quartz/application/Application.hpp index 4f3b27f5..53ed729d 100644 --- a/src/quartz/application/Application.hpp +++ b/src/quartz/application/Application.hpp @@ -43,7 +43,7 @@ class quartz::Application { bool getSceneDebugMode() const { return m_sceneDebugMode; } bool getWireframeDoodadMode() const { return m_wireframeDoodadMode; } - bool getWireframeColliderMode() const { return m_wireframeColliderMode; } + bool getWireframeColliderMode() const { return m_displayColliderMode; } void run(); @@ -75,7 +75,7 @@ class quartz::Application { bool m_sceneDebugMode; bool m_wireframeDoodadMode; - bool m_wireframeColliderMode; + bool m_displayColliderMode; private: // friends friend class quartz::unit_test::ApplicationUnitTestClient; diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 2d87fb06..7a57b867 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -391,7 +391,7 @@ void quartz::rendering::Context::draw( const quartz::scene::Scene& scene, const bool wireframeDoodadMode, - const bool wireframeColliderMode + const bool displayColliderMode ) { // set up @@ -406,14 +406,14 @@ quartz::rendering::Context::draw( ); const bool shouldRecreateDoodadPipeline = (m_doodadRenderingPipeline.getPolygonMode() == vk::PolygonMode::eFill) ? - wireframeDoodadMode || wireframeColliderMode: - !wireframeDoodadMode && !wireframeColliderMode; + wireframeDoodadMode || displayColliderMode: + !wireframeDoodadMode && !displayColliderMode; if ( m_renderingSwapchain.getShouldRecreate() || m_renderingWindow.getWasResized() || shouldRecreateDoodadPipeline ) { - recreateSwapchain(wireframeDoodadMode, wireframeColliderMode); + recreateSwapchain(wireframeDoodadMode, displayColliderMode); return; } @@ -422,7 +422,7 @@ quartz::rendering::Context::draw( // update pipelines updateSkyBoxPipeline(cameraUBO); updateDoodadPipeline(scene, cameraUBO); - if (wireframeColliderMode) { + if (displayColliderMode) { updateColliderPipeline(cameraUBO); } @@ -432,7 +432,7 @@ quartz::rendering::Context::draw( // record pipelines recordSkyBoxPipeline(scene); recordDoodadPipeline(scene); - if (wireframeColliderMode) { + if (displayColliderMode) { recordColliderPipeline(scene); } @@ -442,7 +442,7 @@ quartz::rendering::Context::draw( // housekeeping if (m_renderingSwapchain.getShouldRecreate() || m_renderingWindow.getWasResized()) { - recreateSwapchain(wireframeDoodadMode, wireframeColliderMode); + recreateSwapchain(wireframeDoodadMode, displayColliderMode); return; } @@ -452,7 +452,7 @@ quartz::rendering::Context::draw( void quartz::rendering::Context::recreateSwapchain( const bool wireframeDoodadMode, - const bool wireframeColliderMode + const bool displayColliderMode ) { LOG_FUNCTION_SCOPE_INFOthis(""); m_renderingDevice.waitIdle(); @@ -477,8 +477,8 @@ quartz::rendering::Context::recreateSwapchain( m_renderingRenderPass ); - LOG_INFOthis("Setting doodad pipeline polygon mode to: {}", wireframeDoodadMode || wireframeColliderMode ? "line" : "fill"); - const vk::PolygonMode polygonMode = wireframeDoodadMode || wireframeColliderMode ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; + LOG_INFOthis("Setting doodad pipeline polygon mode to: {}", wireframeDoodadMode || displayColliderMode ? "line" : "fill"); + const vk::PolygonMode polygonMode = wireframeDoodadMode || displayColliderMode ? vk::PolygonMode::eLine : vk::PolygonMode::eFill; m_doodadRenderingPipeline.setPolygonMode(polygonMode); m_doodadRenderingPipeline.recreate( m_renderingDevice, @@ -486,7 +486,7 @@ quartz::rendering::Context::recreateSwapchain( ); /** - * @todo 2025/10/02 If we are not in wireframeColliderMode, we do not need to recreate this pipeline. Disable it somehow?? + * @todo 2025/10/02 If we are not in displayColliderMode, we do not need to recreate this pipeline. Disable it somehow?? */ m_colliderRenderingPipeline.recreate( m_renderingDevice, diff --git a/src/quartz/rendering/context/Context.hpp b/src/quartz/rendering/context/Context.hpp index bf61d827..07f6b84b 100644 --- a/src/quartz/rendering/context/Context.hpp +++ b/src/quartz/rendering/context/Context.hpp @@ -47,7 +47,7 @@ class quartz::rendering::Context { void draw( const quartz::scene::Scene& scene, const bool wireframeDoodadMode, - const bool wireframeColliderMode + const bool displayColliderMode ); void finish(); @@ -74,7 +74,7 @@ class quartz::rendering::Context { private: // member functions void recreateSwapchain( const bool wireframeDoodadMode, - const bool wireframeColliderMode + const bool displayColliderMode ); void waitForImage(); void updateSkyBoxPipeline( const quartz::scene::Camera::UniformBufferObject& cameraUBO); From 472841c3ab9fb988d0a443619697bd251434327e Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 23 Oct 2025 09:53:58 -0600 Subject: [PATCH 15/19] Move cube vertices and indices to primitive --- cmake/QuartzVersion.cmake | 15 ++--- src/quartz/rendering/model/Primitive.cpp | 59 ++++++++++++++++++++ src/quartz/rendering/model/Primitive.hpp | 4 ++ src/quartz/rendering/swapchain/Swapchain.cpp | 52 +---------------- 4 files changed, 70 insertions(+), 60 deletions(-) diff --git a/cmake/QuartzVersion.cmake b/cmake/QuartzVersion.cmake index f700c9e0..41107cc9 100644 --- a/cmake/QuartzVersion.cmake +++ b/cmake/QuartzVersion.cmake @@ -3,15 +3,9 @@ # ==================================================================== function(set_quartz_major_minor_patch_versions major minor patch) - set(QUARTZ_MAJOR_VERSION - ${major} - PARENT_SCOPE) - set(QUARTZ_MINOR_VERSION - ${minor} - PARENT_SCOPE) - set(QUARTZ_PATCH_VERSION - ${patch} - PARENT_SCOPE) + set(QUARTZ_MAJOR_VERSION ${major} PARENT_SCOPE) + set(QUARTZ_MINOR_VERSION ${minor} PARENT_SCOPE) + set(QUARTZ_PATCH_VERSION ${patch} PARENT_SCOPE) endfunction() # -----=====***** the versions *****=====----- # @@ -52,5 +46,6 @@ endfunction() # Minor Version 3 - Scene Debugging Capabilities # set_quartz_major_minor_patch_versions(0 3 0) # enable Quartz to enter a debugging mode -set_quartz_major_minor_patch_versions(0 3 1) # allow for wireframe display of doodads when in scene debugging mode +# set_quartz_major_minor_patch_versions(0 3 1) # allow for wireframe display of doodads when in scene debugging mode +set_quartz_major_minor_patch_versions(0 3 2) # allow for display of box colliders when in scene debugging mode diff --git a/src/quartz/rendering/model/Primitive.cpp b/src/quartz/rendering/model/Primitive.cpp index 1deeb22c..28ac07d1 100644 --- a/src/quartz/rendering/model/Primitive.cpp +++ b/src/quartz/rendering/model/Primitive.cpp @@ -17,6 +17,65 @@ #include "quartz/rendering/model/Vertex.hpp" #include "quartz/rendering/texture/Texture.hpp" +std::vector +quartz::rendering::Primitive::getCubeVertices() { + return { + {-1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + {-1.0f , -1.0f , -1.0f}, + }; +} + +std::vector +quartz::rendering::Primitive::getCubeIndices() { + return { + // tri 0 + 0, 2, 1, + 0, 3, 2, + + // tri 1 + 4, 6, 5, + 4, 7, 6, + + // tri 2 + 8, 10, 9, + 8, 11, 10, + + // tri 3 + 12, 14, 13, + 12, 15, 14, + + // tri 4 + 16, 18, 17, + 16, 19, 18, + + // tri 5 + 20, 22, 21, + 20, 23, 22, + }; +} + bool quartz::rendering::Primitive::handleMissingVertexAttribute( std::vector& verticesToPopulate, diff --git a/src/quartz/rendering/model/Primitive.hpp b/src/quartz/rendering/model/Primitive.hpp index 5318f8a4..b0b459e3 100644 --- a/src/quartz/rendering/model/Primitive.hpp +++ b/src/quartz/rendering/model/Primitive.hpp @@ -17,6 +17,10 @@ namespace rendering { } class quartz::rendering::Primitive { +public: // static functions + static std::vector getCubeVertices(); + static std::vector getCubeIndices(); + public: // member functions Primitive( const quartz::rendering::Device& renderingDevice, diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index 0a21d86b..a32f07bc 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -281,56 +281,8 @@ quartz::rendering::Swapchain::Swapchain( ), m_boxColliderPrimitive( renderingDevice, - /** - * @todo 2025/10/20 Move these anywhere else. Maybe these should be retrieved from a static variable or static - * function within the primitive class - */ - { - {-1.0f , -1.0f , -1.0f}, - { 1.0f , -1.0f , -1.0f}, - { 1.0f , 1.0f , -1.0f}, - {-1.0f , 1.0f , -1.0f}, - { 1.0f , -1.0f , 1.0f}, - {-1.0f , -1.0f , 1.0f}, - {-1.0f , 1.0f , 1.0f}, - { 1.0f , 1.0f , 1.0f}, - { 1.0f , -1.0f , -1.0f}, - { 1.0f , -1.0f , 1.0f}, - { 1.0f , 1.0f , 1.0f}, - { 1.0f , 1.0f , -1.0f}, - {-1.0f , -1.0f , 1.0f}, - {-1.0f , -1.0f , -1.0f}, - {-1.0f , 1.0f , -1.0f}, - {-1.0f , 1.0f , 1.0f}, - {-1.0f , 1.0f , -1.0f}, - { 1.0f , 1.0f , -1.0f}, - { 1.0f , 1.0f , 1.0f}, - {-1.0f , 1.0f , 1.0f}, - {-1.0f , -1.0f , 1.0f}, - { 1.0f , -1.0f , 1.0f}, - { 1.0f , -1.0f , -1.0f}, - {-1.0f , -1.0f , -1.0f}, - }, - { - // tri 0 - 0, 2, 1, - 0, 3, 2, - // tri 1 - 4, 6, 5, - 4, 7, 6, - // tri 2 - 8, 10, 9, - 8, 11, 10, - // tri 3 - 12, 14, 13, - 12, 15, 14, - // tri 4 - 16, 18, 17, - 16, 19, 18, - // tri 5 - 20, 22, 21, - 20, 23, 22, - } + quartz::rendering::Primitive::getCubeVertices(), + quartz::rendering::Primitive::getCubeIndices() ) { LOG_FUNCTION_CALL_TRACEthis(""); From 1abefbe01247211b480f4707bb3508e2fae2ca17 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 23 Oct 2025 11:08:13 -0600 Subject: [PATCH 16/19] Add piping for sphere colliders to be displayed, though currently with box collider vertices and indices --- src/quartz/rendering/context/Context.cpp | 1 - src/quartz/rendering/model/Primitive.cpp | 10 +++++++ src/quartz/rendering/model/Primitive.hpp | 2 ++ src/quartz/rendering/swapchain/Swapchain.cpp | 29 +++++++++++++------- src/quartz/rendering/swapchain/Swapchain.hpp | 2 +- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/quartz/rendering/context/Context.cpp b/src/quartz/rendering/context/Context.cpp index 7a57b867..149da147 100644 --- a/src/quartz/rendering/context/Context.cpp +++ b/src/quartz/rendering/context/Context.cpp @@ -632,7 +632,6 @@ quartz::rendering::Context::recordColliderPipeline( math::Vec3 colliderPosition = o_rigidBody->getPosition(); math::Quaternion colliderRotation = o_rigidBody->getRotation(); m_renderingSwapchain.recordColliderToDrawingCommandBuffer( - m_renderingDevice, m_colliderRenderingPipeline, *o_collider, colliderPosition, diff --git a/src/quartz/rendering/model/Primitive.cpp b/src/quartz/rendering/model/Primitive.cpp index 28ac07d1..69f9fdf2 100644 --- a/src/quartz/rendering/model/Primitive.cpp +++ b/src/quartz/rendering/model/Primitive.cpp @@ -76,6 +76,16 @@ quartz::rendering::Primitive::getCubeIndices() { }; } +std::vector +quartz::rendering::Primitive::getSphereVertices() { + return quartz::rendering::Primitive::getCubeVertices(); +} + +std::vector +quartz::rendering::Primitive::getSphereIndices() { + return quartz::rendering::Primitive::getCubeIndices(); +} + bool quartz::rendering::Primitive::handleMissingVertexAttribute( std::vector& verticesToPopulate, diff --git a/src/quartz/rendering/model/Primitive.hpp b/src/quartz/rendering/model/Primitive.hpp index b0b459e3..2015f72f 100644 --- a/src/quartz/rendering/model/Primitive.hpp +++ b/src/quartz/rendering/model/Primitive.hpp @@ -20,6 +20,8 @@ class quartz::rendering::Primitive { public: // static functions static std::vector getCubeVertices(); static std::vector getCubeIndices(); + static std::vector getSphereVertices(); + static std::vector getSphereIndices(); public: // member functions Primitive( diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index a32f07bc..05f4fb57 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -6,13 +6,14 @@ #include #include -#include "quartz/rendering/model/Primitive.hpp" -#include "quartz/rendering/pipeline/PushConstantInfo.hpp" #include "util/errors/RichException.hpp" +#include "util/logger/Logger.hpp" #include "math/transform/Mat4.hpp" #include "quartz/rendering/device/Device.hpp" +#include "quartz/rendering/model/Primitive.hpp" +#include "quartz/rendering/pipeline/PushConstantInfo.hpp" #include "quartz/rendering/swapchain/Swapchain.hpp" #include "quartz/rendering/vulkan_util/VulkanUtil.hpp" #include "quartz/rendering/window/Window.hpp" @@ -283,7 +284,13 @@ quartz::rendering::Swapchain::Swapchain( renderingDevice, quartz::rendering::Primitive::getCubeVertices(), quartz::rendering::Primitive::getCubeIndices() + ), + m_sphereColliderPrimitive( + renderingDevice, + quartz::rendering::Primitive::getCubeVertices(), + quartz::rendering::Primitive::getCubeIndices() ) + { LOG_FUNCTION_CALL_TRACEthis(""); } @@ -680,23 +687,25 @@ quartz::rendering::Swapchain::recordDoodadToDrawingCommandBuffer( void quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( - UNUSED const quartz::rendering::Device& renderingDevice, /** @todo 2025/10/19 remove this parameter ?? */ const quartz::rendering::Pipeline& colliderRenderingPipeline, const quartz::physics::Collider& collider, const math::Vec3& position, const math::Quaternion& rotation, const uint32_t inFlightFrameIndex ) { - if (collider.getSphereShapeOptional()) { - return; - } + const quartz::rendering::Primitive& colliderPrimitive = collider.getBoxShapeOptional() ? + m_boxColliderPrimitive : + m_sphereColliderPrimitive; uint32_t offset = 0; + const math::Vec3 scale = collider.getBoxShapeOptional() ? + collider.getBoxShapeOptional()->getHalfExtents_m() : + math::Vec3(collider.getSphereShapeOptional()->getRadius_m()); const math::Transform transform( position, rotation, - collider.getBoxShapeOptional()->getHalfExtents_m() + scale ); const math::Mat4 transformationMatrix = transform.calculateTransformationMatrix(); @@ -734,19 +743,19 @@ quartz::rendering::Swapchain::recordColliderToDrawingCommandBuffer( m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindVertexBuffers( 0, - *(m_boxColliderPrimitive.getStagedVertexBuffer().getVulkanLogicalBufferPtr()), + *(colliderPrimitive.getStagedVertexBuffer().getVulkanLogicalBufferPtr()), offset ); m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->bindIndexBuffer( - *(m_boxColliderPrimitive.getStagedIndexBuffer().getVulkanLogicalBufferPtr()), + *(colliderPrimitive.getStagedIndexBuffer().getVulkanLogicalBufferPtr()), 0, vk::IndexType::eUint32 ); // Draw using vertex and index buffer m_vulkanDrawingCommandBufferPtrs[inFlightFrameIndex]->drawIndexed( - m_boxColliderPrimitive.getIndexCount(), + colliderPrimitive.getIndexCount(), 1, 0, 0, diff --git a/src/quartz/rendering/swapchain/Swapchain.hpp b/src/quartz/rendering/swapchain/Swapchain.hpp index 9300ee22..98162136 100644 --- a/src/quartz/rendering/swapchain/Swapchain.hpp +++ b/src/quartz/rendering/swapchain/Swapchain.hpp @@ -81,7 +81,6 @@ class quartz::rendering::Swapchain { const uint32_t inFlightFrameIndex ); void recordColliderToDrawingCommandBuffer( - const quartz::rendering::Device& renderingDevice, const quartz::rendering::Pipeline& colliderRenderingPipeline, const quartz::physics::Collider& collider, const math::Vec3& position, @@ -152,5 +151,6 @@ class quartz::rendering::Swapchain { * think of a better place to put them */ quartz::rendering::Primitive m_boxColliderPrimitive; + quartz::rendering::Primitive m_sphereColliderPrimitive; }; From c119663cc28baa520fc635da3dcc7421ca18da0f Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 23 Oct 2025 13:36:56 -0600 Subject: [PATCH 17/19] Create tool to extract vertices as a c++ style array from a gltf binary buffer --- CMakeLists.txt | 7 ++ cmake/CreateScratchExecutable.cmake | 2 +- cmake/CreateToolExecutable.cmake | 19 +++++ src/tools/CMakeLists.txt | 5 ++ src/tools/PrintVertexArray.cpp | 106 ++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 cmake/CreateToolExecutable.cmake create mode 100644 src/tools/CMakeLists.txt create mode 100644 src/tools/PrintVertexArray.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cdcbd71..fa06305e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -300,6 +300,13 @@ add_subdirectory("${QUARTZ_SOURCE_DIR}/scene/light") add_subdirectory("${QUARTZ_SOURCE_DIR}/scene/scene") add_subdirectory("${QUARTZ_SOURCE_DIR}/scene/sky_box") +#==================================================================== +# Tooling +#==================================================================== + +include(CreateToolExecutable) +add_subdirectory("${QUARTZ_ROOT_SOURCE_DIR}/tools") + #==================================================================== # The tests #==================================================================== diff --git a/cmake/CreateScratchExecutable.cmake b/cmake/CreateScratchExecutable.cmake index dcd239a3..ae3387ce 100644 --- a/cmake/CreateScratchExecutable.cmake +++ b/cmake/CreateScratchExecutable.cmake @@ -1,5 +1,5 @@ #==================================================================== -# Functionality for easily creating scratch unit tests +# Functionality for easily creating scratch tests #==================================================================== function(create_scratch_executable main_file) diff --git a/cmake/CreateToolExecutable.cmake b/cmake/CreateToolExecutable.cmake new file mode 100644 index 00000000..0952cbe0 --- /dev/null +++ b/cmake/CreateToolExecutable.cmake @@ -0,0 +1,19 @@ +#==================================================================== +# Functionality for easily creating tooling executables tests +#==================================================================== + +function(create_tool_executable main_file) + get_filename_component(executable_name ${main_file} NAME_WE) + add_executable(${executable_name} ${main_file}) + + target_compile_definitions(${executable_name} PRIVATE ${QUARTZ_COMPILE_DEFINITIONS}) + target_compile_options(${executable_name} PRIVATE ${QUARTZ_CMAKE_CXX_FLAGS}) + target_include_directories(${executable_name} PRIVATE ${QUARTZ_INCLUDE_DIRS}) + + set(link_libraries ${ARGN}) + + target_link_libraries(${executable_name} PRIVATE ${link_libraries} UTIL_Logger) + + set_target_properties(${executable_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/tools) +endfunction() + diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 00000000..a48cfaf7 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,5 @@ +#==================================================================== +# Tool executables +#==================================================================== + +create_tool_executable(PrintVertexArray.cpp) diff --git a/src/tools/PrintVertexArray.cpp b/src/tools/PrintVertexArray.cpp new file mode 100644 index 00000000..e1b3d756 --- /dev/null +++ b/src/tools/PrintVertexArray.cpp @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include + +using vertex_t = std::array; + +std::optional> getVertices( + const std::string& binaryFilePath, + const uint32_t dataSizeBytes, + const uint32_t dataStartOffsetBytes +); +void printVertices( + const std::vector& vertices +); + +int main( + int argc, + char* argv[] +) { + if (argc != 4) { + std::cerr << "PrintVertexArray requires 3 command line arguments:" << std::endl; + std::cerr << " - the file containing the binary buffer of data (.glb file)" << std::endl; + std::cerr << " - the data size (in bytes)" << std::endl; + std::cerr << " - the data segment's start offset (in bytes)" << std::endl; + return 1; + } + + const std::string binaryFilepath = argv[1]; + const uint32_t dataSizeBytes = std::stoul(argv[2]); + const uint32_t dataStartOffsetBytes = std::stoul(argv[3]); + + const std::optional> o_vertices = getVertices(binaryFilepath, dataSizeBytes, dataStartOffsetBytes); + if (!o_vertices) { + std::cerr << "Unable to read vertices from " << binaryFilepath << " with data size of " << dataSizeBytes << " and a start offset of " << dataStartOffsetBytes << " bytes" << std::endl; + return 1; + } + printVertices(*o_vertices); + + return 0; +} + +std::optional> +getVertices( + const std::string& binaryFilePath, + const uint32_t dataSizeBytes, + const uint32_t dataStartOffsetBytes +) { + std::ifstream inputFile(binaryFilePath, std::ios::ate | std::ios::binary); + if (!inputFile) { + std::cerr << "Unable to open file at " << binaryFilePath << std::endl; + return {}; + } + + const uint32_t fileSizeBytes = inputFile.tellg(); + if (fileSizeBytes < dataSizeBytes + dataStartOffsetBytes) { + std::cerr << binaryFilePath << " only contains " << fileSizeBytes << ", which is insufficient for data of size " << dataSizeBytes << " bytes with a start offset of " << dataStartOffsetBytes << " bytes" << std::endl; + return {}; + } + + const uint32_t bytesPerVertex = 4 * 3; // 4 bytes per float, 3 floats per vertex + if (dataSizeBytes % bytesPerVertex) { + std::cerr << "Specified data size (" << dataSizeBytes << " bytes) does not evenly fit into 3 float vertices" << std::endl; + return {}; + } + + const uint32_t vertexCount = dataSizeBytes / bytesPerVertex; + std::vector vertices(vertexCount); + + inputFile.seekg(dataStartOffsetBytes, std::ios::beg); + for (uint32_t iVertex = 0; iVertex < vertexCount; ++iVertex) { + inputFile.read(reinterpret_cast(&(vertices[iVertex][0])), 4); + inputFile.read(reinterpret_cast(&(vertices[iVertex][1])), 4); + inputFile.read(reinterpret_cast(&(vertices[iVertex][2])), 4); + } + inputFile.close(); + + return vertices; +} + +void +printVertices( + const std::vector& vertices +) { + std::cout << "{\n"; + + for (uint32_t iVertex = 0; iVertex < vertices.size(); ++iVertex) { + const vertex_t& vertex = vertices[iVertex]; + + std::cout << " { "; + std::cout << std::showpoint << vertex[0] << std::noshowpoint << "f , "; + std::cout << std::showpoint << vertex[1] << std::noshowpoint << "f , "; + std::cout << std::showpoint << vertex[2] << std::noshowpoint << "f "; + std::cout << "}"; + + if (iVertex < vertices.size() - 1) { + std::cout << ","; + } + + std::cout << "\n"; + } + + std::cout << "}\n"; +} From d95e4b4b922cce2a24766b5896780f69d70e0358 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 23 Oct 2025 14:03:16 -0600 Subject: [PATCH 18/19] Populate sphere vertices and indices with newly created tools --- src/quartz/rendering/model/Primitive.cpp | 326 ++++++++++++++++++- src/quartz/rendering/swapchain/Swapchain.cpp | 4 +- src/tools/CMakeLists.txt | 2 + src/tools/PrintIndexArray.cpp | 102 ++++++ 4 files changed, 430 insertions(+), 4 deletions(-) create mode 100644 src/tools/PrintIndexArray.cpp diff --git a/src/quartz/rendering/model/Primitive.cpp b/src/quartz/rendering/model/Primitive.cpp index 69f9fdf2..b4ae63df 100644 --- a/src/quartz/rendering/model/Primitive.cpp +++ b/src/quartz/rendering/model/Primitive.cpp @@ -78,12 +78,334 @@ quartz::rendering::Primitive::getCubeIndices() { std::vector quartz::rendering::Primitive::getSphereVertices() { - return quartz::rendering::Primitive::getCubeVertices(); + return { + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f } + }; } std::vector quartz::rendering::Primitive::getSphereIndices() { - return quartz::rendering::Primitive::getCubeIndices(); + return { + 3, 66, 64, + 7, 71, 80, + 1, 62, 95, + 0, 94, 104, + 2, 106, 84, + 9, 81, 123, + 14, 73, 135, + 17, 96, 147, + 20, 111, 158, + 26, 119, 170, + 8, 121, 143, + 12, 132, 154, + 15, 144, 162, + 22, 160, 174, + 28, 173, 127, + 33, 180, 214, + 39, 187, 224, + 42, 195, 228, + 46, 203, 236, + 50, 207, 220, + 216, 237, 58, + 218, 205, 239, + 204, 48, 238, + 235, 233, 56, + 234, 201, 232, + 199, 44, 230, + 231, 225, 55, + 229, 197, 223, + 196, 37, 222, + 227, 211, 57, + 226, 189, 210, + 191, 31, 212, + 213, 217, 59, + 215, 181, 219, + 183, 51, 221, + 128, 209, 52, + 126, 172, 208, + 171, 49, 206, + 176, 202, 45, + 175, 161, 200, + 159, 43, 198, + 164, 193, 40, + 163, 145, 192, + 146, 35, 194, + 153, 186, 38, + 155, 133, 188, + 134, 30, 190, + 141, 182, 34, + 142, 120, 184, + 122, 53, 185, + 169, 179, 47, + 168, 117, 178, + 115, 24, 177, + 156, 166, 41, + 157, 109, 167, + 108, 16, 165, + 148, 150, 36, + 149, 97, 151, + 99, 10, 152, + 137, 139, 32, + 136, 75, 138, + 77, 6, 140, + 125, 131, 54, + 124, 83, 130, + 82, 29, 129, + 87, 118, 25, + 85, 107, 116, + 105, 23, 114, + 103, 113, 21, + 102, 93, 112, + 90, 18, 110, + 91, 98, 19, + 92, 60, 100, + 61, 11, 101, + 79, 89, 27, + 78, 70, 88, + 68, 4, 86, + 63, 72, 13, + 65, 67, 74, + 69, 5, 76 + }; } bool diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index 05f4fb57..e6b73ca0 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -287,8 +287,8 @@ quartz::rendering::Swapchain::Swapchain( ), m_sphereColliderPrimitive( renderingDevice, - quartz::rendering::Primitive::getCubeVertices(), - quartz::rendering::Primitive::getCubeIndices() + quartz::rendering::Primitive::getSphereVertices(), + quartz::rendering::Primitive::getSphereIndices() ) { diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index a48cfaf7..4f502591 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -2,4 +2,6 @@ # Tool executables #==================================================================== +create_tool_executable(PrintIndexArray.cpp) create_tool_executable(PrintVertexArray.cpp) + diff --git a/src/tools/PrintIndexArray.cpp b/src/tools/PrintIndexArray.cpp new file mode 100644 index 00000000..db3bde22 --- /dev/null +++ b/src/tools/PrintIndexArray.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +using index_t = uint16_t; + +std::optional> getIndices( + const std::string& binaryFilePath, + const uint32_t dataSizeBytes, + const uint32_t dataStartOffsetBytes +); +void printIndices( + const std::vector& indices +); + +int main( + int argc, + char* argv[] +) { + if (argc != 4) { + std::cerr << "PrintIndexArray requires 3 command line arguments:" << std::endl; + std::cerr << " - the file containing the binary buffer of data (.glb file)" << std::endl; + std::cerr << " - the data size (in bytes)" << std::endl; + std::cerr << " - the data segment's start offset (in bytes)" << std::endl; + return 1; + } + + const std::string binaryFilepath = argv[1]; + const uint32_t dataSizeBytes = std::stoul(argv[2]); + const uint32_t dataStartOffsetBytes = std::stoul(argv[3]); + + std::optional> o_indices = getIndices(binaryFilepath, dataSizeBytes, dataStartOffsetBytes); + if (!o_indices) { + std::cerr << "Unable to read indices from " << binaryFilepath << " with data size of " << dataSizeBytes << " and a start offset of " << dataStartOffsetBytes << " bytes" << std::endl; + return 1; + } + printIndices(*o_indices); + + return 0; +} + +std::optional> +getIndices( + const std::string& binaryFilePath, + const uint32_t dataSizeBytes, + const uint32_t dataStartOffsetBytes +) { + std::ifstream inputFile(binaryFilePath, std::ios::ate | std::ios::binary); + if (!inputFile) { + std::cerr << "Unable to open file at " << binaryFilePath << std::endl; + return {}; + } + + const uint32_t fileSizeBytes = inputFile.tellg(); + if (fileSizeBytes < dataSizeBytes + dataStartOffsetBytes) { + std::cerr << binaryFilePath << " only contains " << fileSizeBytes << ", which is insufficient for data of size " << dataSizeBytes << " bytes with a start offset of " << dataStartOffsetBytes << " bytes" << std::endl; + return {}; + } + + const uint32_t bytesPerFace = sizeof(index_t) * 3; // N bytes per uintXX_t, 3 uintXX_t per face's indices + if (dataSizeBytes % bytesPerFace) { + std::cerr << "Specified data size (" << dataSizeBytes << " bytes) does not evenly fit into 3 uint32_t indices" << std::endl; + return {}; + } + + const uint32_t indexCount = dataSizeBytes / sizeof(index_t); + std::vector indices(indexCount); + + inputFile.seekg(dataStartOffsetBytes, std::ios::beg); + for (uint32_t iIndex = 0; iIndex < indexCount; ++iIndex) { + inputFile.read(reinterpret_cast(&(indices[iIndex])), sizeof(index_t)); + } + inputFile.close(); + + return indices; +} + +void +printIndices( + const std::vector& indices +) { + std::cout << "{\n"; + + for (uint32_t iStartIndex = 0; iStartIndex < indices.size() - 2; iStartIndex += 3) { + const uint32_t& index0 = indices[iStartIndex+0]; + const uint32_t& index1 = indices[iStartIndex+1]; + const uint32_t& index2 = indices[iStartIndex+2]; + + std::cout << " " << index0 << ", " << index1 << ", " << index2; + + if (iStartIndex < indices.size() - 3) { + std::cout << ","; + } + + std::cout << "\n"; + } + + std::cout << "}\n"; +} + From bc3aedd2880774a40d878229fb425d624f7b61c2 Mon Sep 17 00:00:00 2001 From: Kejoko Date: Thu, 23 Oct 2025 14:12:28 -0600 Subject: [PATCH 19/19] Move the compile time vertices and indices to the basics class --- src/quartz/rendering/model/Basics.cpp | 392 +++++++++++++++++++ src/quartz/rendering/model/Basics.hpp | 24 ++ src/quartz/rendering/model/CMakeLists.txt | 11 +- src/quartz/rendering/model/Primitive.cpp | 391 ------------------ src/quartz/rendering/model/Primitive.hpp | 6 - src/quartz/rendering/swapchain/Swapchain.cpp | 9 +- 6 files changed, 429 insertions(+), 404 deletions(-) create mode 100644 src/quartz/rendering/model/Basics.cpp create mode 100644 src/quartz/rendering/model/Basics.hpp diff --git a/src/quartz/rendering/model/Basics.cpp b/src/quartz/rendering/model/Basics.cpp new file mode 100644 index 00000000..ecff7793 --- /dev/null +++ b/src/quartz/rendering/model/Basics.cpp @@ -0,0 +1,392 @@ +#include "quartz/rendering/model/Basics.hpp" + +std::vector +quartz::rendering::Basics::getCubeVertices() { + return { + {-1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , 1.0f , 1.0f}, + { 1.0f , 1.0f , -1.0f}, + {-1.0f , -1.0f , 1.0f}, + {-1.0f , -1.0f , -1.0f}, + {-1.0f , 1.0f , -1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , -1.0f}, + { 1.0f , 1.0f , 1.0f}, + {-1.0f , 1.0f , 1.0f}, + {-1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , 1.0f}, + { 1.0f , -1.0f , -1.0f}, + {-1.0f , -1.0f , -1.0f}, + }; +} + +std::vector +quartz::rendering::Basics::getCubeIndices() { + return { + // tri 0 + 0, 2, 1, + 0, 3, 2, + + // tri 1 + 4, 6, 5, + 4, 7, 6, + + // tri 2 + 8, 10, 9, + 8, 11, 10, + + // tri 3 + 12, 14, 13, + 12, 15, 14, + + // tri 4 + 16, 18, 17, + 16, 19, 18, + + // tri 5 + 20, 22, 21, + 20, 23, 22, + }; +} + +std::vector +quartz::rendering::Basics::getSphereVertices() { + return { + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.00000f , -1.00000f , -0.00000f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { 0.723607f , -0.447220f , 0.525725f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.276388f , -0.447220f , 0.850649f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.894426f , -0.447216f , -0.00000f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { -0.276388f , -0.447220f , -0.850649f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.723607f , -0.447220f , -0.525725f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { 0.276388f , 0.447220f , 0.850649f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , 0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { -0.723607f , 0.447220f , -0.525725f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.276388f , 0.447220f , -0.850649f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.894426f , 0.447216f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { 0.00000f , 1.00000f , -0.00000f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { -0.162456f , -0.850654f , 0.499995f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.425323f , -0.850654f , 0.309011f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.262869f , -0.525738f , 0.809012f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.850648f , -0.525736f , -0.00000f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { 0.425323f , -0.850654f , -0.309011f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.525730f , -0.850652f , -0.00000f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.688189f , -0.525736f , 0.499997f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.162456f , -0.850654f , -0.499995f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { -0.688189f , -0.525736f , -0.499997f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.262869f , -0.525738f , -0.809012f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , 0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.951058f , 0.00000f , -0.309013f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.00000f , 0.00000f , 1.00000f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { 0.587786f , 0.00000f , 0.809017f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.951058f , 0.00000f , 0.309013f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , 0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.587786f , 0.00000f , -0.809017f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { -0.951058f , 0.00000f , -0.309013f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.587786f , 0.00000f , -0.809017f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.00000f , 0.00000f , -1.00000f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { 0.688189f , 0.525736f , 0.499997f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.262869f , 0.525738f , 0.809012f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.850648f , 0.525736f , -0.00000f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { -0.262869f , 0.525738f , -0.809012f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.688189f , 0.525736f , -0.499997f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.162456f , 0.850654f , 0.499995f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { 0.525730f , 0.850652f , -0.00000f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , 0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { -0.425323f , 0.850654f , -0.309011f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f }, + { 0.162456f , 0.850654f , -0.499995f } + }; +} + +std::vector +quartz::rendering::Basics::getSphereIndices() { + return { + 3, 66, 64, + 7, 71, 80, + 1, 62, 95, + 0, 94, 104, + 2, 106, 84, + 9, 81, 123, + 14, 73, 135, + 17, 96, 147, + 20, 111, 158, + 26, 119, 170, + 8, 121, 143, + 12, 132, 154, + 15, 144, 162, + 22, 160, 174, + 28, 173, 127, + 33, 180, 214, + 39, 187, 224, + 42, 195, 228, + 46, 203, 236, + 50, 207, 220, + 216, 237, 58, + 218, 205, 239, + 204, 48, 238, + 235, 233, 56, + 234, 201, 232, + 199, 44, 230, + 231, 225, 55, + 229, 197, 223, + 196, 37, 222, + 227, 211, 57, + 226, 189, 210, + 191, 31, 212, + 213, 217, 59, + 215, 181, 219, + 183, 51, 221, + 128, 209, 52, + 126, 172, 208, + 171, 49, 206, + 176, 202, 45, + 175, 161, 200, + 159, 43, 198, + 164, 193, 40, + 163, 145, 192, + 146, 35, 194, + 153, 186, 38, + 155, 133, 188, + 134, 30, 190, + 141, 182, 34, + 142, 120, 184, + 122, 53, 185, + 169, 179, 47, + 168, 117, 178, + 115, 24, 177, + 156, 166, 41, + 157, 109, 167, + 108, 16, 165, + 148, 150, 36, + 149, 97, 151, + 99, 10, 152, + 137, 139, 32, + 136, 75, 138, + 77, 6, 140, + 125, 131, 54, + 124, 83, 130, + 82, 29, 129, + 87, 118, 25, + 85, 107, 116, + 105, 23, 114, + 103, 113, 21, + 102, 93, 112, + 90, 18, 110, + 91, 98, 19, + 92, 60, 100, + 61, 11, 101, + 79, 89, 27, + 78, 70, 88, + 68, 4, 86, + 63, 72, 13, + 65, 67, 74, + 69, 5, 76 + }; +} diff --git a/src/quartz/rendering/model/Basics.hpp b/src/quartz/rendering/model/Basics.hpp new file mode 100644 index 00000000..84c8b2be --- /dev/null +++ b/src/quartz/rendering/model/Basics.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "math/transform/Vec3.hpp" + +namespace quartz { +namespace rendering { + class Basics; +} +} + +class quartz::rendering::Basics { +public: + static std::vector getCubeVertices(); + static std::vector getCubeIndices(); + + static std::vector getSphereVertices(); + static std::vector getSphereIndices(); + +private: + Basics() = delete; +}; + diff --git a/src/quartz/rendering/model/CMakeLists.txt b/src/quartz/rendering/model/CMakeLists.txt index 33b4e808..a2989544 100644 --- a/src/quartz/rendering/model/CMakeLists.txt +++ b/src/quartz/rendering/model/CMakeLists.txt @@ -4,6 +4,10 @@ add_library( QUARTZ_RENDERING_Model SHARED + + Basics.hpp + Basics.cpp + Mesh.hpp Mesh.cpp @@ -43,8 +47,8 @@ target_compile_definitions( ) target_compile_definitions( - QUARTZ_RENDERING_Model - PUBLIC ${QUARTZ_COMPILE_DEFINITIONS} + QUARTZ_RENDERING_Model + PUBLIC ${QUARTZ_COMPILE_DEFINITIONS} ) target_link_libraries( @@ -65,4 +69,5 @@ target_link_libraries( QUARTZ_RENDERING_Device QUARTZ_RENDERING_Material QUARTZ_RENDERING_Texture -) \ No newline at end of file +) + diff --git a/src/quartz/rendering/model/Primitive.cpp b/src/quartz/rendering/model/Primitive.cpp index b4ae63df..1deeb22c 100644 --- a/src/quartz/rendering/model/Primitive.cpp +++ b/src/quartz/rendering/model/Primitive.cpp @@ -17,397 +17,6 @@ #include "quartz/rendering/model/Vertex.hpp" #include "quartz/rendering/texture/Texture.hpp" -std::vector -quartz::rendering::Primitive::getCubeVertices() { - return { - {-1.0f , -1.0f , -1.0f}, - { 1.0f , -1.0f , -1.0f}, - { 1.0f , 1.0f , -1.0f}, - {-1.0f , 1.0f , -1.0f}, - { 1.0f , -1.0f , 1.0f}, - {-1.0f , -1.0f , 1.0f}, - {-1.0f , 1.0f , 1.0f}, - { 1.0f , 1.0f , 1.0f}, - { 1.0f , -1.0f , -1.0f}, - { 1.0f , -1.0f , 1.0f}, - { 1.0f , 1.0f , 1.0f}, - { 1.0f , 1.0f , -1.0f}, - {-1.0f , -1.0f , 1.0f}, - {-1.0f , -1.0f , -1.0f}, - {-1.0f , 1.0f , -1.0f}, - {-1.0f , 1.0f , 1.0f}, - {-1.0f , 1.0f , -1.0f}, - { 1.0f , 1.0f , -1.0f}, - { 1.0f , 1.0f , 1.0f}, - {-1.0f , 1.0f , 1.0f}, - {-1.0f , -1.0f , 1.0f}, - { 1.0f , -1.0f , 1.0f}, - { 1.0f , -1.0f , -1.0f}, - {-1.0f , -1.0f , -1.0f}, - }; -} - -std::vector -quartz::rendering::Primitive::getCubeIndices() { - return { - // tri 0 - 0, 2, 1, - 0, 3, 2, - - // tri 1 - 4, 6, 5, - 4, 7, 6, - - // tri 2 - 8, 10, 9, - 8, 11, 10, - - // tri 3 - 12, 14, 13, - 12, 15, 14, - - // tri 4 - 16, 18, 17, - 16, 19, 18, - - // tri 5 - 20, 22, 21, - 20, 23, 22, - }; -} - -std::vector -quartz::rendering::Primitive::getSphereVertices() { - return { - { 0.00000f , -1.00000f , -0.00000f }, - { 0.00000f , -1.00000f , -0.00000f }, - { 0.00000f , -1.00000f , -0.00000f }, - { 0.00000f , -1.00000f , -0.00000f }, - { 0.00000f , -1.00000f , -0.00000f }, - { 0.723607f , -0.447220f , 0.525725f }, - { 0.723607f , -0.447220f , 0.525725f }, - { 0.723607f , -0.447220f , 0.525725f }, - { 0.723607f , -0.447220f , 0.525725f }, - { 0.723607f , -0.447220f , 0.525725f }, - { -0.276388f , -0.447220f , 0.850649f }, - { -0.276388f , -0.447220f , 0.850649f }, - { -0.276388f , -0.447220f , 0.850649f }, - { -0.276388f , -0.447220f , 0.850649f }, - { -0.276388f , -0.447220f , 0.850649f }, - { -0.894426f , -0.447216f , -0.00000f }, - { -0.894426f , -0.447216f , -0.00000f }, - { -0.894426f , -0.447216f , -0.00000f }, - { -0.894426f , -0.447216f , -0.00000f }, - { -0.894426f , -0.447216f , -0.00000f }, - { -0.276388f , -0.447220f , -0.850649f }, - { -0.276388f , -0.447220f , -0.850649f }, - { -0.276388f , -0.447220f , -0.850649f }, - { -0.276388f , -0.447220f , -0.850649f }, - { -0.276388f , -0.447220f , -0.850649f }, - { 0.723607f , -0.447220f , -0.525725f }, - { 0.723607f , -0.447220f , -0.525725f }, - { 0.723607f , -0.447220f , -0.525725f }, - { 0.723607f , -0.447220f , -0.525725f }, - { 0.723607f , -0.447220f , -0.525725f }, - { 0.276388f , 0.447220f , 0.850649f }, - { 0.276388f , 0.447220f , 0.850649f }, - { 0.276388f , 0.447220f , 0.850649f }, - { 0.276388f , 0.447220f , 0.850649f }, - { 0.276388f , 0.447220f , 0.850649f }, - { -0.723607f , 0.447220f , 0.525725f }, - { -0.723607f , 0.447220f , 0.525725f }, - { -0.723607f , 0.447220f , 0.525725f }, - { -0.723607f , 0.447220f , 0.525725f }, - { -0.723607f , 0.447220f , 0.525725f }, - { -0.723607f , 0.447220f , -0.525725f }, - { -0.723607f , 0.447220f , -0.525725f }, - { -0.723607f , 0.447220f , -0.525725f }, - { -0.723607f , 0.447220f , -0.525725f }, - { -0.723607f , 0.447220f , -0.525725f }, - { 0.276388f , 0.447220f , -0.850649f }, - { 0.276388f , 0.447220f , -0.850649f }, - { 0.276388f , 0.447220f , -0.850649f }, - { 0.276388f , 0.447220f , -0.850649f }, - { 0.276388f , 0.447220f , -0.850649f }, - { 0.894426f , 0.447216f , -0.00000f }, - { 0.894426f , 0.447216f , -0.00000f }, - { 0.894426f , 0.447216f , -0.00000f }, - { 0.894426f , 0.447216f , -0.00000f }, - { 0.894426f , 0.447216f , -0.00000f }, - { 0.00000f , 1.00000f , -0.00000f }, - { 0.00000f , 1.00000f , -0.00000f }, - { 0.00000f , 1.00000f , -0.00000f }, - { 0.00000f , 1.00000f , -0.00000f }, - { 0.00000f , 1.00000f , -0.00000f }, - { -0.162456f , -0.850654f , 0.499995f }, - { -0.162456f , -0.850654f , 0.499995f }, - { -0.162456f , -0.850654f , 0.499995f }, - { -0.162456f , -0.850654f , 0.499995f }, - { -0.162456f , -0.850654f , 0.499995f }, - { -0.162456f , -0.850654f , 0.499995f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.425323f , -0.850654f , 0.309011f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.262869f , -0.525738f , 0.809012f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.850648f , -0.525736f , -0.00000f }, - { 0.425323f , -0.850654f , -0.309011f }, - { 0.425323f , -0.850654f , -0.309011f }, - { 0.425323f , -0.850654f , -0.309011f }, - { 0.425323f , -0.850654f , -0.309011f }, - { 0.425323f , -0.850654f , -0.309011f }, - { 0.425323f , -0.850654f , -0.309011f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.525730f , -0.850652f , -0.00000f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.688189f , -0.525736f , 0.499997f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.162456f , -0.850654f , -0.499995f }, - { -0.688189f , -0.525736f , -0.499997f }, - { -0.688189f , -0.525736f , -0.499997f }, - { -0.688189f , -0.525736f , -0.499997f }, - { -0.688189f , -0.525736f , -0.499997f }, - { -0.688189f , -0.525736f , -0.499997f }, - { -0.688189f , -0.525736f , -0.499997f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.262869f , -0.525738f , -0.809012f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , 0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.951058f , 0.00000f , -0.309013f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.00000f , 0.00000f , 1.00000f }, - { 0.587786f , 0.00000f , 0.809017f }, - { 0.587786f , 0.00000f , 0.809017f }, - { 0.587786f , 0.00000f , 0.809017f }, - { 0.587786f , 0.00000f , 0.809017f }, - { 0.587786f , 0.00000f , 0.809017f }, - { 0.587786f , 0.00000f , 0.809017f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.951058f , 0.00000f , 0.309013f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , 0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.587786f , 0.00000f , -0.809017f }, - { -0.951058f , 0.00000f , -0.309013f }, - { -0.951058f , 0.00000f , -0.309013f }, - { -0.951058f , 0.00000f , -0.309013f }, - { -0.951058f , 0.00000f , -0.309013f }, - { -0.951058f , 0.00000f , -0.309013f }, - { -0.951058f , 0.00000f , -0.309013f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.587786f , 0.00000f , -0.809017f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.00000f , 0.00000f , -1.00000f }, - { 0.688189f , 0.525736f , 0.499997f }, - { 0.688189f , 0.525736f , 0.499997f }, - { 0.688189f , 0.525736f , 0.499997f }, - { 0.688189f , 0.525736f , 0.499997f }, - { 0.688189f , 0.525736f , 0.499997f }, - { 0.688189f , 0.525736f , 0.499997f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.262869f , 0.525738f , 0.809012f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.850648f , 0.525736f , -0.00000f }, - { -0.262869f , 0.525738f , -0.809012f }, - { -0.262869f , 0.525738f , -0.809012f }, - { -0.262869f , 0.525738f , -0.809012f }, - { -0.262869f , 0.525738f , -0.809012f }, - { -0.262869f , 0.525738f , -0.809012f }, - { -0.262869f , 0.525738f , -0.809012f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.688189f , 0.525736f , -0.499997f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.162456f , 0.850654f , 0.499995f }, - { 0.525730f , 0.850652f , -0.00000f }, - { 0.525730f , 0.850652f , -0.00000f }, - { 0.525730f , 0.850652f , -0.00000f }, - { 0.525730f , 0.850652f , -0.00000f }, - { 0.525730f , 0.850652f , -0.00000f }, - { 0.525730f , 0.850652f , -0.00000f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , 0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { -0.425323f , 0.850654f , -0.309011f }, - { 0.162456f , 0.850654f , -0.499995f }, - { 0.162456f , 0.850654f , -0.499995f }, - { 0.162456f , 0.850654f , -0.499995f }, - { 0.162456f , 0.850654f , -0.499995f }, - { 0.162456f , 0.850654f , -0.499995f }, - { 0.162456f , 0.850654f , -0.499995f } - }; -} - -std::vector -quartz::rendering::Primitive::getSphereIndices() { - return { - 3, 66, 64, - 7, 71, 80, - 1, 62, 95, - 0, 94, 104, - 2, 106, 84, - 9, 81, 123, - 14, 73, 135, - 17, 96, 147, - 20, 111, 158, - 26, 119, 170, - 8, 121, 143, - 12, 132, 154, - 15, 144, 162, - 22, 160, 174, - 28, 173, 127, - 33, 180, 214, - 39, 187, 224, - 42, 195, 228, - 46, 203, 236, - 50, 207, 220, - 216, 237, 58, - 218, 205, 239, - 204, 48, 238, - 235, 233, 56, - 234, 201, 232, - 199, 44, 230, - 231, 225, 55, - 229, 197, 223, - 196, 37, 222, - 227, 211, 57, - 226, 189, 210, - 191, 31, 212, - 213, 217, 59, - 215, 181, 219, - 183, 51, 221, - 128, 209, 52, - 126, 172, 208, - 171, 49, 206, - 176, 202, 45, - 175, 161, 200, - 159, 43, 198, - 164, 193, 40, - 163, 145, 192, - 146, 35, 194, - 153, 186, 38, - 155, 133, 188, - 134, 30, 190, - 141, 182, 34, - 142, 120, 184, - 122, 53, 185, - 169, 179, 47, - 168, 117, 178, - 115, 24, 177, - 156, 166, 41, - 157, 109, 167, - 108, 16, 165, - 148, 150, 36, - 149, 97, 151, - 99, 10, 152, - 137, 139, 32, - 136, 75, 138, - 77, 6, 140, - 125, 131, 54, - 124, 83, 130, - 82, 29, 129, - 87, 118, 25, - 85, 107, 116, - 105, 23, 114, - 103, 113, 21, - 102, 93, 112, - 90, 18, 110, - 91, 98, 19, - 92, 60, 100, - 61, 11, 101, - 79, 89, 27, - 78, 70, 88, - 68, 4, 86, - 63, 72, 13, - 65, 67, 74, - 69, 5, 76 - }; -} - bool quartz::rendering::Primitive::handleMissingVertexAttribute( std::vector& verticesToPopulate, diff --git a/src/quartz/rendering/model/Primitive.hpp b/src/quartz/rendering/model/Primitive.hpp index 2015f72f..5318f8a4 100644 --- a/src/quartz/rendering/model/Primitive.hpp +++ b/src/quartz/rendering/model/Primitive.hpp @@ -17,12 +17,6 @@ namespace rendering { } class quartz::rendering::Primitive { -public: // static functions - static std::vector getCubeVertices(); - static std::vector getCubeIndices(); - static std::vector getSphereVertices(); - static std::vector getSphereIndices(); - public: // member functions Primitive( const quartz::rendering::Device& renderingDevice, diff --git a/src/quartz/rendering/swapchain/Swapchain.cpp b/src/quartz/rendering/swapchain/Swapchain.cpp index e6b73ca0..469e4754 100644 --- a/src/quartz/rendering/swapchain/Swapchain.cpp +++ b/src/quartz/rendering/swapchain/Swapchain.cpp @@ -12,6 +12,7 @@ #include "math/transform/Mat4.hpp" #include "quartz/rendering/device/Device.hpp" +#include "quartz/rendering/model/Basics.hpp" #include "quartz/rendering/model/Primitive.hpp" #include "quartz/rendering/pipeline/PushConstantInfo.hpp" #include "quartz/rendering/swapchain/Swapchain.hpp" @@ -282,13 +283,13 @@ quartz::rendering::Swapchain::Swapchain( ), m_boxColliderPrimitive( renderingDevice, - quartz::rendering::Primitive::getCubeVertices(), - quartz::rendering::Primitive::getCubeIndices() + quartz::rendering::Basics::getCubeVertices(), + quartz::rendering::Basics::getCubeIndices() ), m_sphereColliderPrimitive( renderingDevice, - quartz::rendering::Primitive::getSphereVertices(), - quartz::rendering::Primitive::getSphereIndices() + quartz::rendering::Basics::getSphereVertices(), + quartz::rendering::Basics::getSphereIndices() ) {