diff --git a/.clang-format b/.clang-format index 0fb55d6..df21f94 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,7 @@ --- BasedOnStyle: LLVM AccessModifierOffset: '-4' -AllowShortFunctionsOnASingleLine: None +AllowShortFunctionsOnASingleLine: InlineOnly AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: 'false' AlwaysBreakTemplateDeclarations: 'true' diff --git a/src/Camera.cpp b/src/Camera.cpp index e557f29..347f145 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -1,12 +1,12 @@ #include "Camera.h" +#include #include #include -Camera::Camera(float fov, float aspectRatio) +Camera::Camera(float fov, float aspectRatio) : m_fov(fov) { - this->m_fov = fov; - m_viewMatrix = glm::mat4(1.0f); + m_viewMatrix = glm::mat4(1.); updateAspectRatio(aspectRatio); updateVPM(); } @@ -19,105 +19,107 @@ void Camera::updateVPM() void Camera::updateAspectRatio(float aspectRatio) { // m_projectionMatrix = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, -10.f, 100.0f); - m_projectionMatrix = glm::perspective(m_fov / 2.0f, aspectRatio, 0.1f, 1000.0f); + m_projectionMatrix = glm::perspective(m_fov / 2.F, aspectRatio, .1F, 1000.F); updateVPM(); } void Camera::translate(glm::vec3 translateVector) { m_position += translateVector; - m_viewMatrix = glm::translate(m_viewMatrix, translateVector * -1.0f); + m_viewMatrix = glm::translate(m_viewMatrix, translateVector * -1.F); } void Camera::lookAtTarget(glm::vec3 target) { - m_viewMatrix = glm::lookAt(m_position, target, m_upVec); + m_viewMatrix = glm::lookAt(m_position, target, UP_VEC); } void Camera::lookForward() { - m_viewMatrix = glm::lookAt(m_position, m_position + m_frontVec, m_upVec); + m_viewMatrix = glm::lookAt(m_position, m_position + m_front_vec, UP_VEC); } -// void Camera::updatePositionFromKeyboardInput(const CameraActionMap &cameraActionMap, float deltaTime) -// { -// glm::vec3 frontVecWithoutY = glm::vec3(m_frontVec.x, 0.0f, m_frontVec.z); +void Camera::updatePositionFromKeyboardInput(KeyInput const &key_input, float deltaTime) +{ + glm::vec3 frontVecWithoutY = glm::vec3(m_front_vec.x, 0., m_front_vec.z); + glm::vec3 deltaPos = glm::vec3(0., 0., 0.); -// glm::vec3 deltaPos = glm::vec3(0.0f, 0.0f, 0.0f); + for (auto const &[key, pressed] : key_input) { + if (key == GLFW_KEY_W && pressed) { + deltaPos += SPEED * deltaTime * glm::normalize(frontVecWithoutY); + } + if (key == GLFW_KEY_S && pressed) { + deltaPos -= SPEED * deltaTime * glm::normalize(frontVecWithoutY); + } + if (key == GLFW_KEY_A && pressed) { + deltaPos -= SPEED * deltaTime * glm::normalize(glm::cross(m_front_vec, UP_VEC)); + } + if (key == GLFW_KEY_D && pressed) { + deltaPos += SPEED * deltaTime * glm::normalize(glm::cross(m_front_vec, UP_VEC)); + } + if (key == GLFW_KEY_SPACE && pressed) { + deltaPos += SPEED * deltaTime * UP_VEC; + } + if (key == GLFW_KEY_LEFT_SHIFT && pressed) { + deltaPos -= SPEED * deltaTime * UP_VEC; + } + } + m_position += deltaPos; +} -// if (cameraActionMap.at(CameraAction::Forward)) { -// deltaPos += m_speed * deltaTime * glm::normalize(frontVecWithoutY); -// } -// if (cameraActionMap.at(CameraAction::Backward)) { -// deltaPos -= m_speed * deltaTime * glm::normalize(frontVecWithoutY); -// } -// if (cameraActionMap.at(CameraAction::Left)) { -// deltaPos -= m_speed * deltaTime * glm::normalize(glm::cross(m_frontVec, m_upVec)); -// } -// if (cameraActionMap.at(CameraAction::Right)) { -// deltaPos += m_speed * deltaTime * glm::normalize(glm::cross(m_frontVec, m_upVec)); -// } -// if (cameraActionMap.at(CameraAction::Up)) { -// deltaPos += m_speed * deltaTime * m_upVec; -// } -// if (cameraActionMap.at(CameraAction::Down)) { -// deltaPos -= m_speed * deltaTime * m_upVec; -// } +void Camera::updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input) +{ + auto [deltaX, deltaY] = mouse_cursor_input; -// m_position += deltaPos; -// } + if (deltaX == 0 && deltaY == 0) { + return; + } -// void Camera::updateDirectionFromMouseInput(const CameraMouseActionMap &cameraMouseActionMap) -// { + m_yaw += deltaX; + m_pitch += deltaY; -// if (cameraMouseActionMap.at(CameraMouseAction::DeltaX) == 0 && -// cameraMouseActionMap.at(CameraMouseAction::DeltaY) == 0) { -// return; -// } + static constexpr float CLIP = 89.; -// m_yaw += cameraMouseActionMap.at(CameraMouseAction::DeltaX); -// m_pitch += cameraMouseActionMap.at(CameraMouseAction::DeltaY); + if (m_pitch > CLIP) { + m_pitch = CLIP; + } + if (m_pitch < -CLIP) { + m_pitch = -CLIP; + } -// if (m_pitch > 89.0f) { -// m_pitch = 89.0f; -// } -// if (m_pitch < -89.0f) { -// m_pitch = -89.0f; -// } - -// glm::vec3 direction; -// direction.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); -// direction.y = sin(glm::radians(m_pitch)); -// direction.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); -// m_frontVec = glm::normalize(direction); -// } + glm::vec3 direction; + direction.x = std::cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); + direction.y = std::sin(glm::radians(m_pitch)); + direction.z = std::sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); + m_front_vec = glm::normalize(direction); +} void Camera::setPosition(glm::vec3 position) { this->m_position = position; } -glm::mat4 Camera::getView() +auto Camera::getView() const -> glm::mat4 { return m_viewMatrix; } -glm::mat4 Camera::getProj() +auto Camera::getProj() const -> glm::mat4 { return m_projectionMatrix; } -glm::mat4 Camera::getViewProj() +auto Camera::getViewProj() const -> glm::mat4 { return m_viewProjectionMatrix; } -glm::vec3 Camera::getPosition() +auto Camera::getPosition() const -> glm::vec3 { return m_position; } -glm::vec3 Camera::getDirection() +auto Camera::getDirection() const -> glm::vec3 { - return m_frontVec; + return m_front_vec; } diff --git a/src/Camera.h b/src/Camera.h index 9e244f7..dc165d7 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -1,28 +1,29 @@ #pragma once +#include "Window.h" + #include class Camera { public: Camera(float fov, float aspectRatio); - ~Camera() = default; void updateVPM(); void updateAspectRatio(float aspectRatio); - // void updatePositionFromKeyboardInput(const CameraActionMap &cameraActionMap, float deltaTime); - // void updateDirectionFromMouseInput(const CameraMouseActionMap &cameraMouseActionMap); + void updatePositionFromKeyboardInput(KeyInput const &key_input, float deltaTime); + void updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input); void translate(glm::vec3 translateVector); void lookAtTarget(glm::vec3 target); void lookForward(); - glm::mat4 getView(); - glm::mat4 getProj(); - glm::mat4 getViewProj(); - glm::vec3 getPosition(); - glm::vec3 getDirection(); + [[nodiscard]] auto getView() const -> glm::mat4; + [[nodiscard]] auto getProj() const -> glm::mat4; + [[nodiscard]] auto getViewProj() const -> glm::mat4; + [[nodiscard]] auto getPosition() const -> glm::vec3; + [[nodiscard]] auto getDirection() const -> glm::vec3; void setPosition(glm::vec3 position); @@ -31,14 +32,15 @@ private: glm::mat4 m_projectionMatrix; glm::mat4 m_viewProjectionMatrix; - glm::vec3 m_position = glm::vec3(0.0f, 0.0f, 0.0f); - glm::vec3 m_frontVec = glm::vec3(0.0f, 0.0f, -1.0f); - glm::vec3 m_upVec = glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 m_position = glm::vec3(0., 0., 0.); + glm::vec3 m_front_vec = glm::vec3(0., 0., -1.); - float m_pitch = 0.0f; - float m_yaw = -90.0f; + static constexpr glm::vec3 UP_VEC = glm::vec3(0., 1., 0.); + static constexpr float SPEED = 2.; + static constexpr float DEFAULT_YAW = -90.; - float m_speed = 2.0f; + float m_pitch{}; + float m_yaw = DEFAULT_YAW; float m_fov; }; diff --git a/src/Controller.cpp b/src/Controller.cpp index 10d996f..329325a 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -19,8 +19,7 @@ #include Controller::Controller() - : m_gameWindow(std::make_shared()), - m_camera(std::make_shared(90.0f, m_gameWindow->getWindowAspectRatio())) + : m_gameWindow(std::make_shared()), m_camera(std::make_shared(90., m_gameWindow->aspectRatio())) { std::array shaderProgramPrototypes{ ShaderProgram::Prototype{"defaultProgram", "data/shaders/basic.vert", "data/shaders/basic.frag", ""}, @@ -39,9 +38,9 @@ Controller::Controller() Log::logger().info("Loaded shaderprogram \"{}\"", prototype.name); } - m_postProcessFrameBuffer = - std::make_shared(m_gameWindow->getWindowWidth(), m_gameWindow->getWindowHeight(), - getShaderProgramByName("postProcessingProgram").get()); + auto dimensions = m_gameWindow->dimensions(); + m_postProcessFrameBuffer = std::make_shared(dimensions.first, dimensions.second, + getShaderProgramByName("postProcessingProgram").get()); m_scene = std::make_shared(m_shaderPrograms); } @@ -51,42 +50,29 @@ void Controller::run() updateExposure(*getShaderProgramByName("postProcessingProgram")); auto lightSource = m_scene->getEntityByName("light"); - lightSource->setScale(0.1f); - lightSource->setRotation(glm::vec3(0.f)); - lightSource->setPosition(glm::vec3(-2.f, 1.5f, 2.f)); + lightSource->setScale(.1); + lightSource->setRotation(glm::vec3(0.)); + lightSource->setPosition(glm::vec3(-2., 1.5, 2.)); - m_camera->translate(glm::vec3(0.0f, 1.5f, 5.0f)); + m_camera->translate(glm::vec3(0., 1.5, 5.)); - bool drawShadows = false; - float intensity = 7.5; + static constexpr float INTENSITY = 7.5; glm::vec3 lightColor{1., 1., 1.}; // This is the game loop - while (!glfwWindowShouldClose(m_gameWindow->getGLFWwindow())) { + while (!glfwWindowShouldClose(m_gameWindow->glfw_window().get())) { // --- Timing --- limit_framerate(); // --- Update game --- - m_scene->updatePointLight(0, true, m_scene->getEntityByName("light")->getPosition(), lightColor, intensity); + m_scene->updatePointLight(0, true, m_scene->getEntityByName("light")->getPosition(), lightColor, INTENSITY); m_scene->updateDirectionalLight(true, m_scene->getDirectionalLight()->getDirection(), lightColor); getShaderProgramByName("lightProgram")->bind(); getShaderProgramByName("lightProgram")->setUniform("v_lightColor", glm::vec3{1., 1., 1.} * 100.0f); getShaderProgramByName("lightProgram")->unbind(); // --- Render and buffer swap --- - - // Calc shadows - getShaderProgramByName("defaultProgram")->bind(); - getShaderProgramByName("defaultProgram")->setUniform("b_drawShadows", (int)drawShadows); - getShaderProgramByName("defaultProgram")->unbind(); - // static bool firstRun = true; - // if (drawShadows || firstRun) { - // firstRun = false; - // m_scene->calculateShadows(getShaderProgramByName("directionalShadowDepthProgram"), - // getShaderProgramByName("pointShadowDepthProgram")); - // } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_postProcessFrameBuffer->bind(); @@ -101,16 +87,27 @@ void Controller::run() m_postProcessFrameBuffer->unbind(); m_postProcessFrameBuffer->drawOnEntireScreen(); - glfwSwapBuffers(m_gameWindow->getGLFWwindow()); + glfwSwapBuffers(m_gameWindow->glfw_window().get()); // Update window size - if (m_gameWindow->isWindowResized()) { - m_gameWindow->updateWindowDimensions(); - updateWindowDimensions(); + if (m_gameWindow->dimensions_changed()) { + m_gameWindow->update_dimensions(); + update_window_dimensions(); } // --- Check events, handle input --- + m_gameWindow->clear_mouse_cursor_input(); glfwPollEvents(); + + auto const &key_input = m_gameWindow->key_input(); + auto const &mouse_cursor_input = m_gameWindow->mouse_cursor_input(); + auto const &mouse_button_input = m_gameWindow->mouse_button_input(); + + m_camera->updatePositionFromKeyboardInput(key_input, (float)m_deltaTime); + + if (m_gameWindow->cursor_catched()) { + m_camera->updateDirectionFromMouseInput(mouse_cursor_input); + } } } @@ -131,12 +128,13 @@ void Controller::limit_framerate() startingTime = glfwGetTime(); } -void Controller::updateWindowDimensions() +void Controller::update_window_dimensions() { - m_camera->updateAspectRatio(m_gameWindow->getWindowAspectRatio()); + m_camera->updateAspectRatio(m_gameWindow->aspectRatio()); // m_gameEventHandler->setFirstMouseInput(1); - m_postProcessFrameBuffer->changeDimensions(m_gameWindow->getWindowWidth(), m_gameWindow->getWindowHeight()); + auto dimensions = m_gameWindow->dimensions(); + m_postProcessFrameBuffer->changeDimensions(dimensions.first, dimensions.second); } void Controller::updateExposure(ShaderProgram &shaderProgram) diff --git a/src/Controller.h b/src/Controller.h index 7cbc31c..a82c368 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -26,7 +26,7 @@ public: private: void limit_framerate(); - void updateWindowDimensions(); + void update_window_dimensions(); std::shared_ptr m_gameWindow; std::shared_ptr m_scene; @@ -38,7 +38,7 @@ private: std::shared_ptr m_postProcessFrameBuffer; static constexpr unsigned MAX_FPS = 60; - double m_deltaTime; - float m_exposure = 1.0f; + double m_deltaTime{}; + float m_exposure = 1.0; }; diff --git a/src/Window.cpp b/src/Window.cpp index c0286ed..ca1ba0f 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -9,8 +9,9 @@ Window::Window() { // Initialize GLFW - if (!glfwInit()) - exit(-1); + if (glfwInit() == 0) { + std::terminate(); + } m_width = INIT_WINDOW_WIDTH; m_height = INIT_WINDOW_HEIGHT; @@ -27,32 +28,34 @@ Window::Window() glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); #endif - m_window = glfwCreateWindow(m_width, m_height, "OpenGL", NULL, NULL); - if (!m_window) + m_glfw_window = std::shared_ptr(glfwCreateWindow(m_width, m_height, "OpenGL", nullptr, nullptr), + [](GLFWwindow *window) { glfwDestroyWindow(window); }); + if (!m_glfw_window) { Log::logger().critical("Failed to create window"); + } // Wait for window to maximize (in case) // Helper::sleep(1000); - glfwGetWindowPos(m_window, &m_posX, &m_posY); - glfwGetWindowSize(m_window, &m_width, &m_height); + glfwGetWindowPos(m_glfw_window.get(), &m_posX, &m_posY); + glfwGetWindowSize(m_glfw_window.get(), &m_width, &m_height); // Create OpenGL context - glfwMakeContextCurrent(m_window); + glfwMakeContextCurrent(m_glfw_window.get()); // Initialize GLAD - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) { Log::logger().critical("Failed to initialize GLAD"); - exit(-1); + std::terminate(); } #ifdef _DEBUG Log::logger().debug("OpenGL version: {}", glGetString(GL_VERSION)); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageCallback(Helper::gl_debug_callback, NULL); + glDebugMessageCallback(Helper::gl_debug_callback, nullptr); // Disable mouse cursor - m_mouseCatched = false; + m_mouse_catched = false; #endif // Enable z buffer @@ -69,52 +72,55 @@ Window::Window() // Disable VSync since my sleep function handles this glfwSwapInterval(0); - setCatchedCursor(m_mouseCatched); + set_catched_cursor(m_mouse_catched); glViewport(0, 0, m_width, m_height); + glfwSetWindowUserPointer(m_glfw_window.get(), this); + glfwSetKeyCallback(m_glfw_window.get(), key_callback); + glfwSetMouseButtonCallback(m_glfw_window.get(), mouse_button_callback); + glfwSetCursorPosCallback(m_glfw_window.get(), mouse_cursor_callback); + // Tell GLFW which function to call when window is resized // glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); } -Window::~Window() -{ - glfwDestroyWindow(m_window); -} - -bool Window::isWindowResized() +auto Window::dimensions_changed() const -> bool { int new_width{}; int new_height{}; int new_posx{}; int new_posy{}; - glfwGetFramebufferSize(m_window, &new_width, &new_height); - glfwGetWindowPos(m_window, &new_posx, &new_posy); + + glfwGetFramebufferSize(m_glfw_window.get(), &new_width, &new_height); + glfwGetWindowPos(m_glfw_window.get(), &new_posx, &new_posy); return !(new_width == m_width && new_height == m_height && new_posx == m_posX && new_posy == m_posY); } -void Window::updateWindowDimensions() +void Window::update_dimensions() { - glfwGetFramebufferSize(m_window, &m_width, &m_height); - glfwGetWindowPos(m_window, &m_posX, &m_posY); + glfwGetFramebufferSize(m_glfw_window.get(), &m_width, &m_height); + glfwGetWindowPos(m_glfw_window.get(), &m_posX, &m_posY); glViewport(0, 0, m_width, m_height); } -void Window::setCatchedCursor(bool value) +void Window::set_catched_cursor(bool value) { if (value) { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(m_glfw_window.get(), GLFW_CURSOR, GLFW_CURSOR_DISABLED); } else { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetInputMode(m_glfw_window.get(), GLFW_CURSOR, GLFW_CURSOR_NORMAL); } + + m_mouse_catched = value; } // GLFW error function void Window::glfw_error_callback(int error, const char *description) { - fprintf(stderr, "[Error] GLFW Error %d: %s\n", error, description); + Log::logger().warn("GLFW [%d]: %s\n", error, description); } // This function is called when the window gets resized (currently not used) @@ -124,22 +130,73 @@ void Window::framebuffer_size_callback(GLFWwindow *window, int width, int height glViewport(0, 0, width, height); } -GLFWwindow *Window::getGLFWwindow() +void Window::key_callback(GLFWwindow *glfw_window, int key, int scancode, int action, + int mods) // NOLINT(bugprone-easily-swappable-parameters) { - return m_window; + (void)mods; + (void)scancode; + + auto &window = *static_cast(glfwGetWindowUserPointer(glfw_window)); + + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(glfw_window, GLFW_TRUE); + } else if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_PRESS) { + window.set_catched_cursor(!window.m_mouse_catched); + } else if (key == GLFW_KEY_O && action == GLFW_PRESS) { + window.m_wire_frame_mode = !window.m_wire_frame_mode; + glPolygonMode(GL_FRONT_AND_BACK, window.m_wire_frame_mode ? GL_LINE : GL_FILL); + } else if (action == GLFW_PRESS || action == GLFW_RELEASE) { + window.m_key_input[key] = (action == GLFW_PRESS); + } } -int Window::getWindowWidth() +void Window::mouse_button_callback(GLFWwindow *glfw_window, int button, int action, + int mods) // NOLINT(bugprone-easily-swappable-parameters) { - return m_width; + (void)mods; + (void)button; + (void)action; + + auto &window = *static_cast(glfwGetWindowUserPointer(glfw_window)); + (void)window; } -int Window::getWindowHeight() +void Window::mouse_cursor_callback(GLFWwindow *glfw_window, double xpos, double ypos) { - return m_height; + auto &window = *static_cast(glfwGetWindowUserPointer(glfw_window)); + + double deltaCursorPosX = xpos - window.m_last_cursor_pos_x; + double deltaCursorPosY = -(ypos - window.m_last_cursor_pos_y); + + window.m_last_cursor_pos_x = xpos; + window.m_last_cursor_pos_y = ypos; + + // Check if this is the first VALID mouse event after window being resized + if (window.m_first_mouse_input && !(deltaCursorPosX == 0 && deltaCursorPosY == 0)) { + window.m_first_mouse_input = false; + deltaCursorPosX = 0.0; + deltaCursorPosY = 0.0; + } + + deltaCursorPosX *= MOUSE_SENSITIVITY; + deltaCursorPosY *= MOUSE_SENSITIVITY; + + auto &[deltaX, deltaY] = window.m_mouse_cursor_input; + deltaX += deltaCursorPosX; + deltaY += deltaCursorPosY; } -float Window::getWindowAspectRatio() +auto Window::dimensions() const -> std::pair +{ + return {m_width, m_height}; +} + +auto Window::aspectRatio() const -> float { return (float)m_width / (float)m_height; } + +void Window::clear_mouse_cursor_input() +{ + m_mouse_cursor_input = {}; +}; diff --git a/src/Window.h b/src/Window.h index e47776b..b4425c2 100644 --- a/src/Window.h +++ b/src/Window.h @@ -1,32 +1,59 @@ #pragma once +#include +#include +#include + +using KeyInput = std::unordered_map; +using MouseButtonInput = std::unordered_map; +using MouseCursorInput = std::pair; + class GLFWwindow; class Window { public: Window(); - ~Window(); - GLFWwindow *getGLFWwindow(); + [[nodiscard]] auto glfw_window() -> std::shared_ptr { return m_glfw_window; } + [[nodiscard]] auto dimensions() const -> std::pair; + [[nodiscard]] auto dimensions_changed() const -> bool; + [[nodiscard]] auto aspectRatio() const -> float; + [[nodiscard]] auto key_input() const -> auto const & { return m_key_input; } + [[nodiscard]] auto mouse_cursor_input() const -> auto const & { return m_mouse_cursor_input; } + [[nodiscard]] auto mouse_button_input() const -> auto const & { return m_mouse_button_input; } + [[nodiscard]] auto cursor_catched() const -> auto { return m_mouse_catched; } - int getWindowWidth(); - int getWindowHeight(); - float getWindowAspectRatio(); - - bool isWindowResized(); - void updateWindowDimensions(); + void clear_mouse_cursor_input(); + void update_dimensions(); private: + static void key_callback(GLFWwindow *glfw_window, int key, int scancode, int action, int mods); + static void mouse_button_callback(GLFWwindow *glfw_window, int button, int action, int mods); + static void mouse_cursor_callback(GLFWwindow *glfw_window, double xpos, double ypos); + static void glfw_error_callback(int error, const char *description); - static void framebuffer_size_callback(GLFWwindow *window, int width, int height); - void setCatchedCursor(bool value); + static void framebuffer_size_callback(GLFWwindow *glfw_window, int width, int height); - GLFWwindow *m_window; + static constexpr float MOUSE_SENSITIVITY = 0.15; - int m_posX, m_posY; - int m_width, m_height; + void set_catched_cursor(bool value); - bool m_mouseCatched = true; - bool m_wireFrameMode = false; + std::shared_ptr m_glfw_window; + + // + KeyInput m_key_input; + MouseButtonInput m_mouse_button_input; + MouseCursorInput m_mouse_cursor_input; + + int m_posX{}; + int m_posY{}; + int m_width{}; + int m_height{}; + double m_last_cursor_pos_x = 0.0; + double m_last_cursor_pos_y = 0.0; + + bool m_first_mouse_input = false; + bool m_mouse_catched = true; + bool m_wire_frame_mode = false; };