Added support for persistent debug draw

This commit is contained in:
Kah Wei 2022-11-02 10:06:39 +08:00
parent 1371302a40
commit 41e1f01f29
5 changed files with 291 additions and 20 deletions

View File

@ -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();
}

View File

@ -43,20 +43,41 @@ namespace SHADE
return;
}
// Get the system
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(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<SHDebugDrawSystem*>(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<SHVkBuffer>& 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<SHVkBuffer>& 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<SHVec3> 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<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
{
if (storage.size() > MAX_POINTS)

View File

@ -126,6 +126,78 @@ namespace SHADE
/// <param name="size">Size of the rendered sphere.</param>
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
/*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Renders a line between two points in world space that will persist until
/// ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param>
void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
/// <summary>
/// Renders a triangle indicated by three points in world space that will persist
/// until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param>
void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary>
/// Renders a quadrilateral indicated by four points in world space that will persist
/// until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param>
void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called.
/// </summary>
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointListBegin">
/// Iterator to the first point of the point container.
/// </param>
/// <param name="pointListEnd">
/// One past last iterator of the point container.
/// </param>
template<typename IterType>
void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world space
/// that will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the cube.</param>
/// <param name="pos">Position where the cube wil be centered at.</param>
/// <param name="size">Size of the rendered cube.</param>
void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
/// <summary>
/// Renders a wireframe sphere centered around the position specified in world space
/// that will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the sphere.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param>
/// <param name="size">Size of the rendered sphere.</param>
void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
/// <summary>
/// Clears any persistent drawn debug primitives.
/// </summary>
void ClearPersistentDraws();
private:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -136,7 +208,8 @@ namespace SHADE
SHVec4 Color;
};
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/*---------------------------------------------------------------------------------*/
/* 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<SHVec3> spherePoints;
@ -165,6 +241,13 @@ namespace SHADE
void drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size);
void drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius);
};
template<typename IterType>
void SHADE::SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
{
}
}
#include "SHDebugDrawSystem.hpp"

View File

@ -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<SHVec3> 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();
}
}

View File

@ -92,6 +92,64 @@ namespace SHADE
/// <param name="size">Size of the rendered sphere.</param>
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius);
/*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Renders a line between two points in world space that will persist until
/// ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param>
static void PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
/// <summary>
/// Renders a triangle indicated by three points in world space that will persist
/// until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param>
static void PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary>
/// Renders a quadrilateral indicated by four points in world space that will persist
/// until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param>
static void PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
static void PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world space
/// that will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the cube.</param>
/// <param name="pos">Position where the cube wil be centered at.</param>
/// <param name="size">Size of the rendered cube.</param>
static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
/// <summary>
/// Renders a wireframe sphere centered around the position specified in world space
/// that will persist until ClearPersistentDraws() is called.
/// </summary>
/// <param name="color">Colour of the sphere.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param>
/// <param name="size">Size of the rendered sphere.</param>
static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
/// <summary>
/// Clears any persistent drawn debug primitives.
/// </summary>
static void ClearPersistentDraws();
private:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */