diff --git a/Assets/Shaders/DebugDrawMesh_VS.glsl b/Assets/Shaders/DebugDrawMesh_VS.glsl new file mode 100644 index 00000000..2f035261 --- /dev/null +++ b/Assets/Shaders/DebugDrawMesh_VS.glsl @@ -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; +} \ No newline at end of file diff --git a/Assets/Shaders/DebugDrawMesh_VS.shshaderb b/Assets/Shaders/DebugDrawMesh_VS.shshaderb new file mode 100644 index 00000000..442cd789 Binary files /dev/null and b/Assets/Shaders/DebugDrawMesh_VS.shshaderb differ diff --git a/Assets/Shaders/DebugDrawMesh_VS.shshaderb.shmeta b/Assets/Shaders/DebugDrawMesh_VS.shshaderb.shmeta new file mode 100644 index 00000000..043dd287 --- /dev/null +++ b/Assets/Shaders/DebugDrawMesh_VS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: DebugDrawMesh_VS +ID: 42127043 +Type: 2 diff --git a/Assets/Shaders/DebugDraw_VS.glsl b/Assets/Shaders/DebugDraw_VS.glsl index 7b370730..42a48c01 100644 --- a/Assets/Shaders/DebugDraw_VS.glsl +++ b/Assets/Shaders/DebugDraw_VS.glsl @@ -1,14 +1,13 @@ #version 450 #extension GL_KHR_vulkan_glsl : enable -layout(location = 0) in vec4 aVertexPos; +layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec4 aVertColor; - +// Output layout(location = 0) out struct { vec4 vertColor; // location 0 - } Out; layout(set = 2, binding = 0) uniform CameraData @@ -22,6 +21,6 @@ layout(set = 2, binding = 0) uniform CameraData void main() { - gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f); + gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f); Out.vertColor = aVertColor; } \ No newline at end of file diff --git a/Assets/Shaders/DebugDraw_VS.shshaderb b/Assets/Shaders/DebugDraw_VS.shshaderb index 2d8cd0ed..9f5f7766 100644 Binary files a/Assets/Shaders/DebugDraw_VS.shshaderb and b/Assets/Shaders/DebugDraw_VS.shshaderb differ diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index bcc7f09d..a5edd124 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -231,8 +231,6 @@ namespace Sandbox SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->RemoveAllScripts(testObj); } - - SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f)); } void SBTestScene::Render() diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index abddf457..4f1586ac 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -271,7 +271,7 @@ namespace SHADE void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes) { // Clear existing lines - SHDebugDraw::ClearPersistentDraws(); + SHDebugDraw::Persistent::ClearDraws(); static constexpr float DELTA = 1.0f; static constexpr int EXTENT_COUNT = static_cast(500.0f /* TODO: Remove hard code */ / DELTA); @@ -284,30 +284,34 @@ namespace SHADE for (int i = 1; i < EXTENT_COUNT; ++i) { // X-Axis Lines - SHDebugDraw::PersistentLine - ( - GRID_COL, + SHDebugDraw::Persistent::Line + ( SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA }, - SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA } - ); - SHDebugDraw::PersistentLine - ( + SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA }, 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 }, + GRID_COL, + true ); // 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 } - ); - SHDebugDraw::PersistentLine - ( + SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH }, 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 }, + GRID_COL, + true ); } } @@ -319,25 +323,28 @@ namespace SHADE const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL; const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL; // 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 }, + X_AXIS_COL, + true ); // 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 }, + Y_AXIS_COL, + true ); // 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 }, + Z_AXIS_COL, + true ); } } @@ -353,7 +360,7 @@ namespace SHADE break; case State::PLAY: default: - SHDebugDraw::ClearPersistentDraws(); + SHDebugDraw::Persistent::ClearDraws(); break; } return eventData->handle; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index 0bfa89a2..d77fbeb0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -25,308 +25,696 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* DrawRoutine */ - /*---------------------------------------------------------------------------------*/ - SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine() + /*-----------------------------------------------------------------------------------*/ + /* DrawRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine() : SHSystemRoutine("Debug Draw", true) + { + SystemFamily::GetID(); + } + + void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept + { + auto gfxSys = SHSystemManager::GetSystem(); + if (!gfxSys) { - SystemFamily::GetID(); + SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system."); + return; } - void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept - { - auto gfxSys = SHSystemManager::GetSystem(); - if (!gfxSys) - { - SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system."); - return; - } + // Get the system + SHDebugDrawSystem* system = static_cast(GetSystem()); - // Get the system - SHDebugDrawSystem* system = static_cast(GetSystem()); - - // Get current frame index - const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex(); - - /* Non-Persistent Buffer */ - // Update the buffer - system->numPoints[FRAME_IDX] = system->points.size(); - const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size(); - if (DATA_SIZE > 0) - { - system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0); - } - - // Reset for next frame - system->points.clear(); - - /* Persistent Buffer */ - // Check if there are changes - if (system->persistentBuffersCleared[FRAME_IDX] - || - system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size()) - { - // Update Buffer - system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size(); - const uint32_t DATA_SIZE = sizeof(PointVertex) * system->persistentPoints.size(); - if (DATA_SIZE > 0) - { - system->persistentVertexBuffers[FRAME_IDX]->WriteToMemory(system->persistentPoints.data(), DATA_SIZE, 0, 0); - } - - // Reset Flag - system->persistentBuffersCleared[FRAME_IDX] = false; - } - } + // Get current frame index + const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex(); - /*---------------------------------------------------------------------------------*/ - /* SHSystem overrides */ - /*---------------------------------------------------------------------------------*/ - void SHDebugDrawSystem::Init() + // Set up line batches + for (auto& batch : system->lineBatches) { - // Register function for subpass - const auto* GFX_SYSTEM = SHSystemManager::GetSystem(); - auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers(); - auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph(); - auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); - subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle& cmdBuffer, uint32_t frameIndex) + system->prepareBatch(batch, FRAME_IDX); + batch.Points.clear(); + } + + // Set up mesh batches + for (auto& batch : system->meshBatches) + { + system->prepareBatch(batch, FRAME_IDX); + for (auto& subBatch : batch.SubBatches) + { + subBatch.second.InstanceColors.clear(); + subBatch.second.InstanceTransforms.clear(); + } + } + + // 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 */ + /*-----------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::Init() + { + gfxSystem = SHSystemManager::GetSystem(); + if (!gfxSystem) + { + SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system."); + return; + } + + // Create all batches + createLineBatches(); + createMeshBatches(); + + // Register function for subpass + auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers(); + auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph(); + auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); + subPass->AddExteriorDrawCalls([this](Handle& cmdBuffer, uint32_t frameIndex) + { + const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex(); + cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)"); + { + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)"); { - // Get Current frame index - const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex(); - - // Don't draw if no points - if (numPoints[FRAME_IDX] > 0) - { - cmdBuffer->BeginLabeledSegment("SHDebugDraw"); - cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); - cmdBuffer->SetLineWidth(LineWidth); - cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); - cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0); - } - }); - auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth"); - subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle& cmdBuffer, uint32_t frameIndex) - { - // Get Current frame index - const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex(); - - // Don't draw if no points - if (numPersistentPoints[FRAME_IDX] > 0) - { - cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)"); - cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); - cmdBuffer->SetLineWidth(LineWidth); - cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); - cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); - cmdBuffer->EndLabeledSegment(); - } - }); - - // Reset trackers - std::fill_n(numPoints.begin(), numPoints.size(), 0); - std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0); - for (bool& cleared : persistentBuffersCleared) - cleared = true; - - // Allocate buffers - // - Non-Persistent Draws - static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex); - for (Handle& bufHandle : vertexBuffers) - { - bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer - ( - BUFFER_SIZE, - nullptr, - 0, - vk::BufferUsageFlagBits::eVertexBuffer, - VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT, - "Debug Draw Non-Persistent Vertex Buffer" - ); + renderBatch(lineBatches[static_cast(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX); + renderBatch(persistentLineBatches[static_cast(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX); } - // - Persistent Draws - for (Handle& bufHandle : persistentVertexBuffers) + cmdBuffer->EndLabeledSegment(); + + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)"); { - bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer - ( - BUFFER_SIZE, - nullptr, - 0, - vk::BufferUsageFlagBits::eVertexBuffer, - VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT, - "Debug Draw Persistent Vertex Buffer" - ); + renderBatch(meshBatches[static_cast(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX); + renderBatch(meshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX); + renderBatch(persistentMeshBatches[static_cast(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX); + renderBatch(persistentMeshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX); } - } - - void SHDebugDrawSystem::Exit() + cmdBuffer->EndLabeledSegment(); + } + cmdBuffer->EndLabeledSegment(); + }); + auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth"); + subPassWithDepth->AddExteriorDrawCalls([this](Handle& cmdBuffer, uint32_t frameIndex) { - for (auto vertexBuffer : vertexBuffers) + const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex(); + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)"); + { + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)"); { - if (vertexBuffer) - vertexBuffer.Free(); + renderBatch(lineBatches[static_cast(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX); + renderBatch(persistentLineBatches[static_cast(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX); } - for (auto vertexBuffer : persistentVertexBuffers) + cmdBuffer->EndLabeledSegment(); + + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)"); { - if (vertexBuffer) - vertexBuffer.Free(); + renderBatch(meshBatches[static_cast(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX); + renderBatch(meshBatches[static_cast(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX); + renderBatch(persistentMeshBatches[static_cast(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX); + renderBatch(persistentMeshBatches[static_cast(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX); } - } + cmdBuffer->EndLabeledSegment(); + } + cmdBuffer->EndLabeledSegment(); + }); + } - /*---------------------------------------------------------------------------------*/ - /* Draw Functions */ - /*---------------------------------------------------------------------------------*/ - void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) + void SHDebugDrawSystem::Exit() + { + // Destroy buffers in the batches + destroyLineBatches(); + destroyMeshBatches(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Draw Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested) + { + // Insert into the batch + drawLine(getLineBatch(depthTested), start, end, color); + } + + void SHDebugDrawSystem::DrawLineLoop(std::initializer_list points, const SHColour& color, bool depthTested) + { + DrawLineLoop(points.begin(), points.end(), color, depthTested); + } + + void SHDebugDrawSystem::DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested) + { + DrawLineLoop({ p1, p2, p3 }, color, depthTested); + } + + void SHDebugDrawSystem::DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested) + { + DrawLineLoop({ p1, p2, p3, p4 }, color, depthTested); + } + + void SHDebugDrawSystem::DrawCircle(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/) + { + drawCircle(getMeshBatch(false, depthTested), matrix, color); + } + + void SHDebugDrawSystem::DrawWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested) + { + 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 */ + /*-----------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested) + { + // Insert into the batch + drawLine(getPersistentLineBatch(depthTested), start, end, color); + markPersistentDrawsDirty(); + } + void SHDebugDrawSystem::DrawPersistentLineLoop(std::initializer_list points, const SHColour& color, bool depthTested) + { + DrawPersistentLineLoop(points.begin(), points.end(), color, depthTested); + markPersistentDrawsDirty(); + } + + void SHDebugDrawSystem::DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested) + { + DrawPersistentLineLoop({ p1, p2, p3 }, color, depthTested); + markPersistentDrawsDirty(); + } + + void SHDebugDrawSystem::DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested) + { + DrawPersistentLineLoop({ p1, p2, p3, p4 }, color, depthTested); + markPersistentDrawsDirty(); + } + + void SHDebugDrawSystem::DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color, bool depthTested) + { + drawCircle(getPersistentMeshBatch(false, depthTested), matrix, color); + markPersistentDrawsDirty(); + } + + void SHDebugDrawSystem::DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested) + { + drawWireCube(getPersistentMeshBatch(false, depthTested), matrix, color); + markPersistentDrawsDirty(); + } + + void SHDebugDrawSystem::DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color, bool depthTested) + { + 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() + { + for (auto& batch : persistentLineBatches) + batch.Points.clear(); + markPersistentDrawsDirty(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Draw Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color) + { + // Check if points exceeded max + if (batch.Points.size() >= MAX_POINTS) { - drawLine(points, color, startPt, endPt); + SHLOG_WARNING("[SHDebugDrawSystem] Exceeded maximum size of drawable debug lines. Ignoring."); + return; } - void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) + batch.Points.emplace_back(start, color); + batch.Points.emplace_back(end, color); + } + + void SHDebugDrawSystem::drawMesh(Handle mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color) + { + // Create if doesn't exist + if (!batch.SubBatches.contains(mesh)) { - drawPoly(points, color, { pt1, pt2, pt3 }); + MeshBatch::MultiDrawSet set; + set.Mesh = mesh; + batch.SubBatches.emplace(mesh, std::move(set)); } - void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) + // Add to the batch + auto& subBatch = batch.SubBatches[mesh]; + subBatch.InstanceTransforms.emplace_back(transformMatrix); + subBatch.InstanceColors.emplace_back(color); + } + + void SHDebugDrawSystem::drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color) + { + drawMesh + ( + gfxSystem->GetMeshPrimitive(PrimitiveType::LineCube), + batch, transformMatrix, color + ); + } + + void SHDebugDrawSystem::drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color) + { + drawMesh + ( + gfxSystem->GetMeshPrimitive(PrimitiveType::Sphere), + batch, transformMatrix, color + ); + } + + void SHDebugDrawSystem::drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color) + { + drawMesh + ( + gfxSystem->GetMeshPrimitive(PrimitiveType::Cube), + batch, transformMatrix, color + ); + } + + void SHDebugDrawSystem::drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color) + { + 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(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)]; + } + SHDebugDrawSystem::LinesBatch& SHDebugDrawSystem::getPersistentLineBatch(bool depthTested) + { + return persistentLineBatches[static_cast(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)]; + } + + void SHDebugDrawSystem::createLineBatches() + { + auto gfxSys = SHSystemManager::GetSystem(); + if (!gfxSys) { - drawPoly(points, color, { pt1, pt2, pt3, pt4 }); + SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system."); + return; } - void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list pointList) + // 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 pipeline, const std::string& vertexBufferName) + { + auto gfxSys = SHSystemManager::GetSystem(); + if (!gfxSys) { - drawPoly(points, color, pointList.begin(), pointList.end()); + SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system."); + return; } - void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) + batch.Pipeline = pipeline; + for (auto& vBuffer : batch.VertexBuffers) { - drawCube(points, color, pos, size); + 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 + ); } + } - void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius) + + void SHDebugDrawSystem::prepareBatch(LinesBatch& batch, uint32_t frameIndex) + { + // Parameter checks + if (frameIndex > batch.VertexBuffers.size()) { - drawSphere(points, color, pos, radius); + SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping."); + return; } - /*---------------------------------------------------------------------------------*/ - /* Persistent Draw Functions */ - /*---------------------------------------------------------------------------------*/ - void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) + // 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) { - drawLine(persistentPoints, color, startPt, endPt); + batch.VertexBuffers[frameIndex]->WriteToMemory(batch.Points.data(), DATA_SIZE, 0, 0); } + } - void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) + void SHDebugDrawSystem::renderBatch(LinesBatch& batch, Handle cmdBuffer, uint32_t frameIndex) + { + if (batch.NumPoints[frameIndex] > 0) { - drawPoly(persistentPoints, color, { pt1, pt2, pt3 }); + cmdBuffer->BindPipeline(batch.Pipeline); + cmdBuffer->SetLineWidth(LineWidth); + cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0); + cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0); } + } - void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) + void SHDebugDrawSystem::destroyBatch(LinesBatch& batch) + { + for (auto& vBuffer : batch.VertexBuffers) { - drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 }); + if (vBuffer) + { + vBuffer.Free(); + vBuffer = {}; + } } + } - void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list pointList) + 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) { - drawPoly(persistentPoints, color, pointList.begin(), pointList.end()); + mode = depthTested ? MeshRenderMode::FilledDepthTested + : MeshRenderMode::FilledNoDepthTest; } - - void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) + else { - drawCube(persistentPoints, color, pos, size); + mode = depthTested ? MeshRenderMode::WireDepthTested + : MeshRenderMode::WireNoDepthTest; } - void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) + return meshBatches[static_cast(mode)]; + } + + SHDebugDrawSystem::MeshBatch& SHDebugDrawSystem::getPersistentMeshBatch(bool filled, bool depthTested) + { + MeshRenderMode mode = {}; + + if (filled) { - drawSphere(persistentPoints, color, pos, radius); + mode = depthTested ? MeshRenderMode::FilledDepthTested + : MeshRenderMode::FilledNoDepthTest; } - - void SHDebugDrawSystem::ClearPersistentDraws() + else { - persistentPoints.clear(); - for (bool& cleared : persistentBuffersCleared) - cleared = true; + mode = depthTested ? MeshRenderMode::WireDepthTested + : MeshRenderMode::WireNoDepthTest; } - void SHDebugDrawSystem::drawLine(std::vector& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) + return persistentMeshBatches[static_cast(mode)]; + } + + void SHDebugDrawSystem::createMeshBatches() + { + auto gfxSys = SHSystemManager::GetSystem(); + if (!gfxSys) { - if (storage.size() > MAX_POINTS) - { - SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements."); - return; - } - - storage.emplace_back(PointVertex{ startPt, color }); - storage.emplace_back(PointVertex{ endPt, color }); + SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system."); + return; } - void SHDebugDrawSystem::drawLineSet(std::vector& storage, const SHVec4& color, std::initializer_list pointList) + // Set up batches + initBatch + ( + meshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest) + ); + initBatch + ( + meshBatches[static_cast(MeshRenderMode::FilledDepthTested)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested) + ); + initBatch + ( + meshBatches[static_cast(MeshRenderMode::WireNoDepthTest)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest) + ); + initBatch + ( + meshBatches[static_cast(MeshRenderMode::WireDepthTested)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested) + ); + + // Set up persistent batches + initBatch + ( + persistentMeshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest) + ); + initBatch + ( + persistentMeshBatches[static_cast(MeshRenderMode::FilledDepthTested)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested) + ); + initBatch + ( + persistentMeshBatches[static_cast(MeshRenderMode::WireNoDepthTest)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest) + ); + initBatch + ( + persistentMeshBatches[static_cast(MeshRenderMode::WireDepthTested)], + gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested) + ); + } + void SHDebugDrawSystem::initBatch(MeshBatch& batch, Handle pipeline) + { + batch.Pipeline = pipeline; + } + + void SHDebugDrawSystem::prepareBatch(MeshBatch& batch, uint32_t frameIndex) + { + // Parameter checks + if (frameIndex > batch.MDIBuffer.size()) { - drawLineSet(storage, color, pointList.begin(), pointList.end()); + SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping."); + return; } - void SHDebugDrawSystem::drawPoly(std::vector& storage, const SHVec4& color, std::initializer_list pointList) + // Clear existing data + batch.InstanceTransforms.clear(); + batch.InstanceColors.clear(); + batch.MDIData.clear(); + + // Populate + for (auto& subBatch : batch.SubBatches) { - drawPoly(storage, color, pointList.begin(), pointList.end()); - } + auto& multiDrawSet = subBatch.second; - void SHDebugDrawSystem::drawCube(std::vector& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size) + // 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(multiDrawSet.InstanceTransforms.size()), + .firstIndex = multiDrawSet.Mesh->FirstIndex, + .vertexOffset = multiDrawSet.Mesh->FirstVertex, + .firstInstance = static_cast(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(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(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(batch.InstanceColors.size() * sizeof(SHVec4)), + vk::BufferUsageFlagBits::eVertexBuffer, + "Debug Draw Mesh Batch Instance Color Buffer" + ); + } + } + + void SHDebugDrawSystem::renderBatch(MeshBatch& batch, Handle 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(batch.MDIData.size())); + } + + void SHDebugDrawSystem::destroyBatch(MeshBatch& batch) + { + for (auto& buffer : batch.InstanceColorBuffer) { - static const SHVec3 EXTENTS = SHVec3{ 0.5f, 0.5f, 0.5f }; - 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, - 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 - } - ); + if (buffer) + { + buffer.Free(); + buffer = {}; + } } - - void SHDebugDrawSystem::drawSphere(std::vector& storage, const SHVec4& color, const SHVec3& pos, double radius) + for (auto& buffer : batch.InstanceTransformBuffer) { - //if (spherePoints.empty()) - { - spherePoints.clear(); - // Generate - static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere(); - for (const auto& idx : SPHERE.Indices) - { - spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius + pos); - } - } - drawLineSet(storage, color, spherePoints.begin(), spherePoints.end()); + if (buffer) + { + buffer.Free(); + buffer = {}; + } } + for (auto& buffer : batch.MDIBuffer) + { + if (buffer) + { + buffer.Free(); + buffer = {}; + } + } + } + void SHDebugDrawSystem::destroyMeshBatches() + { + destroyBatch(meshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)]); + destroyBatch(meshBatches[static_cast(MeshRenderMode::FilledDepthTested)]); + destroyBatch(meshBatches[static_cast(MeshRenderMode::WireNoDepthTest)]); + destroyBatch(meshBatches[static_cast(MeshRenderMode::WireDepthTested)]); + + destroyBatch(persistentMeshBatches[static_cast(MeshRenderMode::FilledNoDepthTest)]); + destroyBatch(persistentMeshBatches[static_cast(MeshRenderMode::FilledDepthTested)]); + destroyBatch(persistentMeshBatches[static_cast(MeshRenderMode::WireNoDepthTest)]); + destroyBatch(persistentMeshBatches[static_cast(MeshRenderMode::WireDepthTested)]); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHDebugDrawSystem::markPersistentDrawsDirty() + { + for (bool& dirty : persistentBuffersUpdated) + dirty = true; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h index 20ddcd42..2978d68e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h @@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec4.h" +#include "Math/SHMatrix.h" #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "Resource/SHHandle.h" @@ -30,7 +31,10 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Forward Declarations */ /*-----------------------------------------------------------------------------------*/ + class SHGraphicsSystem; class SHVkBuffer; + class SHMesh; + class SHVkPipeline; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -47,7 +51,7 @@ namespace SHADE class SH_API ProcessPointsRoutine final : public SHSystemRoutine { public: - ProcessPointsRoutine(); + ProcessPointsRoutine(); virtual void Execute(double dt) noexcept override final; }; @@ -69,134 +73,201 @@ namespace SHADE /* Draw Functions */ /*---------------------------------------------------------------------------------*/ /// - /// Renders a line between two points in world space. + /// Draws a line between two specified points. /// - /// Colour of the line. - /// First point of the line. - /// Second point of the line. - void DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); + /// Starting point. + /// Ending point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a triangle indicated by three points in world space. + /// Draws a set of points as a connected set of lines that loops back. /// - /// Colour of the triangle. - /// First point of the triangle. - /// Second point of the triangle. - /// Third point of the triangle. - void DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); + /// List of points to draw the line across. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawLineLoop(std::initializer_list points, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a quadrilateral indicated by four points in world space. + /// Draws a set of points as a connected set of lines that loops back. /// - /// Colour of the quadrilateral. - /// First point of the triangle. - /// Second point of the quadrilateral. - /// Third point of the quadrilateral. - /// Third point of the quadrilateral. - void DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); - /// - /// Renders a polygon indicated by the specified set of points in world space. - /// - /// Colour of the polygon. - /// List of points for the polygon. - void DrawPoly(const SHVec4& color, std::initializer_list pointList); - /// - /// Renders a polygon indicated by the specified set of points in world space. - /// - /// Iterator for a STL-like container. - /// Colour of the polygon. - /// - /// Iterator to the first point of the point container. - /// - /// - /// One past last iterator of the point container. - /// + /// + /// Type of iterator of the container that contains the points. + /// + /// Starting iterator to the line points. + /// One past end iterator to the line points. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. template - void DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); + void DrawLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe cube centered around the position specified in world space. + /// Draws a triangle from the specified set of points. /// - /// Colour of the cube. - /// Position where the cube wil be centered at. - /// Size of the rendered cube. - void DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); + /// 1st point. + /// 2nd point. + /// 3rd point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe sphere centered around the position specified in world space. + /// Draws a quad from the specified set of points. /// - /// Colour of the sphere. - /// Position where the sphere wil be centered at. - /// Size of the rendered sphere. - void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius); + /// 1st point. + /// 2nd point. + /// 3rd point. + /// 4th point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a 2-dimensional circle. + /// + /// + /// Matrix transformation that defines how the circle should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a cube. + /// + /// + /// Matrix transformation that defines how the wire cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a sphere. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube. + /// + /// + /// Matrix transformation that defines how the cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); /*---------------------------------------------------------------------------------*/ /* Persistent Draw Functions */ /*---------------------------------------------------------------------------------*/ /// - /// Renders a line between two points in world space that will persist until - /// ClearPersistentDraws() is called. These lines are depth tested. + /// Draws a persistent line between two specified points. + /// This will remain drawn until ClearPersistentDraws() is called. /// - /// Colour of the line. - /// First point of the line. - /// Second point of the line. - void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); + /// Starting point. + /// Ending point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a triangle indicated by three points in world space that will persist - /// until ClearPersistentDraws() is called. These lines are depth tested. + /// Draws a persistent set of points as a connected set of lines that loops back. + /// This will remain drawn until ClearPersistentDraws() is called. /// - /// Colour of the triangle. - /// First point of the triangle. - /// Second point of the triangle. - /// Third point of the triangle. - void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); + /// List of points to draw the line across. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentLineLoop(std::initializer_list points, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a quadrilateral indicated by four points in world space that will persist - /// until ClearPersistentDraws() is called. These lines are depth tested. + /// Draws a persistent set of points as a connected set of lines that loops back. + /// This will remain drawn until ClearPersistentDraws() is called. /// - /// Colour of the quadrilateral. - /// First point of the triangle. - /// Second point of the quadrilateral. - /// Third point of the quadrilateral. - /// Third point of the quadrilateral. - void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); - /// - /// Renders a polygon indicated by the specified set of points in world space that - /// will persist until ClearPersistentDraws() is called. These lines are depth - /// tested. - /// - /// Colour of the polygon. - /// List of points for the polygon. - void DrawPersistentPoly(const SHVec4& color, std::initializer_list pointList); - /// - /// Renders a polygon indicated by the specified set of points in world space that - /// will persist until ClearPersistentDraws() is called. These lines are depth - /// tested. - /// - /// Iterator for a STL-like container. - /// Colour of the polygon. - /// - /// Iterator to the first point of the point container. - /// - /// - /// One past last iterator of the point container. - /// + /// + /// Type of iterator of the container that contains the points. + /// + /// Starting iterator to the line points. + /// One past end iterator to the line points. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. template - void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); + void DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe cube centered around the position specified in world space - /// that will persist until ClearPersistentDraws() is called. These lines are depth - /// tested. + /// Draws a persistent triangle from the specified set of points. + /// This will remain drawn until ClearPersistentDraws() is called. /// - /// Colour of the cube. - /// Position where the cube wil be centered at. - /// Size of the rendered cube. - void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); + /// 1st point. + /// 2nd point. + /// 3rd point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe sphere centered around the position specified in world space - /// that will persist until ClearPersistentDraws() is called. These lines are depth - /// tested. + /// Draws a persistent quad from the specified set of points. + /// This will remain drawn until ClearPersistentDraws() is called. /// - /// Colour of the sphere. - /// Position where the sphere wil be centered at. - /// Size of the rendered sphere. - void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); + /// 1st point. + /// 2nd point. + /// 3rd point. + /// 4th point. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a persistent 2-dimensional circle. + /// This will remain drawn until ClearPersistentDraws() is called. + /// + /// + /// Matrix transformation that defines how the circle should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a persistent cube. + /// This will remain drawn until ClearPersistentDraws() is called. + /// + /// + /// Matrix transformation that defines how the wire cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a persistent sphere. + /// This will remain drawn until ClearPersistentDraws() is called. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a persistent filled cube. + /// This will remain drawn until ClearPersistentDraws() is called. + /// + /// + /// Matrix transformation that defines how the cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a persistent filled sphere. + /// This will remain drawn until ClearPersistentDraws() is called. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false); /// /// Clears any persistent drawn debug primitives. /// @@ -206,47 +277,144 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ + using TripleBuffer = std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS>; + using TripleUInt = std::array; + using TripleBool = std::array; + /// + /// Defines the rendering mode for debug lines. + /// + enum class LineRenderMode : uint32_t + { + NoDepthTest, + DepthTested, + Count + }; + /// + /// Defines the rendering mode for debug meshes. + /// + enum class MeshRenderMode : uint32_t + { + FilledNoDepthTest, + FilledDepthTested, + WireNoDepthTest, + WireDepthTested, + Count + }; + /// + /// Defines a coloured Vertex + /// struct SH_API PointVertex { SHVec4 Position; SHVec4 Color; }; - using TripleBuffer = std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS>; - using TripleUInt = std::array; - using TripleBool = std::array; + struct Batch + { + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + Handle Pipeline; + }; + + struct LinesBatch : public Batch + { + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + // CPU Buffers + std::vector Points; + // GPU Buffers + TripleBuffer VertexBuffers; + TripleUInt NumPoints; + }; + + struct MeshBatch : public Batch + { + /*-------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-------------------------------------------------------------------------------*/ + struct MultiDrawSet + { + Handle Mesh; + std::vector InstanceTransforms; + std::vector InstanceColors; + }; + + /*-------------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------------*/ + // CPU Buffers + std::unordered_map, MultiDrawSet> SubBatches; + std::vector InstanceTransforms; + std::vector InstanceColors; + std::vector MDIData; + // GPU Buffers + TripleBuffer MDIBuffer; + TripleBuffer InstanceTransformBuffer; + TripleBuffer InstanceColorBuffer; + }; /*---------------------------------------------------------------------------------*/ /* Constants */ /*---------------------------------------------------------------------------------*/ static constexpr uint32_t MAX_POINTS = 100'000; + static constexpr size_t LINE_MODE_COUNT = static_cast(LineRenderMode::Count); + static constexpr size_t MESH_MODE_COUNT = static_cast(MeshRenderMode::Count); /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - // CPU Buffers - std::vector points; - std::vector persistentPoints; - // GPU Buffers - TripleBuffer vertexBuffers; - TripleUInt numPoints; - TripleBuffer persistentVertexBuffers; - TripleUInt numPersistentPoints; - TripleBool persistentBuffersCleared; - // Cached Points for polygon drawing - std::vector spherePoints; + // References + SHGraphicsSystem* gfxSystem = nullptr; + // Batches + std::array lineBatches; + std::array persistentLineBatches; + std::array meshBatches; + std::array persistentMeshBatches; + // Tracking + TripleBool persistentBuffersUpdated = { true, true, true }; /*---------------------------------------------------------------------------------*/ /* Helper Draw Functions */ /*---------------------------------------------------------------------------------*/ - void drawLine(std::vector& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); - void drawLineSet(std::vector& storage, const SHVec4& color, std::initializer_list pointList); + void drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color); template - void drawLineSet(std::vector& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); - void drawPoly(std::vector& storage, const SHVec4& color, std::initializer_list pointList); - template - void drawPoly(std::vector& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); - void drawCube(std::vector& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size); - void drawSphere(std::vector& storage, const SHVec4& color, const SHVec3& pos, double radius); + void drawLineLoop(LinesBatch& batch, IterType pointListBegin, IterType pointListEnd, const SHColour& color); + void drawMesh(Handle mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color); + void drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color); + void drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color); + void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color); + 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 pipeline, const std::string& vertexBufferName); + void prepareBatch(LinesBatch& batch, uint32_t frameIndex); + void renderBatch(LinesBatch& batch, Handle 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 pipeline); + void prepareBatch(MeshBatch& batch, uint32_t frameIndex); + void renderBatch(MeshBatch& batch, Handle cmdBuffer, uint32_t frameIndex); + void destroyBatch(MeshBatch& batch);; + void destroyMeshBatches(); + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void markPersistentDrawsDirty(); }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.hpp index 2a171e73..36c7d2b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.hpp @@ -17,73 +17,44 @@ namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Draw Functions */ - /*-----------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ template - 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 + void SHADE::SHDebugDrawSystem::DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color , bool depthTested) + { + // Get Batch + drawLineLoop(getPersistentLineBatch(depthTested), pointListBegin, pointListEnd, color); + } + /*-----------------------------------------------------------------------------------*/ /* Helper Draw Functions */ /*-----------------------------------------------------------------------------------*/ template - void SHDebugDrawSystem::drawLineSet(std::vector& 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 - static_assert(std::is_same_v>, "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; + static_assert(std::is_same_v>, "Parameters to DrawLineLoop must be SHVec3."); + // Invalid polygon + const size_t POINTS_COUNT = pointListEnd - pointListBegin; if (POINTS_COUNT < 2) { - SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly()."); - 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 - void SHDebugDrawSystem::drawPoly(std::vector& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd) - { - // Ensure dereferenced type is SHVec3 - static_assert(std::is_same_v>, "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()."); + SHLOG_WARNING("[SHDebugDrawSystem] Insufficient points provided to drawLineLoop()."); return; } // Trace the polygon for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter) { - storage.emplace_back(PointVertex{ *(pointIter - 1), color }); - storage.emplace_back(PointVertex{ *pointIter , color }); + drawLine(batch, *(pointIter - 1), *pointIter, color); } // Close the line loop - storage.emplace_back(PointVertex{ *(pointListEnd - 1), color }); - storage.emplace_back(PointVertex{ *pointListBegin , color }); + drawLine(batch, *(pointListEnd - 1), *pointListBegin, color); } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bd1d60cd..9a599a07 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -124,20 +124,12 @@ namespace SHADE 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 static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet(VS_DEBUG); static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet(FS_DEBUG); + static constexpr AssetID VS_DEBUG_MESH = 42127043; debugMeshVertShader = SHResourceManager::LoadOrGet(VS_DEBUG_MESH); static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet(CS_COMPOSITE); static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet(SSAO); static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet(SSAO_BLUR); @@ -335,14 +327,31 @@ namespace SHADE screenRenderer->SetCamera(screenCamera); screenRenderer->SetCameraDirector(worldCameraDirector); - // 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::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout"); - debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw"); + 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::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 @@ -405,6 +414,8 @@ namespace SHADE // Create default meshes primitiveMeshes[static_cast(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary); primitiveMeshes[static_cast(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary); + primitiveMeshes[static_cast(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary); + primitiveMeshes[static_cast(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary); BuildMeshBuffers(); // Create default materials @@ -829,6 +840,8 @@ namespace SHADE { case PrimitiveType::Cube: case PrimitiveType::Sphere: + case PrimitiveType::LineCube: + case PrimitiveType::LineCircle: return primitiveMeshes[static_cast(type)]; default: return {}; @@ -1083,34 +1096,68 @@ namespace SHADE return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data()); } - SHADE::SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept + Handle 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; } - Handle SHGraphicsSystem::createDebugDrawPipeline(Handle renderPass, Handle subpass) + Handle SHGraphicsSystem::createDebugDrawPipeline(Handle renderPass, Handle subpass, bool filled, bool triMesh, bool instanced) { auto pipelineLayout = resourceManager.Create ( device, SHPipelineLayoutParams { - .shaderModules = { debugVertShader, debugFragShader }, + .shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader }, .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() } ); auto pipeline = resourceManager.Create(device, pipelineLayout, nullptr, renderPass, subpass); pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState { - .polygonMode = vk::PolygonMode::eLine, - .cull_mode = vk::CullModeFlagBits::eNone + .polygonMode = filled ? vk::PolygonMode::eFill : vk::PolygonMode::eLine, + .cull_mode = filled ? vk::CullModeFlagBits::eBack : vk::CullModeFlagBits::eNone }); pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState { - .topology = vk::PrimitiveTopology::eLineList + .topology = triMesh ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eLineList }); 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); SHColorBlendState colorBlendState{}; colorBlendState.logic_op_enable = VK_FALSE; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 8c65f233..75b48c9b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -70,9 +70,23 @@ namespace SHADE enum class PrimitiveType { 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 GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle GetPrimaryRenderpass() const noexcept; - Handle GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; } - Handle GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; } + Handle GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept; uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); } SHFontLibrary const& GetFontLibrary (void) const noexcept; + const SHMeshLibrary& GetMeshLibrary() const noexcept { return meshLibrary; }; /*-----------------------------------------------------------------------------*/ /* Getters */ @@ -439,6 +453,7 @@ namespace SHADE Handle defaultFragShader; Handle debugVertShader; Handle debugFragShader; + Handle debugMeshVertShader; Handle deferredCompositeShader; Handle ssaoShader; Handle ssaoBlurShader; @@ -454,6 +469,12 @@ namespace SHADE Handle defaultMaterial; Handle debugDrawPipeline; Handle debugDrawDepthPipeline; + Handle debugDrawLineMeshPipeline; + Handle debugDrawLineMeshDepthPipeline; + Handle debugDrawWireMeshPipeline; + Handle debugDrawWireMeshDepthPipeline; + Handle debugDrawFilledPipeline; + Handle debugDrawFilledDepthPipeline; // Built-In Textures Handle defaultTexture; @@ -482,6 +503,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ - Handle createDebugDrawPipeline(Handle renderPass, Handle subpass); + Handle createDebugDrawPipeline(Handle renderPass, Handle subpass, bool filled, bool triMesh, bool instanced); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp index 60decded..444a6630 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp @@ -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 of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ +// Precompiled Header #include "SHpch.h" +// Primary Includes #include "SHPrimitiveGenerator.h" - +// STL Includes +#include +// Project Includes #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" @@ -23,6 +27,8 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHMeshData SHPrimitiveGenerator::cubeMesh; SHMeshData SHPrimitiveGenerator::sphereMesh; + SHMeshData SHPrimitiveGenerator::lineCubeMesh; + SHMeshData SHPrimitiveGenerator::lineCircleMesh; /*-----------------------------------------------------------------------------------*/ /* Primitive Generation Functions */ @@ -207,14 +213,14 @@ namespace SHADE return addMeshDataTo(cubeMesh, meshLibrary); } - Handle SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept + Handle SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept { if (cubeMesh.VertexPositions.empty()) cubeMesh = Cube(); return addMeshDataTo(cubeMesh, gfxSystem); } - SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept + SHMeshData SHPrimitiveGenerator::Sphere() noexcept { SHMeshData meshData; @@ -265,7 +271,7 @@ namespace SHADE return meshData; } - SHADE::Handle SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept + Handle SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept { if (sphereMesh.VertexPositions.empty()) sphereMesh = Sphere(); @@ -273,7 +279,7 @@ namespace SHADE return addMeshDataTo(sphereMesh, meshLibrary); } - SHADE::Handle SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept + Handle SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept { if (sphereMesh.VertexPositions.empty()) sphereMesh = Sphere(); @@ -281,6 +287,111 @@ namespace SHADE 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 SHPrimitiveGenerator::LineCube(SHMeshLibrary& meshLibrary) noexcept + { + if (lineCubeMesh.VertexPositions.empty()) + lineCubeMesh = LineCube(); + + return addMeshDataTo(lineCubeMesh, meshLibrary); + } + + Handle 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 * 2.0f) / static_cast(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(i - 1)); + mesh.Indices.emplace_back(static_cast(i)); + } + // Last line to complete the circle + mesh.Indices.emplace_back(static_cast(SPLITS - 1)); + mesh.Indices.emplace_back(static_cast(0)); + + mesh.VertexNormals.resize(mesh.VertexPositions.size()); + mesh.VertexTangents.resize(mesh.VertexPositions.size()); + mesh.VertexTexCoords.resize(mesh.VertexPositions.size()); + + return mesh; + } + + Handle SHPrimitiveGenerator::LineCircle(SHMeshLibrary& meshLibrary) noexcept + { + if (lineCircleMesh.VertexPositions.empty()) + lineCircleMesh = LineCircle(); + + return addMeshDataTo(lineCircleMesh, meshLibrary); + } + + Handle SHPrimitiveGenerator::LineCircle(SHGraphicsSystem& gfxSystem) noexcept + { + if (lineCircleMesh.VertexPositions.empty()) + lineCircleMesh = LineCircle(); + + return addMeshDataTo(lineCircleMesh, gfxSystem); + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ @@ -288,7 +399,7 @@ namespace SHADE { return meshLibrary.AddMesh ( - static_cast(meshData.VertexPositions.size()), + static_cast(meshData.VertexPositions.size()), meshData.VertexPositions.data(), meshData.VertexTexCoords.data(), meshData.VertexTangents.data(), @@ -302,12 +413,12 @@ namespace SHADE { return gfxSystem.AddMesh ( - static_cast(meshData.VertexPositions.size()), + static_cast(meshData.VertexPositions.size()), meshData.VertexPositions.data(), meshData.VertexTexCoords.data(), meshData.VertexTangents.data(), meshData.VertexNormals.data(), - static_cast(meshData.Indices.size()), + static_cast(meshData.Indices.size()), meshData.Indices.data() ); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h index 7719e4c3..9bcd2f3c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h @@ -43,7 +43,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Primitive Generation Functions */ - /*---------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ /***********************************************************************************/ /*! \brief @@ -116,6 +116,84 @@ namespace SHADE */ /***********************************************************************************/ [[nodiscard]] static Handle 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 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 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 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 LineCircle(SHGraphicsSystem& gfxSystem) noexcept; private: /*---------------------------------------------------------------------------------*/ @@ -129,5 +207,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ static SHMeshData cubeMesh; static SHMeshData sphereMesh; + static SHMeshData lineCubeMesh; + static SHMeshData lineCircleMesh; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index 1ca7ae39..96af5e39 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -195,7 +195,7 @@ namespace SHADE const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray(); 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 @@ -207,7 +207,7 @@ namespace SHADE const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray(); 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 } @@ -225,7 +225,7 @@ namespace SHADE const auto& LINE_ARRAY = rp3dRenderer->getLinesArray(); 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 @@ -237,7 +237,7 @@ namespace SHADE const auto& LINE_ARRAY = rp3dRenderer->getLinesArray(); 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 } @@ -261,7 +261,7 @@ namespace SHADE const float RENDER_DIST = raycastResult.distance == std::numeric_limits::infinity() ? SHRay::MAX_RAYCAST_DIST : raycastResult.distance; 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); // 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 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 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 @@ -327,8 +327,9 @@ namespace SHADE // Calculate final position & orientation const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); 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 \ No newline at end of file diff --git a/SHADE_Engine/src/Tools/SHDebugDraw.cpp b/SHADE_Engine/src/Tools/SHDebugDraw.cpp index b8aa8b0e..02eca592 100644 --- a/SHADE_Engine/src/Tools/SHDebugDraw.cpp +++ b/SHADE_Engine/src/Tools/SHDebugDraw.cpp @@ -15,6 +15,8 @@ of DigiPen Institute of Technology is prohibited. #include "SHDebugDraw.h" // Project Includes #include "Math/Vector/SHVec4.h" +#include "Math/SHQuaternion.h" +#include "Math/SHQuaternion.h" #include "Math/SHColour.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -41,69 +43,181 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* 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 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 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 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 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(); } - -} \ No newline at end of file +} diff --git a/SHADE_Engine/src/Tools/SHDebugDraw.h b/SHADE_Engine/src/Tools/SHDebugDraw.h index 04504c3a..c28b93e6 100644 --- a/SHADE_Engine/src/Tools/SHDebugDraw.h +++ b/SHADE_Engine/src/Tools/SHDebugDraw.h @@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SH_API.h" +#include "Math/SHColour.h" namespace SHADE { @@ -22,7 +23,8 @@ namespace SHADE class SHDebugDrawSystem; class SHVec4; class SHVec3; - class SHColour; + class SHQuaternion; + class SHMatrix; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -50,105 +52,324 @@ namespace SHADE /// /// Renders a line between two points in world space. /// - /// Colour of the line. /// First point of the line. /// Second point of the line. - static void Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); + /// Colour of the line. + /// Whether or not drawn object will be occluded. + static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false); /// /// Renders a triangle indicated by three points in world space. /// - /// Colour of the triangle. /// First point of the triangle. /// Second point of the triangle. /// Third point of the triangle. - static void Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); + /// Colour of the triangle. + /// Whether or not drawn object will be occluded. + static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false); /// /// Renders a quadrilateral indicated by four points in world space. /// - /// Colour of the quadrilateral. /// First point of the triangle. /// Second point of the quadrilateral. /// Third point of the quadrilateral. /// Third point of the quadrilateral. - static void Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); + /// Colour of the quadrilateral. + /// Whether or not drawn object will be occluded. + static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a 2-dimensional circle in world space. + /// + /// + /// Matrix transformation that defines how the circle should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false); /// /// Renders a polygon indicated by the specified set of points in world space. /// - /// Colour of the polygon. /// List of points for the polygon. - static void Poly(const SHVec4& color, std::initializer_list pointList); + /// Colour of the polygon. + /// Whether or not drawn object will be occluded. + static void LineLoop(std::initializer_list pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe cube centered around the position specified in world space. + /// Draws a filled cube in world space. /// - /// Colour of the cube. - /// Position where the cube wil be centered at. - /// Size of the rendered cube. - static void Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); + /// + /// Matrix transformation that defines how the cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); /// - /// Renders a wireframe sphere centered around the position specified in world space. + /// Draws a filled cube in world space. /// - /// Colour of the sphere. - /// Position where the sphere wil be centered at. - /// Size of the rendered sphere. - static void Sphere(const SHVec4& color, const SHVec3& pos, double radius); + /// Center of the Cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// + /// Center of the Cube. + /// Orientation of the cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// + /// Center of the Cube. + /// Euler angle rotation of the cube in radians. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// + /// Center point of the sphere. + /// Size of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// + /// Center point of the sphere. + /// Orientation of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// + /// Center point of the sphere. + /// Euler angle rotation of the sphere in radians. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a cube in world space. + /// + /// + /// Matrix transformation that defines how the wire cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a cube in world space. + /// + /// Center of the Cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a sphere in world space. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a sphere in world space. + /// + /// Center point of the sphere. + /// Size of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + 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" */ /*---------------------------------------------------------------------------------*/ - /// - /// Renders a line between two points in world space that will persist until - /// ClearPersistentDraws() is called. - /// - /// Colour of the line. - /// First point of the line. - /// Second point of the line. - static void PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); - /// - /// Renders a triangle indicated by three points in world space that will persist - /// until ClearPersistentDraws() is called. - /// - /// Colour of the triangle. - /// First point of the triangle. - /// Second point of the triangle. - /// Third point of the triangle. - static void PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); - /// - /// Renders a quadrilateral indicated by four points in world space that will persist - /// until ClearPersistentDraws() is called. - /// - /// Colour of the quadrilateral. - /// First point of the triangle. - /// Second point of the quadrilateral. - /// Third point of the quadrilateral. - /// Third point of the quadrilateral. - static void PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); - /// - /// Renders a polygon indicated by the specified set of points in world space that - /// will persist until ClearPersistentDraws() is called. - /// - /// Colour of the polygon. - /// List of points for the polygon. - static void PersistentPoly(const SHVec4& color, std::initializer_list pointList); - /// - /// Renders a wireframe cube centered around the position specified in world space - /// that will persist until ClearPersistentDraws() is called. - /// - /// Colour of the cube. - /// Position where the cube wil be centered at. - /// Size of the rendered cube. - static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); - /// - /// Renders a wireframe sphere centered around the position specified in world space - /// that will persist until ClearPersistentDraws() is called. - /// - /// Colour of the sphere. - /// Position where the sphere wil be centered at. - /// Size of the rendered sphere. - static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); - /// - /// Clears any persistent drawn debug primitives. - /// - static void ClearPersistentDraws(); + struct SH_API Persistent + { + /*-------------------------------------------------------------------------------*/ + /* Persistent Draw Functions */ + /*-------------------------------------------------------------------------------*/ + /// + /// Renders a line between two points in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// First point of the line. + /// Second point of the line. + /// Colour of the line. + /// Whether or not drawn object will be occluded. + static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Renders a triangle indicated by three points in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// First point of the triangle. + /// Second point of the triangle. + /// Third point of the triangle. + /// Colour of the triangle. + /// Whether or not drawn object will be occluded. + static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Renders a quadrilateral indicated by four points in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// First point of the triangle. + /// Second point of the quadrilateral. + /// Third point of the quadrilateral. + /// Third point of the quadrilateral. + /// Colour of the quadrilateral. + /// Whether or not drawn object will be occluded. + static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a 2-dimensional circle in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// + /// Matrix transformation that defines how the circle should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Renders a polygon indicated by the specified set of points in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// List of points for the polygon. + /// Colour of the polygon. + /// Whether or not drawn object will be occluded. + static void LineLoop(std::initializer_list pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// + /// Matrix transformation that defines how the cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center of the Cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center of the Cube. + /// Orientation of the cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center of the Cube. + /// Euler angle rotation of the cube in radians. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center point of the sphere. + /// Size of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center point of the sphere. + /// Orientation of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws a filled sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center point of the sphere. + /// Euler angle rotation of the sphere in radians. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// + /// Matrix transformation that defines how the wire cube should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the outline of a cube in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center of the Cube. + /// Size of the Cube. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// + /// Matrix transformation that defines how the sphere should be drawn. + /// + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Draws the wireframe of a sphere in world space. + /// This will remain drawn until ClearDraws() is called. + /// + /// Center point of the sphere. + /// Size of the sphere. + /// Colour to draw with. + /// Whether or not drawn object will be occluded. + static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false); + /// + /// Clears any persistent drawn debug primitives. + /// + static void ClearDraws(); + }; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Utility/Gizmos.cxx b/SHADE_Managed/src/Utility/Gizmos.cxx index 21636a5d..cccdbad1 100644 --- a/SHADE_Managed/src/Utility/Gizmos.cxx +++ b/SHADE_Managed/src/Utility/Gizmos.cxx @@ -44,7 +44,27 @@ namespace SHADE 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) @@ -54,7 +74,7 @@ namespace SHADE 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) @@ -64,6 +84,6 @@ namespace SHADE 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)); } } diff --git a/SHADE_Managed/src/Utility/Gizmos.hxx b/SHADE_Managed/src/Utility/Gizmos.hxx index 1878d867..f96f1261 100644 --- a/SHADE_Managed/src/Utility/Gizmos.hxx +++ b/SHADE_Managed/src/Utility/Gizmos.hxx @@ -56,6 +56,38 @@ namespace SHADE /// Colour of the line. static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color); /// + /// Renders a cube centered around the position specified in world + /// space. + /// Uses Color to render. + /// + /// Position where the cube wil be centered at. + /// Size of the rendered cube. + static void DrawCube(Vector3 center, Vector3 extents); + /// + /// Renders a cube centered around the position specified in world + /// space. + /// + /// Position where the cube wil be centered at. + /// Size of the rendered cube. + /// Colour of the cube. + static void DrawCube(Vector3 center, Vector3 extents, SHADE::Color color); + /// + /// Renders a sphere centered around the position specified in world + /// space. + /// Uses Color to render. + /// + /// Position where the sphere wil be centered at. + /// Radius of the rendered sphere. + static void DrawSphere(Vector3 center, float radius); + /// + /// Renders a sphere centered around the position specified in world + /// space. + /// + /// Position where the sphere wil be centered at. + /// Radius of the rendered sphere. + /// Colour of the sphere. + static void DrawSphere(Vector3 center, float radius, SHADE::Color color); + /// /// Renders a wireframe cube centered around the position specified in world /// space. /// Uses Color to render.