From 389a2903623647da2c2ab46bfce4ebe5fb9c9b34 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 22 Feb 2023 13:41:52 -0800 Subject: [PATCH] Added basic debug lines --- cmake/CMakeLists.txt | 20 ++- src/dawn/CMakeLists.txt | 9 +- src/dawn/display/RenderPipeline.cpp | 31 ++++- src/dawn/display/RenderPipeline.hpp | 1 + src/dawn/display/shader/Shader.hpp | 124 +++++++++--------- src/dawn/prefabs/SimpleSpinningCubePrefab.hpp | 2 +- src/dawn/scene/CMakeLists.txt | 34 ++--- src/dawn/scene/Scene.hpp | 10 +- src/dawn/scene/debug/CMakeLists.txt | 10 ++ src/dawn/scene/debug/SceneDebugLine.cpp | 100 ++++++++++++++ src/dawn/scene/debug/SceneDebugLine.hpp | 48 +++++++ src/dawnopengl/display/mesh/Mesh.hpp | 3 +- .../display/shader/SimpleTexturedShader.cpp | 90 ++++++------- .../display/shader/SimpleTexturedShader.hpp | 3 +- src/dawntictactoe/scenes/TicTacToeScene.hpp | 11 +- 15 files changed, 357 insertions(+), 139 deletions(-) create mode 100644 src/dawn/scene/debug/CMakeLists.txt create mode 100644 src/dawn/scene/debug/SceneDebugLine.cpp create mode 100644 src/dawn/scene/debug/SceneDebugLine.hpp diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index aac45b2a..74968aea 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,7 +1,15 @@ -# Copyright (c) 2022 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -add_subdirectory(hosts) +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Defines +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(DAWN_DEBUG_BUILD true CACHE INTERNAL ${DAWN_CACHE_TARGET}) +else() + set(DAWN_DEBUG_BUILD false CACHE INTERNAL ${DAWN_CACHE_TARGET}) +endif() + +# Includes +add_subdirectory(hosts) add_subdirectory(targets) \ No newline at end of file diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt index fb66e0fd..5d3fa62e 100644 --- a/src/dawn/CMakeLists.txt +++ b/src/dawn/CMakeLists.txt @@ -38,4 +38,11 @@ add_subdirectory(ui) if(DAWN_VISUAL_NOVEL) add_subdirectory(visualnovel) -endif() \ No newline at end of file +endif() + +# Definitions +target_compile_definitions(${DAWN_TARGET_NAME} + PUBLIC + ${DAWN_SHARED_DEFINITIONS} + DAWN_DEBUG_BUILD=${DAWN_DEBUG_BUILD} +) \ No newline at end of file diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp index 56d902f7..49d74803 100644 --- a/src/dawn/display/RenderPipeline.cpp +++ b/src/dawn/display/RenderPipeline.cpp @@ -6,6 +6,10 @@ #include "RenderPipeline.hpp" #include "game/DawnGame.hpp" +#if DAWN_DEBUG_BUILD + #include "scene/debug/SceneDebugLine.hpp" +#endif + using namespace Dawn; RenderPipeline::RenderPipeline(RenderManager *renderManager) { @@ -159,6 +163,27 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { ++itCanvas; } + // Debug Lines + #if DAWN_DEBUG_BUILD + Mesh lineMesh; + int32_t lineIndex = 0; + lineMesh.createBuffers( + scene->debugLines.size() * SCENE_DEBUG_LINE_VERTICE_COUNT, + scene->debugLines.size() * SCENE_DEBUG_LINE_INDICE_COUNT + ); + auto itDebugLine = scene->debugLines.begin(); + while(itDebugLine != scene->debugLines.end()) { + auto item = itDebugLine->createShaderItem( + &lineMesh, + &lineIndex, + camera, + &this->renderManager->simpleShader + ); + shaderPassItems.push_back(item); + ++itDebugLine; + } + #endif + // Now we've queued everything, let's sort the rendering queue by the priority std::sort( shaderPassItems.begin(), @@ -246,11 +271,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { this->renderManager->setRenderFlags(item.renderFlags); // Thank god that's done, now just draw the damn mesh. - item.mesh->draw( - MESH_DRAW_MODE_TRIANGLES, - item.start, - item.count - ); + item.mesh->draw(item.drawMode, item.start, item.count); ++itPassItem; } } diff --git a/src/dawn/display/RenderPipeline.hpp b/src/dawn/display/RenderPipeline.hpp index bd601f7d..e8541540 100644 --- a/src/dawn/display/RenderPipeline.hpp +++ b/src/dawn/display/RenderPipeline.hpp @@ -11,6 +11,7 @@ #include "scene/components/scene/SubSceneController.hpp" #include "ui/UIComponent.hpp" + namespace Dawn { class RenderManager; diff --git a/src/dawn/display/shader/Shader.hpp b/src/dawn/display/shader/Shader.hpp index 25235d9d..f50c3048 100644 --- a/src/dawn/display/shader/Shader.hpp +++ b/src/dawn/display/shader/Shader.hpp @@ -1,62 +1,64 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "display/shader/ShaderProgram.hpp" -#include "scene/components/display/MeshRenderer.hpp" -#include "scene/components/display/Camera.hpp" -#include "display/_RenderManager.hpp" - -namespace Dawn { - class Material; - - struct ShaderPassItem { - ShaderProgram *shaderProgram = nullptr; - int32_t priority = 0; - - Mesh *mesh; - int32_t start = 0; - int32_t count = -1; - float_t w = 0; - renderflag_t renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST; - - // Parameters - std::map colorValues; - std::map boolValues; - std::map matrixValues; - std::map vec3Values; - std::map textureValues; - std::map floatValues; - - // Textures - std::map textureSlots; - }; - - class Shader { - public: - int_fast16_t renderId = 0; - - /** - * Compile all programs for this shader. This amy not remain forever as I - * may decide to allow shaders to share programs somehow. For now though - * this is clean enough. - */ - virtual void compile() = 0; - - /** - * Returns the list of pass items to render for the given scene item. - * - * @param mesh Mesh Renderer for the scene item. - * @param material Material for the scene item. - * @param camera Camera for the scene. - * @return List of passes to render. - */ - virtual std::vector getPassItems( - Mesh *mesh, - Material *material, - Camera *camera - ) = 0; - }; +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/shader/ShaderProgram.hpp" +#include "display/mesh/Mesh.hpp" +#include "display/_RenderManager.hpp" + +namespace Dawn { + class Material; + class MeshRenderer; + class Camera; + + struct ShaderPassItem { + ShaderProgram *shaderProgram = nullptr; + int32_t priority = 0; + + Mesh *mesh; + int32_t start = 0; + int32_t count = -1; + float_t w = 0; + renderflag_t renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST; + enum MeshDrawMode drawMode = MESH_DRAW_MODE_TRIANGLES; + + // Parameters + std::map colorValues; + std::map boolValues; + std::map matrixValues; + std::map vec3Values; + std::map textureValues; + std::map floatValues; + + // Textures + std::map textureSlots; + }; + + class Shader { + public: + int_fast16_t renderId = 0; + + /** + * Compile all programs for this shader. This amy not remain forever as I + * may decide to allow shaders to share programs somehow. For now though + * this is clean enough. + */ + virtual void compile() = 0; + + /** + * Returns the list of pass items to render for the given scene item. + * + * @param mesh Mesh Renderer for the scene item. + * @param material Material for the scene item. + * @param camera Camera for the scene. + * @return List of passes to render. + */ + virtual std::vector getPassItems( + Mesh *mesh, + Material *material, + Camera *camera + ) = 0; + }; } \ No newline at end of file diff --git a/src/dawn/prefabs/SimpleSpinningCubePrefab.hpp b/src/dawn/prefabs/SimpleSpinningCubePrefab.hpp index 0c21eec3..972acfe2 100644 --- a/src/dawn/prefabs/SimpleSpinningCubePrefab.hpp +++ b/src/dawn/prefabs/SimpleSpinningCubePrefab.hpp @@ -31,7 +31,7 @@ namespace Dawn { void prefabInit(AssetManager *man) override { auto meshRenderer = this->addComponent(); meshHost = this->addComponent(); - // auto spinning = this->addComponent(); + auto spinning = this->addComponent(); material = this->addComponent(); meshHost->mesh.createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT); diff --git a/src/dawn/scene/CMakeLists.txt b/src/dawn/scene/CMakeLists.txt index d28de14d..1c943bb4 100644 --- a/src/dawn/scene/CMakeLists.txt +++ b/src/dawn/scene/CMakeLists.txt @@ -1,15 +1,19 @@ -# Copyright (c) 2022 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DAWN_TARGET_NAME} - PRIVATE - Scene.cpp - SceneItem.cpp - SceneItemComponent.cpp -) - -# Subdirs -add_subdirectory(components) \ No newline at end of file +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + Scene.cpp + SceneItem.cpp + SceneItemComponent.cpp +) + +# Subdirs +add_subdirectory(components) + +if(DAWN_DEBUG_BUILD) + add_subdirectory(debug) +endif() \ No newline at end of file diff --git a/src/dawn/scene/Scene.hpp b/src/dawn/scene/Scene.hpp index 1af075b1..b54e9c7e 100644 --- a/src/dawn/scene/Scene.hpp +++ b/src/dawn/scene/Scene.hpp @@ -6,6 +6,7 @@ #pragma once #include "event/Event.hpp" #include "asset/Asset.hpp" +#include "scene/debug/SceneDebugLine.hpp" namespace Dawn { class DawnGame; @@ -23,7 +24,7 @@ namespace Dawn { sceneitemid_t nextId; std::map items; std::map itemsNotInitialized; - + public: DawnGame *game; Event<> eventSceneUpdate; @@ -130,6 +131,13 @@ namespace Dawn { return components; } + // Scene debugging functions + #if DAWN_DEBUG_BUILD + std::vector debugLines; + void debugLine(struct SceneDebugLine line); + void debugCube(struct SceneDebugCube cube); + #endif + /** * Destroys a previously initialized Scene. */ diff --git a/src/dawn/scene/debug/CMakeLists.txt b/src/dawn/scene/debug/CMakeLists.txt new file mode 100644 index 00000000..b9d7ed5d --- /dev/null +++ b/src/dawn/scene/debug/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + SceneDebugLine.cpp +) \ No newline at end of file diff --git a/src/dawn/scene/debug/SceneDebugLine.cpp b/src/dawn/scene/debug/SceneDebugLine.cpp new file mode 100644 index 00000000..88d0e8c7 --- /dev/null +++ b/src/dawn/scene/debug/SceneDebugLine.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "SceneDebugLine.hpp" +#include "display/shader/SimpleTexturedShader.hpp" +#include "scene/components/display/Camera.hpp" +#include "scene/Scene.hpp" + +using namespace Dawn; + +struct ShaderPassItem SceneDebugLine::createShaderItem( + Mesh *mesh, + int32_t *lineIndex, + Camera *camera, + SimpleTexturedShader *shader +) { + struct ShaderPassItem item; + item.priority = SCENE_DEBUG_LINE_PRIORITY; + + item.shaderProgram = &shader->program; + item.colorValues[shader->program.paramColor] = this->color; + item.matrixValues[shader->program.paramModel] = this->translation; + item.matrixValues[shader->program.paramView] = camera->transform->getWorldTransform(); + item.matrixValues[shader->program.paramProjection] = camera->projection; + item.boolValues[shader->program.paramHasTexture] = false; + + item.renderFlags = 0x00; + + auto i = *lineIndex; + item.mesh = mesh; + item.drawMode = MESH_DRAW_MODE_LINES; + item.start = i * SCENE_DEBUG_LINE_INDICE_COUNT; + item.count = SCENE_DEBUG_LINE_INDICE_COUNT; + + glm::vec3 positions[SCENE_DEBUG_LINE_VERTICE_COUNT] = { this->v0, this->v1 }; + mesh->bufferPositions( + i * SCENE_DEBUG_LINE_VERTICE_COUNT, + positions, + SCENE_DEBUG_LINE_VERTICE_COUNT + ); + + meshindice_t indices[SCENE_DEBUG_LINE_INDICE_COUNT] = { + i * SCENE_DEBUG_LINE_VERTICE_COUNT, + (i*SCENE_DEBUG_LINE_VERTICE_COUNT) + 1 + }; + mesh->bufferIndices( + i * SCENE_DEBUG_LINE_INDICE_COUNT, + indices, + SCENE_DEBUG_LINE_INDICE_COUNT + ); + + (*lineIndex)++; + return item; +} + +// Scene Implementations (done here to keep things cleaner in scene) +void Scene::debugLine(struct SceneDebugLine line) { + this->debugLines.push_back(line); +} + +void Scene::debugCube(struct SceneDebugCube cube) { + auto min = cube.min; + auto max = cube.max; + + struct SceneDebugLine line; + line.color = cube.color; + line.translation = cube.translation; + + // Bottom Face + line.v0 = glm::vec3(min.x, min.y, min.z), line.v1 = glm::vec3(max.x, min.y, min.z); + this->debugLine(line); + line.v0 = glm::vec3(min.x, min.y, min.z), line.v1 = glm::vec3(min.x, min.y, max.z); + this->debugLine(line); + line.v0 = glm::vec3(max.x, min.y, min.z), line.v1 = glm::vec3(max.x, min.y, max.z); + this->debugLine(line); + line.v0 = glm::vec3(min.x, min.y, max.z), line.v1 = glm::vec3(max.x, min.y, max.z); + this->debugLine(line); + + // Top Face + line.v0 = glm::vec3(min.x, max.y, min.z), line.v1 = glm::vec3(max.x, max.y, min.z); + this->debugLine(line); + line.v0 = glm::vec3(min.x, max.y, min.z), line.v1 = glm::vec3(min.x, max.y, max.z); + this->debugLine(line); + line.v0 = glm::vec3(max.x, max.y, min.z), line.v1 = glm::vec3(max.x, max.y, max.z); + this->debugLine(line); + line.v0 = glm::vec3(min.x, max.y, max.z), line.v1 = glm::vec3(max.x, max.y, max.z); + this->debugLine(line); + + // Rails + line.v0 = glm::vec3(min.x, min.y, min.z), line.v1 = glm::vec3(min.x, max.y, min.z); + this->debugLine(line); + line.v0 = glm::vec3(max.x, min.y, min.z), line.v1 = glm::vec3(max.x, max.y, min.z); + this->debugLine(line); + line.v0 = glm::vec3(min.x, min.y, max.z), line.v1 = glm::vec3(min.x, max.y, max.z); + this->debugLine(line); + line.v0 = glm::vec3(max.x, min.y, max.z), line.v1 = glm::vec3(max.x, max.y, max.z); + this->debugLine(line); +} \ No newline at end of file diff --git a/src/dawn/scene/debug/SceneDebugLine.hpp b/src/dawn/scene/debug/SceneDebugLine.hpp new file mode 100644 index 00000000..a0bf9b77 --- /dev/null +++ b/src/dawn/scene/debug/SceneDebugLine.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/Color.hpp" +#include "display/mesh/Mesh.hpp" +#include "display/shader/Shader.hpp" + +#define SCENE_DEBUG_LINE_VERTICE_COUNT 2 +#define SCENE_DEBUG_LINE_INDICE_COUNT 2 +#define SCENE_DEBUG_LINE_PRIORITY 100 + +namespace Dawn { + class SimpleTexturedShader; + class Camera; + + struct SceneDebugCube { + glm::vec3 min; + glm::vec3 max; + struct Color color = COLOR_RED; + glm::mat4 translation = glm::mat4(1.0f); + }; + + struct SceneDebugLine { + glm::vec3 v0 = glm::vec3(0, 0, 0); + glm::vec3 v1 = glm::vec3(1, 1, 1); + struct Color color = COLOR_RED; + glm::mat4 translation = glm::mat4(1.0f); + + /** + * Creates a renderable shader item for this debug line. + * + * @param mesh Mesh that this debug line will buffer its indices in to + * @param lineIndex Currently iterated line index. + * @param camera Camera for this line index to set the shader params for. + * @param shader Shader that the params will be set for. + * @return The queueable shader pass item. + */ + struct ShaderPassItem createShaderItem( + Mesh *mesh, + int32_t *lineIndex, + Camera *camera, + SimpleTexturedShader *shader + ); + }; +} \ No newline at end of file diff --git a/src/dawnopengl/display/mesh/Mesh.hpp b/src/dawnopengl/display/mesh/Mesh.hpp index f85e6668..e32b3c8e 100644 --- a/src/dawnopengl/display/mesh/Mesh.hpp +++ b/src/dawnopengl/display/mesh/Mesh.hpp @@ -13,7 +13,8 @@ typedef int32_t meshindice_t; namespace Dawn { enum MeshDrawMode { - MESH_DRAW_MODE_TRIANGLES = GL_TRIANGLES + MESH_DRAW_MODE_TRIANGLES = GL_TRIANGLES, + MESH_DRAW_MODE_LINES = GL_LINES }; class Mesh { diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.cpp b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp index 5f7376d1..2a9acd49 100644 --- a/src/dawnopengl/display/shader/SimpleTexturedShader.cpp +++ b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp @@ -1,45 +1,47 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "SimpleTexturedShader.hpp" - -using namespace Dawn; - -void SimpleTexturedShader::compile() { - this->program.compile(); -} - -std::vector SimpleTexturedShader::getPassItems( - Mesh *mesh, - Material *material, - Camera *camera -) { - SimpleTexturedMaterial *simpleMaterial = dynamic_cast(material); - assertNotNull(simpleMaterial); - - struct ShaderPassItem onlyPass; - onlyPass.mesh = mesh; - onlyPass.shaderProgram = &program; - onlyPass.colorValues[program.paramColor] = simpleMaterial->color; - onlyPass.matrixValues[program.paramModel] = material->transform->getWorldTransform(); - onlyPass.matrixValues[program.paramView] = camera->transform->getWorldTransform(); - onlyPass.matrixValues[program.paramProjection] = camera->projection; - onlyPass.renderFlags = ( - RENDER_MANAGER_RENDER_FLAG_BLEND | - RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST - ); - - if(simpleMaterial->texture != nullptr) { - onlyPass.boolValues[program.paramHasTexture] = true; - onlyPass.textureSlots[0] = simpleMaterial->texture; - onlyPass.textureValues[program.paramTexture] = 0; - } else { - onlyPass.boolValues[program.paramHasTexture] = false; - } - - std::vector passes; - passes.push_back(onlyPass); - return passes; +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "SimpleTexturedShader.hpp" +#include "scene/components/display/MeshRenderer.hpp" +#include "scene/components/display/Camera.hpp" + +using namespace Dawn; + +void SimpleTexturedShader::compile() { + this->program.compile(); +} + +std::vector SimpleTexturedShader::getPassItems( + Mesh *mesh, + Material *material, + Camera *camera +) { + SimpleTexturedMaterial *simpleMaterial = dynamic_cast(material); + assertNotNull(simpleMaterial); + + struct ShaderPassItem onlyPass; + onlyPass.mesh = mesh; + onlyPass.shaderProgram = &program; + onlyPass.colorValues[program.paramColor] = simpleMaterial->color; + onlyPass.matrixValues[program.paramModel] = material->transform->getWorldTransform(); + onlyPass.matrixValues[program.paramView] = camera->transform->getWorldTransform(); + onlyPass.matrixValues[program.paramProjection] = camera->projection; + onlyPass.renderFlags = ( + RENDER_MANAGER_RENDER_FLAG_BLEND | + RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST + ); + + if(simpleMaterial->texture != nullptr) { + onlyPass.boolValues[program.paramHasTexture] = true; + onlyPass.textureSlots[0] = simpleMaterial->texture; + onlyPass.textureValues[program.paramTexture] = 0; + } else { + onlyPass.boolValues[program.paramHasTexture] = false; + } + + std::vector passes; + passes.push_back(onlyPass); + return passes; } \ No newline at end of file diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp index acae63d3..0ab4370a 100644 --- a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp +++ b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp @@ -10,10 +10,9 @@ namespace Dawn { class SimpleTexturedShader : public Shader { - protected: + public: SimpleTexturedShaderProgram program; - public: void compile() override; std::vector getPassItems( diff --git a/src/dawntictactoe/scenes/TicTacToeScene.hpp b/src/dawntictactoe/scenes/TicTacToeScene.hpp index 09e6c7d9..b6bdf535 100644 --- a/src/dawntictactoe/scenes/TicTacToeScene.hpp +++ b/src/dawntictactoe/scenes/TicTacToeScene.hpp @@ -17,8 +17,9 @@ namespace Dawn { void stage() override { camera = Camera::create(this); - camera->transform->lookAt(glm::vec3(0, 0, 5), glm::vec3(0, 0, 0)); - camera->type = CAMERA_TYPE_ORTHONOGRAPHIC; + // camera->transform->lookAt(glm::vec3(0, 0, 5), glm::vec3(0, 0, 0)); + // camera->type = CAMERA_TYPE_ORTHONOGRAPHIC; + camera->transform->lookAt(glm::vec3(1, 2, 3), glm::vec3(0, 0, 0)); float_t s = 2.0f; camera->orthoTop = -s; @@ -43,6 +44,12 @@ namespace Dawn { // tile->ticTacToe->setState(i % 2 == 0 ? TIC_TAC_TOE_CROSS : TIC_TAC_TOE_NOUGHT); } } + + this->debugCube((struct SceneDebugCube){ + .min = glm::vec3(-0.5f, -0.5f, -0.5f), + .max = glm::vec3(0.5f, 0.5f, 0.5f), + COLOR_BLUE + }); } std::vector getRequiredAssets() override {