From 41e1f01f29174fbfaa8cc700bbef9e79b07e5173 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 2 Nov 2022 10:06:39 +0800 Subject: [PATCH] Added support for persistent debug draw --- .../src/Application/SBApplication.cpp | 4 + .../MiddleEnd/Interface/SHDebugDrawSystem.cpp | 126 +++++++++++++++--- .../MiddleEnd/Interface/SHDebugDrawSystem.h | 85 +++++++++++- SHADE_Engine/src/Tools/SHDebugDraw.cpp | 38 +++++- SHADE_Engine/src/Tools/SHDebugDraw.h | 58 ++++++++ 5 files changed, 291 insertions(+), 20 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index b865f028..8b437584 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -146,6 +146,10 @@ namespace Sandbox if(editor->editorState == SHEditor::State::PLAY) SHSceneManager::SceneUpdate(0.016f); #endif + SHDebugDraw::Line(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), SHVec3(-5.0f, 0.0f, 0.0f), SHVec3(5.0f, 0.0f, 0.0f)); + SHDebugDraw::Line(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), SHVec3(-5.0f, 1.0f, 0.0f), SHVec3(5.0f, 1.0f, 0.0f)); + SHDebugDraw::Cube(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), {}, SHVec3(1.0f, 1.0f, 1.0f)); + SHDebugDraw::Sphere(SHVec4(1.0f, 1.0f, 1.0f, 1.0f), {}, 3.0f); SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); editor->PollPicking(); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index 715b7d69..16069564 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -43,20 +43,41 @@ namespace SHADE return; } + // Get the system + SHDebugDrawSystem* system = static_cast(GetSystem()); + // Get current frame index const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex(); - // Create the buffer if it doesn't exist or just update it - SHDebugDrawSystem* system = static_cast(GetSystem()); + /* Non-Persistent Buffer */ + // Update the buffer system->numPoints[FRAME_IDX] = system->points.size(); const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size(); if (DATA_SIZE > 0) { - system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0); + system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0); } // Reset for next frame system->points.clear(); + + /* Persistent Buffer */ + // Check if there are changes + if (system->persistentBuffersCleared[FRAME_IDX] + || + system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size()) + { + // Update Buffer + system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size(); + const uint32_t DATA_SIZE = sizeof(PointVertex) * system->persistentPoints.size(); + if (DATA_SIZE > 0) + { + system->persistentVertexBuffers[FRAME_IDX]->WriteToMemory(system->persistentPoints.data(), DATA_SIZE, 0, 0); + } + + // Reset Flag + system->persistentBuffersCleared[FRAME_IDX] = false; + } } /*---------------------------------------------------------------------------------*/ @@ -74,32 +95,56 @@ namespace SHADE // Get Current frame index const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex(); - // Don't draw if no points - if (numPoints[FRAME_IDX] <= 0) - return; - + // Set Pipeline cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); cmdBuffer->SetLineWidth(LineWidth); - cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); - cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0); + + // Don't draw if no points + if (numPoints[FRAME_IDX] > 0) + { + cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); + cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0); + } + if (numPersistentPoints[FRAME_IDX] > 0) + { + cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); + cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); + } }); // Reset trackers std::fill_n(numPoints.begin(), numPoints.size(), 0); + std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0); + for (bool& cleared : persistentBuffersCleared) + cleared = true; // Allocate buffers + // - Non-Persistent Draws static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex); for (Handle& bufHandle : vertexBuffers) { - bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer - ( - BUFFER_SIZE, - nullptr, - 0, - vk::BufferUsageFlagBits::eVertexBuffer, - VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT - ); + bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer + ( + BUFFER_SIZE, + nullptr, + 0, + vk::BufferUsageFlagBits::eVertexBuffer, + VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT + ); + } + // - Persistent Draws + for (Handle& bufHandle : persistentVertexBuffers) + { + bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer + ( + BUFFER_SIZE, + nullptr, + 0, + vk::BufferUsageFlagBits::eVertexBuffer, + VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT + ); } } @@ -110,6 +155,11 @@ namespace SHADE if (vertexBuffer) vertexBuffer.Free(); } + for (auto vertexBuffer : persistentVertexBuffers) + { + if (vertexBuffer) + vertexBuffer.Free(); + } } /*---------------------------------------------------------------------------------*/ @@ -145,6 +195,46 @@ namespace SHADE drawSphere(points, color, pos, radius); } + /*---------------------------------------------------------------------------------*/ + /* Persistent Draw Functions */ + /*---------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) + { + drawLine(persistentPoints, color, startPt, endPt); + } + + void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) + { + drawPoly(persistentPoints, color, { pt1, pt2, pt3 }); + } + + void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) + { + drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 }); + } + + void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list pointList) + { + drawPoly(persistentPoints, color, pointList.begin(), pointList.end()); + } + + void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) + { + drawCube(persistentPoints, color, pos, size); + } + + void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) + { + drawSphere(persistentPoints, color, pos, radius); + } + + void SHDebugDrawSystem::ClearPersistentDraws() + { + persistentPoints.clear(); + for (bool& cleared : persistentBuffersCleared) + cleared = true; + } + void SHDebugDrawSystem::drawLine(std::vector& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) { if (storage.size() > MAX_POINTS) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h index 41a0dd77..7c9e7c81 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h @@ -126,6 +126,78 @@ namespace SHADE /// Size of the rendered sphere. void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius); + /*---------------------------------------------------------------------------------*/ + /* Persistent Draw Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Renders a line between two points in world space that will persist until + /// ClearPersistentDraws() is called. + /// + /// Colour of the line. + /// First point of the line. + /// Second point of the line. + void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); + /// + /// Renders a triangle indicated by three points in world space that will persist + /// until ClearPersistentDraws() is called. + /// + /// Colour of the triangle. + /// First point of the triangle. + /// Second point of the triangle. + /// Third point of the triangle. + void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); + /// + /// Renders a quadrilateral indicated by four points in world space that will persist + /// until ClearPersistentDraws() is called. + /// + /// Colour of the quadrilateral. + /// First point of the triangle. + /// Second point of the quadrilateral. + /// Third point of the quadrilateral. + /// Third point of the quadrilateral. + void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); + /// + /// Renders a polygon indicated by the specified set of points in world space that + /// will persist until ClearPersistentDraws() is called. + /// + /// Colour of the polygon. + /// List of points for the polygon. + void DrawPersistentPoly(const SHVec4& color, std::initializer_list pointList); + /// + /// Renders a polygon indicated by the specified set of points in world space that + /// will persist until ClearPersistentDraws() is called. + /// + /// Iterator for a STL-like container. + /// Colour of the polygon. + /// + /// Iterator to the first point of the point container. + /// + /// + /// One past last iterator of the point container. + /// + template + void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); + /// + /// Renders a wireframe cube centered around the position specified in world space + /// that will persist until ClearPersistentDraws() is called. + /// + /// Colour of the cube. + /// Position where the cube wil be centered at. + /// Size of the rendered cube. + void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); + /// + /// Renders a wireframe sphere centered around the position specified in world space + /// that will persist until ClearPersistentDraws() is called. + /// + /// Colour of the sphere. + /// Position where the sphere wil be centered at. + /// Size of the rendered sphere. + void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); + /// + /// Clears any persistent drawn debug primitives. + /// + void ClearPersistentDraws(); + private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -136,7 +208,8 @@ namespace SHADE SHVec4 Color; }; using TripleBuffer = std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS>; - using TripleUInt = std::array; + using TripleUInt = std::array; + using TripleBool = std::array; /*---------------------------------------------------------------------------------*/ /* Constants */ @@ -152,6 +225,9 @@ namespace SHADE // GPU Buffers TripleBuffer vertexBuffers; TripleUInt numPoints; + TripleBuffer persistentVertexBuffers; + TripleUInt numPersistentPoints; + TripleBool persistentBuffersCleared; // Cached Points for polygon drawing std::vector spherePoints; @@ -165,6 +241,13 @@ namespace SHADE void drawCube(std::vector& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size); void drawSphere(std::vector& storage, const SHVec4& color, const SHVec3& pos, double radius); }; + + template + void SHADE::SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd) + { + + } + } #include "SHDebugDrawSystem.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Tools/SHDebugDraw.cpp b/SHADE_Engine/src/Tools/SHDebugDraw.cpp index a5b86c42..b8aa8b0e 100644 --- a/SHADE_Engine/src/Tools/SHDebugDraw.cpp +++ b/SHADE_Engine/src/Tools/SHDebugDraw.cpp @@ -25,7 +25,7 @@ namespace SHADE /* Static Member Definitions */ /*-----------------------------------------------------------------------------------*/ SHDebugDrawSystem* SHDebugDraw::dbgDrawSys = nullptr; - + /*-----------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*-----------------------------------------------------------------------------------*/ @@ -70,4 +70,40 @@ namespace SHADE { dbgDrawSys->DrawSphere(color, pos, radius); } + + void SHDebugDraw::PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) + { + dbgDrawSys->DrawPersistentLine(color, startPt, endPt); + } + + void SHDebugDraw::PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) + { + dbgDrawSys->DrawPersistentTri(color, pt1, pt2, pt3); + } + + void SHDebugDraw::PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) + { + dbgDrawSys->DrawPersistentQuad(color, pt1, pt2, pt3, pt4); + } + + void SHDebugDraw::PersistentPoly(const SHVec4& color, std::initializer_list pointList) + { + dbgDrawSys->DrawPersistentPoly(color, pointList); + } + + void SHDebugDraw::PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) + { + dbgDrawSys->DrawPersistentCube(color, pos, size); + } + + void SHDebugDraw::PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) + { + dbgDrawSys->DrawPersistentSphere(color, pos, radius); + } + + void SHDebugDraw::ClearPersistentDraws() + { + dbgDrawSys->ClearPersistentDraws(); + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Tools/SHDebugDraw.h b/SHADE_Engine/src/Tools/SHDebugDraw.h index 7ce44ec2..04504c3a 100644 --- a/SHADE_Engine/src/Tools/SHDebugDraw.h +++ b/SHADE_Engine/src/Tools/SHDebugDraw.h @@ -92,6 +92,64 @@ namespace SHADE /// Size of the rendered sphere. static void Sphere(const SHVec4& color, const SHVec3& pos, double radius); + /*---------------------------------------------------------------------------------*/ + /* Persistent Draw Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Renders a line between two points in world space that will persist until + /// ClearPersistentDraws() is called. + /// + /// Colour of the line. + /// First point of the line. + /// Second point of the line. + static void PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); + /// + /// Renders a triangle indicated by three points in world space that will persist + /// until ClearPersistentDraws() is called. + /// + /// Colour of the triangle. + /// First point of the triangle. + /// Second point of the triangle. + /// Third point of the triangle. + static void PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); + /// + /// Renders a quadrilateral indicated by four points in world space that will persist + /// until ClearPersistentDraws() is called. + /// + /// Colour of the quadrilateral. + /// First point of the triangle. + /// Second point of the quadrilateral. + /// Third point of the quadrilateral. + /// Third point of the quadrilateral. + static void PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); + /// + /// Renders a polygon indicated by the specified set of points in world space that + /// will persist until ClearPersistentDraws() is called. + /// + /// Colour of the polygon. + /// List of points for the polygon. + static void PersistentPoly(const SHVec4& color, std::initializer_list pointList); + /// + /// Renders a wireframe cube centered around the position specified in world space + /// that will persist until ClearPersistentDraws() is called. + /// + /// Colour of the cube. + /// Position where the cube wil be centered at. + /// Size of the rendered cube. + static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); + /// + /// Renders a wireframe sphere centered around the position specified in world space + /// that will persist until ClearPersistentDraws() is called. + /// + /// Colour of the sphere. + /// Position where the sphere wil be centered at. + /// Size of the rendered sphere. + static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); + /// + /// Clears any persistent drawn debug primitives. + /// + static void ClearPersistentDraws(); + private: /*---------------------------------------------------------------------------------*/ /* Static Data Members */