diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 672f4ea..7af07e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ add_library(fever_engine shader.cpp transform.cpp light.cpp + input.cpp ) target_compile_features(fever_engine PUBLIC cxx_std_20) diff --git a/src/Controller.cpp b/src/Controller.cpp index ef3efac..5765d33 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -3,9 +3,11 @@ #include "Helper.h" #include "Window.h" #include "gltf_loader.h" +#include "input.h" #include "light.h" #include "render.h" #include "shader.h" +#include "time.h" #include "util/Log.h" #include @@ -43,7 +45,7 @@ Controller::Controller() entt::resource gltf_document = m_gltf_cache.load(document_hash, document_path).first->second; - m_scene = gltf_document->default_scene.value().handle(); + m_scene = gltf_document->default_scene.value_or(gltf_document->scenes.at(0)).handle(); } void Controller::run() @@ -60,21 +62,20 @@ void Controller::run() while (glfwWindowShouldClose(&m_gameWindow->glfw_window()) == GLFW_FALSE) { // --- Timing --- limit_framerate(); + update_delta_time(m_scene->registry()); // --- 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(); + Input::handle_keyboard_input(m_scene->registry(), m_gameWindow->key_input()); + Input::handle_mouse_cursor_input(m_scene->registry(), m_gameWindow->mouse_cursor_input()); + Input::handle_mouse_button_input(m_scene->registry(), m_gameWindow->mouse_button_input()); + m_gameWindow->update_catched_mouse(m_scene->registry()); + m_gameWindow->update_descriptor(m_scene->registry()); - static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000; - m_scene->update( - std::chrono::microseconds(static_cast(m_deltaTime * MICROSECONDS_PER_SECOND)), - key_input, - mouse_cursor_input, - m_gameWindow->aspectRatio(), - m_gameWindow->cursor_catched()); + // --- Update game state --- + m_scene->update(); // --- Render and buffer swap --- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -114,7 +115,6 @@ void Controller::limit_framerate() } m_deltaTime = glfwGetTime() - startingTime; - startingTime = glfwGetTime(); } @@ -133,3 +133,11 @@ void Controller::updateExposure(Shader &shader) const shader.set_uniform("u_exposure", m_exposure); Shader::unbind(); } + +void Controller::update_delta_time(entt::registry ®istry) const +{ + static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000; + + registry.ctx().erase(); + registry.ctx().emplace(std::chrono::microseconds(static_cast(m_deltaTime * MICROSECONDS_PER_SECOND))); +} diff --git a/src/Controller.h b/src/Controller.h index 8fc1d47..1a29df6 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -1,9 +1,9 @@ #pragma once #include "FrameBuffer.h" +#include "gltf_loader.h" #include "scene.h" #include "shader.h" -#include "gltf_loader.h" #include #include @@ -27,6 +27,7 @@ public: private: void limit_framerate(); + void update_delta_time(entt::registry ®istry) const; void update_window_dimensions(); std::shared_ptr m_gameWindow; diff --git a/src/Window.cpp b/src/Window.cpp index 1d07866..cdc92e9 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -32,7 +32,8 @@ Window::Window() #endif m_glfw_window = std::shared_ptr( - glfwCreateWindow(static_cast(m_width), static_cast(m_height), "OpenGL", nullptr, nullptr), + glfwCreateWindow( + static_cast(m_width), static_cast(m_height), "OpenGL", nullptr, nullptr), [](GLFWwindow *window) { glfwDestroyWindow(window); }); if (!m_glfw_window) { @@ -60,12 +61,15 @@ Window::Window() } #ifndef NDEBUG - Log::logger().debug("OpenGL version: {}", reinterpret_cast(glGetString(GL_VERSION))); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) + Log::logger().debug("OpenGL version: {}", + reinterpret_cast(glGetString(GL_VERSION))); + // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback(&Helper::gl_debug_callback, nullptr); // Disable mouse cursor - m_mouse_catched = false; + m_mouse_catched.catched = false; #endif // Enable z buffer @@ -82,7 +86,7 @@ Window::Window() // Disable VSync since my sleep function handles this glfwSwapInterval(0); - set_catched_cursor(m_mouse_catched); + set_catched_cursor(m_mouse_catched.catched); glViewport(0, 0, static_cast(m_width), static_cast(m_height)); @@ -99,7 +103,8 @@ auto Window::dimensions_changed() const -> bool glfwGetFramebufferSize(m_glfw_window.get(), &new_width, &new_height); - return !(static_cast(new_width) == m_width && static_cast(new_height) == m_height); + return !(static_cast(new_width) == m_width && + static_cast(new_height) == m_height); } void Window::update_dimensions() @@ -117,13 +122,11 @@ void Window::update_dimensions() void Window::set_catched_cursor(bool value) { - if (value) { - glfwSetInputMode(m_glfw_window.get(), GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } else { - glfwSetInputMode(m_glfw_window.get(), GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } - m_mouse_catched = value; + glfwSetInputMode( + m_glfw_window.get(), GLFW_CURSOR, value ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL); + + m_mouse_catched.catched = value; } // GLFW error function @@ -151,16 +154,18 @@ void Window::key_callback(GLFWwindow *glfw_window, int key, int scancode, int ac 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); + window.set_catched_cursor(!window.m_mouse_catched.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); + window.m_key_input.key_map[key] = (action == GLFW_PRESS); } } // NOLINTBEGIN(bugprone-easily-swappable-parameters) -void Window::mouse_button_callback(GLFWwindow *glfw_window, int button, int action, +void Window::mouse_button_callback(GLFWwindow *glfw_window, + int button, + int action, int mods) // NOLINT(bugprone-easily-swappable-parameters) // NOLINTEND(bugprone-easily-swappable-parameters) { @@ -183,8 +188,9 @@ void Window::mouse_cursor_callback(GLFWwindow *glfw_window, double xpos, double 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 && !(std::abs(deltaCursorPosX) < std::numeric_limits::epsilon() && - std::abs(deltaCursorPosY) < std::numeric_limits::epsilon())) { + if (window.m_first_mouse_input && + !(std::abs(deltaCursorPosX) < std::numeric_limits::epsilon() && + std::abs(deltaCursorPosY) < std::numeric_limits::epsilon())) { window.m_first_mouse_input = false; deltaCursorPosX = 0.0; deltaCursorPosY = 0.0; @@ -193,7 +199,7 @@ void Window::mouse_cursor_callback(GLFWwindow *glfw_window, double xpos, double deltaCursorPosX *= MOUSE_SENSITIVITY; deltaCursorPosY *= MOUSE_SENSITIVITY; - auto &[deltaX, deltaY] = window.m_mouse_cursor_input; + auto &[deltaX, deltaY] = window.m_mouse_cursor_input.cursor_movement; deltaX += deltaCursorPosX; deltaY += deltaCursorPosY; } @@ -212,3 +218,16 @@ void Window::clear_mouse_cursor_input() { m_mouse_cursor_input = {}; }; + +void Window::update_catched_mouse(entt::registry ®istry) const +{ + registry.ctx().erase(); + registry.ctx().emplace(m_mouse_catched); +} + +void Window::update_descriptor(entt::registry ®istry) const +{ + registry.ctx().erase(); + registry.ctx().emplace( + Descriptor{.width = m_width, .height = m_height, .aspect_ratio = aspectRatio()}); +} diff --git a/src/Window.h b/src/Window.h index fc7c60b..13cd14a 100644 --- a/src/Window.h +++ b/src/Window.h @@ -11,6 +11,18 @@ class GLFWwindow; class Window { public: + struct MouseCatched + { + bool catched = true; + }; + + struct Descriptor + { + uint32_t width{}; + uint32_t height{}; + float aspect_ratio{}; + }; + Window(); [[nodiscard]] auto glfw_window() -> GLFWwindow & { return *m_glfw_window; } @@ -24,6 +36,8 @@ public: void clear_mouse_cursor_input(); void update_dimensions(); + void update_catched_mouse(entt::registry ®istry) const; + void update_descriptor(entt::registry ®istry) const; private: static void key_callback(GLFWwindow *glfw_window, int key, int scancode, int action, int mods); @@ -40,9 +54,9 @@ private: std::shared_ptr m_glfw_window; // - KeyInput m_key_input; - MouseButtonInput m_mouse_button_input; - MouseCursorInput m_mouse_cursor_input; + Input::Key m_key_input; + Input::MouseButton m_mouse_button_input; + Input::MouseCursor m_mouse_cursor_input; uint32_t m_width{}; uint32_t m_height{}; @@ -50,6 +64,6 @@ private: double m_last_cursor_pos_y = 0.0; bool m_first_mouse_input = false; - bool m_mouse_catched = true; + MouseCatched m_mouse_catched; bool m_wire_frame_mode = false; }; diff --git a/src/camera.cpp b/src/camera.cpp index 46da2cc..3b1f1e8 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,8 @@ #include "camera.h" #include "util/Log.h" +#include "input.h" +#include "time.h" +#include "Window.h" #include #include @@ -29,16 +32,16 @@ auto Camera::front_vector(GlobalTransform const &transform) -> glm::vec3 return glm::normalize(transform.transform * glm::vec4(0.0, 0.0, 1.0, 0.0)); } -void Camera::keyboard_movement(entt::registry ®istry, - KeyInput const &key_input, - std::chrono::duration delta_time) +void Camera::keyboard_movement(entt::registry ®istry) { struct KeyboardMovementContext { bool accelerate{}; }; - auto &context = registry.ctx().emplace(); + auto &movement_context = registry.ctx().emplace(); + auto const& key_input = registry.ctx().at(); + auto const& delta_time = registry.ctx().at(); auto camera_view = registry.view(); auto camera_entity = camera_view.front(); @@ -48,10 +51,10 @@ void Camera::keyboard_movement(entt::registry ®istry, front_vec.y = 0; // NOLINT (cppcoreguidelines-pro-type-union-access) glm::vec3 delta_pos = glm::vec3(0., 0., 0.); - float delta_factor = SPEED * delta_time.count() * (context.accelerate ? ACCELERATION : 1.0F); - context.accelerate = false; + float delta_factor = SPEED * delta_time.delta.count() * (movement_context.accelerate ? ACCELERATION : 1.0F); + movement_context.accelerate = false; - for (auto const &[key, pressed] : key_input) { + for (auto const &[key, pressed] : key_input.key_map) { if (key == GLFW_KEY_W && pressed) { delta_pos += delta_factor * glm::normalize(front_vec); } @@ -71,19 +74,20 @@ void Camera::keyboard_movement(entt::registry ®istry, delta_pos -= delta_factor * UP_VECTOR; } if (key == GLFW_KEY_LEFT_ALT && pressed) { - context.accelerate = true; + movement_context.accelerate = true; } } camera_transform.translation += delta_pos; } -void Camera::mouse_orientation(entt::registry ®istry, MouseCursorInput const &mouse_cursor_input) +void Camera::mouse_orientation(entt::registry ®istry) { auto camera_view = registry.view(); auto camera_entity = camera_view.front(); auto [camera, camera_transform] = camera_view.get(camera_entity); - auto [deltaX, deltaY] = mouse_cursor_input; + auto const& mouse_cursor_input = registry.ctx().at(); + auto [deltaX, deltaY] = mouse_cursor_input.cursor_movement; if (std::abs(deltaX) < std::numeric_limits::epsilon() && std::abs(deltaY) < std::numeric_limits::epsilon()) { @@ -108,8 +112,10 @@ void Camera::mouse_orientation(entt::registry ®istry, MouseCursorInput const glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0)); } -void Camera::aspect_ratio_update(entt::registry ®istry, float aspect_ratio) +void Camera::aspect_ratio_update(entt::registry ®istry) { + float aspect_ratio = registry.ctx().at().aspect_ratio; + auto camera_view = registry.view(); auto camera_entity = camera_view.front(); auto [camera] = camera_view.get(camera_entity); diff --git a/src/camera.h b/src/camera.h index d9bad00..53e9611 100644 --- a/src/camera.h +++ b/src/camera.h @@ -1,6 +1,5 @@ #pragma once -#include "input.h" #include "transform.h" #include @@ -49,9 +48,7 @@ struct Camera [[nodiscard]] static auto view_matrix(GlobalTransform const &transform) -> glm::mat4; [[nodiscard]] static auto front_vector(GlobalTransform const &transform) -> glm::vec3; - static void keyboard_movement(entt::registry ®istry, - KeyInput const &key_input, - std::chrono::duration delta_time); - static void mouse_orientation(entt::registry ®istry, MouseCursorInput const &mouse_cursor_input); - static void aspect_ratio_update(entt::registry ®istry, float aspect_ratio); + static void keyboard_movement(entt::registry ®istry); + static void mouse_orientation(entt::registry ®istry); + static void aspect_ratio_update(entt::registry ®istry); }; diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..db585bc --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,21 @@ +#include "input.h" + +void Input::handle_keyboard_input(entt::registry ®istry, Key const &key_input) +{ + registry.ctx().erase(); + registry.ctx().emplace(key_input); +} + +void Input::handle_mouse_button_input(entt::registry ®istry, + MouseButton const &mouse_button_input) +{ + registry.ctx().erase(); + registry.ctx().emplace(mouse_button_input); +} + +void Input::handle_mouse_cursor_input(entt::registry ®istry, + MouseCursor const &mouse_cursor_input) +{ + registry.ctx().erase(); + registry.ctx().emplace(mouse_cursor_input); +} diff --git a/src/input.h b/src/input.h index 146dfcf..f2e8e67 100644 --- a/src/input.h +++ b/src/input.h @@ -1,8 +1,27 @@ #pragma once +#include #include #include -using KeyInput = std::unordered_map; -using MouseButtonInput = std::unordered_map; -using MouseCursorInput = std::pair; +namespace Input { + +struct Key +{ + std::unordered_map key_map; +}; + +struct MouseButton +{ + std::unordered_map button_map; +}; +struct MouseCursor +{ + std::pair cursor_movement; +}; + +void handle_keyboard_input(entt::registry ®istry, Key const &key_input); +void handle_mouse_button_input(entt::registry ®istry, MouseButton const &mouse_button_input); +void handle_mouse_cursor_input(entt::registry ®istry, MouseCursor const &mouse_cursor_input); + +}; // namespace Input diff --git a/src/scene.cpp b/src/scene.cpp index aa473da..08d36e9 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -7,6 +7,7 @@ #include "shader.h" #include "transform.h" #include "util/Log.h" +#include "Window.h" Scene::Scene(entt::registry registry) : m_registry(std::move(registry)) { @@ -46,16 +47,13 @@ Scene::Scene(entt::registry registry) : m_registry(std::move(registry)) PointLight{.intensity = PointLight::DEFAULT_INTENSITY}); } -void Scene::update(std::chrono::duration delta, - KeyInput const &key_input, - MouseCursorInput const &mouse_cursor_input, - float aspect_ratio, - bool cursor_catched) +void Scene::update() { GlobalTransform::update(m_registry); - Camera::aspect_ratio_update(m_registry, aspect_ratio); - Camera::keyboard_movement(m_registry, key_input, delta); - if (cursor_catched) { - Camera::mouse_orientation(m_registry, mouse_cursor_input); + Camera::aspect_ratio_update(m_registry); + Camera::keyboard_movement(m_registry); + + if (m_registry.ctx().at().catched) { + Camera::mouse_orientation(m_registry); } } diff --git a/src/scene.h b/src/scene.h index 309dbea..b67ec3c 100644 --- a/src/scene.h +++ b/src/scene.h @@ -1,6 +1,5 @@ #pragma once -#include "input.h" #include "gltf.h" #include @@ -13,13 +12,8 @@ class Scene public: Scene(entt::registry registry); - void update(std::chrono::duration delta_time, - KeyInput const &key_input, - MouseCursorInput const &mouse_cursor_input, - float aspect_ratio, - bool cursor_catched); - - auto registry() -> entt::registry & { return m_registry; } + void update(); + auto registry() -> auto & { return m_registry; } private: entt::registry m_registry; diff --git a/src/time.h b/src/time.h new file mode 100644 index 0000000..8ca33ec --- /dev/null +++ b/src/time.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace Time { + +struct Delta +{ + std::chrono::duration delta; +}; + +} // namespace Time \ No newline at end of file