Merge pull request #294 from SHADE-DP/SP3-1-DebugDraw

Reworked DebugDraw System
This commit is contained in:
XiaoQiDigipen 2022-12-16 02:21:32 +08:00 committed by GitHub
commit c479e6c8d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1800 additions and 592 deletions

View File

@ -0,0 +1,27 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in mat4 worldTransform;
layout(location = 5) in vec4 color;
// Output
layout(location = 0) out struct
{
vec4 Color;
} Out;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
void main()
{
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos.xyz, 1.0f);
Out.Color = color;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDrawMesh_VS
ID: 42127043
Type: 2

View File

@ -1,14 +1,13 @@
#version 450 #version 450
#extension GL_KHR_vulkan_glsl : enable #extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec4 aVertexPos; layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec4 aVertColor; layout(location = 1) in vec4 aVertColor;
// Output
layout(location = 0) out struct layout(location = 0) out struct
{ {
vec4 vertColor; // location 0 vec4 vertColor; // location 0
} Out; } Out;
layout(set = 2, binding = 0) uniform CameraData layout(set = 2, binding = 0) uniform CameraData
@ -22,6 +21,6 @@ layout(set = 2, binding = 0) uniform CameraData
void main() void main()
{ {
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f); gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f);
Out.vertColor = aVertColor; Out.vertColor = aVertColor;
} }

View File

@ -231,8 +231,6 @@ namespace Sandbox
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>()); SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->RemoveAllScripts(testObj); scriptEngine->RemoveAllScripts(testObj);
} }
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
} }
void SBTestScene::Render() void SBTestScene::Render()

View File

@ -271,7 +271,7 @@ namespace SHADE
void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes) void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes)
{ {
// Clear existing lines // Clear existing lines
SHDebugDraw::ClearPersistentDraws(); SHDebugDraw::Persistent::ClearDraws();
static constexpr float DELTA = 1.0f; static constexpr float DELTA = 1.0f;
static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA); static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA);
@ -284,30 +284,34 @@ namespace SHADE
for (int i = 1; i < EXTENT_COUNT; ++i) for (int i = 1; i < EXTENT_COUNT; ++i)
{ {
// X-Axis Lines // X-Axis Lines
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
GRID_COL,
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA },
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA } SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA },
);
SHDebugDraw::PersistentLine
(
GRID_COL, GRID_COL,
true
);
SHDebugDraw::Persistent::Line
(
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA },
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA } SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA },
GRID_COL,
true
); );
// Y-Axis Lines // Y-Axis Lines
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
GRID_COL,
SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH } SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH },
);
SHDebugDraw::PersistentLine
(
GRID_COL, GRID_COL,
true
);
SHDebugDraw::Persistent::Line
(
SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH } SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH },
GRID_COL,
true
); );
} }
} }
@ -319,25 +323,28 @@ namespace SHADE
const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL; const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL;
const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL; const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL;
// X // X
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
X_AXIS_COL,
SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f },
SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f } SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f },
X_AXIS_COL,
true
); );
// Y // Y
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
Y_AXIS_COL,
SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f }, SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f },
SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f } SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f },
Y_AXIS_COL,
true
); );
// Z // Z
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
Z_AXIS_COL,
SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH } SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH },
Z_AXIS_COL,
true
); );
} }
} }
@ -353,7 +360,7 @@ namespace SHADE
break; break;
case State::PLAY: case State::PLAY:
default: default:
SHDebugDraw::ClearPersistentDraws(); SHDebugDraw::Persistent::ClearDraws();
break; break;
} }
return eventData->handle; return eventData->handle;

View File

@ -25,9 +25,9 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* DrawRoutine */ /* DrawRoutine */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine() SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
: SHSystemRoutine("Debug Draw", true) : SHSystemRoutine("Debug Draw", true)
{ {
@ -39,7 +39,7 @@ namespace SHADE
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys) if (!gfxSys)
{ {
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system."); SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return; return;
} }
@ -49,284 +49,672 @@ namespace SHADE
// Get current frame index // Get current frame index
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex(); const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
/* Non-Persistent Buffer */ // Set up line batches
// Update the buffer for (auto& batch : system->lineBatches)
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->prepareBatch(batch, FRAME_IDX);
batch.Points.clear();
} }
// Reset for next frame // Set up mesh batches
system->points.clear(); for (auto& batch : system->meshBatches)
/* Persistent Buffer */
// Check if there are changes
if (system->persistentBuffersCleared[FRAME_IDX]
||
system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size())
{ {
// Update Buffer system->prepareBatch(batch, FRAME_IDX);
system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size(); for (auto& subBatch : batch.SubBatches)
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); subBatch.second.InstanceColors.clear();
} subBatch.second.InstanceTransforms.clear();
// Reset Flag
system->persistentBuffersCleared[FRAME_IDX] = false;
} }
} }
/*---------------------------------------------------------------------------------*/ // Set up persistent batches if it was changed
if (system->persistentBuffersUpdated[FRAME_IDX])
{
for (auto& batch : system->persistentLineBatches)
{
system->prepareBatch(batch, FRAME_IDX);
}
for (auto& batch : system->persistentMeshBatches)
{
system->prepareBatch(batch, FRAME_IDX);
}
system->persistentBuffersUpdated[FRAME_IDX] = false;
}
}
/*-----------------------------------------------------------------------------------*/
/* SHSystem overrides */ /* SHSystem overrides */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::Init() void SHDebugDrawSystem::Init()
{ {
gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
{
SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Create all batches
createLineBatches();
createMeshBatches();
// Register function for subpass // Register function for subpass
const auto* GFX_SYSTEM = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph(); auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex) subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{ {
// Get Current frame index const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex(); cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
// Don't draw if no points
if (numPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw"); cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); {
cmdBuffer->SetLineWidth(LineWidth); renderBatch(lineBatches[static_cast<int>(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); renderBatch(persistentLineBatches[static_cast<int>(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
} }
}); cmdBuffer->EndLabeledSegment();
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
// Don't draw if no points cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)");
if (numPersistentPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)"); renderBatch(meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); renderBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->SetLineWidth(LineWidth); renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX);
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); }
cmdBuffer->EndLabeledSegment(); cmdBuffer->EndLabeledSegment();
} }
cmdBuffer->EndLabeledSegment();
}); });
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
// Reset trackers subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
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 const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
( cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
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,
"Debug Draw Non-Persistent Vertex Buffer"
);
}
// - Persistent Draws
for (Handle<SHVkBuffer>& bufHandle : persistentVertexBuffers)
{ {
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)");
( {
BUFFER_SIZE, renderBatch(lineBatches[static_cast<int>(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX);
nullptr, renderBatch(persistentLineBatches[static_cast<int>(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX);
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Persistent Vertex Buffer"
);
} }
cmdBuffer->EndLabeledSegment();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)");
{
renderBatch(meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX);
renderBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX);
renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX);
renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX);
}
cmdBuffer->EndLabeledSegment();
}
cmdBuffer->EndLabeledSegment();
});
} }
void SHDebugDrawSystem::Exit() void SHDebugDrawSystem::Exit()
{ {
for (auto vertexBuffer : vertexBuffers) // Destroy buffers in the batches
{ destroyLineBatches();
if (vertexBuffer) destroyMeshBatches();
vertexBuffer.Free();
}
for (auto vertexBuffer : persistentVertexBuffers)
{
if (vertexBuffer)
vertexBuffer.Free();
}
} }
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Draw Functions */ /* Draw Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDrawSystem::DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested)
{ {
drawLine(points, color, startPt, endPt); // Insert into the batch
drawLine(getLineBatch(depthTested), start, end, color);
} }
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDrawSystem::DrawLineLoop(std::initializer_list<SHVec3> points, const SHColour& color, bool depthTested)
{ {
drawPoly(points, color, { pt1, pt2, pt3 }); DrawLineLoop(points.begin(), points.end(), color, depthTested);
} }
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDrawSystem::DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested)
{ {
drawPoly(points, color, { pt1, pt2, pt3, pt4 }); DrawLineLoop({ p1, p2, p3 }, color, depthTested);
} }
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDrawSystem::DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested)
{ {
drawPoly(points, color, pointList.begin(), pointList.end()); DrawLineLoop({ p1, p2, p3, p4 }, color, depthTested);
} }
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDrawSystem::DrawCircle(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{ {
drawCube(points, color, pos, size); drawCircle(getMeshBatch(false, depthTested), matrix, color);
} }
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDrawSystem::DrawWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{ {
drawSphere(points, color, pos, radius); drawWireCube(getMeshBatch(false, depthTested), matrix, color);
} }
/*---------------------------------------------------------------------------------*/ void SHDebugDrawSystem::DrawWireSphere(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawWireSphere(getMeshBatch(false, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawCube(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawCube(getMeshBatch(true, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawSphere(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawSphere(getMeshBatch(true, depthTested), matrix, color);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */ /* Persistent Draw Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDrawSystem::DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested)
{ {
drawLine(persistentPoints, color, startPt, endPt); // Insert into the batch
drawLine(getPersistentLineBatch(depthTested), start, end, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentLineLoop(std::initializer_list<SHVec3> points, const SHColour& color, bool depthTested)
{
DrawPersistentLineLoop(points.begin(), points.end(), color, depthTested);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDrawSystem::DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested)
{ {
drawPoly(persistentPoints, color, { pt1, pt2, pt3 }); DrawPersistentLineLoop({ p1, p2, p3 }, color, depthTested);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDrawSystem::DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested)
{ {
drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 }); DrawPersistentLineLoop({ p1, p2, p3, p4 }, color, depthTested);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDrawSystem::DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{ {
drawPoly(persistentPoints, color, pointList.begin(), pointList.end()); drawCircle(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDrawSystem::DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{ {
drawCube(persistentPoints, color, pos, size); drawWireCube(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDrawSystem::DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{ {
drawSphere(persistentPoints, color, pos, radius); drawWireSphere(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawCube(getPersistentMeshBatch(true, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawSphere(getPersistentMeshBatch(true, depthTested), matrix, color);
markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::ClearPersistentDraws() void SHDebugDrawSystem::ClearPersistentDraws()
{ {
persistentPoints.clear(); for (auto& batch : persistentLineBatches)
for (bool& cleared : persistentBuffersCleared) batch.Points.clear();
cleared = true; markPersistentDrawsDirty();
} }
void SHDebugDrawSystem::drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) /*-----------------------------------------------------------------------------------*/
/* Helper Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color)
{ {
if (storage.size() > MAX_POINTS) // Check if points exceeded max
if (batch.Points.size() >= MAX_POINTS)
{ {
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements."); SHLOG_WARNING("[SHDebugDrawSystem] Exceeded maximum size of drawable debug lines. Ignoring.");
return; return;
} }
storage.emplace_back(PointVertex{ startPt, color }); batch.Points.emplace_back(start, color);
storage.emplace_back(PointVertex{ endPt, color }); batch.Points.emplace_back(end, color);
} }
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDrawSystem::drawMesh(Handle<SHMesh> mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{ {
drawLineSet(storage, color, pointList.begin(), pointList.end()); // Create if doesn't exist
if (!batch.SubBatches.contains(mesh))
{
MeshBatch::MultiDrawSet set;
set.Mesh = mesh;
batch.SubBatches.emplace(mesh, std::move(set));
} }
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList) // Add to the batch
{ auto& subBatch = batch.SubBatches[mesh];
drawPoly(storage, color, pointList.begin(), pointList.end()); subBatch.InstanceTransforms.emplace_back(transformMatrix);
subBatch.InstanceColors.emplace_back(color);
} }
void SHDebugDrawSystem::drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDrawSystem::drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{ {
static const SHVec3 EXTENTS = SHVec3{ 0.5f, 0.5f, 0.5f }; drawMesh
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3{ pos - EXTENTS };
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3{ pos + EXTENTS };
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
drawLineSet
( (
storage, gfxSystem->GetMeshPrimitive(PrimitiveType::LineCube),
color, batch, transformMatrix, color
{
// Bottom Square
BOT_LEFT_BACK , BOT_RIGHT_BACK,
BOT_RIGHT_BACK , BOT_RIGHT_FRONT,
BOT_RIGHT_FRONT, BOT_LEFT_FRONT,
BOT_LEFT_FRONT , BOT_LEFT_BACK,
// Top Square
TOP_LEFT_BACK , TOP_RIGHT_BACK,
TOP_RIGHT_BACK , TOP_RIGHT_FRONT,
TOP_RIGHT_FRONT, TOP_LEFT_FRONT,
TOP_LEFT_FRONT , TOP_LEFT_BACK,
// Middle Lines
TOP_LEFT_BACK , BOT_LEFT_BACK,
TOP_RIGHT_BACK , BOT_RIGHT_BACK,
TOP_RIGHT_FRONT, BOT_RIGHT_FRONT,
TOP_LEFT_FRONT , BOT_LEFT_FRONT
}
); );
} }
void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDrawSystem::drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{ {
//if (spherePoints.empty()) drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::Sphere),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{ {
spherePoints.clear(); drawMesh
// Generate (
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere(); gfxSystem->GetMeshPrimitive(PrimitiveType::Cube),
for (const auto& idx : SPHERE.Indices) batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{ {
spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius + pos); drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::Sphere),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCircle),
batch, transformMatrix, color
);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */
/*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::LinesBatch& SHDebugDrawSystem::getLineBatch(bool depthTested)
{
return lineBatches[static_cast<int>(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)];
}
SHDebugDrawSystem::LinesBatch& SHDebugDrawSystem::getPersistentLineBatch(bool depthTested)
{
return persistentLineBatches[static_cast<int>(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)];
}
void SHDebugDrawSystem::createLineBatches()
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Line Batches
initBatch
(
getLineBatch(false),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineNoDepthTest),
"Debug Draw Non-Persistent Vertex Buffer"
);
initBatch
(
getLineBatch(true),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineDepthTested),
"Debug Draw Depth Tested Non-Persistent Vertex Buffer"
);
// Persistent Line Batches
initBatch
(
getPersistentLineBatch(false),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineNoDepthTest),
"Debug Draw Persistent Vertex Buffer"
);
initBatch
(
getPersistentLineBatch(true),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineDepthTested),
"Debug Draw Depth Tested Persistent Vertex Buffer"
);
}
void SHDebugDrawSystem::initBatch(LinesBatch& batch, Handle<SHVkPipeline> pipeline, const std::string& vertexBufferName)
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
batch.Pipeline = pipeline;
for (auto& vBuffer : batch.VertexBuffers)
{
vBuffer = gfxSys->GetDevice()->CreateBuffer
(
sizeof(PointVertex) * MAX_POINTS,
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,
vertexBufferName
);
} }
} }
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
void SHDebugDrawSystem::prepareBatch(LinesBatch& batch, uint32_t frameIndex)
{
// Parameter checks
if (frameIndex > batch.VertexBuffers.size())
{
SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping.");
return;
} }
// Fill data into the buffers
batch.NumPoints[frameIndex] = batch.Points.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * batch.Points.size();
if (DATA_SIZE > 0)
{
batch.VertexBuffers[frameIndex]->WriteToMemory(batch.Points.data(), DATA_SIZE, 0, 0);
}
}
void SHDebugDrawSystem::renderBatch(LinesBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
if (batch.NumPoints[frameIndex] > 0)
{
cmdBuffer->BindPipeline(batch.Pipeline);
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
}
}
void SHDebugDrawSystem::destroyBatch(LinesBatch& batch)
{
for (auto& vBuffer : batch.VertexBuffers)
{
if (vBuffer)
{
vBuffer.Free();
vBuffer = {};
}
}
}
void SHDebugDrawSystem::destroyLineBatches()
{
destroyBatch(getLineBatch(true));
destroyBatch(getLineBatch(false));
destroyBatch(getPersistentLineBatch(true));
destroyBatch(getPersistentLineBatch(false));
}
/*-----------------------------------------------------------------------------------*/
/* Helper Batch Functions - Meshes */
/*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::MeshBatch& SHDebugDrawSystem::getMeshBatch(bool filled, bool depthTested)
{
MeshRenderMode mode = {};
if (filled)
{
mode = depthTested ? MeshRenderMode::FilledDepthTested
: MeshRenderMode::FilledNoDepthTest;
}
else
{
mode = depthTested ? MeshRenderMode::WireDepthTested
: MeshRenderMode::WireNoDepthTest;
}
return meshBatches[static_cast<int>(mode)];
}
SHDebugDrawSystem::MeshBatch& SHDebugDrawSystem::getPersistentMeshBatch(bool filled, bool depthTested)
{
MeshRenderMode mode = {};
if (filled)
{
mode = depthTested ? MeshRenderMode::FilledDepthTested
: MeshRenderMode::FilledNoDepthTest;
}
else
{
mode = depthTested ? MeshRenderMode::WireDepthTested
: MeshRenderMode::WireNoDepthTest;
}
return persistentMeshBatches[static_cast<int>(mode)];
}
void SHDebugDrawSystem::createMeshBatches()
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Set up batches
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested)
);
// Set up persistent batches
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested)
);
}
void SHDebugDrawSystem::initBatch(MeshBatch& batch, Handle<SHVkPipeline> pipeline)
{
batch.Pipeline = pipeline;
}
void SHDebugDrawSystem::prepareBatch(MeshBatch& batch, uint32_t frameIndex)
{
// Parameter checks
if (frameIndex > batch.MDIBuffer.size())
{
SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping.");
return;
}
// Clear existing data
batch.InstanceTransforms.clear();
batch.InstanceColors.clear();
batch.MDIData.clear();
// Populate
for (auto& subBatch : batch.SubBatches)
{
auto& multiDrawSet = subBatch.second;
// Nothing to populate with
if (multiDrawSet.InstanceTransforms.empty())
continue;
// Populate batch data on CPU
batch.MDIData.emplace_back(vk::DrawIndexedIndirectCommand
{
.indexCount = multiDrawSet.Mesh->IndexCount,
.instanceCount = static_cast<uint32_t>(multiDrawSet.InstanceTransforms.size()),
.firstIndex = multiDrawSet.Mesh->FirstIndex,
.vertexOffset = multiDrawSet.Mesh->FirstVertex,
.firstInstance = static_cast<uint32_t>(batch.InstanceTransforms.size())
});
batch.InstanceTransforms.insert
(
batch.InstanceTransforms.end(),
multiDrawSet.InstanceTransforms.begin(),
multiDrawSet.InstanceTransforms.end()
);
batch.InstanceColors.insert
(
batch.InstanceColors.end(),
multiDrawSet.InstanceColors.begin(),
multiDrawSet.InstanceColors.end()
);
// Copy to GPU
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.MDIBuffer[frameIndex],
batch.MDIData.data(), static_cast<uint32_t>(batch.MDIData.size() * sizeof(vk::DrawIndexedIndirectCommand)),
vk::BufferUsageFlagBits::eIndirectBuffer,
"Debug Draw Mesh Batch MDI Buffer"
);
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.InstanceTransformBuffer[frameIndex],
batch.InstanceTransforms.data(), static_cast<uint32_t>(batch.InstanceTransforms.size() * sizeof(SHMatrix)),
vk::BufferUsageFlagBits::eVertexBuffer,
"Debug Draw Mesh Batch Instance Transform Buffer"
);
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.InstanceColorBuffer[frameIndex],
batch.InstanceColors.data(), static_cast<uint32_t>(batch.InstanceColors.size() * sizeof(SHVec4)),
vk::BufferUsageFlagBits::eVertexBuffer,
"Debug Draw Mesh Batch Instance Color Buffer"
);
}
}
void SHDebugDrawSystem::renderBatch(MeshBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
static constexpr uint32_t TRANSFORM_BIND_PT = 1;
static constexpr uint32_t COLOR_BIND_PT = 2;
// Nothing to draw
if (batch.MDIData.empty())
return;
// Bind Pipeline
cmdBuffer->BindPipeline(batch.Pipeline);
// Bind meshes
cmdBuffer->BindVertexBuffer(0, gfxSystem->GetMeshLibrary().GetVertexPositionsBuffer(), 0);
cmdBuffer->BindIndexBuffer(gfxSystem->GetMeshLibrary().GetIndexBuffer(), 0);
// Bind instance attributes
cmdBuffer->BindVertexBuffer(TRANSFORM_BIND_PT, batch.InstanceTransformBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(COLOR_BIND_PT, batch.InstanceColorBuffer[frameIndex], 0);
// Execute draw
cmdBuffer->DrawMultiIndirect(batch.MDIBuffer[frameIndex], static_cast<uint32_t>(batch.MDIData.size()));
}
void SHDebugDrawSystem::destroyBatch(MeshBatch& batch)
{
for (auto& buffer : batch.InstanceColorBuffer)
{
if (buffer)
{
buffer.Free();
buffer = {};
}
}
for (auto& buffer : batch.InstanceTransformBuffer)
{
if (buffer)
{
buffer.Free();
buffer = {};
}
}
for (auto& buffer : batch.MDIBuffer)
{
if (buffer)
{
buffer.Free();
buffer = {};
}
}
}
void SHDebugDrawSystem::destroyMeshBatches()
{
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)]);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::markPersistentDrawsDirty()
{
for (bool& dirty : persistentBuffersUpdated)
dirty = true;
}
} }

View File

@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Math/SHMatrix.h"
#include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
@ -30,7 +31,10 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Forward Declarations */ /* Forward Declarations */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SHGraphicsSystem;
class SHVkBuffer; class SHVkBuffer;
class SHMesh;
class SHVkPipeline;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -69,134 +73,201 @@ namespace SHADE
/* Draw Functions */ /* Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Renders a line between two points in world space. /// Draws a line between two specified points.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param> /// <param name="start">Starting point.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="end">Ending point.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="color">Colour to draw with.</param>
void DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space. /// Draws a set of points as a connected set of lines that loops back.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param> /// <param name="points">List of points to draw the line across.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="color">Colour to draw with.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt3">Third point of the triangle.</param> void DrawLineLoop(std::initializer_list<SHVec3> points, const SHColour& color = SHColour::WHITE, bool depthTested = false);
void DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space. /// Draws a set of points as a connected set of lines that loops back.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param> /// <typeparam name="IterType">
/// <param name="pt1">First point of the triangle.</param> /// Type of iterator of the container that contains the points.
/// <param name="pt2">Second point of the quadrilateral.</param> /// </typeparam>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pointListBegin">Starting iterator to the line points.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pointListEnd">One past end iterator to the line points.</param>
void DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour to draw with.</param>
/// <summary> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </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> template<typename IterType>
void DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void DrawLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space. /// Draws a triangle from the specified set of points.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the cube wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered cube.</param> /// <param name="p3">3rd point.</param>
void DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space. /// Draws a quad from the specified set of points.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="p3">3rd point.</param>
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="p4">4th point.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a 2-dimensional circle.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */ /* Persistent Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Renders a line between two points in world space that will persist until /// Draws a persistent line between two specified points.
/// ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param> /// <param name="start">Starting point.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="end">Ending point.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="color">Colour to draw with.</param>
void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space that will persist /// Draws a persistent set of points as a connected set of lines that loops back.
/// until ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param> /// <param name="points">List of points to draw the line across.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="color">Colour to draw with.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt3">Third point of the triangle.</param> void DrawPersistentLineLoop(std::initializer_list<SHVec3> points, const SHColour& color = SHColour::WHITE, bool depthTested = false);
void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space that will persist /// Draws a persistent set of points as a connected set of lines that loops back.
/// until ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param> /// <typeparam name="IterType">
/// <param name="pt1">First point of the triangle.</param> /// Type of iterator of the container that contains the points.
/// <param name="pt2">Second point of the quadrilateral.</param> /// </typeparam>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pointListBegin">Starting iterator to the line points.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pointListEnd">One past end iterator to the line points.</param>
void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour to draw with.</param>
/// <summary> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called. These lines are depth
/// tested.
/// </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. These lines are depth
/// tested.
/// </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> template<typename IterType>
void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space /// Draws a persistent triangle from the specified set of points.
/// that will persist until ClearPersistentDraws() is called. These lines are depth /// This will remain drawn until ClearPersistentDraws() is called.
/// tested.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the cube wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered cube.</param> /// <param name="p3">3rd point.</param>
void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space /// Draws a persistent quad from the specified set of points.
/// that will persist until ClearPersistentDraws() is called. These lines are depth /// This will remain drawn until ClearPersistentDraws() is called.
/// tested.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="p3">3rd point.</param>
void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="p4">4th point.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent 2-dimensional circle.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a persistent cube.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a persistent sphere.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent filled cube.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent filled sphere.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Clears any persistent drawn debug primitives. /// Clears any persistent drawn debug primitives.
/// </summary> /// </summary>
@ -206,47 +277,144 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/// <summary>
/// Defines the rendering mode for debug lines.
/// </summary>
enum class LineRenderMode : uint32_t
{
NoDepthTest,
DepthTested,
Count
};
/// <summary>
/// Defines the rendering mode for debug meshes.
/// </summary>
enum class MeshRenderMode : uint32_t
{
FilledNoDepthTest,
FilledDepthTested,
WireNoDepthTest,
WireDepthTested,
Count
};
/// <summary>
/// Defines a coloured Vertex
/// </summary>
struct SH_API PointVertex struct SH_API PointVertex
{ {
SHVec4 Position; SHVec4 Position;
SHVec4 Color; SHVec4 Color;
}; };
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>; struct Batch
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>; {
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>; /*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
Handle<SHVkPipeline> Pipeline;
};
struct LinesBatch : public Batch
{
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
// CPU Buffers
std::vector<PointVertex> Points;
// GPU Buffers
TripleBuffer VertexBuffers;
TripleUInt NumPoints;
};
struct MeshBatch : public Batch
{
/*-------------------------------------------------------------------------------*/
/* Type Definitions */
/*-------------------------------------------------------------------------------*/
struct MultiDrawSet
{
Handle<SHMesh> Mesh;
std::vector<SHMatrix> InstanceTransforms;
std::vector<SHVec4> InstanceColors;
};
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
// CPU Buffers
std::unordered_map<Handle<SHMesh>, MultiDrawSet> SubBatches;
std::vector<SHMatrix> InstanceTransforms;
std::vector<SHVec4> InstanceColors;
std::vector<vk::DrawIndexedIndirectCommand> MDIData;
// GPU Buffers
TripleBuffer MDIBuffer;
TripleBuffer InstanceTransformBuffer;
TripleBuffer InstanceColorBuffer;
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constants */ /* Constants */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static constexpr uint32_t MAX_POINTS = 100'000; static constexpr uint32_t MAX_POINTS = 100'000;
static constexpr size_t LINE_MODE_COUNT = static_cast<size_t>(LineRenderMode::Count);
static constexpr size_t MESH_MODE_COUNT = static_cast<size_t>(MeshRenderMode::Count);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// CPU Buffers // References
std::vector<PointVertex> points; SHGraphicsSystem* gfxSystem = nullptr;
std::vector<PointVertex> persistentPoints; // Batches
// GPU Buffers std::array<LinesBatch, LINE_MODE_COUNT> lineBatches;
TripleBuffer vertexBuffers; std::array<LinesBatch, LINE_MODE_COUNT> persistentLineBatches;
TripleUInt numPoints; std::array<MeshBatch , MESH_MODE_COUNT> meshBatches;
TripleBuffer persistentVertexBuffers; std::array<MeshBatch , MESH_MODE_COUNT> persistentMeshBatches;
TripleUInt numPersistentPoints; // Tracking
TripleBool persistentBuffersCleared; TripleBool persistentBuffersUpdated = { true, true, true };
// Cached Points for polygon drawing
std::vector<SHVec3> spherePoints;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Draw Functions */ /* Helper Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); void drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color);
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
template<typename IterType> template<typename IterType>
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void drawLineLoop(LinesBatch& batch, IterType pointListBegin, IterType pointListEnd, const SHColour& color);
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList); void drawMesh(Handle<SHMesh> mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
template<typename IterType> void drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size); void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius); void drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
/*---------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */
/*---------------------------------------------------------------------------------*/
LinesBatch& getLineBatch(bool depthTested);
LinesBatch& getPersistentLineBatch(bool depthTested);
void createLineBatches();
void initBatch(LinesBatch& batch, Handle<SHVkPipeline> pipeline, const std::string& vertexBufferName);
void prepareBatch(LinesBatch& batch, uint32_t frameIndex);
void renderBatch(LinesBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
void destroyBatch(LinesBatch& batch);
void destroyLineBatches();
/*---------------------------------------------------------------------------------*/
/* Helper Batch Functions - Meshes */
/*---------------------------------------------------------------------------------*/
MeshBatch& getMeshBatch(bool filled, bool depthTested);
MeshBatch& getPersistentMeshBatch(bool filled, bool depthTested);
void createMeshBatches();
void initBatch(MeshBatch& batch, Handle<SHVkPipeline> pipeline);
void prepareBatch(MeshBatch& batch, uint32_t frameIndex);
void renderBatch(MeshBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
void destroyBatch(MeshBatch& batch);;
void destroyMeshBatches();
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
void markPersistentDrawsDirty();
}; };
} }

View File

@ -19,71 +19,42 @@ namespace SHADE
/* Draw Functions */ /* Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
template<typename IterType> template<typename IterType>
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd) void SHDebugDrawSystem::DrawLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color, bool depthTested)
{ {
drawPoly(points, color, pointListBegin, pointListEnd); // Get Batch
drawLineLoop(getLineBatch(depthTested), pointListBegin, pointListEnd, color);
}
template<typename IterType>
void SHADE::SHDebugDrawSystem::DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color , bool depthTested)
{
// Get Batch
drawLineLoop(getPersistentLineBatch(depthTested), pointListBegin, pointListEnd, color);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Draw Functions */ /* Helper Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
template<typename IterType> template<typename IterType>
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd) void SHDebugDrawSystem::drawLineLoop(LinesBatch& batch, IterType pointListBegin, IterType pointListEnd, const SHColour& color)
{ {
// Ensure dereferenced type is SHVec3 // Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3."); static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawLineLoop must be SHVec3.");
// Check if points exceeded max
if (storage.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon // Invalid polygon
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
if (POINTS_COUNT < 2) if (POINTS_COUNT < 2)
{ {
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly()."); SHLOG_WARNING("[SHDebugDrawSystem] Insufficient points provided to drawLineLoop().");
return;
}
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
{
storage.emplace_back(PointVertex{ *pointIter, color });
}
}
template<typename IterType>
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
{
// Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
// Check if points exceeded max
if (storage.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon
if (POINTS_COUNT < 2)
{
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly().");
return; return;
} }
// Trace the polygon // Trace the polygon
for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter) for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter)
{ {
storage.emplace_back(PointVertex{ *(pointIter - 1), color }); drawLine(batch, *(pointIter - 1), *pointIter, color);
storage.emplace_back(PointVertex{ *pointIter , color });
} }
// Close the line loop // Close the line loop
storage.emplace_back(PointVertex{ *(pointListEnd - 1), color }); drawLine(batch, *(pointListEnd - 1), *pointListBegin, color);
storage.emplace_back(PointVertex{ *pointListBegin , color });
} }
} }

View File

@ -124,20 +124,12 @@ namespace SHADE
SHFreetypeInstance::Init(); SHFreetypeInstance::Init();
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_FS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG); static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG); static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
static constexpr AssetID VS_DEBUG_MESH = 42127043; debugMeshVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG_MESH);
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE); static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO); static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR); static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
@ -335,14 +327,31 @@ namespace SHADE
screenRenderer->SetCamera(screenCamera); screenRenderer->SetCamera(screenCamera);
screenRenderer->SetCameraDirector(worldCameraDirector); screenRenderer->SetCameraDirector(worldCameraDirector);
// Create debug draw pipeline // Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw");
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, false, false);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test");
debugDrawLineMeshPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawLineMeshPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Line Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawLineMeshPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Line Mesh");
debugDrawLineMeshDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, false, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawLineMeshDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Line Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawLineMeshDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Line Mesh with Depth Test");
debugDrawWireMeshPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawWireMeshPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Wire Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawWireMeshPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Wire Mesh");
debugDrawWireMeshDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawWireMeshDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Wire Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawWireMeshDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Wire Mesh with Depth Test");
debugDrawFilledPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, true, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawFilledPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Filled Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawFilledPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Filled Mesh");
debugDrawFilledDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, true, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawFilledDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Filled Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawFilledDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Filled Mesh with Depth Test");
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -405,6 +414,8 @@ namespace SHADE
// Create default meshes // Create default meshes
primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary); primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary); primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary);
BuildMeshBuffers(); BuildMeshBuffers();
// Create default materials // Create default materials
@ -829,6 +840,8 @@ namespace SHADE
{ {
case PrimitiveType::Cube: case PrimitiveType::Cube:
case PrimitiveType::Sphere: case PrimitiveType::Sphere:
case PrimitiveType::LineCube:
case PrimitiveType::LineCircle:
return primitiveMeshes[static_cast<int>(type)]; return primitiveMeshes[static_cast<int>(type)];
default: default:
return {}; return {};
@ -1083,34 +1096,68 @@ namespace SHADE
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data()); return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
} }
SHADE::SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
{
switch (type)
{
case DebugDrawPipelineType::LineNoDepthTest: return debugDrawPipeline;
case DebugDrawPipelineType::LineDepthTested: return debugDrawDepthPipeline;
case DebugDrawPipelineType::LineMeshNoDepthTest: return debugDrawLineMeshPipeline;
case DebugDrawPipelineType::LineMeshDepthTested: return debugDrawLineMeshDepthPipeline;
case DebugDrawPipelineType::WireMeshNoDepthTest: return debugDrawWireMeshPipeline;
case DebugDrawPipelineType::WireMeshDepthTested: return debugDrawWireMeshDepthPipeline;
case DebugDrawPipelineType::FilledMeshNoDepthTest: return debugDrawFilledPipeline;
case DebugDrawPipelineType::FilledMeshDepthTested: return debugDrawFilledDepthPipeline;
}
SHLOG_WARNING("[SHGraphicsSystem] Attempted to retrieve an invalid Debug Draw Pipeline. Default Debug Draw Pipeline returned.");
return debugDrawPipeline;
}
SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept
{ {
return fontLibrary; return fontLibrary;
} }
Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass) Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass, bool filled, bool triMesh, bool instanced)
{ {
auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout> auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout>
( (
device, SHPipelineLayoutParams device, SHPipelineLayoutParams
{ {
.shaderModules = { debugVertShader, debugFragShader }, .shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader },
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
} }
); );
auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass); auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass);
pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
{ {
.polygonMode = vk::PolygonMode::eLine, .polygonMode = filled ? vk::PolygonMode::eFill : vk::PolygonMode::eLine,
.cull_mode = vk::CullModeFlagBits::eNone .cull_mode = filled ? vk::CullModeFlagBits::eBack : vk::CullModeFlagBits::eNone
}); });
pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
{ {
.topology = vk::PrimitiveTopology::eLineList .topology = triMesh ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eLineList
}); });
SHVertexInputState debugDrawVertexInputState; SHVertexInputState debugDrawVertexInputState;
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); if (instanced)
{
debugDrawVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // 0: Vertex World Space Position
debugDrawVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // 1: Instance Transform Matrix (4 Slots)
debugDrawVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // 5: Instance Color
}
else
{
debugDrawVertexInputState.AddBinding
(
false, true,
{
SHVertexAttribute(SHAttribFormat::FLOAT_4D), // Vertex World Space Position
SHVertexAttribute(SHAttribFormat::FLOAT_4D) // Vertex Color
}
);
}
pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState); pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
SHColorBlendState colorBlendState{}; SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE; colorBlendState.logic_op_enable = VK_FALSE;

View File

@ -70,9 +70,23 @@ namespace SHADE
enum class PrimitiveType enum class PrimitiveType
{ {
Cube, Cube,
Sphere Sphere,
LineCube,
LineCircle
}; };
static constexpr int MAX_PRIMITIVE_TYPES = 2; static constexpr int MAX_PRIMITIVE_TYPES = 4;
enum class DebugDrawPipelineType
{
LineNoDepthTest,
LineDepthTested,
LineMeshNoDepthTest,
LineMeshDepthTested,
WireMeshNoDepthTest,
WireMeshDepthTested,
FilledMeshNoDepthTest,
FilledMeshDepthTested
};
static constexpr int MAX_DEBUG_DRAW_PIPELINE_TYPES = 8;
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
@ -371,10 +385,10 @@ namespace SHADE
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept; Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; } Handle<SHVkPipeline> GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept;
Handle<SHVkPipeline> GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; }
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); } uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
SHFontLibrary const& GetFontLibrary (void) const noexcept; SHFontLibrary const& GetFontLibrary (void) const noexcept;
const SHMeshLibrary& GetMeshLibrary() const noexcept { return meshLibrary; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getters */ /* Getters */
@ -439,6 +453,7 @@ namespace SHADE
Handle<SHVkShaderModule> defaultFragShader; Handle<SHVkShaderModule> defaultFragShader;
Handle<SHVkShaderModule> debugVertShader; Handle<SHVkShaderModule> debugVertShader;
Handle<SHVkShaderModule> debugFragShader; Handle<SHVkShaderModule> debugFragShader;
Handle<SHVkShaderModule> debugMeshVertShader;
Handle<SHVkShaderModule> deferredCompositeShader; Handle<SHVkShaderModule> deferredCompositeShader;
Handle<SHVkShaderModule> ssaoShader; Handle<SHVkShaderModule> ssaoShader;
Handle<SHVkShaderModule> ssaoBlurShader; Handle<SHVkShaderModule> ssaoBlurShader;
@ -454,6 +469,12 @@ namespace SHADE
Handle<SHMaterial> defaultMaterial; Handle<SHMaterial> defaultMaterial;
Handle<SHVkPipeline> debugDrawPipeline; Handle<SHVkPipeline> debugDrawPipeline;
Handle<SHVkPipeline> debugDrawDepthPipeline; Handle<SHVkPipeline> debugDrawDepthPipeline;
Handle<SHVkPipeline> debugDrawLineMeshPipeline;
Handle<SHVkPipeline> debugDrawLineMeshDepthPipeline;
Handle<SHVkPipeline> debugDrawWireMeshPipeline;
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
Handle<SHVkPipeline> debugDrawFilledPipeline;
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
// Built-In Textures // Built-In Textures
Handle<SHTexture> defaultTexture; Handle<SHTexture> defaultTexture;
@ -482,6 +503,6 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass); Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass, bool filled, bool triMesh, bool instanced);
}; };
} }

View File

@ -10,9 +10,13 @@ Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Header
#include "SHpch.h" #include "SHpch.h"
// Primary Includes
#include "SHPrimitiveGenerator.h" #include "SHPrimitiveGenerator.h"
// STL Includes
#include <numbers>
// Project Includes
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
@ -23,6 +27,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::cubeMesh; SHMeshData SHPrimitiveGenerator::cubeMesh;
SHMeshData SHPrimitiveGenerator::sphereMesh; SHMeshData SHPrimitiveGenerator::sphereMesh;
SHMeshData SHPrimitiveGenerator::lineCubeMesh;
SHMeshData SHPrimitiveGenerator::lineCircleMesh;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Primitive Generation Functions */ /* Primitive Generation Functions */
@ -207,14 +213,14 @@ namespace SHADE
return addMeshDataTo(cubeMesh, meshLibrary); return addMeshDataTo(cubeMesh, meshLibrary);
} }
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept Handle<SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
{ {
if (cubeMesh.VertexPositions.empty()) if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube(); cubeMesh = Cube();
return addMeshDataTo(cubeMesh, gfxSystem); return addMeshDataTo(cubeMesh, gfxSystem);
} }
SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept SHMeshData SHPrimitiveGenerator::Sphere() noexcept
{ {
SHMeshData meshData; SHMeshData meshData;
@ -265,7 +271,7 @@ namespace SHADE
return meshData; return meshData;
} }
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept Handle<SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept
{ {
if (sphereMesh.VertexPositions.empty()) if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere(); sphereMesh = Sphere();
@ -273,7 +279,7 @@ namespace SHADE
return addMeshDataTo(sphereMesh, meshLibrary); return addMeshDataTo(sphereMesh, meshLibrary);
} }
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept Handle<SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept
{ {
if (sphereMesh.VertexPositions.empty()) if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere(); sphereMesh = Sphere();
@ -281,6 +287,111 @@ namespace SHADE
return addMeshDataTo(sphereMesh, gfxSystem); return addMeshDataTo(sphereMesh, gfxSystem);
} }
SHMeshData SHPrimitiveGenerator::LineCube() noexcept
{
SHMeshData mesh;
mesh.VertexPositions =
{
// Front
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
// Back
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, -0.5f)
};
mesh.VertexNormals.resize(mesh.VertexPositions.size());
mesh.VertexTangents.resize(mesh.VertexPositions.size());
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
mesh.Indices =
{
// Front
0, 1,
1, 2,
2, 3,
3, 0,
// Connectors
0, 4,
1, 5,
2, 6,
3, 7,
// Back
4, 5,
5, 6,
6, 7,
7, 4,
};
return mesh;
}
Handle<SHMesh> SHPrimitiveGenerator::LineCube(SHMeshLibrary& meshLibrary) noexcept
{
if (lineCubeMesh.VertexPositions.empty())
lineCubeMesh = LineCube();
return addMeshDataTo(lineCubeMesh, meshLibrary);
}
Handle<SHMesh> SHPrimitiveGenerator::LineCube(SHGraphicsSystem& gfxSystem) noexcept
{
if (lineCubeMesh.VertexPositions.empty())
lineCubeMesh = LineCube();
return addMeshDataTo(lineCubeMesh, gfxSystem);
}
SHMeshData SHPrimitiveGenerator::LineCircle() noexcept
{
SHMeshData mesh;
// Generate points of the circle
static constexpr int SPLITS = 36;
static constexpr float ANGLE_INCREMENTS = (std::numbers::pi_v<float> * 2.0f) / static_cast<float>(SPLITS);
for (int i = 0; i < SPLITS; ++i)
{
const float ANGLE = ANGLE_INCREMENTS * i;
mesh.VertexPositions.emplace_back(cos(ANGLE) * 0.5f, sin(ANGLE) * 0.5f, 0.0f);
}
// Generate lines of the circle
for (int i = 1; i < SPLITS; ++i)
{
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
}
// Last line to complete the circle
mesh.Indices.emplace_back(static_cast<uint32_t>(SPLITS - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(0));
mesh.VertexNormals.resize(mesh.VertexPositions.size());
mesh.VertexTangents.resize(mesh.VertexPositions.size());
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
return mesh;
}
Handle<SHMesh> SHPrimitiveGenerator::LineCircle(SHMeshLibrary& meshLibrary) noexcept
{
if (lineCircleMesh.VertexPositions.empty())
lineCircleMesh = LineCircle();
return addMeshDataTo(lineCircleMesh, meshLibrary);
}
Handle<SHMesh> SHPrimitiveGenerator::LineCircle(SHGraphicsSystem& gfxSystem) noexcept
{
if (lineCircleMesh.VertexPositions.empty())
lineCircleMesh = LineCircle();
return addMeshDataTo(lineCircleMesh, gfxSystem);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -116,6 +116,84 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept; [[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cube that is comprised only of lines with no diagonal lines and store
the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the line cube.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData LineCube() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line cube and constructs a SHMesh using the SHGraphicsSystem provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a line cube mesh in.
\return
SHMesh object that points to the generated line cube mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCube(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line cube and constructs a SHMesh using the SHGraphicsSystem provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a line cube mesh in.
\return
SHMesh object that points to the generated line cube mesh in the
SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCube(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a circle that is comprised only of lines with no diagonal lines and
store the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the line circle.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData LineCircle() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line circle and constructs a SHMesh using the SHGraphicsSystem
provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCircle(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line circle and constructs a SHMesh using the SHGraphicsSystem
provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the
SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCircle(SHGraphicsSystem& gfxSystem) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -129,5 +207,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static SHMeshData cubeMesh; static SHMeshData cubeMesh;
static SHMeshData sphereMesh; static SHMeshData sphereMesh;
static SHMeshData lineCubeMesh;
static SHMeshData lineCircleMesh;
}; };
} }

View File

@ -195,7 +195,7 @@ namespace SHADE
const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray(); const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray();
for (int i = 0; i < NUM_TRIS; ++i) for (int i = 0; i < NUM_TRIS; ++i)
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3); debugRenderer->DrawTri(TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3, SHColour::RED);
} }
#else #else
@ -207,7 +207,7 @@ namespace SHADE
const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray(); const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray();
for (int i = 0; i < NUM_TRIS; ++i) for (int i = 0; i < NUM_TRIS; ++i)
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3); debugRenderer->DrawTri(TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3, SHColour::RED);
#endif #endif
} }
@ -225,7 +225,7 @@ namespace SHADE
const auto& LINE_ARRAY = rp3dRenderer->getLinesArray(); const auto& LINE_ARRAY = rp3dRenderer->getLinesArray();
for (int i = 0; i < NUM_LINES; ++i) for (int i = 0; i < NUM_LINES; ++i)
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2); debugRenderer->DrawLine(LINE_ARRAY[i].point1, LINE_ARRAY[i].point2, SHColour::RED);
} }
#else #else
@ -237,7 +237,7 @@ namespace SHADE
const auto& LINE_ARRAY = rp3dRenderer->getLinesArray(); const auto& LINE_ARRAY = rp3dRenderer->getLinesArray();
for (int i = 0; i < NUM_LINES; ++i) for (int i = 0; i < NUM_LINES; ++i)
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2); debugRenderer->DrawLine(LINE_ARRAY[i].point1, LINE_ARRAY[i].point2, SHColour::RED);
#endif #endif
} }
@ -261,7 +261,7 @@ namespace SHADE
const float RENDER_DIST = raycastResult.distance == std::numeric_limits<float>::infinity() ? SHRay::MAX_RAYCAST_DIST : raycastResult.distance; const float RENDER_DIST = raycastResult.distance == std::numeric_limits<float>::infinity() ? SHRay::MAX_RAYCAST_DIST : raycastResult.distance;
const SHVec3 END_POS = ray.position + (ray.direction * RENDER_DIST); const SHVec3 END_POS = ray.position + (ray.direction * RENDER_DIST);
debugRenderer->DrawLine(RAY_COLOUR, ray.position, END_POS); debugRenderer->DrawLine(ray.position, END_POS, RAY_COLOUR);
} }
} }
@ -306,16 +306,16 @@ namespace SHADE
transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS); transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS);
// Draw 4 line to connect the quads // Draw 4 line to connect the quads
debugRenderer->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); debugRenderer->DrawLine(transformedVertices[IDX1], transformedVertices[IDX2], COLLIDER_COLOUR);
} }
// A, B, C, D // A, B, C, D
std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] }; std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] };
debugRenderer->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); debugRenderer->DrawLineLoop(backQuad.begin(), backQuad.end(), COLLIDER_COLOUR);
// E, F, G, H // E, F, G, H
std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] }; std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] };
debugRenderer->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); debugRenderer->DrawLineLoop(frontQuad.begin(), frontQuad.end(), COLLIDER_COLOUR);
} }
void SHPhysicsDebugDrawSystem::debugDrawSphere(SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept void SHPhysicsDebugDrawSystem::debugDrawSphere(SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept
@ -328,7 +328,8 @@ namespace SHADE
const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset());
const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition()); const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition());
debugRenderer->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius()); /* #KWFix */
//debugRenderer->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius());
} }
} // namespace SHADE } // namespace SHADE

View File

@ -15,6 +15,8 @@ of DigiPen Institute of Technology is prohibited.
#include "SHDebugDraw.h" #include "SHDebugDraw.h"
// Project Includes // Project Includes
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Math/SHQuaternion.h"
#include "Math/SHQuaternion.h"
#include "Math/SHColour.h" #include "Math/SHColour.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
@ -41,69 +43,181 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Draw Functions */ /* Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDraw::Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawLine(color, startPt, endPt); dbgDrawSys->DrawLine(startPt, endPt, color, depthTested);
} }
void SHDebugDraw::Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDraw::Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawTri(color, pt1, pt2, pt3); dbgDrawSys->DrawTri(pt1, pt2, pt3, color, depthTested);
} }
void SHDebugDraw::Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDraw::Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawQuad(color, pt1, pt2, pt3, pt4); dbgDrawSys->DrawQuad(pt1, pt2, pt3, pt4, color, depthTested);
} }
void SHDebugDraw::Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDraw::Circle(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPoly(color, pointList); dbgDrawSys->DrawCircle(mat, color, depthTested);
} }
void SHDebugDraw::Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDraw::LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawCube(color, pos, size); dbgDrawSys->DrawLineLoop(pointList, color, depthTested);
} }
void SHDebugDraw::Sphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDraw::Cube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawSphere(color, pos, radius); dbgDrawSys->DrawCube(mat, color, depthTested);
} }
void SHDebugDraw::PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDraw::Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentLine(color, startPt, endPt); dbgDrawSys->DrawCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
} }
void SHDebugDraw::PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDraw::Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentTri(color, pt1, pt2, pt3); dbgDrawSys->DrawCube(SHMatrix::Transform(center, orientation, scale), color, depthTested);
} }
void SHDebugDraw::PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDraw::Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentQuad(color, pt1, pt2, pt3, pt4); dbgDrawSys->DrawCube(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
} }
void SHDebugDraw::PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDraw::Sphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentPoly(color, pointList); dbgDrawSys->DrawSphere(mat, color, depthTested);
} }
void SHDebugDraw::PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDraw::Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentCube(color, pos, size); dbgDrawSys->DrawSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
} }
void SHDebugDraw::PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDraw::Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentSphere(color, pos, radius); dbgDrawSys->DrawSphere(SHMatrix::Transform(center, orientation, scale), color, depthTested);
} }
void SHDebugDraw::ClearPersistentDraws() void SHDebugDraw::Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawSphere(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::WireCube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireCube(mat, color, depthTested);
}
void SHDebugDraw::WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::WireSphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireSphere(mat, color, depthTested);
}
void SHDebugDraw::WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Persistent::Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentLine(startPt, endPt, color, depthTested);
}
void SHDebugDraw::Persistent::Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentTri(pt1, pt2, pt3, color, depthTested);
}
void SHDebugDraw::Persistent::Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentQuad(pt1, pt2, pt3, pt4, color, depthTested);
}
void SHDebugDraw::Persistent::Circle(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCircle(mat, color, depthTested);
}
void SHDebugDraw::Persistent::LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentLineLoop(pointList, color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(mat, color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, orientation, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(mat, color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, orientation, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::Persistent::WireCube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireCube(mat, color, depthTested);
}
void SHDebugDraw::Persistent::WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::WireSphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireSphere(mat, color, depthTested);
}
void SHDebugDraw::Persistent::WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::ClearDraws()
{ {
dbgDrawSys->ClearPersistentDraws(); dbgDrawSys->ClearPersistentDraws();
} }
} }

View File

@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "SH_API.h" #include "SH_API.h"
#include "Math/SHColour.h"
namespace SHADE namespace SHADE
{ {
@ -22,7 +23,8 @@ namespace SHADE
class SHDebugDrawSystem; class SHDebugDrawSystem;
class SHVec4; class SHVec4;
class SHVec3; class SHVec3;
class SHColour; class SHQuaternion;
class SHMatrix;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -50,105 +52,324 @@ namespace SHADE
/// <summary> /// <summary>
/// Renders a line between two points in world space. /// Renders a line between two points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="endPt">Second point of the line.</param>
static void Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="color">Colour of the line.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space. /// Renders a triangle indicated by three points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param> /// <param name="pt3">Third point of the triangle.</param>
static void Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); /// <param name="color">Colour of the triangle.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space. /// Renders a quadrilateral indicated by four points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param> /// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pt4">Third point of the quadrilateral.</param>
static void Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour of the quadrilateral.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a 2-dimensional circle in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a polygon indicated by the specified set of points in world space. /// Renders a polygon indicated by the specified set of points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param> /// <param name="pointList">List of points for the polygon.</param>
static void Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList); /// <param name="color">Colour of the polygon.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space. /// Draws a filled cube in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="matrix">
/// <param name="pos">Position where the cube wil be centered at.</param> /// Matrix transformation that defines how the cube should be drawn.
/// <param name="size">Size of the rendered cube.</param> /// </param>
static void Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space. /// Draws a filled cube in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="center">Center of the Cube.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="scale">Size of the Cube.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="color">Colour to draw with.</param>
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="orientation">Orientation of the cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="eulerAngles">Euler angle rotation of the cube in radians.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="orientation">Orientation of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="eulerAngles">Euler angle rotation of the sphere in radians.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */ /* Persistent Draw Function Class "Folder" */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
struct SH_API Persistent
{
/*-------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Renders a line between two points in world space that will persist until /// Renders a line between two points in world space.
/// ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second 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); /// <param name="color">Colour of the line.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space that will persist /// Renders a triangle indicated by three points in world space.
/// until ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third 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); /// <param name="color">Colour of the triangle.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space that will persist /// Renders a quadrilateral indicated by four points in world space.
/// until ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param> /// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">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); /// <param name="color">Colour of the quadrilateral.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a polygon indicated by the specified set of points in world space that /// Draws a 2-dimensional circle in world space.
/// will persist until ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param> /// <param name="pointList">List of points for the polygon.</param>
static void PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList); /// <param name="color">Colour of the polygon.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space /// Draws a filled cube in world space.
/// that will persist until ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="matrix">
/// <param name="pos">Position where the cube wil be centered at.</param> /// Matrix transformation that defines how the cube should be drawn.
/// <param name="size">Size of the rendered cube.</param> /// </param>
static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space /// Draws a filled cube in world space.
/// that will persist until ClearPersistentDraws() is called. /// This will remain drawn until ClearDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="center">Center of the Cube.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="scale">Size of the Cube.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="color">Colour to draw with.</param>
static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="orientation">Orientation of the cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="eulerAngles">Euler angle rotation of the cube in radians.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="orientation">Orientation of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="eulerAngles">Euler angle rotation of the sphere in radians.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Clears any persistent drawn debug primitives. /// Clears any persistent drawn debug primitives.
/// </summary> /// </summary>
static void ClearPersistentDraws(); static void ClearDraws();
};
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -44,7 +44,27 @@ namespace SHADE
void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color) void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color)
{ {
SHDebugDraw::Line(Convert::ToNative(color), Convert::ToNative(from), Convert::ToNative(to)); SHDebugDraw::Line(Convert::ToNative(from), Convert::ToNative(to), Convert::ToNative(color));
}
void Gizmos::DrawCube(Vector3 center, Vector3 extents)
{
DrawCube(center, extents, defaultColor);
}
void Gizmos::DrawCube(Vector3 center, Vector3 extents, SHADE::Color color)
{
SHDebugDraw::Cube(Convert::ToNative(center), Convert::ToNative(extents), Convert::ToNative(color));
}
void Gizmos::DrawSphere(Vector3 center, float radius)
{
DrawSphere(center, radius, defaultColor);
}
void Gizmos::DrawSphere(Vector3 center, float radius, SHADE::Color color)
{
SHDebugDraw::Sphere(Convert::ToNative(center), SHVec3(radius, radius, radius), Convert::ToNative(color));
} }
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents) void Gizmos::DrawWireCube(Vector3 center, Vector3 extents)
@ -54,7 +74,7 @@ namespace SHADE
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color) void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color)
{ {
SHDebugDraw::Cube(Convert::ToNative(color), Convert::ToNative(center), Convert::ToNative(extents)); SHDebugDraw::WireCube(Convert::ToNative(center), Convert::ToNative(extents), Convert::ToNative(color));
} }
void Gizmos::DrawWireSphere(Vector3 center, float radius) void Gizmos::DrawWireSphere(Vector3 center, float radius)
@ -64,6 +84,6 @@ namespace SHADE
void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color) void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color)
{ {
SHDebugDraw::Sphere(Convert::ToNative(color), Convert::ToNative(center), radius); SHDebugDraw::WireSphere(Convert::ToNative(center), SHVec3(radius, radius, radius), Convert::ToNative(color));
} }
} }

View File

@ -56,6 +56,38 @@ namespace SHADE
/// <param name="color">Colour of the line.</param> /// <param name="color">Colour of the line.</param>
static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color); static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color);
/// <summary> /// <summary>
/// Renders a cube centered around the position specified in world
/// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render.
/// </summary>
/// <param name="center">Position where the cube wil be centered at.</param>
/// <param name="extents">Size of the rendered cube.</param>
static void DrawCube(Vector3 center, Vector3 extents);
/// <summary>
/// Renders a cube centered around the position specified in world
/// space.
/// </summary>
/// <param name="center">Position where the cube wil be centered at.</param>
/// <param name="extents">Size of the rendered cube.</param>
/// <param name="color">Colour of the cube.</param>
static void DrawCube(Vector3 center, Vector3 extents, SHADE::Color color);
/// <summary>
/// Renders a sphere centered around the position specified in world
/// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render.
/// </summary>
/// <param name="center">Position where the sphere wil be centered at.</param>
/// <param name="radius">Radius of the rendered sphere.</param>
static void DrawSphere(Vector3 center, float radius);
/// <summary>
/// Renders a sphere centered around the position specified in world
/// space.
/// </summary>
/// <param name="center">Position where the sphere wil be centered at.</param>
/// <param name="radius">Radius of the rendered sphere.</param>
/// <param name="color">Colour of the sphere.</param>
static void DrawSphere(Vector3 center, float radius, SHADE::Color color);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world /// Renders a wireframe cube centered around the position specified in world
/// space. /// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render. /// Uses <see cref="Gizmos.Color">Color</see> to render.