diff --git a/CMakeLists.txt b/CMakeLists.txt index 398e633..5f276cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,6 @@ enable_testing() # Targets #========================================= add_executable(CaderaApp src/cadera.cpp - src/selection.cpp src/callbacks.cpp src/main.cpp ) @@ -41,6 +40,7 @@ target_include_directories(pch_interface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/s target_include_directories(CaderaApp PRIVATE src/) +add_subdirectory(src/input) add_subdirectory(src/render) add_subdirectory(src/sketch) add_subdirectory(src/text) @@ -51,8 +51,6 @@ add_subdirectory(src/ux) # Libraries #========================================= - - find_package(Vulkan REQUIRED) target_link_libraries(pch_interface INTERFACE Vulkan::Vulkan) @@ -68,8 +66,8 @@ target_link_libraries(pch_interface INTERFACE glm::glm) find_package(Stb REQUIRED) target_include_directories(pch_interface INTERFACE ${Stb_INCLUDE_DIR}) -target_link_libraries(CaderaApp PRIVATE sketchlib) -target_link_libraries(CaderaApp PRIVATE textlib) +# Cadera Project Libraries +target_link_libraries(CaderaApp PRIVATE inputlib) # Precompiled Headers target_link_libraries(CaderaApp PUBLIC pch_interface) @@ -112,5 +110,12 @@ add_subdirectory(test) #========================================= set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) -install(TARGETS CaderaApp RUNTIME DESTINATION bin) +install(TARGETS CaderaApp + RUNTIME + DESTINATION bin) + +if(WIN32) + include(InstallRequiredSystemLibraries) +endif(WIN32) + include(CPack) diff --git a/src/cadera.cpp b/src/cadera.cpp index c5d8f1b..88880f2 100644 --- a/src/cadera.cpp +++ b/src/cadera.cpp @@ -5,14 +5,14 @@ namespace CADERA_APP_NAMESPACE { void Cadera::initCallbacks() { - glfwSetWindowUserPointer(Render.mMainWindow, this); + glfwSetWindowUserPointer(mRender.mMainWindow, &this->input); - glfwSetMouseButtonCallback(Render.mMainWindow, mouse_button_callback); - glfwSetScrollCallback(Render.mMainWindow, scroll_callback); - glfwSetFramebufferSizeCallback(Render.mMainWindow, + glfwSetMouseButtonCallback(mRender.mMainWindow, mouse_button_callback); + glfwSetScrollCallback(mRender.mMainWindow, scroll_callback); + glfwSetFramebufferSizeCallback(mRender.mMainWindow, framebuffer_resize_callback); - glfwSetCursorPosCallback(Render.mMainWindow, cursor_position_callback); - glfwSetKeyCallback(Render.mMainWindow, key_callback); + glfwSetCursorPosCallback(mRender.mMainWindow, cursor_position_callback); + glfwSetKeyCallback(mRender.mMainWindow, key_callback); } Cadera::Cadera() { @@ -20,84 +20,30 @@ Cadera::Cadera() { // Sketch.setType(cad_sketch); } -Cadera::~Cadera() { Render.destroy(); } - -void Cadera::SketchEvents() { - - if (flags.test(cadera_delete) && !Render.Sel.selectedPoints.empty()) { - Sketch.deletion(Render.Sel.getSelectedPointIds()); - Render.Sel.clear(); - Render.Sel.setFlags(); - Render.flags.set(render_update_sketch); - flags.reset(cadera_delete); - } else { - flags.reset(cadera_delete); - } - - if (Render.flags.test(render_update_sketch)) { - Render.render(Sketch); - } - - if (Sketch.flags.test(sketch::skt_move_points)) { - - Render.Sel.select(Render.Cam.mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), - Render.Cam.cameraVec, Render.Cam.pos, Render.Cam.cross, - Render.Cam.flags.test(cad::cam::ortho)); - - Sketch.movePoints(Render.Sel.selectedPoints, Render.Sel.point, - Render.Sel.flags.test(cad::sel::select_first_click)); - - std::vector ids = Render.Sel.getSelectedPointIds(); - - std::map newPoints; - - for (const auto &id : ids) { - newPoints[id] = Sketch.Points[id]; - } - - Render.Sel.update(newPoints); - - Render.Sel.flags.reset(cad::sel::select_first_click); - - Render.flags.set(render_update_sketch); - } - - if (Sketch.flags.test(sketch::skt_point_tool)) { - - Render.renderSketchPointTool(); - } - - if (Sketch.flags.test(sketch::skt_event_tool_deactivated)) { - Render.deleteBuffer(BufferName::sketch_point_tool); - Sketch.flags.reset(sketch::skt_event_tool_deactivated); - } -} +Cadera::~Cadera() { mRender.destroy(); } void Cadera::run() { - Render.setBGColor(glm::vec4(0.3f, 0.3f, 0.3f, 0.1f)); + mRender.setBGColor(glm::vec4(0.3f, 0.3f, 0.3f, 0.1f)); - Render.Cam.flags.set(cam::ortho); - Render.setup(); + mRender.Cam.flags.set(cam::ortho); + mRender.setup(); initCallbacks(); - Render.initImgui(); + mRender.initImgui(); - Render.SktSolver.setActiveSketch(&Sketch); + mSelector.addRender(&mRender); + //Keyboard and Mouse Commands + input.setSketchCommands(&mSketch, &mRender.Cam, &mSelector); + input.setCameraCommands(&mRender.Cam); + input.setRenderCommands(&mRender); - // Mouse Commands - // TODO: Determine better way to handle commands - sketchAddPointCmd.setSketch(&Sketch); - sketchAddPointCmd.setSelector(&Render.Sel); - sketchAddPointCmd.setCamera(&Render.Cam); - - cameraZoomCmd.setCamera(&Render.Cam); - - Render.mouse.setScrollMouseSlot(&cameraZoomCmd); - Render.mouse.setLeftMouseSlot(&sketchAddPointCmd); + input.setMouse(); + input.setKeyboard(); + mainLoop(); } @@ -109,17 +55,19 @@ void Cadera::run() { */ void Cadera::mainLoop() { - while (!glfwWindowShouldClose(Render.mMainWindow)) { + while (!glfwWindowShouldClose(mRender.mMainWindow)) { glfwPollEvents(); - gui::imguiRun(Sketch, Render, Render.Sel); + gui::imguiRun(mSketch, mRender, mSelector); + + input.sketchMode(mSketch.flags); - SketchEvents(); + mRender.createCommandBuffers(); + mRender.drawFrame(); + mRender.runCamera(); - Render.createCommandBuffers(); - Render.drawFrame(); - Render.runCamera(); + mRender.render(); glfwWaitEvents(); } diff --git a/src/cadera.hpp b/src/cadera.hpp index 7e714fe..514313f 100644 --- a/src/cadera.hpp +++ b/src/cadera.hpp @@ -1,5 +1,6 @@ #pragma once #include "ux/gui.hpp" +#include "callbacks.hpp" namespace CADERA_APP_NAMESPACE { @@ -27,14 +28,22 @@ class Cadera { int modelIdCounter; + sel::Selector mSelector; + CADRender mRender; + + sketch::Sketch mSketch; + public: // TODO: Restructure - command::SketchAddPointCommand sketchAddPointCmd; - command::CameraZoomCommand cameraZoomCmd; + + + + command::Input input; //------------- - CADRender Render; - sketch::Sketch Sketch; + + + std::bitset flags; @@ -42,8 +51,6 @@ class Cadera { ~Cadera(); - void SketchEvents(); - void run(); void mainLoop(); diff --git a/src/callbacks.cpp b/src/callbacks.cpp index c797cd9..59c388f 100644 --- a/src/callbacks.cpp +++ b/src/callbacks.cpp @@ -2,17 +2,10 @@ #include "cadera.hpp" #include "pch.hpp" -void sketch_mode_callbacks(cad::Cadera *app, int &button, int &action, - int &mods); - -void sketch_select_addPoint(cad::Cadera *app); - -void sketch_select_removePoint(cad::Cadera *app); - void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { - auto app = reinterpret_cast( + auto input = reinterpret_cast( glfwGetWindowUserPointer(window)); ImGuiIO &io = ImGui::GetIO(); @@ -20,20 +13,24 @@ void mouse_button_callback(GLFWwindow *window, int button, int action, // (2) ONLY forward mouse data to your underlying app/game. if (!io.WantCaptureMouse) { - if (app->Sketch.flags.test(CADERA_APP_NAMESPACE::sketch::skt_active)) { - - sketch_mode_callbacks(app, button, action, mods); + if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { + + input->mouse.leftMouseClick(); + + } else if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) { + + input->mouse.leftMouseRelease(); } + if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS) { - app->Render.Cam.flags.set(cad::cam::pan); - app->Render.Cam.flags.set(cad::cam::mouseFirstPressed); + input->mouse.middleMouseClick(); } if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_RELEASE) { - app->Render.Cam.flags.reset(cad::cam::pan); + input->mouse.middleMouseRelease(); } } @@ -46,104 +43,64 @@ void mouse_button_callback(GLFWwindow *window, int button, int action, void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) { - auto app = reinterpret_cast( + auto input = reinterpret_cast( glfwGetWindowUserPointer(window)); if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_::ImGuiHoveredFlags_AnyWindow)) { - app->Render.mouse.scroll(yoffset); + input->mouse.scroll(yoffset); } } void framebuffer_resize_callback(GLFWwindow *window, int width, int height) { - auto app = reinterpret_cast( + auto input = reinterpret_cast( glfwGetWindowUserPointer(window)); - app->Render.frameBufferResized = true; + input->framebufferResized(); + } void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { - auto app = reinterpret_cast( + auto input = reinterpret_cast( glfwGetWindowUserPointer(window)); if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - app->Sketch.deactivateTools(); + input->keyboard.escapePress(); } if (key == GLFW_KEY_DELETE && action == GLFW_PRESS) { - app->flags.set(CADERA_APP_NAMESPACE::cadera_delete); + + input->keyboard.deletePress(); + } if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_PRESS) { - app->Render.Sel.flags.set(CADERA_APP_NAMESPACE::sel::select_isCTRL); + input->keyboard.lCtrlPress(); } if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_RELEASE) { - app->Render.Sel.flags.reset(CADERA_APP_NAMESPACE::sel::select_isCTRL); + input->keyboard.lCtrlRelease(); } } -void cursor_position_callback(GLFWwindow *window, double xpos, double ypos) {} - -void sketch_mode_callbacks(cad::Cadera *app, int &button, int &action, - int &mods) { - - if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { - if (app->Sketch.flags.test(CADERA_APP_NAMESPACE::sketch::skt_tool_active)) { - - app->Render.mouse.leftMouseClick(); - - app->Render.flags.set(CADERA_APP_NAMESPACE::render_update_sketch); - } - else { - - sketch_select_addPoint(app); - app->Sketch.flags.set(cad::sketch::skt_move_points); - } - - } else if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) { +void cursor_position_callback(GLFWwindow *window, double xpos, double ypos) { - if (!app->Sketch.flags.test( - CADERA_APP_NAMESPACE::sketch::skt_tool_active)) { - - if (!app->Sketch.flags.test(cad::sketch::skt_points_have_moved)) - sketch_select_removePoint(app); - - app->Render.Sel.flags.set(cad::sel::select_first_click); - app->Sketch.flags.reset(cad::sketch::skt_move_points); - app->Sketch.flags.reset(cad::sketch::skt_points_have_moved); - } + // Only run when left mouse button is being held + if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE) + { + return; } -} -void sketch_select_addPoint(cad::Cadera *app) { - - app->Render.Sel.select(app->Render.Cam.mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), - app->Render.Cam.cameraVec, app->Render.Cam.pos, - app->Render.Cam.cross, - app->Render.Cam.flags.test(cad::cam::ortho)); - - int id = app->Render.Sel.add(app->Render.Sel.point, app->Sketch.Points, - app->Render.Cam.camDistance); + ImGuiIO &io = ImGui::GetIO(); + + auto input = reinterpret_cast( + glfwGetWindowUserPointer(window)); - if (id >= 0 || app->Render.Sel.selectedPoints.empty()) { - app->Render.flags.set(cad::render_update_sketch); + if (!io.WantCaptureMouse) { + input->mouse.leftMouseHold(); } -} - -void sketch_select_removePoint(cad::Cadera *app) { - app->Render.Sel.select(app->Render.Cam.mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), - app->Render.Cam.cameraVec, app->Render.Cam.pos, - app->Render.Cam.cross, - app->Render.Cam.flags.test(cad::cam::ortho)); - - int id = app->Render.Sel.remove(app->Render.Sel.point, app->Sketch.Points, - app->Render.Cam.camDistance); +} - if (id >= 0 || app->Render.Sel.selectedPoints.empty()) { - app->Render.flags.set(cad::render_update_sketch); - } -} \ No newline at end of file diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt new file mode 100644 index 0000000..67ac39d --- /dev/null +++ b/src/input/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.5) + + + + + +add_library(inputlib ${CMAKE_CURRENT_LIST_DIR}/input.cpp + ${CMAKE_CURRENT_LIST_DIR}/keyboard.cpp + ${CMAKE_CURRENT_LIST_DIR}/mouse.cpp + ${CMAKE_CURRENT_LIST_DIR}/command.cpp + ${CMAKE_CURRENT_LIST_DIR}/sketchcommands.cpp + ${CMAKE_CURRENT_LIST_DIR}/rendercommands.cpp + ${CMAKE_CURRENT_LIST_DIR}/cameracommands.cpp + ) + +target_include_directories(inputlib PRIVATE ${CMAKE_CURRENT_LIST_DIR}/) + +target_link_libraries(inputlib PUBLIC renderlib) \ No newline at end of file diff --git a/src/input/cameracommands.cpp b/src/input/cameracommands.cpp new file mode 100644 index 0000000..1d03c03 --- /dev/null +++ b/src/input/cameracommands.cpp @@ -0,0 +1,59 @@ +#include "cameracommands.hpp" +#include "pch.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + + +// Camera Zoom Command +//----------------------------------------------------------------------------- +CameraZoomCommand::CameraZoomCommand() : mCamera{nullptr} {} + + +void CameraZoomCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void CameraZoomCommand::execute(double yoffset) { + if (mCamera) { + + mCamera->zoom(static_cast(yoffset)); + + } +} +//----------------------------------------------------------------------------- + +// Camera Pan Command +//----------------------------------------------------------------------------- +CameraPanCommand::CameraPanCommand() : mCamera{nullptr} {} + +void CameraPanCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void CameraPanCommand::execute() { + if (mCamera) { + mCamera->flags.set(cad::cam::pan); + mCamera->flags.set(cad::cam::mouseFirstPressed); + } +} +//----------------------------------------------------------------------------- + +// Camera Unset Pan Command +//----------------------------------------------------------------------------- +CameraUnsetPanCommand::CameraUnsetPanCommand() : mCamera{nullptr} {} + +void CameraUnsetPanCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void CameraUnsetPanCommand::execute() { + if (mCamera) { + mCamera->flags.reset(cad::cam::pan); + } +} +//----------------------------------------------------------------------------- + +} +} \ No newline at end of file diff --git a/src/input/cameracommands.hpp b/src/input/cameracommands.hpp new file mode 100644 index 0000000..3541b2e --- /dev/null +++ b/src/input/cameracommands.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "sketchcommands.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + + +class CameraZoomCommand : public Command { +public: + + CameraZoomCommand(); + + void setCamera(cam::Camera* cam); + + void execute(double) override; + +private: + cam::Camera* mCamera; + +}; + +class CameraPanCommand : public Command { +public: + + CameraPanCommand(); + + void setCamera(cam::Camera* cam); + + void execute() override; + +private: + cam::Camera* mCamera; + +}; + +class CameraUnsetPanCommand : public Command { +public: + + CameraUnsetPanCommand(); + + void setCamera(cam::Camera* cam); + + void execute() override; + +private: + cam::Camera* mCamera; + +}; + +} +} \ No newline at end of file diff --git a/src/ux/command/command.cpp b/src/input/command.cpp similarity index 100% rename from src/ux/command/command.cpp rename to src/input/command.cpp diff --git a/src/ux/command/command.hpp b/src/input/command.hpp similarity index 88% rename from src/ux/command/command.hpp rename to src/input/command.hpp index 66da265..0ddbbb2 100644 --- a/src/ux/command/command.hpp +++ b/src/input/command.hpp @@ -1,6 +1,6 @@ #pragma once -#include "render/camera.hpp" +#include "render/cadrender.hpp" namespace CADERA_APP_NAMESPACE { diff --git a/src/input/input.cpp b/src/input/input.cpp new file mode 100644 index 0000000..6209a8d --- /dev/null +++ b/src/input/input.cpp @@ -0,0 +1,99 @@ +#include "input.hpp" +#include "pch.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +Input::Input() : mFramebufferResizeSlot{nullptr} { + +} + +void Input::setFramebufferResizeSlot(Command* framebufferResizeCmd) { + mFramebufferResizeSlot = framebufferResizeCmd; +} + +void Input::framebufferResized() +{ + + if (mFramebufferResizeSlot) { + mFramebufferResizeSlot->execute(); + } + else { + throw std::runtime_error("Input Framebuffer Resize Slot not valid!\n"); + } +} + +void Input::setSketchCommands(sketch::Sketch *sketch, cam::Camera *camera, + sel::Selector *selector) { + + + sketchAddPointCmd.setSketch(sketch); + sketchAddPointCmd.setSelector(selector); + sketchAddPointCmd.setCamera(camera); + sketchMovePointCmd.setSketch(sketch); + sketchMovePointCmd.setSelector(selector); + sketchMovePointCmd.setCamera(camera); + sketchSelectPointCmd.setSketch(sketch); + sketchSelectPointCmd.setSelector(selector); + sketchSelectPointCmd.setCamera(camera); + sketchDeselectPointCmd.setSketch(sketch); + sketchDeselectPointCmd.setSelector(selector); + sketchDeselectPointCmd.setCamera(camera); + sketchSelectSetCtrlCmd.setSelector(selector); + sketchSelectUnsetCtrlCmd.setSelector(selector); + sketchDisableToolsCmd.setSketch(sketch); + sketchDeleteCmd.setSketch(sketch); + sketchDeleteCmd.setSelector(selector); + +} +void Input::setCameraCommands(cam::Camera *camera) { + + + cameraZoomCmd.setCamera(camera); + cameraPanCmd.setCamera(camera); + cameraUnsetPanCmd.setCamera(camera); + +} + +void Input::setRenderCommands(CADRender* render) { + + renderFramebufferResizeCmd.setRender(render); + + mFramebufferResizeSlot = &renderFramebufferResizeCmd; +} + +void Input::setMouse() { + + mouse.setScrollMouseSlot(&cameraZoomCmd); + mouse.setLeftMouseSlot(&sketchAddPointCmd); + mouse.setMiddleMouseSlot(&cameraPanCmd); + mouse.setMiddleMouseReleaseSlot(&cameraUnsetPanCmd); +} + +void Input::setKeyboard() { + + keyboard.setEscapeSlot(&sketchDisableToolsCmd); + keyboard.setDeleteSlot(&sketchDeleteCmd); + keyboard.setLCtrlSlot(&sketchSelectSetCtrlCmd); + keyboard.setLCtrlReleaseSlot(&sketchSelectUnsetCtrlCmd); + +} + +void Input::sketchMode(std::bitset &sketchFlags) { + + + if (sketchFlags.test(sketch::skt_tool_active)) { + mouse.setLeftMouseSlot(&sketchAddPointCmd); + mouse.setLeftMouseHoldSlot(nullptr); + mouse.setLeftMouseReleaseSlot(nullptr); + } else { + mouse.setLeftMouseSlot(&sketchSelectPointCmd); + mouse.setLeftMouseHoldSlot(&sketchMovePointCmd); + mouse.setLeftMouseReleaseSlot(&sketchDeselectPointCmd); + } + +} + +} +} \ No newline at end of file diff --git a/src/input/input.hpp b/src/input/input.hpp new file mode 100644 index 0000000..1d65c69 --- /dev/null +++ b/src/input/input.hpp @@ -0,0 +1,53 @@ +#pragma once +#include "keyboard.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +class Input { +public: + + Input(); + + void setFramebufferResizeSlot(Command* framebufferResizeCmd); + + void framebufferResized(); + + void setSketchCommands(sketch::Sketch* sketch, cam::Camera* camera, sel::Selector* selector); + + void setCameraCommands(cam::Camera* camera); + + void setRenderCommands(CADRender* render); + + void setMouse(); + + void setKeyboard(); + + void sketchMode(std::bitset& sketchFlags); + + + Keyboard keyboard; + Mouse mouse; + +private: + + Command* mFramebufferResizeSlot; + + SketchAddPointCommand sketchAddPointCmd; + SketchMovePointCommand sketchMovePointCmd; + SketchSelectPointCommand sketchSelectPointCmd; + SketchSelectSetCtrlCommand sketchSelectSetCtrlCmd; + SketchSelectUnsetCtrlCommand sketchSelectUnsetCtrlCmd; + SketchDeselectPointCommand sketchDeselectPointCmd; + SketchDisableToolsCommand sketchDisableToolsCmd; + SketchDeleteCommand sketchDeleteCmd; + CameraZoomCommand cameraZoomCmd; + CameraPanCommand cameraPanCmd; + CameraUnsetPanCommand cameraUnsetPanCmd; + RenderFramebufferResizeCommand renderFramebufferResizeCmd; + +}; + +} +} \ No newline at end of file diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp new file mode 100644 index 0000000..f37f909 --- /dev/null +++ b/src/input/keyboard.cpp @@ -0,0 +1,63 @@ +#include "mouse.hpp" +#include "pch.hpp" +#include "keyboard.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +Keyboard::Keyboard() : + mEscapeSlot{nullptr}, + mLCtrlSlot{nullptr}, + mLCtrlReleaseSlot{nullptr}, + mDeleteSlot{nullptr} {} + + +void Keyboard::setEscapeSlot(Command * escape) +{ + mEscapeSlot = escape; +} + +void Keyboard::setLCtrlSlot(Command * lCtrl) +{ + mLCtrlSlot = lCtrl; +} + +void Keyboard::setLCtrlReleaseSlot(Command * lCtrl) +{ + mLCtrlReleaseSlot = lCtrl; +} + +void Keyboard::setDeleteSlot(Command * del) +{ + mDeleteSlot = del; +} + +void Keyboard::escapePress() +{ + if (mEscapeSlot) { + mEscapeSlot->execute(); + } +} + +void Keyboard::lCtrlPress() +{ + if (mLCtrlSlot) { + mLCtrlSlot->execute(); + } +} +void Keyboard::lCtrlRelease() +{ + if (mLCtrlReleaseSlot) { + mLCtrlReleaseSlot->execute(); + } +} +void Keyboard::deletePress() +{ + if (mDeleteSlot) { + mDeleteSlot->execute(); + } +} + +} // namespace command +} \ No newline at end of file diff --git a/src/input/keyboard.hpp b/src/input/keyboard.hpp new file mode 100644 index 0000000..040fae5 --- /dev/null +++ b/src/input/keyboard.hpp @@ -0,0 +1,36 @@ +#pragma once +#include "mouse.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +class Keyboard { +public: + + Keyboard(); + + void setEscapeSlot(Command* escape); + void setLCtrlSlot(Command* lCtrl); + void setLCtrlReleaseSlot(Command* lCtrl); + void setDeleteSlot(Command* del); + + + void escapePress(); + void lCtrlPress(); + void lCtrlRelease(); + void deletePress(); + + +private: + + Command* mEscapeSlot; + Command* mLCtrlSlot; + Command* mLCtrlReleaseSlot; + Command* mDeleteSlot; + + +}; + +} +} \ No newline at end of file diff --git a/src/input/mouse.cpp b/src/input/mouse.cpp new file mode 100644 index 0000000..577ab5b --- /dev/null +++ b/src/input/mouse.cpp @@ -0,0 +1,92 @@ +#include "mouse.hpp" +#include "pch.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +Mouse::Mouse() : + mRightMouseSlot{nullptr}, + mMiddleMouseSlot{nullptr}, + mMiddleMouseReleaseSlot{nullptr}, + mScrollMouseSlot{nullptr}, + mLeftMouseSlot{nullptr}, + mLeftMouseHoldSlot{nullptr}, + mLeftMouseReleaseSlot{nullptr} {} + +void Mouse::setRightMouseSlot(Command *rightMouse) { + mRightMouseSlot = rightMouse; +} + +void Mouse::setMiddleMouseSlot(Command *middleMouse) { + mMiddleMouseSlot = middleMouse; +} + +void Mouse::setMiddleMouseReleaseSlot(Command * middleMouseRelease) +{ + mMiddleMouseReleaseSlot = middleMouseRelease; +} + +void Mouse::setScrollMouseSlot(Command *scrollMouse) { + mScrollMouseSlot = scrollMouse; +} + +void Mouse::setLeftMouseSlot(Command *leftMouse) { + mLeftMouseSlot = leftMouse; +} + +void Mouse::setLeftMouseHoldSlot(Command * leftMouseHold) +{ + mLeftMouseHoldSlot = leftMouseHold; +} + +void Mouse::setLeftMouseReleaseSlot(Command *leftMouseRelease) { + mLeftMouseReleaseSlot = leftMouseRelease; +} + +void Mouse::rightMouseClick() { + if (mRightMouseSlot) + mRightMouseSlot->execute(); + +} + +void Mouse::middleMouseClick() +{ + if (mMiddleMouseSlot) { + mMiddleMouseSlot->execute(); + } +} + +void Mouse::middleMouseRelease() +{ + if (mMiddleMouseReleaseSlot) { + mMiddleMouseReleaseSlot->execute(); + } +} + +void Mouse::scroll(double yOffset) { + if (mScrollMouseSlot) + mScrollMouseSlot->execute(yOffset); +} + + +void Mouse::leftMouseClick() { + if (mLeftMouseSlot) + mLeftMouseSlot->execute(); + +} + +void Mouse::leftMouseHold() { + if (mLeftMouseHoldSlot) { + mLeftMouseHoldSlot->execute(); + } +} + +void Mouse::leftMouseRelease() { + if (mLeftMouseReleaseSlot) { + mLeftMouseReleaseSlot->execute(); + } +} + +} // namespace command +} \ No newline at end of file diff --git a/src/ux/command/mouse.hpp b/src/input/mouse.hpp similarity index 55% rename from src/ux/command/mouse.hpp rename to src/input/mouse.hpp index ceb9cb0..d48a55d 100644 --- a/src/ux/command/mouse.hpp +++ b/src/input/mouse.hpp @@ -1,5 +1,5 @@ #pragma once -#include "cameracommands.hpp" +#include "rendercommands.hpp" namespace CADERA_APP_NAMESPACE { @@ -12,20 +12,33 @@ class Mouse { void setRightMouseSlot(Command* rightMouse); void setMiddleMouseSlot(Command* middleMouse); + void setMiddleMouseReleaseSlot(Command* middleMouseRelease); void setScrollMouseSlot(Command* scrollMouse); void setLeftMouseSlot(Command* leftMouse); + void setLeftMouseHoldSlot(Command* leftMouseHold); + void setLeftMouseReleaseSlot(Command* leftMouseRelease); void rightMouseClick(); + + void middleMouseClick(); + void middleMouseRelease(); + void scroll(double yOffset); + void leftMouseClick(); + void leftMouseHold(); + void leftMouseRelease(); private: Command* mRightMouseSlot; Command* mMiddleMouseSlot; + Command* mMiddleMouseReleaseSlot; Command* mScrollMouseSlot; Command* mLeftMouseSlot; + Command* mLeftMouseHoldSlot; + Command* mLeftMouseReleaseSlot; }; diff --git a/src/input/rendercommands.cpp b/src/input/rendercommands.cpp new file mode 100644 index 0000000..37794b4 --- /dev/null +++ b/src/input/rendercommands.cpp @@ -0,0 +1,32 @@ +#include "rendercommands.hpp" +#include "pch.hpp" + + +namespace CADERA_APP_NAMESPACE { + +namespace command { + + +// Render Framebuffer Resize Command +//----------------------------------------------------------------------------- +RenderFramebufferResizeCommand::RenderFramebufferResizeCommand() : mRender{nullptr} {} + +void RenderFramebufferResizeCommand::setRender(CADRender * render) { + mRender = render; +} + + + + +void RenderFramebufferResizeCommand::execute() { + if (mRender) { + + mRender->frameBufferResized = true;; + + } +} +//----------------------------------------------------------------------------- + + +} +} \ No newline at end of file diff --git a/src/input/rendercommands.hpp b/src/input/rendercommands.hpp new file mode 100644 index 0000000..41f6297 --- /dev/null +++ b/src/input/rendercommands.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "cameracommands.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + + +class RenderFramebufferResizeCommand : public Command { +public: + + RenderFramebufferResizeCommand(); + + void setRender(CADRender* render); + + void execute() override; + +private: + CADRender* mRender; + +}; + + +} +} \ No newline at end of file diff --git a/src/input/sketchcommands.cpp b/src/input/sketchcommands.cpp new file mode 100644 index 0000000..6bb8870 --- /dev/null +++ b/src/input/sketchcommands.cpp @@ -0,0 +1,258 @@ +#include "sketchcommands.hpp" +#include "pch.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + +// Sketch Add Point Command +//----------------------------------------------------------------------------- +SketchAddPointCommand::SketchAddPointCommand() : mSketch{nullptr}, + mSelector{nullptr}, + mCamera{nullptr} + {} + + +void SketchAddPointCommand::setSketch(sketch::Sketch *S) { mSketch = S; } + + +void SketchAddPointCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchAddPointCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void SketchAddPointCommand::execute() { + if (mSketch && mSelector && mCamera) { + + mSelector->select(mCamera->mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), + mCamera->cameraVec, mCamera->pos, + mCamera->cross, + mCamera->flags.test(cad::cam::ortho)); + + if (!mSelector->existingPoint(mSelector->point)) + mSketch->add(mSelector->point); + + mSketch->notify(); + + + } +} +//----------------------------------------------------------------------------- + +// Sketch Move Point Command +//----------------------------------------------------------------------------- +SketchMovePointCommand::SketchMovePointCommand() : mSketch{nullptr}, + mSelector{nullptr}, + mCamera{nullptr} + {} + +void SketchMovePointCommand::setSketch(sketch::Sketch *S) { mSketch = S; } + +void SketchMovePointCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchMovePointCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void SketchMovePointCommand::execute() { + if (mSketch && mSelector && mCamera) { + + mSelector->select(mCamera->mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), + mCamera->cameraVec, mCamera->pos, + mCamera->cross, + mCamera->flags.test(cad::cam::ortho)); + + + mSketch->movePoints(mSelector->selectedPoints, mSelector->point, + mSelector->flags.test(cad::sel::select_first_click)); + + std::vector ids = mSelector->getSelectedPointIds(); + + std::map newPoints; + + for (const auto &id : ids) { + newPoints[id] = mSketch->Points[id]; + } + + mSelector->update(newPoints); + + mSelector->flags.reset(cad::sel::select_first_click); + + mSketch->notify(); + mSelector->notify(); + + } +} +//----------------------------------------------------------------------------- + + +// Sketch Select Point Command +//----------------------------------------------------------------------------- +SketchSelectPointCommand::SketchSelectPointCommand() : mSketch{nullptr}, + mSelector{nullptr}, + mCamera{nullptr} {} + +void SketchSelectPointCommand::setSketch(sketch::Sketch *S) { mSketch = S; } + +void SketchSelectPointCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchSelectPointCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void SketchSelectPointCommand::execute() { + if (mSketch && mSelector && mCamera) { + + mSelector->select(mCamera->mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), + mCamera->cameraVec, mCamera->pos, + mCamera->cross, + mCamera->flags.test(cad::cam::ortho)); + + int id = mSelector->add(mSelector->point, mSketch->Points, + mCamera->camDistance); + + if (id >= 0 || mSelector->selectedPoints.empty()) { + mSketch->notify(); + mSelector->notify(); + } + + mSketch->flags.set(cad::sketch::skt_move_points); + + } +} +//----------------------------------------------------------------------------- + +// Sketch Deselect Point Command +//----------------------------------------------------------------------------- +SketchDeselectPointCommand::SketchDeselectPointCommand() : mSketch{nullptr}, + mSelector{nullptr}, + mCamera{nullptr} {} + +void SketchDeselectPointCommand::setSketch(sketch::Sketch *S) { mSketch = S; } + +void SketchDeselectPointCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchDeselectPointCommand::setCamera(cam::Camera *cam) { + mCamera = cam; +} + +void SketchDeselectPointCommand::execute() { + + if (mSketch && mSelector && mCamera) { + + if (!mSketch->flags.test(cad::sketch::skt_points_have_moved)) { + + mSelector->select(mCamera->mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), + mCamera->cameraVec, mCamera->pos, + mCamera->cross, + mCamera->flags.test(cad::cam::ortho)); + + int id = mSelector->remove(mSelector->point, mSketch->Points, + mCamera->camDistance); + + if (id >= 0 || mSelector->selectedPoints.empty()) { + mSketch->notify(); + mSelector->notify(); + } + } + + + mSelector->flags.set(cad::sel::select_first_click); + mSketch->flags.reset(cad::sketch::skt_move_points); + mSketch->flags.reset(cad::sketch::skt_points_have_moved); + + } + + +} +//----------------------------------------------------------------------------- + +// Sketch Select Set Ctrl Command +//----------------------------------------------------------------------------- +SketchSelectSetCtrlCommand::SketchSelectSetCtrlCommand() : mSelector{nullptr} +{ +} + +void SketchSelectSetCtrlCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchSelectSetCtrlCommand::execute() { + if (mSelector) + mSelector->flags.set(sel::select_isCTRL); +} + + +//----------------------------------------------------------------------------- + +// Sketch Select Unset Ctrl Command +//----------------------------------------------------------------------------- +SketchSelectUnsetCtrlCommand::SketchSelectUnsetCtrlCommand() : mSelector{nullptr} +{ +} + +void SketchSelectUnsetCtrlCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchSelectUnsetCtrlCommand::execute() { + if (mSelector) + mSelector->flags.reset(sel::select_isCTRL); +} + + +//----------------------------------------------------------------------------- + +// Sketch Disable Tools Command +//----------------------------------------------------------------------------- +SketchDisableToolsCommand::SketchDisableToolsCommand() : mSketch{nullptr} {} + +void SketchDisableToolsCommand::setSketch(sketch::Sketch *S) { + mSketch = S; +} + +void SketchDisableToolsCommand::execute() { + if (mSketch) { + mSketch->deactivateTools(); + } +} +//----------------------------------------------------------------------------- + +// Sketch Delete Point Command +//----------------------------------------------------------------------------- +SketchDeleteCommand::SketchDeleteCommand() : mSketch{nullptr}, + mSelector{nullptr} {} + +void SketchDeleteCommand::setSketch(sketch::Sketch *S) { mSketch = S; } + +void SketchDeleteCommand::setSelector(sel::Selector *sel) { + mSelector = sel; +} + +void SketchDeleteCommand::execute() { + if (mSketch && mSelector) { + + if (!mSelector->getSelectedPointIds().empty()) { + + mSketch->deletion(mSelector->getSelectedPointIds()); + mSelector->clear(); + mSelector->setFlags(); + + mSketch->notify(); + mSelector->notify(); + } + } +} + +//----------------------------------------------------------------------------- +} +} \ No newline at end of file diff --git a/src/input/sketchcommands.hpp b/src/input/sketchcommands.hpp new file mode 100644 index 0000000..62d3ee0 --- /dev/null +++ b/src/input/sketchcommands.hpp @@ -0,0 +1,146 @@ +#pragma once +#include "command.hpp" + +namespace CADERA_APP_NAMESPACE { + +namespace command { + + +class SketchAddPointCommand : public Command { +public: + + SketchAddPointCommand(); + + void setSketch(sketch::Sketch* S); + void setSelector(sel::Selector* sel); + void setCamera(cam::Camera* cam); + + void execute() override; + +private: + + sketch::Sketch* mSketch; + sel::Selector* mSelector; + cam::Camera* mCamera; + +}; + +class SketchMovePointCommand : public Command { + public: + + SketchMovePointCommand(); + + void setSketch(sketch::Sketch* S); + void setSelector(sel::Selector* sel); + void setCamera(cam::Camera* cam); + + void execute() override; + + private: + + sketch::Sketch* mSketch; + sel::Selector* mSelector; + cam::Camera* mCamera; + + }; + +class SketchSelectPointCommand : public Command { +public: + + SketchSelectPointCommand(); + + void setSketch(sketch::Sketch* S); + void setSelector(sel::Selector* sel); + void setCamera(cam::Camera* cam); + + void execute() override; + +private: + + sketch::Sketch* mSketch; + sel::Selector* mSelector; + cam::Camera* mCamera; + +}; + +class SketchDeselectPointCommand : public Command { + public: + + SketchDeselectPointCommand(); + + void setSketch(sketch::Sketch* S); + void setSelector(sel::Selector* sel); + void setCamera(cam::Camera* cam); + + void execute() override; + + private: + + sketch::Sketch* mSketch; + sel::Selector* mSelector; + cam::Camera* mCamera; + +}; + +class SketchSelectSetCtrlCommand : public Command { +public: + + SketchSelectSetCtrlCommand(); + + void setSelector(sel::Selector* sel); + void execute() override; + +private: + + sel::Selector* mSelector; + +}; + +class SketchSelectUnsetCtrlCommand : public Command { +public: + + SketchSelectUnsetCtrlCommand(); + + void setSelector(sel::Selector* sel); + void execute() override; + +private: + + sel::Selector* mSelector; + +}; + +class SketchDisableToolsCommand : public Command { +public: + + SketchDisableToolsCommand(); + + void setSketch(sketch::Sketch* S); + + void execute() override; + +private: + + sketch::Sketch* mSketch; + +}; + +class SketchDeleteCommand : public Command { + public: + + SketchDeleteCommand(); + + void setSketch(sketch::Sketch* S); + void setSelector(sel::Selector* sel); + + void execute() override; + + private: + + sketch::Sketch* mSketch; + sel::Selector* mSelector; + + }; + +} +} \ No newline at end of file diff --git a/src/pch.hpp b/src/pch.hpp index f9a9e8d..459cdc0 100644 --- a/src/pch.hpp +++ b/src/pch.hpp @@ -27,6 +27,7 @@ // Vulkan #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 +// #define VK_NO_PROTOTYPES #include // GLM diff --git a/src/render/CMakeLists.txt b/src/render/CMakeLists.txt index 33cc8b1..00719c5 100644 --- a/src/render/CMakeLists.txt +++ b/src/render/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.5) -target_sources(CaderaApp PRIVATE ${CMAKE_CURRENT_LIST_DIR}/cadrender.cpp - ${CMAKE_CURRENT_LIST_DIR}/camera.cpp - ) \ No newline at end of file +add_library(renderlib ${CMAKE_CURRENT_LIST_DIR}/cadrender.cpp + ${CMAKE_CURRENT_LIST_DIR}/camera.cpp + ${CMAKE_CURRENT_LIST_DIR}/selection.cpp + ) + + +target_link_libraries(renderlib PUBLIC sketchlib) \ No newline at end of file diff --git a/src/render/cadrender.cpp b/src/render/cadrender.cpp index f2bd37c..9109fb9 100644 --- a/src/render/cadrender.cpp +++ b/src/render/cadrender.cpp @@ -9,6 +9,10 @@ const int MAX_FRAMES_IN_FLIGHT = 2; namespace CADERA_APP_NAMESPACE { + + +CADRender::CADRender() {} + void CADRender::setup() { // GLFW @@ -17,13 +21,16 @@ void CADRender::setup() { // mInstance createInstance(); createSurface(); - + // Physical mDevice pickPhysicalDevice(); - + // Logical mDevice createLogicalDevice(); + // Debug + setupDebugUtils(); + // Swapchain createSwapChain(); createImageViews(); @@ -63,12 +70,18 @@ void CADRender::createWindow() { glfwSetInputMode(mMainWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } -void CADRender::createInstance() { +vk::Result CADRender::createInstance() { vkGetInstanceProcAddr = dl.getProcAddress("vkGetInstanceProcAddr"); + VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); + // VULKAN_HPP_DEFAULT_DISPATCHER.init(); + + mAppInfo.pApplicationName = "Cadera"; + mAppInfo.applicationVersion = 1; + mAppInfo.apiVersion = 0; vk::InstanceCreateInfo createInfo; @@ -77,22 +90,23 @@ void CADRender::createInstance() { auto glfwExtensionCount = 0u; auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); - const char *layers = "VK_LAYER_KHRONOS_validation"; + const char* layers = ""; - createInfo.enabledLayerCount = 1; // static_cast(layers.size()); + createInfo.enabledLayerCount = 0; createInfo.ppEnabledLayerNames = &layers; createInfo.enabledExtensionCount = - glfwExtensionCount; // static_cast(glfwExtensionsVector.size()); + glfwExtensionCount; createInfo.ppEnabledExtensionNames = - glfwExtensions; // glfwExtensionsVector.data(); + glfwExtensions; createInfo.pApplicationInfo = &mAppInfo; vk::Result result = vk::createInstance(&createInfo, nullptr, &mInstance); VULKAN_HPP_DEFAULT_DISPATCHER.init(mInstance); - + return result; + } void CADRender::createSurface() { @@ -104,6 +118,83 @@ void CADRender::createSurface() { } } +void CADRender::setupDebugUtils() { + + // Check if the debug utils extension is present (which is the case if run from a graphics debugger) + bool extensionPresent = false; + uint32_t extensionCount; + vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); + std::vector extensions(extensionCount) ;//= vk::enumerateInstanceExtensionProperties(); + vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data()); + for (auto& extension : extensions) { + if (strcmp(extension.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) { + extensionPresent = true; + break; + } + } + + if (extensionPresent) { + // As with an other extension, function pointers need to be manually loaded + vkCreateDebugUtilsMessengerEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkCreateDebugUtilsMessengerEXT")); + vkDestroyDebugUtilsMessengerEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkDestroyDebugUtilsMessengerEXT")); + vkCmdBeginDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkCmdBeginDebugUtilsLabelEXT")); + vkCmdInsertDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkCmdInsertDebugUtilsLabelEXT")); + vkCmdEndDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkCmdEndDebugUtilsLabelEXT")); + vkQueueBeginDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkQueueBeginDebugUtilsLabelEXT")); + vkQueueInsertDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkQueueInsertDebugUtilsLabelEXT")); + vkQueueEndDebugUtilsLabelEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkQueueEndDebugUtilsLabelEXT")); + vkSetDebugUtilsObjectNameEXT = reinterpret_cast(vkGetInstanceProcAddr(mInstance, "vkSetDebugUtilsObjectNameEXT")); + pfnDebugMarkerSetObjectTag = (PFN_vkDebugMarkerSetObjectTagEXT)vkGetDeviceProcAddr(mDevice, "vkDebugMarkerSetObjectTagEXT"); + + // Set flag if at least one function pointer is present + debugUtilsSupported = (vkCreateDebugUtilsMessengerEXT != VK_NULL_HANDLE); + } + else { + std::cout << "Warning: " << VK_EXT_DEBUG_UTILS_EXTENSION_NAME << " not present, debug utils are disabled."; + std::cout << "Try running the sample from inside a Vulkan graphics debugger (e.g. RenderDoc)" << std::endl; + } +} + +void CADRender::cmd_begin_label(vk::CommandBuffer cmdBuffer, const char* name, glm::vec4 color ) { + + if (debugUtilsSupported && vkCmdBeginDebugUtilsLabelEXT) { + + float col[4] = {color.x, color.y, color.z, color.w}; + VkDebugUtilsLabelEXT labelInfo { + VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + nullptr, + name + }; + + std::copy(std::begin(col), std::end(col), std::begin(labelInfo.color)); + // memcpy(labelInfo.color, &color[0], sizeof(float)*4); + vkCmdBeginDebugUtilsLabelEXT(cmdBuffer, &labelInfo); + + } +} + +void CADRender::cmd_end_label(vk::CommandBuffer cmdBuffer) { + + if (debugUtilsSupported && vkCmdEndDebugUtilsLabelEXT) + vkCmdEndDebugUtilsLabelEXT(cmdBuffer); +} + +void CADRender::setObjectName(VkDevice device, uint64_t object, VkDebugReportObjectTypeEXT objectType, const char *name) { + // Check for valid function pointer (may not be present if not running in a debugging application) + if (debugUtilsSupported && pfnDebugMarkerSetObjectTag) { + VkDebugMarkerObjectTagInfoEXT tagInfo = {}; + tagInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT; + tagInfo.objectType = objectType; + tagInfo.object = object; + tagInfo.tagName = 0; + tagInfo.pTag = name; + tagInfo.tagSize = strlen(name); + + //tagInfo.pObjectName = name; + pfnDebugMarkerSetObjectTag(device, &tagInfo); + } +} + void CADRender::pickPhysicalDevice() { std::vector devices = @@ -1126,7 +1217,7 @@ void CADRender::createSketchPointPipeline() { PipelineCreateInfo.basePipelineIndex = -1; PipelineCreateInfo.layout = mPipelineLayout; - Pipelines.SketchPoint = + pipelines.SketchPoint = mDevice .createGraphicsPipeline(mPipelineCache, PipelineCreateInfo, nullptr) .value; @@ -1227,13 +1318,16 @@ void CADRender::createSketchLinePipeline() { PipelineCreateInfo.basePipelineIndex = -1; PipelineCreateInfo.layout = mPipelineLayout; - Pipelines.SketchLine = + pipelines.SketchLine = mDevice .createGraphicsPipeline(mPipelineCache, PipelineCreateInfo, nullptr) .value; mDevice.destroyShaderModule(vertShaderModule, nullptr); mDevice.destroyShaderModule(fragShaderModule, nullptr); + + // setObjectName(mDevice, VK_OBJECT_TYPE_PIPELINE, (uint64_t)0, "Sketch Line pipeline"); + } void CADRender::createSketchGridPipeline() { @@ -1351,7 +1445,7 @@ void CADRender::createSketchGridPipeline() { PipelineCreateInfo.basePipelineIndex = -1; PipelineCreateInfo.layout = mPipelineLayout; - Pipelines.SketchGrid = + pipelines.SketchGrid = mDevice.createGraphicsPipeline({}, PipelineCreateInfo, nullptr).value; mDevice.destroyShaderModule(vertShaderModule, nullptr); @@ -1491,7 +1585,7 @@ void CADRender::copyBuffer(vk::Buffer srcBuffer, vk::Buffer dstBuffer, endSingleTimeCommands(commandBuffer); } -void CADRender::deleteBuffer(BufferName id) { +void CADRender::deleteBuffer(int id) { mBuffers[id].isEmpty = true; mDevice.destroyBuffer(mBuffers[id].mBuffer); @@ -1526,6 +1620,8 @@ void CADRender::createCommandBuffers() { mRenderPass, mFramebuffers[i], renderArea, static_cast(clearValues.size()), clearValues.data()); + cmd_begin_label(mCommandBuffers[i], "Model Render", {0.5f, 0.76f, 0.34f, 1.0f}); + mCommandBuffers[i].beginRenderPass(renderPassInfo, vk::SubpassContents::eInline); @@ -1535,65 +1631,75 @@ void CADRender::createCommandBuffers() { mPipelineLayout, 0, 1, &mDescriptorSets[i], 0, nullptr); - // Selection Points - if (!mBuffers[BufferName::selection_points].isEmpty) { - mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, - Pipelines.SketchPoint); - mCommandBuffers[i].bindVertexBuffers( - 0, 1, &mBuffers[BufferName::selection_points].mBuffer, offsets); - mCommandBuffers[i].draw(mBuffers[BufferName::selection_points].mPointSize, - 1, 0, 0); - } - - // Sketch Points - if (!mBuffers[BufferName::sketch_points].isEmpty) { - mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, - Pipelines.SketchPoint); - mCommandBuffers[i].bindVertexBuffers( - 0, 1, &mBuffers[BufferName::sketch_points].mBuffer, offsets); - mCommandBuffers[i].draw( - mBuffers[BufferName::sketch_points].mPointSize + 2, 1, 0, 0); - } - - // Sketch Tools - if (!mBuffers[BufferName::sketch_point_tool].isEmpty) { - mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, - Pipelines.SketchPoint); - mCommandBuffers[i].bindVertexBuffers( - 0, 1, &mBuffers[BufferName::sketch_point_tool].mBuffer, offsets); - mCommandBuffers[i].draw( - mBuffers[BufferName::sketch_point_tool].mPointSize, 1, 0, 0); - } + - // Grid - if (!mBuffers[BufferName::sketch_grid_line].isEmpty) { - mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, - Pipelines.SketchGrid); - mCommandBuffers[i].bindVertexBuffers( - 0, 1, &mBuffers[BufferName::sketch_grid_line].mBuffer, offsets); - mCommandBuffers[i].bindVertexBuffers( - 1, 1, &mBuffers[BufferName::sketch_grid_axii].mBuffer, offsets); - mCommandBuffers[i].draw( - 2, mBuffers[BufferName::sketch_grid_axii].mPointSize, 0, 0); - } + for (const auto& rData : mRenderData) { + + int renderId = rData.first; + + if (renderId == 0) { + cmd_begin_label(mCommandBuffers[i], "Selection Points", {1.0f, 1.0f, 1.0f, 1.0f}); + if (!mBuffers[0].isEmpty) { + mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, + pipelines.SketchPoint); + mCommandBuffers[i].bindVertexBuffers( + 0, 1, &mBuffers[0].mBuffer, offsets); + mCommandBuffers[i].draw( + mBuffers[0].mPointSize, 1, 0, 0); + } + + cmd_end_label(mCommandBuffers[i]); + + continue; + } + + // Sketch Points + if (!mBuffers[renderId * number_of_buffers_per_model].isEmpty) { + mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, + pipelines.SketchPoint); + mCommandBuffers[i].bindVertexBuffers( + 0, 1, &mBuffers[renderId * number_of_buffers_per_model].mBuffer, offsets); + mCommandBuffers[i].draw( + mBuffers[renderId * number_of_buffers_per_model].mPointSize + 2, 1, 0, 0); + } + + // Sketch Grid + if (!mBuffers[renderId * number_of_buffers_per_model + 1].isEmpty) { + mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, + pipelines.SketchGrid); + mCommandBuffers[i].bindVertexBuffers( + 0, 1, &mBuffers[renderId * number_of_buffers_per_model + 1].mBuffer, offsets); + mCommandBuffers[i].bindVertexBuffers( + 1, 1, &mBuffers[renderId * number_of_buffers_per_model + 2].mBuffer, offsets); + mCommandBuffers[i].draw( + 2, mBuffers[renderId * number_of_buffers_per_model + 2].mPointSize, 0, 0); + } + + // Text + + if (!mBuffers[renderId * number_of_buffers_per_model + 3].isEmpty) { + mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, + mTextPipeline); + mCommandBuffers[i].bindVertexBuffers( + 0, 1, &mBuffers[renderId * number_of_buffers_per_model + 3].mBuffer, offsets); + mCommandBuffers[i].bindIndexBuffer( + mBuffers[renderId * number_of_buffers_per_model + 4].mBuffer, 0, + vk::IndexType::eUint32); + mCommandBuffers[i].drawIndexed( + mBuffers[renderId * number_of_buffers_per_model + 4].mPointSize, 1, 0, 0, 0); + } - // Text - if (!mBuffers[BufferName::text_vertices].isEmpty) { - mCommandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, - mTextPipeline); - mCommandBuffers[i].bindVertexBuffers( - 0, 1, &mBuffers[BufferName::text_vertices].mBuffer, offsets); - mCommandBuffers[i].bindIndexBuffer( - mBuffers[BufferName::text_indices].mBuffer, 0, - vk::IndexType::eUint32); - mCommandBuffers[i].drawIndexed( - mBuffers[BufferName::text_indices].mPointSize, 1, 0, 0, 0); } + cmd_begin_label(mCommandBuffers[i], "Draw ImGui", {0.0f, 1.0f, 0.0f, 1.0f}); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), mCommandBuffers[i]); + cmd_end_label(mCommandBuffers[i]); mCommandBuffers[i].endRenderPass(); + + cmd_end_label(mCommandBuffers[i]); + mCommandBuffers[i].end(); } } @@ -1692,9 +1798,9 @@ void CADRender::drawFrame() { void CADRender::destroyPipelines() { - mDevice.destroyPipeline(Pipelines.SketchPoint); - mDevice.destroyPipeline(Pipelines.SketchLine); - mDevice.destroyPipeline(Pipelines.SketchGrid); + mDevice.destroyPipeline(pipelines.SketchPoint); + mDevice.destroyPipeline(pipelines.SketchLine); + mDevice.destroyPipeline(pipelines.SketchGrid); mDevice.destroyPipeline(mTextPipeline); } @@ -1773,10 +1879,10 @@ void CADRender::cleanup() { mDevice.destroySwapchainKHR(mSwapchain, nullptr); - vkDestroyDevice(mDevice, nullptr); - vkDestroySurfaceKHR(mInstance, mImguiSurface, nullptr); - vkDestroySurfaceKHR(mInstance, mSurface, nullptr); - vkDestroyInstance(mInstance, nullptr); + mDevice.destroy(); + mInstance.destroySurfaceKHR(mImguiSurface); + mInstance.destroySurfaceKHR(mSurface); + mInstance.destroy(); glfwTerminate(); } @@ -1805,138 +1911,106 @@ void CADRender::runCamera() { Cam.update(); } -void CADRender::render(Model &M) { - - if (M.getType() == cad_sketch) { - renderSketchGrid(M); - renderSketchPoints(M); - renderSketchNotes(M); - } - - flags.reset(render_update_sketch); -} - -void CADRender::renderSketchGrid(Model &S) { - - std::vector axii; - std::vector line; +void CADRender::render() { - std::vector Vertices; + for (const auto& rData : mRenderData) { - axii = S.getGridAxii(); - line = S.getGridLine(); + int renderId = rData.first; - // Convert vector of glm::vec3 to vector of Vertex - for (const auto &point : line) { + if (renderId == 0) { - Vertex V = {point, {0.0f, 0.0f, 0.0f}}; - Vertices.push_back(V); - } + std::vector pointVertices; - if (!axii.empty() && !Vertices.empty()) { - updateBuffer(BufferName::sketch_grid_line, Vertices, - vk::BufferUsageFlagBits::eVertexBuffer); - updateBuffer(BufferName::sketch_grid_axii, axii, - vk::BufferUsageFlagBits::eVertexBuffer); - } else { - deleteBuffer(BufferName::sketch_grid_line); - deleteBuffer(BufferName::sketch_grid_axii); - } -} + for (const auto& point : rData.second.points) { + pointVertices.push_back({point, {mRenderColors.selPointColor.x, + mRenderColors.selPointColor.y, + mRenderColors.selPointColor.z}}); + } -void CADRender::renderSketchNotes(Model &S) { + + if (!pointVertices.empty()) { + updateBuffer(0, pointVertices, + vk::BufferUsageFlagBits::eVertexBuffer); + } else if (!mBuffers[0].isEmpty) { + deleteBuffer(0); + } - TxtRend.clearTexts(); + continue; + } - for (const auto &N : S.Notes) { - TxtRend.addText(N.second); - } - // Relation Symbols - std::vector RelationTexts; - RelationTexts = S.getRelationTexts(); + // Create Sketch Points buffers + std::vector pointVertices; - for (const auto &T : RelationTexts) { - TxtRend.addText(T); - } + for (const auto& point : rData.second.points) { + pointVertices.push_back({point, {mRenderColors.sketchPointColor.x, + mRenderColors.sketchPointColor.y, + mRenderColors.sketchPointColor.z}}); + } - std::vector txtVertices = TxtRend.generateQuads(mRenderColors.bgColor); - std::vector txtIndices = TxtRend.generateIndices(); - - if (!txtVertices.empty()) { - updateBuffer(BufferName::text_vertices, txtVertices, - vk::BufferUsageFlagBits::eVertexBuffer); - updateBuffer(BufferName::text_indices, txtIndices, - vk::BufferUsageFlagBits::eIndexBuffer); - } else if (!mBuffers[BufferName::text_vertices].isEmpty) { - deleteBuffer(BufferName::text_vertices); - deleteBuffer(BufferName::text_indices); - } -} + + if (!pointVertices.empty()) { + updateBuffer(renderId * number_of_buffers_per_model, pointVertices, + vk::BufferUsageFlagBits::eVertexBuffer); + } else if (!mBuffers[renderId * number_of_buffers_per_model].isEmpty) { + deleteBuffer(renderId * number_of_buffers_per_model); + } -void CADRender::renderSketchPoints(Model &S) { + // Create Grid buffers + std::vector gridVertices; + + std::vector axii; + std::vector line; + + // Convert gridLine to vector of Vertex + for (const auto& point : rData.second.gridLine) { + gridVertices.push_back({point, mRenderColors.sketchGridColor}); + } - std::vector pointColors; - std::vector pointVertices = S.getVertices(pointColors); - std::vector selPointVertices = Sel.getVertices(); + axii = rData.second.gridAxii; - std::vector Vertices; + if (!axii.empty() && !gridVertices.empty()) { + updateBuffer(renderId * number_of_buffers_per_model + 1, gridVertices, + vk::BufferUsageFlagBits::eVertexBuffer); + updateBuffer(renderId * number_of_buffers_per_model + 2, axii, + vk::BufferUsageFlagBits::eVertexBuffer); + } else { + deleteBuffer(renderId * number_of_buffers_per_model + 1); + deleteBuffer(renderId * number_of_buffers_per_model + 2); + } - if (!selPointVertices.empty()) { - for (const auto &v : selPointVertices) { - Vertices.push_back({v, {mRenderColors.selPointColor.x, mRenderColors.selPointColor.y, mRenderColors.selPointColor.z}}); - } - } + // Create Text buffers - if (!pointVertices.empty() && !pointColors.empty()) { - for (size_t i = 0; i < pointVertices.size(); i++) { + TxtRend.clearTexts(); - Vertices.push_back({pointVertices[i], pointColors[i]}); + + TxtRend.addText(rData.second.texts); + + std::vector txtVertices = TxtRend.generateQuads(mRenderColors.bgColor); + std::vector txtIndices = TxtRend.generateIndices(); + + if (!txtVertices.empty()) { + updateBuffer(renderId * number_of_buffers_per_model + 3, txtVertices, + vk::BufferUsageFlagBits::eVertexBuffer); + updateBuffer(renderId * number_of_buffers_per_model + 4, txtIndices, + vk::BufferUsageFlagBits::eIndexBuffer); + } else if (!mBuffers[renderId * number_of_buffers_per_model + 3].isEmpty) { + deleteBuffer(renderId * number_of_buffers_per_model + 3); + deleteBuffer(renderId * number_of_buffers_per_model + 4); } - } - - if (!Vertices.empty()) { - updateBuffer(BufferName::sketch_points, Vertices, - vk::BufferUsageFlagBits::eVertexBuffer); - } else if (!mBuffers[BufferName::sketch_points].isEmpty) { - deleteBuffer(BufferName::sketch_points); + } } -void CADRender::renderSketchPointTool() { - glm::vec3 origin = glm::vec3(0.0f, 0.0f, 0.0f); - std::vector pointToolPoint; - std::vector Vertices; +void CADRender::onNotify(int id, const RenderData& rData) { - glm::vec3 point; - if (Cam.flags.test(cam::ortho)) { - glm::vec3 up = glm::cross(Cam.cross, Cam.cameraVec); - - glm::vec3 x = Cam.mouseRay.x * Cam.cross; - glm::vec3 y = Cam.mouseRay.y * up; - - glm::vec3 posOnPlane = origin + (up + Cam.cross) * Cam.pos; - point = posOnPlane + x + y; - } else { - point = sel::calcPOnPlane(Cam.mouseRay, origin, Cam.cameraVec, Cam.pos); - } + mRenderData[id] = rData; - pointToolPoint.push_back(point); - if (!pointToolPoint.empty()) { - - Vertices.push_back({point, {1.0f, 1.0f, 1.0f}}); - } - - if (!Vertices.empty()) { - updateBuffer(BufferName::sketch_point_tool, Vertices, - vk::BufferUsageFlagBits::eVertexBuffer); - } else if (!mBuffers[BufferName::sketch_point_tool].isEmpty) { - deleteBuffer(BufferName::sketch_point_tool); - } } + } // namespace CADERA_APP_NAMESPACE diff --git a/src/render/cadrender.hpp b/src/render/cadrender.hpp index cfe8da5..97accd2 100644 --- a/src/render/cadrender.hpp +++ b/src/render/cadrender.hpp @@ -1,10 +1,12 @@ #pragma once -#include "ux/command/mouse.hpp" -#include "callbacks.hpp" +#include "camera.hpp" + namespace CADERA_APP_NAMESPACE { +static constexpr int number_of_buffers_per_model = 5; + struct Vertex { glm::vec3 pos; glm::vec3 col; @@ -61,8 +63,15 @@ struct RendorColors { glm::vec4 sketchGridColor = {0.5f, 0.5f, 0.5f, 1.0f}; }; +struct Pipelines { + + vk::Pipeline SketchPoint; + vk::Pipeline SketchLine; + vk::Pipeline SketchGrid; + +}; -class CADRender { +class CADRender : public Observer{ private: std::vector validationLayers = { @@ -74,30 +83,37 @@ class CADRender { vk::DescriptorPool mGuiDescriptorPool; VkAllocationCallbacks *mGuiAllocator; - PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; - PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = 0; - PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTag = 0; - PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectName = 0; - PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBegin = 0; - PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEnd = 0; - PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsert = 0; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr{nullptr}; + PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr{nullptr}; - struct { + + + + std::map mRenderData; + Pipelines pipelines; - vk::Pipeline SketchPoint; - vk::Pipeline SketchLine; - vk::Pipeline SketchGrid; - } Pipelines; + + +public: + + CADRender(); + // PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; + PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT{nullptr}; + PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT{ nullptr }; + PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT{ nullptr }; + PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT{ nullptr }; + PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{ nullptr }; + PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT{ nullptr }; + PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT{ nullptr }; + PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT{ nullptr }; + PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{ nullptr }; + PFN_vkDebugMarkerSetObjectTagEXT pfnDebugMarkerSetObjectTag = VK_NULL_HANDLE; -public: - // Restructure - command::Mouse mouse; // GLFW GLFWwindow *mMainWindow; @@ -112,6 +128,7 @@ class CADRender { // mInstance vk::detail::DynamicLoader dl; + vk::detail::DispatchLoaderDynamic dld; vk::detail::DispatchLoaderDynamic dldy; VkDebugUtilsMessengerEXT mDebug; vk::ApplicationInfo mAppInfo; @@ -119,6 +136,9 @@ class CADRender { vk::DebugUtilsMessengerEXT mCallback; vk::SurfaceKHR mSurface; + // Debugging + bool debugUtilsSupported = false; + // Physical mDevice QueueFamilyIndices mIndices; @@ -161,7 +181,7 @@ class CADRender { vk::DescriptorPool mDescriptorPool; std::vector mDescriptorSets; - std::map mBuffers; + std::map mBuffers; // Textures vk::Image mTextureImage; @@ -185,8 +205,6 @@ class CADRender { cam::Camera Cam; - sel::Selector Sel; - sketch::SketchSolver SktSolver; txt::TextRender TxtRend; @@ -203,7 +221,9 @@ class CADRender { //------------------------------------------- // Functions - + + void render(); + void setBGColor(glm::vec4 color); // GLFW @@ -212,10 +232,30 @@ class CADRender { // Instance - void createInstance(); + vk::Result createInstance(); void createSurface(); + // Debug + + void setupDebugUtils(); + + // void cmd_begin_label(vk::CommandBuffer &cmdBuffer, const char *name, + // glm::vec4 color); + + void cmd_begin_label(vk::CommandBuffer cmdBuffer, const char *name, + glm::vec4 color); + + void cmd_end_label(vk::CommandBuffer cmdBuffer); + + // void cmd_begin_label(vk::CommandBuffer cmdBuffer, const char *name, + // float color[4]); + + // void cmd_end_label(vk::CommandBuffer &cmdBuffer); + + void setObjectName(VkDevice device, uint64_t object, + VkDebugReportObjectTypeEXT objectType, const char *name); + // Physical Device void pickPhysicalDevice(); @@ -336,7 +376,7 @@ class CADRender { void copyBuffer(vk::Buffer srcBuffer, vk::Buffer dstBuffer, vk::DeviceSize size); - void deleteBuffer(BufferName id); + void deleteBuffer(int id); void createCommandBuffers(); @@ -345,7 +385,7 @@ class CADRender { void drawFrame(); template - inline void createDeviceBuffer(BufferName id, std::vector const &points, + inline void createDeviceBuffer(int id, std::vector const &points, vk::BufferUsageFlagBits const &flag) { vk::Buffer stagingBuffer; @@ -382,7 +422,7 @@ class CADRender { }; template - inline void updateBuffer(BufferName id, std::vector const &points, + inline void updateBuffer(int id, std::vector const &points, vk::BufferUsageFlagBits const &flag) { if (mBuffers[id].isEmpty) { createDeviceBuffer(id, points, flag); @@ -403,14 +443,8 @@ class CADRender { void runCamera(); - void render(Model &M); - - void renderSketchGrid(Model &S); + void onNotify(int id, const RenderData& renderables) override; void renderSketchNotes(Model &S); - - void renderSketchPoints(Model &S); - - void renderSketchPointTool(); }; } // namespace CADERA_APP_NAMESPACE diff --git a/src/render/camera.cpp b/src/render/camera.cpp index f3b430b..7e6ae3c 100644 --- a/src/render/camera.cpp +++ b/src/render/camera.cpp @@ -63,7 +63,7 @@ void Camera::zoom(float yoffset) { } } else { - glm::vec3 normalPos = {0.0f, pos.y, pos.z}; + // glm::vec3 normalPos = {0.0f, pos.y, pos.z}; if (yoffset > 0) { pos -= 1.0f * glm::normalize(cameraVec); diff --git a/src/selection.cpp b/src/render/selection.cpp similarity index 96% rename from src/selection.cpp rename to src/render/selection.cpp index 2392e2b..c850359 100644 --- a/src/selection.cpp +++ b/src/render/selection.cpp @@ -96,7 +96,7 @@ glm::vec3 calcCurrentRay(float x, float y, glm::mat4 viewMat, glm::mat4 projMat, return currentRay; } -Selector::Selector() { +Selector::Selector() : mId{0} { point = {0.0f, 0.0f, 0.0f}; @@ -188,6 +188,7 @@ int Selector::add(glm::vec3 pointToAdd, std::map &points, if (!flags.test(select_isCTRL)) { selectedPoints.clear(); + setFlags(); } @@ -306,5 +307,20 @@ std::vector Selector::getSelectedPointIds() { return ids; } +void Selector::notify() { + + mRenderData.points.clear(); + + for (const auto& point : selectedPoints) { + mRenderData.points.push_back(point.second.pos); + } + + for (const auto& observer : observers) { + + observer->onNotify(mId, mRenderData); + } + +} + } // namespace sel } // namespace CADERA_APP_NAMESPACE diff --git a/src/selection.hpp b/src/render/selection.hpp similarity index 95% rename from src/selection.hpp rename to src/render/selection.hpp index 5cbb04a..b68209a 100644 --- a/src/selection.hpp +++ b/src/render/selection.hpp @@ -29,10 +29,14 @@ enum SelectionFlags { select_number_flags // Number of flags for bitset }; -class Selector { +class Selector : public Subject { sketch::Sketch *pActiveSketch = nullptr; + int mId; + + RenderData mRenderData; + public: std::bitset flags; @@ -68,6 +72,8 @@ class Selector { std::vector getVertices(); std::vector getSelectedPointIds(); + + void notify() override; }; } // namespace sel } // namespace CADERA_APP_NAMESPACE diff --git a/src/sketch/CMakeLists.txt b/src/sketch/CMakeLists.txt index 9af35ab..197134c 100644 --- a/src/sketch/CMakeLists.txt +++ b/src/sketch/CMakeLists.txt @@ -12,15 +12,15 @@ add_library(sketchlib ${CMAKE_CURRENT_LIST_DIR}/relation.cpp ${CMAKE_CURRENT_LIST_DIR}/point.cpp ${CMAKE_CURRENT_LIST_DIR}/model.cpp ${CMAKE_CURRENT_LIST_DIR}/grid.cpp + ${CMAKE_CURRENT_LIST_DIR}/observer.cpp + ${CMAKE_CURRENT_LIST_DIR}/subject.cpp ) target_include_directories(sketchlib PRIVATE ${CMAKE_CURRENT_LIST_DIR}/) target_include_directories(sketchlib PRIVATE ${CMAKE_SOURCE_DIR}/src/text/) -target_link_libraries(sketchlib PUBLIC pch_interface) - -target_link_libraries(sketchlib PRIVATE textlib) +target_link_libraries(sketchlib PUBLIC textlib) find_package(glm CONFIG REQUIRED) target_link_libraries(sketchlib PRIVATE glm::glm) \ No newline at end of file diff --git a/src/sketch/feature.cpp b/src/sketch/feature.cpp index f79fe17..e6a9784 100644 --- a/src/sketch/feature.cpp +++ b/src/sketch/feature.cpp @@ -3,7 +3,7 @@ namespace CADERA_APP_NAMESPACE { -Feature::Feature() { mId = -1; } +Feature::Feature() : mId{-1} {} Feature::Feature(int id) { mId = id; } diff --git a/src/sketch/feature.hpp b/src/sketch/feature.hpp index 8a3b55f..d24130f 100644 --- a/src/sketch/feature.hpp +++ b/src/sketch/feature.hpp @@ -15,6 +15,7 @@ enum FeatureType { class Feature { int mId; + public: Feature(); diff --git a/src/sketch/model.cpp b/src/sketch/model.cpp index c1fb5eb..782d6e9 100644 --- a/src/sketch/model.cpp +++ b/src/sketch/model.cpp @@ -3,7 +3,7 @@ namespace CADERA_APP_NAMESPACE { -Model::Model() {} +Model::Model() : mId{1} {} Model::Model(int id) { mId = id; } @@ -15,6 +15,14 @@ void Model::setType(ModelType type) { mType = type; } ModelType Model::getType() { return mType; } +void Model::notify() { + + for (const auto& observer : observers) { + std::cout << "Model notifies." << std::endl; + observer->onNotify(mId, mRenderItems); + } +} + std::vector Model::getGridLine() { return std::vector(); } std::vector Model::getGridAxii() { diff --git a/src/sketch/model.hpp b/src/sketch/model.hpp index c196673..14dfa0b 100644 --- a/src/sketch/model.hpp +++ b/src/sketch/model.hpp @@ -1,15 +1,11 @@ #pragma once -#include "textrender.hpp" -#include "grid.hpp" +#include "subject.hpp" namespace CADERA_APP_NAMESPACE { enum ModelType { cad_sketch, cad_layout, cad_part, cad_assembly, cad_drawing }; -class Model { - - int mId; - ModelType mType; +class Model : public Subject { public: Model(); @@ -25,6 +21,8 @@ class Model { std::map Notes; + void notify() override; + virtual std::vector getGridLine(); virtual std::vector getGridAxii(); @@ -32,6 +30,15 @@ class Model { virtual std::vector getVertices(); virtual std::vector getVertices(std::vector &colors); + +protected: + RenderData mRenderItems; + +private: + int mId; + ModelType mType; + + }; } // namespace CADERA_APP_NAMESPACE diff --git a/src/sketch/observer.cpp b/src/sketch/observer.cpp new file mode 100644 index 0000000..f31267f --- /dev/null +++ b/src/sketch/observer.cpp @@ -0,0 +1,15 @@ +#include "pch.hpp" +#include "observer.hpp" + +namespace CADERA_APP_NAMESPACE { + +Observer::Observer() {} + +Observer::~Observer() {} + +void Observer::onNotify(int id, const RenderData& renderables) +{ + std::cout << renderables << std::endl; +} + +} \ No newline at end of file diff --git a/src/sketch/observer.hpp b/src/sketch/observer.hpp new file mode 100644 index 0000000..3beed86 --- /dev/null +++ b/src/sketch/observer.hpp @@ -0,0 +1,42 @@ +#pragma once +#include "text/textrender.hpp" +#include "grid.hpp" + +namespace CADERA_APP_NAMESPACE { + +class RenderData { + + friend std::ostream &operator<<(std::ostream &os, const RenderData &ri) { + + os << "RenderItems:" << std::endl; + + if (ri.points.empty()) + return os; + os << "Points:" << std::endl; + for (const auto &p : ri.points) { + + os << std::format("P,{:.2f},{:.2f},{:.2f}", p.x, p.y, p.z); + os << std::endl; + } + os << std::endl; + return os; + } + +public: + std::vector points; + std::vector gridAxii; + std::vector gridLine; + std::vector texts; +}; + +class Observer { + +public: + Observer(); + virtual ~Observer(); + + virtual void onNotify(int id, const RenderData &renderables); + +private: +}; +} \ No newline at end of file diff --git a/src/sketch/sketch.cpp b/src/sketch/sketch.cpp index 17c1315..82c7d10 100644 --- a/src/sketch/sketch.cpp +++ b/src/sketch/sketch.cpp @@ -218,6 +218,33 @@ void Sketch::deletion(std::vector ids) { } } +void Sketch::notify() { + + mRenderItems.points.clear(); + + for (const auto& point : Points) { + mRenderItems.points.push_back(point.second.pos); + } + + mRenderItems.gridAxii = mGrid.createGridInstanceAxii(); + mRenderItems.gridLine = mGrid.line; + + + + mRenderItems.texts.clear(); + + for (const auto& note : Notes) { + + mRenderItems.texts.push_back(note.second); + + } + + for (const auto& observer : observers) { + observer->onNotify(getId(), mRenderItems); + } + +} + std::vector Sketch::getGridLine() { return mGrid.line; } std::vector Sketch::getGridAxii() { diff --git a/src/sketch/sketch.hpp b/src/sketch/sketch.hpp index b656dde..bcb5cab 100644 --- a/src/sketch/sketch.hpp +++ b/src/sketch/sketch.hpp @@ -78,6 +78,8 @@ class Sketch : public Model { void deletion(std::vector ids); + void notify() override; + std::vector getGridLine(); std::vector getGridAxii(); diff --git a/src/sketch/subject.cpp b/src/sketch/subject.cpp new file mode 100644 index 0000000..ac13e5f --- /dev/null +++ b/src/sketch/subject.cpp @@ -0,0 +1,31 @@ +#include "subject.hpp" +#include "pch.hpp" + +namespace CADERA_APP_NAMESPACE { + +Subject::Subject() +{ +} + +Subject::~Subject() {} + +void Subject::addRender(Observer *observer) { + + observers.push_back(observer); + +} + +void Subject::removeRender(Observer *observer) { + +} + +void Subject::notify() { + + for (const auto& observer : observers) { + std::cout << "Subject notifies." << std::endl; + observer->onNotify(int {0}, RenderData{}); + } + +} + +} \ No newline at end of file diff --git a/src/sketch/subject.hpp b/src/sketch/subject.hpp new file mode 100644 index 0000000..17096d1 --- /dev/null +++ b/src/sketch/subject.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "observer.hpp" + +namespace CADERA_APP_NAMESPACE { + +class Subject { + +public: + Subject(); + ~Subject(); + + void addRender(Observer* observer); + void removeRender(Observer* observer); + virtual void notify(); + +protected: + +std::vector observers; + +private: + + + + +}; +} \ No newline at end of file diff --git a/src/text/textrender.cpp b/src/text/textrender.cpp index 8402bfc..9f1ab2f 100644 --- a/src/text/textrender.cpp +++ b/src/text/textrender.cpp @@ -10,16 +10,12 @@ void coutVec3(glm::vec3 v) { namespace CADERA_APP_NAMESPACE { namespace txt { -TextRender::TextRender() { - mFontSize = 100.0; - mAtlasSize = 2864.0f; - - mCursorPos = {0.0f, 0.0f, 0.0f}; - mCursorDirX = {0.0f, 0.0f, 1.0f}; - mCursorDirY = {0.0f, 1.0f, 0.0f}; - - textCounter = 0; -} +TextRender::TextRender() : mFontSize{100.0f}, + mAtlasSize{2864.0f}, + mCursorPos{0.0f, 0.0f, 0.0f}, + mCursorDirX{0.0f, 0.0f, 0.0f}, + mCursorDirY{0.0f, 0.0f, 0.0f}, + textCounter{0} {} TextRender::~TextRender() {} @@ -61,6 +57,8 @@ void TextRender::loadFont(std::string filePath) { Characters[(int)values[0]] = C; } + + fontAtlasCsv.close(); } void TextRender::setCursorPos(glm::vec3 pos) { mCursorPos = pos; } diff --git a/src/text/textrender.hpp b/src/text/textrender.hpp index 8421d7f..3b7fc8c 100644 --- a/src/text/textrender.hpp +++ b/src/text/textrender.hpp @@ -4,13 +4,13 @@ namespace CADERA_APP_NAMESPACE { namespace txt { struct Text { - std::string text; - float textSize = 1.0f; - glm::vec3 textColor; - glm::vec3 cursorPos; - glm::vec3 cursorDirX; - glm::vec3 cursorDirY; - glm::vec2 offset = {0.0f, 0.0f}; + std::string text{}; + float textSize{1.0f}; + glm::vec3 textColor{}; + glm::vec3 cursorPos{}; + glm::vec3 cursorDirX{}; + glm::vec3 cursorDirY{}; + glm::vec2 offset{}; }; struct Vertex { @@ -39,7 +39,7 @@ class TextRender { void loadFont(std::string filePath); - void setCursorPos(glm::vec3 pos); + void setPlane(glm::vec3 xDir, glm::vec3 yDir); void addText(Text T); @@ -63,6 +63,8 @@ class TextRender { int numChars; int textCounter; + + void setCursorPos(glm::vec3 pos); }; } // namespace txt } // namespace CADERA_APP_NAMESPACE diff --git a/src/ux/CMakeLists.txt b/src/ux/CMakeLists.txt index 621fc52..9e858aa 100644 --- a/src/ux/CMakeLists.txt +++ b/src/ux/CMakeLists.txt @@ -1,12 +1,7 @@ cmake_minimum_required(VERSION 3.5) -target_sources(CaderaApp PRIVATE ${CMAKE_CURRENT_LIST_DIR}/gui.cpp - ${CMAKE_CURRENT_LIST_DIR}/command/command.cpp - ${CMAKE_CURRENT_LIST_DIR}/command/mouse.cpp - ${CMAKE_CURRENT_LIST_DIR}/command/sketchcommands.cpp - ${CMAKE_CURRENT_LIST_DIR}/command/cameracommands.cpp - ) +target_sources(CaderaApp PRIVATE ${CMAKE_CURRENT_LIST_DIR}/gui.cpp) diff --git a/src/ux/command/cameracommands.cpp b/src/ux/command/cameracommands.cpp deleted file mode 100644 index 72a6c3a..0000000 --- a/src/ux/command/cameracommands.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "cameracommands.hpp" -#include "pch.hpp" - -namespace CADERA_APP_NAMESPACE { - -namespace command { - - - -CameraZoomCommand::CameraZoomCommand() : mCamera{nullptr} {} - - -void CameraZoomCommand::setCamera(cam::Camera *cam) { - mCamera = cam; -} - -void CameraZoomCommand::execute(double yoffset) { - if (mCamera) { - - mCamera->zoom(static_cast(yoffset)); - - } -} - -} -} \ No newline at end of file diff --git a/src/ux/command/cameracommands.hpp b/src/ux/command/cameracommands.hpp deleted file mode 100644 index 8a24680..0000000 --- a/src/ux/command/cameracommands.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include "sketchcommands.hpp" - -namespace CADERA_APP_NAMESPACE { - -namespace command { - - -class CameraZoomCommand : public Command { -public: - - CameraZoomCommand(); - - void setCamera(cam::Camera* cam); - - void execute(double) override; - -private: - cam::Camera* mCamera; - -}; - -} -} \ No newline at end of file diff --git a/src/ux/command/mouse.cpp b/src/ux/command/mouse.cpp deleted file mode 100644 index f3bc389..0000000 --- a/src/ux/command/mouse.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "mouse.hpp" -#include "pch.hpp" - -namespace CADERA_APP_NAMESPACE { - -namespace command { - -Mouse::Mouse() : - mRightMouseSlot{nullptr}, - mMiddleMouseSlot{nullptr}, - mScrollMouseSlot{nullptr}, - mLeftMouseSlot{nullptr} {} - -void Mouse::setRightMouseSlot(Command *rightMouse) { - mRightMouseSlot = rightMouse; -} - -void Mouse::setMiddleMouseSlot(Command *middleMouse) { - mMiddleMouseSlot = middleMouse; -} - -void Mouse::setScrollMouseSlot(Command *scrollMouse) { - mScrollMouseSlot = scrollMouse; -} - -void Mouse::setLeftMouseSlot(Command *leftMouse) { - mLeftMouseSlot = leftMouse; -} - -void Mouse::rightMouseClick() { - if (mRightMouseSlot) - mRightMouseSlot->execute(); - -} - -void Mouse::scroll(double yOffset) { - if (mScrollMouseSlot) - mScrollMouseSlot->execute(yOffset); -} - - -void Mouse::leftMouseClick() { - if (mLeftMouseSlot) - mLeftMouseSlot->execute(); - -} - -} // namespace command -} \ No newline at end of file diff --git a/src/ux/command/sketchcommands.cpp b/src/ux/command/sketchcommands.cpp deleted file mode 100644 index 7105e95..0000000 --- a/src/ux/command/sketchcommands.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "sketchcommands.hpp" -#include "pch.hpp" - -namespace CADERA_APP_NAMESPACE { - -namespace command { - - - -SketchAddPointCommand::SketchAddPointCommand() : mSketch{nullptr}, - mSelector{nullptr}, - mCamera{nullptr} - {} - -void SketchAddPointCommand::setSketch(sketch::Sketch *S) { - - mSketch = S; -} - -void SketchAddPointCommand::setSelector(sel::Selector *sel) { - mSelector = sel; -} - -void SketchAddPointCommand::setCamera(cam::Camera *cam) { - mCamera = cam; -} - -void SketchAddPointCommand::execute() { - if (mSketch && mSelector && mCamera) { - - mSelector->select(mCamera->mouseRay, glm::vec3(0.0f, 0.0f, 0.0f), - mCamera->cameraVec, mCamera->pos, - mCamera->cross, - mCamera->flags.test(cad::cam::ortho)); - - if (!mSelector->existingPoint(mSelector->point)) - mSketch->add(mSelector->point); - - - } -} - - -} -} \ No newline at end of file diff --git a/src/ux/command/sketchcommands.hpp b/src/ux/command/sketchcommands.hpp deleted file mode 100644 index 63add37..0000000 --- a/src/ux/command/sketchcommands.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "command.hpp" - -namespace CADERA_APP_NAMESPACE { - -namespace command { - - -class SketchAddPointCommand : public Command { -public: - - SketchAddPointCommand(); - - void setSketch(sketch::Sketch* S); - void setSelector(sel::Selector* sel); - void setCamera(cam::Camera* cam); - - void execute() override; - -private: - - sketch::Sketch* mSketch; - sel::Selector* mSelector; - cam::Camera* mCamera; - -}; - -} -} \ No newline at end of file diff --git a/src/ux/gui.cpp b/src/ux/gui.cpp index 9098cde..4a02ad5 100644 --- a/src/ux/gui.cpp +++ b/src/ux/gui.cpp @@ -94,9 +94,10 @@ void startMenu(sketch::Sketch &Sketch, CADRender &Render, sel::Selector &Sel, Sketch.flags.set(sketch::skt_active); Sketch.setType(cad_sketch); Sketch.setCameraDistance(&Render.Cam.camDistance); + Sketch.addRender(&Render); Sel.setActiveSketch(&Sketch); - Render.flags.set(render_update_sketch); + Sketch.notify(); flags.reset(gui_start_menu); } @@ -231,8 +232,15 @@ void showDebugWindow(sketch::Sketch &Sketch, CADRender &Render, if (ImGui::CollapsingHeader("Render", ImGuiTreeNodeFlags_None)) { - // Copy of selection point color to check for changes + if (Render.debugUtilsSupported) + ImGui::Text("Debug Utils Supported!"); + + if (Render.vkSetDebugUtilsObjectNameEXT) + ImGui::Text("vkSetDebugUtilsObjectNameEXT"); + + // Copies of point colors to check for changes glm::vec4 selPointColor = Render.mRenderColors.selPointColor; + glm::vec4 sketchPointColor = Render.mRenderColors.sketchPointColor; ImGui::ColorPicker4("Background Color", (float *)&Render.mRenderColors.bgColor); ImGui::ColorPicker4("Selection Point Color", @@ -246,8 +254,12 @@ void showDebugWindow(sketch::Sketch &Sketch, CADRender &Render, // Update rendering if selection point color has changed if (selPointColor != Render.mRenderColors.selPointColor) { - Render.flags.set(render_update_sketch); - std::cout << "Selection Point Color has changed!" << std::endl; + Sel.notify(); + } + + // Update rendering if sketch point color has changed + if (sketchPointColor != Render.mRenderColors.sketchPointColor) { + Sketch.notify(); } } @@ -322,13 +334,13 @@ void showDebugWindow(sketch::Sketch &Sketch, CADRender &Render, ImGui::Text("Selection Flags"); ImGui::Text("First Click: %d", - Render.Sel.flags.test(sel::select_first_click)); + Sel.flags.test(sel::select_first_click)); ImGui::Text("Single Point: %d", - Render.Sel.flags.test(sel::select_single_point)); + Sel.flags.test(sel::select_single_point)); ImGui::Text("Double Point: %d", - Render.Sel.flags.test(sel::select_double_point)); + Sel.flags.test(sel::select_double_point)); ImGui::Text("Multi Point: %d", - Render.Sel.flags.test(sel::select_multi_point)); + Sel.flags.test(sel::select_multi_point)); ImGui::NewLine(); diff --git a/src/ux/gui.hpp b/src/ux/gui.hpp index 8e0eae3..d4106fa 100644 --- a/src/ux/gui.hpp +++ b/src/ux/gui.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../render/cadrender.hpp" +#include "input/input.hpp" namespace CADERA_APP_NAMESPACE { namespace gui { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 12119e3..3edfdbb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,6 +27,25 @@ find_package(GTest REQUIRED) # target_include_directories(Test_Cadera_Camera PRIVATE ${GTEST_INCLUDE_DIRS} ) # target_link_libraries(Test_Cadera_Camera PRIVATE ${GTEST_BOTH_LIBRARIES}) +# Test_Render +add_executable(Test_Cadera_Render test_render.cpp) +target_include_directories(Test_Cadera_Render PRIVATE ${CMAKE_SOURCE_DIR}/src) + + +target_link_libraries(Test_Cadera_Render PRIVATE renderlib) + +target_include_directories(Test_Cadera_Render PRIVATE ${GTEST_INCLUDE_DIRS} ) +target_link_libraries(Test_Cadera_Render PRIVATE ${GTEST_BOTH_LIBRARIES}) + +# Test_Input +add_executable(Test_Cadera_Input test_input.cpp) +target_include_directories(Test_Cadera_Input PRIVATE ${CMAKE_SOURCE_DIR}/src) + + +target_link_libraries(Test_Cadera_Input PRIVATE inputlib) + +target_include_directories(Test_Cadera_Input PRIVATE ${GTEST_INCLUDE_DIRS} ) +target_link_libraries(Test_Cadera_Input PRIVATE ${GTEST_BOTH_LIBRARIES}) # Test_Sketch @@ -54,5 +73,7 @@ target_link_libraries(Test_Cadera_Text PRIVATE ${GTEST_BOTH_LIBRARIES}) include(GoogleTest) +gtest_discover_tests(Test_Cadera_Render) +gtest_discover_tests(Test_Cadera_Input) gtest_discover_tests(Test_Cadera_Sketch) gtest_discover_tests(Test_Cadera_Text) diff --git a/test/test_input.cpp b/test/test_input.cpp new file mode 100644 index 0000000..0d5fe8d --- /dev/null +++ b/test/test_input.cpp @@ -0,0 +1,31 @@ +#include +#include "input/input.hpp" + +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE + +TEST(Input, inputFramebufferResized_Throw) { + + cad::command::Input input; + + + EXPECT_ANY_THROW(input.framebufferResized()); + + +} + +TEST(Input, inputFramebufferResized_NoThrow) { + + cad::command::Input input; + + cad::CADRender render; + + cad::command::RenderFramebufferResizeCommand cmd; + + cmd.setRender(&render); + + input.setFramebufferResizeSlot(&cmd); + + EXPECT_NO_THROW(input.framebufferResized()); + + +} \ No newline at end of file diff --git a/test/test_render.cpp b/test/test_render.cpp new file mode 100644 index 0000000..7bd20fd --- /dev/null +++ b/test/test_render.cpp @@ -0,0 +1,581 @@ +#include "config.hpp" +#include "pch.hpp" +#include "render/cadrender.hpp" +#include + +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE + +TEST(render, createInstance) { + + CADERA_APP_NAMESPACE::CADRender render; + + vk::Result result = render.createInstance(); + + EXPECT_EQ(result, vk::Result::eSuccess); + + //vkDestroyInstance(render.mInstance, nullptr); +} + +TEST(render, createWindow) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + + EXPECT_NE(render.mMainWindow, nullptr); + + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createSurface) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + + render.createSurface(); + + EXPECT_NE(render.mSurface, nullptr); + + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, pickPhysicalDevice) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + + render.pickPhysicalDevice(); + + EXPECT_NE(render.mPhysicalDevice, nullptr); + + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createLogicalDevice) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + + render.createLogicalDevice(); + + EXPECT_NE(render.mDevice, nullptr); + + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createSwapChain) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + + render.createSwapChain(); + + EXPECT_NE(render.mSwapchain, nullptr); + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createImageView) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + + render.createSwapChain(); + + vk::Image image = render.mImages[0]; + vk::Format format = vk::Format::eR8G8B8A8Srgb; + vk::ImageAspectFlags aspectFlags = vk::ImageAspectFlagBits::eColor; + vk::ImageView imageView = render.createImageView(image, format, aspectFlags); + + EXPECT_NE(imageView, nullptr); + + // vkDestroyImageView(render.mDevice, imageView, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createImageViews) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createImageViews(); + + EXPECT_NE(render.mImageViews.size(), 0); + + // for (auto imageView : render.mImageViews) { + // vkDestroyImageView(render.mDevice, imageView, nullptr); + // } + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createRenderPass) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createRenderPass(); + + EXPECT_NE(render.mRenderPass, nullptr); + + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createDescriptorSetLayout) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createRenderPass(); + + render.createDescriptorSetLayout(); + + EXPECT_NE(render.mDescriptorSetLayout, nullptr); + + // vkDestroyDescriptorSetLayout(render.mDevice, render.mDescriptorSetLayout, + // nullptr); + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createPipelineLayout) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createRenderPass(); + render.createDescriptorSetLayout(); + + render.createPipelineLayout(); + + EXPECT_NE(render.mPipelineLayout, nullptr); + + // vkDestroyPipelineLayout(render.mDevice, render.mPipelineLayout, nullptr); + // vkDestroyDescriptorSetLayout(render.mDevice, render.mDescriptorSetLayout, + // nullptr); + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, preparePipelines) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createRenderPass(); + render.createDescriptorSetLayout(); + render.createPipelineLayout(); + + render.preparePipelines(); + + // vk::Pipeline pipeline = render.getSketchPointPipeline(); + // EXPECT_NE(pipeline, nullptr); + + // // vkDestroyPipeline(render.mDevice, render.Pipelines.SketchPoint, nullptr); + // vkDestroyPipelineLayout(render.mDevice, render.mPipelineLayout, nullptr); + // vkDestroyDescriptorSetLayout(render.mDevice, render.mDescriptorSetLayout, + // nullptr); + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createCommandPool) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + + render.createCommandPool(); + + EXPECT_NE(render.mCommandPool, nullptr); + + // vkDestroyCommandPool(render.mDevice, render.mCommandPool, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createDepthResources) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createDepthResources(); + + EXPECT_NE(render.depthImage, nullptr); + EXPECT_NE(render.depthImageMemory, nullptr); + EXPECT_NE(render.depthImageView, nullptr); + + // vkDestroyImageView(render.mDevice, render.depthImageView, nullptr); + // vkDestroyImage(render.mDevice, render.depthImage, nullptr); + // vkFreeMemory(render.mDevice, render.depthImageMemory, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createFramebuffers) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createImageViews(); + + render.createRenderPass(); + + render.createDepthResources(); + + render.createFramebuffers(); + + EXPECT_NE(render.mFramebuffers.size(), 0); + + // for (auto framebuffer : render.mFramebuffers) { + // vkDestroyFramebuffer(render.mDevice, framebuffer, nullptr); + // } + + // vkDestroyImageView(render.mDevice, render.depthImageView, nullptr); + // vkDestroyImage(render.mDevice, render.depthImage, nullptr); + // vkFreeMemory(render.mDevice, render.depthImageMemory, nullptr); + + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + + // for (auto imageView : render.mImageViews) { + // vkDestroyImageView(render.mDevice, imageView, nullptr); + // } + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createUniformBuffer) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createUniformBuffer(); + + EXPECT_NE(render.mUniformBuffers.size(), 0); + EXPECT_NE(render.mUniformBufferMemories.size(), 0); + + // for (auto buffer : render.mUniformBuffers) { + // vkDestroyBuffer(render.mDevice, buffer, nullptr); + // } + + // for (auto memory : render.mUniformBufferMemories) { + // vkFreeMemory(render.mDevice, memory, nullptr); + // } + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createDescriptorPool) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createDescriptorSetLayout(); + + render.createDescriptorPool(); + + + EXPECT_NE(render.mDescriptorPool, nullptr); + + // vkDestroyDescriptorPool(render.mDevice, render.mDescriptorPool, nullptr); + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, createDescriptorSets) { + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createDescriptorSetLayout(); + + render.createCommandPool(); + + render.createUniformBuffer(); + + render.createTextureImage(); + render.createTextureImageView(); + render.createTextureSampler(); + + render.createDescriptorPool(); + + render.createDescriptorSets(); + + EXPECT_NE(render.mDescriptorSets.size(), 0); + + // vkDestroyDescriptorPool(render.mDevice, render.mDescriptorPool, nullptr); + + // for (auto buffer : render.mUniformBuffers) { + // vkDestroyBuffer(render.mDevice, buffer, nullptr); + // } + + // for (auto memory : render.mUniformBufferMemories) { + // vkFreeMemory(render.mDevice, memory, nullptr); + // } + + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); +} + +TEST(render, allocCommandBuffers) { + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + render.createSwapChain(); + + render.createImageViews(); + + render.createRenderPass(); + render.createCommandPool(); + render.createDepthResources(); + + render.createFramebuffers(); + + + render.allocCommandBuffers(); + + EXPECT_EQ(render.mCommandBuffers.size(), render.mFramebuffers.size()); + + // for (auto framebuffer : render.mFramebuffers) { + // vkDestroyFramebuffer(render.mDevice, framebuffer, nullptr); + // } + + // vkDestroyImageView(render.mDevice, render.depthImageView, nullptr); + // vkDestroyImage(render.mDevice, render.depthImage, nullptr); + // vkFreeMemory(render.mDevice, render.depthImageMemory, nullptr); + + // vkDestroyRenderPass(render.mDevice, render.mRenderPass, nullptr); + + // for (auto imageView : render.mImageViews) { + // vkDestroyImageView(render.mDevice, imageView, nullptr); + // } + + // vkDestroyCommandPool(render.mDevice, render.mCommandPool, nullptr); + // vkDestroySwapchainKHR(render.mDevice, render.mSwapchain, nullptr); + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); + +} + +TEST(render, createSyncObjects) { + + + glfwInit(); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + CADERA_APP_NAMESPACE::CADRender render; + + render.createWindow(); + render.createInstance(); + render.createSurface(); + render.pickPhysicalDevice(); + render.createLogicalDevice(); + + render.createSyncObjects(); + + for (int i = 0; i < 2; i++) { + render.mDevice.destroySemaphore(render.mImageAvailableSemaphores[i]); + render.mDevice.destroySemaphore(render.mRenderFinishedSemaphores[i]); + render.mDevice.destroyFence(render.mInFlightFences[i]); + } + + // vkDestroyDevice(render.mDevice, nullptr); + // vkDestroySurfaceKHR(render.mInstance, render.mSurface, nullptr); + // vkDestroyInstance(render.mInstance, nullptr); + glfwDestroyWindow(render.mMainWindow); + glfwTerminate(); + +} \ No newline at end of file diff --git a/test/test_text.cpp b/test/test_text.cpp index 2803939..f6080ff 100644 --- a/test/test_text.cpp +++ b/test/test_text.cpp @@ -1,5 +1,78 @@ #include #include +#include "config.hpp" + +class TextRenderTest : public testing::Test { + +protected: + + TextRenderTest() { + + mTextRender.loadFont(cad::config::arial_font_coordinates_file_path); + + cad::txt::Text T; + + T.text = "a"; + + mTextRender.addText(T); + + } + + cad::txt::TextRender mTextRender; + +}; + +// @brief +TEST_F(TextRenderTest, clearTexts) { + + mTextRender.clearTexts(); + + std::vector vertices{mTextRender.generateQuads(glm::vec3{})}; + + EXPECT_TRUE(vertices.empty()); + + std::vector indices{mTextRender.generateIndices()}; + + EXPECT_TRUE(indices.empty()); + +} + +TEST_F(TextRenderTest, generateQuads) { + + + std::vector vertices{mTextRender.generateQuads(glm::vec3{})}; + + EXPECT_EQ(vertices.size(), 4); + + cad::txt::Text T; + + T.text = "b"; + + mTextRender.addText(T); + + vertices = mTextRender.generateQuads(glm::vec3{}); + + EXPECT_EQ(vertices.size(), 8); + +} + +TEST_F(TextRenderTest, generateIndices) { + + + std::vector vertices{mTextRender.generateQuads(glm::vec3{})}; + std::vector indices{mTextRender.generateIndices()}; + + EXPECT_EQ(indices.size(), 6); + + cad::txt::Text T; + + T.text = "b"; + + mTextRender.addText(T); + + vertices = mTextRender.generateQuads(glm::vec3{}); + indices = mTextRender.generateIndices(); + EXPECT_EQ(indices.size(), 12); + +} -// @brief Test if id of Point without an input id is -1 -TEST(Text, Text) { EXPECT_EQ(1, 1); } \ No newline at end of file