diff --git a/src/PlotWindow.cpp b/src/PlotWindow.cpp index 96ea26b..de986ae 100644 --- a/src/PlotWindow.cpp +++ b/src/PlotWindow.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -26,11 +27,14 @@ fCmplx test_function(fCmplx z) PlotWindow::PlotWindow(int w, int h, int id, unsigned int detail, std::string title) : window(nullptr), id(id), - model(glm::mat4(1.0f)), view(glm::mat4(1.0f)), projection(glm::mat4(1.0f)), + projection(glm::mat4(1.0f)), VAO(0), VBO(0), EBO(0) { IMGUI_CHECKVERSION(); + width = w; + height = h; + window = glfwCreateWindow(w, h, ("Plot " + std::to_string(id) + " | " + title).c_str(), NULL, NULL); if (window == nullptr) { @@ -44,6 +48,9 @@ PlotWindow::PlotWindow(int w, int h, int id, unsigned int detail, std::string ti glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, FramebufferSizeCallback); + glfwSetMouseButtonCallback(window, MouseButtonCallback); + glfwSetScrollCallback(window, ScrollCallback); + glfwSetCursorPosCallback(window, CursorPositionCallback); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { @@ -120,8 +127,8 @@ PlotWindow::PlotWindow(int w, int h, int id, unsigned int detail, std::string ti glEnable(GL_DEPTH_TEST); - view = glm::rotate(view, glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - view = glm::translate(view, glm::vec3(0.0f, -3.0f, -3.0f)); + //view = glm::rotate(view, glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f)); + view = glm::translate(view, glm::vec3(0.0f, -0.0f, -3.0f)); projection = glm::perspective(45.0f, (float)w / (float)h, 0.1f, 10.0f); } @@ -156,7 +163,6 @@ void PlotWindow::Display() static float transX = 0.0f, transY = 0.0f, transZ = 0.0f; static float pitch = 0.0f, yaw = 0.0f, roll = 0.0f; - static float scale = 1.0f; static bool grid = true; ImGui_ImplOpenGL3_NewFrame(); @@ -169,7 +175,7 @@ void PlotWindow::Display() if (ImGui::CollapsingHeader("Plot")) { ImGui::Checkbox("Grid", &grid); - ImGui::SliderFloat("Scale", &scale, 0.0f, 10.0f); + ImGui::SliderFloat("Scale", &scaling, 0.0f, 10.0f); ImGui::Separator(); ImGui::SliderFloat("X", &transX, -5.0f, 5.0f); ImGui::SliderFloat("Y", &transY, -5.0f, 5.0f); @@ -182,15 +188,18 @@ void PlotWindow::Display() ImGui::End(); - model = glm::mat4(1.0f); - model = glm::translate(model, glm::vec3(transX, transY, transZ)); - model = glm::scale(model, glm::vec3(scale, scale, scale)); - model = glm::rotate(model, pitch, glm::vec3(1.0f, 0.0f, 0.0f)); - model = glm::rotate(model, yaw, glm::vec3(0.0f, 1.0f, 0.0f)); - model = glm::rotate(model, roll, glm::vec3(0.0f, 0.0f, 1.0f)); + //model = glm::mat4(1.0f); + //model = glm::translate(model, glm::vec3(transX, transY, transZ)); + //model = glm::scale(model, glm::vec3(scale, scale, scale)); + //model = glm::rotate(model, pitch, glm::vec3(1.0f, 0.0f, 0.0f)); + //model = glm::rotate(model, yaw, glm::vec3(0.0f, 1.0f, 0.0f)); + //model = glm::rotate(model, roll, glm::vec3(0.0f, 0.0f, 1.0f)); glBindVertexArray(VAO); + model *= glm::toMat4(modelRotation); + projection = glm::perspective(45.0f, (float)width / (float)height, 0.1f, 100.0f); + if (grid) { gridShader->Use(); @@ -218,5 +227,40 @@ void PlotWindow::Display() void PlotWindow::FramebufferSizeCallback(GLFWwindow* window, int w, int h) { glfwMakeContextCurrent(window); + width = w; + height = h; glViewport(0, 0, w, h); } + +void PlotWindow::MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) +{ + isLeftButtonDown = ((button == GLFW_MOUSE_BUTTON_LEFT) && (action == GLFW_PRESS)); + isRightButtonDown = ((button == GLFW_MOUSE_BUTTON_RIGHT) && (action == GLFW_PRESS)); +} + +void PlotWindow::ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) +{ + model = glm::scale(model, glm::vec3(1.0f + yoffset / 5.0f)); +} + +void PlotWindow::CursorPositionCallback(GLFWwindow* window, double xpos, double ypos) +{ + glm::vec2 currentPos = glm::vec2(-ypos, -xpos); + glm::vec2 diff = currentPos - prevCursorPos; + + if (isRightButtonDown) + { + static glm::vec3 xAxis, yAxis; + xAxis = glm::inverse(model) * glm::inverse(view) * glm::vec4(1.0f, 0.0f, 0.0, 0.0f); + yAxis = glm::inverse(model) * glm::inverse(view) * glm::vec4(0.0f, 1.0f, 0.0, 0.0f); + model = glm::rotate(model, -diff.x / 30.f, xAxis); + model = glm::rotate(model, -diff.y / 30.f, yAxis); + } + + if (isLeftButtonDown) + { + view = glm::translate(view, glm::vec3(-diff.y, diff.x, 0.0f) / 50.0f); + } + + prevCursorPos = currentPos; +} diff --git a/src/PlotWindow.hpp b/src/PlotWindow.hpp index 4e69dcf..54f87ac 100644 --- a/src/PlotWindow.hpp +++ b/src/PlotWindow.hpp @@ -5,7 +5,9 @@ #include #include + #include +#include #include @@ -34,8 +36,6 @@ public: private: int id; GLFWwindow* window; - - static void FramebufferSizeCallback(GLFWwindow* window, int w, int h); BufferObject VAO, VBO, EBO; Shader* plotShader, *gridShader; @@ -43,7 +43,25 @@ private: std::vector vertices; std::vector indices; - glm::mat4 model, view, projection; + static inline glm::mat4 model = glm::mat4(1.0f); + static inline glm::quat modelRotation = glm::quat(); + static inline glm::mat4 modelScale = glm::mat4(1.0f); + static inline glm::mat4 view = glm::mat4(1.0f); + glm::mat4 projection; static inline bool isInit = false; + static inline bool isLeftButtonDown = false; + static inline bool isRightButtonDown = false; + + static inline float scaling = 1.0f; + + static inline glm::vec2 prevCursorPos = glm::vec2(1.0f, 1.0f); + + static inline int width = 0, height = 0; + +private: + static void FramebufferSizeCallback(GLFWwindow* window, int w, int h); + static void MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); + static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); + static void CursorPositionCallback(GLFWwindow* window, double xpos, double ypos); }; \ No newline at end of file