Provide a set of context variables

This commit is contained in:
2022-10-23 17:42:22 +02:00
parent 71a86bdae2
commit 886c7ab47c
12 changed files with 160 additions and 70 deletions

View File

@@ -14,6 +14,7 @@ add_library(fever_engine
shader.cpp shader.cpp
transform.cpp transform.cpp
light.cpp light.cpp
input.cpp
) )
target_compile_features(fever_engine PUBLIC cxx_std_20) target_compile_features(fever_engine PUBLIC cxx_std_20)

View File

@@ -3,9 +3,11 @@
#include "Helper.h" #include "Helper.h"
#include "Window.h" #include "Window.h"
#include "gltf_loader.h" #include "gltf_loader.h"
#include "input.h"
#include "light.h" #include "light.h"
#include "render.h" #include "render.h"
#include "shader.h" #include "shader.h"
#include "time.h"
#include "util/Log.h" #include "util/Log.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -43,7 +45,7 @@ Controller::Controller()
entt::resource<Gltf> gltf_document = entt::resource<Gltf> gltf_document =
m_gltf_cache.load(document_hash, document_path).first->second; 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() void Controller::run()
@@ -60,21 +62,20 @@ void Controller::run()
while (glfwWindowShouldClose(&m_gameWindow->glfw_window()) == GLFW_FALSE) { while (glfwWindowShouldClose(&m_gameWindow->glfw_window()) == GLFW_FALSE) {
// --- Timing --- // --- Timing ---
limit_framerate(); limit_framerate();
update_delta_time(m_scene->registry());
// --- Check events, handle input --- // --- Check events, handle input ---
m_gameWindow->clear_mouse_cursor_input(); m_gameWindow->clear_mouse_cursor_input();
glfwPollEvents(); glfwPollEvents();
auto const &key_input = m_gameWindow->key_input(); Input::handle_keyboard_input(m_scene->registry(), m_gameWindow->key_input());
auto const &mouse_cursor_input = m_gameWindow->mouse_cursor_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; // --- Update game state ---
m_scene->update( m_scene->update();
std::chrono::microseconds(static_cast<unsigned>(m_deltaTime * MICROSECONDS_PER_SECOND)),
key_input,
mouse_cursor_input,
m_gameWindow->aspectRatio(),
m_gameWindow->cursor_catched());
// --- Render and buffer swap --- // --- Render and buffer swap ---
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -114,7 +115,6 @@ void Controller::limit_framerate()
} }
m_deltaTime = glfwGetTime() - startingTime; m_deltaTime = glfwGetTime() - startingTime;
startingTime = glfwGetTime(); startingTime = glfwGetTime();
} }
@@ -133,3 +133,11 @@ void Controller::updateExposure(Shader &shader) const
shader.set_uniform("u_exposure", m_exposure); shader.set_uniform("u_exposure", m_exposure);
Shader::unbind(); Shader::unbind();
} }
void Controller::update_delta_time(entt::registry &registry) const
{
static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000;
registry.ctx().erase<Time::Delta>();
registry.ctx().emplace<Time::Delta>(std::chrono::microseconds(static_cast<unsigned>(m_deltaTime * MICROSECONDS_PER_SECOND)));
}

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "FrameBuffer.h" #include "FrameBuffer.h"
#include "gltf_loader.h"
#include "scene.h" #include "scene.h"
#include "shader.h" #include "shader.h"
#include "gltf_loader.h"
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@@ -27,6 +27,7 @@ public:
private: private:
void limit_framerate(); void limit_framerate();
void update_delta_time(entt::registry &registry) const;
void update_window_dimensions(); void update_window_dimensions();
std::shared_ptr<Window> m_gameWindow; std::shared_ptr<Window> m_gameWindow;

View File

@@ -32,7 +32,8 @@ Window::Window()
#endif #endif
m_glfw_window = std::shared_ptr<GLFWwindow>( m_glfw_window = std::shared_ptr<GLFWwindow>(
glfwCreateWindow(static_cast<int>(m_width), static_cast<int>(m_height), "OpenGL", nullptr, nullptr), glfwCreateWindow(
static_cast<int>(m_width), static_cast<int>(m_height), "OpenGL", nullptr, nullptr),
[](GLFWwindow *window) { glfwDestroyWindow(window); }); [](GLFWwindow *window) { glfwDestroyWindow(window); });
if (!m_glfw_window) { if (!m_glfw_window) {
@@ -60,12 +61,15 @@ Window::Window()
} }
#ifndef NDEBUG #ifndef NDEBUG
Log::logger().debug("OpenGL version: {}", reinterpret_cast<const char *>(glGetString(GL_VERSION))); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
Log::logger().debug("OpenGL version: {}",
reinterpret_cast<const char *>(glGetString(GL_VERSION)));
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(&Helper::gl_debug_callback, nullptr); glDebugMessageCallback(&Helper::gl_debug_callback, nullptr);
// Disable mouse cursor // Disable mouse cursor
m_mouse_catched = false; m_mouse_catched.catched = false;
#endif #endif
// Enable z buffer // Enable z buffer
@@ -82,7 +86,7 @@ Window::Window()
// Disable VSync since my sleep function handles this // Disable VSync since my sleep function handles this
glfwSwapInterval(0); glfwSwapInterval(0);
set_catched_cursor(m_mouse_catched); set_catched_cursor(m_mouse_catched.catched);
glViewport(0, 0, static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height)); glViewport(0, 0, static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height));
@@ -99,7 +103,8 @@ auto Window::dimensions_changed() const -> bool
glfwGetFramebufferSize(m_glfw_window.get(), &new_width, &new_height); glfwGetFramebufferSize(m_glfw_window.get(), &new_width, &new_height);
return !(static_cast<uint32_t>(new_width) == m_width && static_cast<uint32_t>(new_height) == m_height); return !(static_cast<uint32_t>(new_width) == m_width &&
static_cast<uint32_t>(new_height) == m_height);
} }
void Window::update_dimensions() void Window::update_dimensions()
@@ -117,13 +122,11 @@ void Window::update_dimensions()
void Window::set_catched_cursor(bool value) 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 // 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) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(glfw_window, GLFW_TRUE); glfwSetWindowShouldClose(glfw_window, GLFW_TRUE);
} else if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_PRESS) { } 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) { } else if (key == GLFW_KEY_O && action == GLFW_PRESS) {
window.m_wire_frame_mode = !window.m_wire_frame_mode; window.m_wire_frame_mode = !window.m_wire_frame_mode;
glPolygonMode(GL_FRONT_AND_BACK, window.m_wire_frame_mode ? GL_LINE : GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, window.m_wire_frame_mode ? GL_LINE : GL_FILL);
} else if (action == GLFW_PRESS || action == GLFW_RELEASE) { } 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) // 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) int mods) // NOLINT(bugprone-easily-swappable-parameters)
// NOLINTEND(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; window.m_last_cursor_pos_y = ypos;
// Check if this is the first VALID mouse event after window being resized // 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<double>::epsilon() && if (window.m_first_mouse_input &&
std::abs(deltaCursorPosY) < std::numeric_limits<double>::epsilon())) { !(std::abs(deltaCursorPosX) < std::numeric_limits<double>::epsilon() &&
std::abs(deltaCursorPosY) < std::numeric_limits<double>::epsilon())) {
window.m_first_mouse_input = false; window.m_first_mouse_input = false;
deltaCursorPosX = 0.0; deltaCursorPosX = 0.0;
deltaCursorPosY = 0.0; deltaCursorPosY = 0.0;
@@ -193,7 +199,7 @@ void Window::mouse_cursor_callback(GLFWwindow *glfw_window, double xpos, double
deltaCursorPosX *= MOUSE_SENSITIVITY; deltaCursorPosX *= MOUSE_SENSITIVITY;
deltaCursorPosY *= 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; deltaX += deltaCursorPosX;
deltaY += deltaCursorPosY; deltaY += deltaCursorPosY;
} }
@@ -212,3 +218,16 @@ void Window::clear_mouse_cursor_input()
{ {
m_mouse_cursor_input = {}; m_mouse_cursor_input = {};
}; };
void Window::update_catched_mouse(entt::registry &registry) const
{
registry.ctx().erase<MouseCatched>();
registry.ctx().emplace<MouseCatched>(m_mouse_catched);
}
void Window::update_descriptor(entt::registry &registry) const
{
registry.ctx().erase<Descriptor>();
registry.ctx().emplace<Descriptor>(
Descriptor{.width = m_width, .height = m_height, .aspect_ratio = aspectRatio()});
}

View File

@@ -11,6 +11,18 @@ class GLFWwindow;
class Window class Window
{ {
public: public:
struct MouseCatched
{
bool catched = true;
};
struct Descriptor
{
uint32_t width{};
uint32_t height{};
float aspect_ratio{};
};
Window(); Window();
[[nodiscard]] auto glfw_window() -> GLFWwindow & { return *m_glfw_window; } [[nodiscard]] auto glfw_window() -> GLFWwindow & { return *m_glfw_window; }
@@ -24,6 +36,8 @@ public:
void clear_mouse_cursor_input(); void clear_mouse_cursor_input();
void update_dimensions(); void update_dimensions();
void update_catched_mouse(entt::registry &registry) const;
void update_descriptor(entt::registry &registry) const;
private: private:
static void key_callback(GLFWwindow *glfw_window, int key, int scancode, int action, int mods); static void key_callback(GLFWwindow *glfw_window, int key, int scancode, int action, int mods);
@@ -40,9 +54,9 @@ private:
std::shared_ptr<GLFWwindow> m_glfw_window; std::shared_ptr<GLFWwindow> m_glfw_window;
// <Key, Action> // <Key, Action>
KeyInput m_key_input; Input::Key m_key_input;
MouseButtonInput m_mouse_button_input; Input::MouseButton m_mouse_button_input;
MouseCursorInput m_mouse_cursor_input; Input::MouseCursor m_mouse_cursor_input;
uint32_t m_width{}; uint32_t m_width{};
uint32_t m_height{}; uint32_t m_height{};
@@ -50,6 +64,6 @@ private:
double m_last_cursor_pos_y = 0.0; double m_last_cursor_pos_y = 0.0;
bool m_first_mouse_input = false; bool m_first_mouse_input = false;
bool m_mouse_catched = true; MouseCatched m_mouse_catched;
bool m_wire_frame_mode = false; bool m_wire_frame_mode = false;
}; };

View File

@@ -1,5 +1,8 @@
#include "camera.h" #include "camera.h"
#include "util/Log.h" #include "util/Log.h"
#include "input.h"
#include "time.h"
#include "Window.h"
#include <algorithm> #include <algorithm>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@@ -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)); return glm::normalize(transform.transform * glm::vec4(0.0, 0.0, 1.0, 0.0));
} }
void Camera::keyboard_movement(entt::registry &registry, void Camera::keyboard_movement(entt::registry &registry)
KeyInput const &key_input,
std::chrono::duration<float> delta_time)
{ {
struct KeyboardMovementContext struct KeyboardMovementContext
{ {
bool accelerate{}; bool accelerate{};
}; };
auto &context = registry.ctx().emplace<KeyboardMovementContext>(); auto &movement_context = registry.ctx().emplace<KeyboardMovementContext>();
auto const& key_input = registry.ctx().at<Input::Key>();
auto const& delta_time = registry.ctx().at<Time::Delta>();
auto camera_view = registry.view<Camera const, Transform, GlobalTransform const>(); auto camera_view = registry.view<Camera const, Transform, GlobalTransform const>();
auto camera_entity = camera_view.front(); auto camera_entity = camera_view.front();
@@ -48,10 +51,10 @@ void Camera::keyboard_movement(entt::registry &registry,
front_vec.y = 0; // NOLINT (cppcoreguidelines-pro-type-union-access) front_vec.y = 0; // NOLINT (cppcoreguidelines-pro-type-union-access)
glm::vec3 delta_pos = glm::vec3(0., 0., 0.); glm::vec3 delta_pos = glm::vec3(0., 0., 0.);
float delta_factor = SPEED * delta_time.count() * (context.accelerate ? ACCELERATION : 1.0F); float delta_factor = SPEED * delta_time.delta.count() * (movement_context.accelerate ? ACCELERATION : 1.0F);
context.accelerate = false; 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) { if (key == GLFW_KEY_W && pressed) {
delta_pos += delta_factor * glm::normalize(front_vec); delta_pos += delta_factor * glm::normalize(front_vec);
} }
@@ -71,19 +74,20 @@ void Camera::keyboard_movement(entt::registry &registry,
delta_pos -= delta_factor * UP_VECTOR; delta_pos -= delta_factor * UP_VECTOR;
} }
if (key == GLFW_KEY_LEFT_ALT && pressed) { if (key == GLFW_KEY_LEFT_ALT && pressed) {
context.accelerate = true; movement_context.accelerate = true;
} }
} }
camera_transform.translation += delta_pos; camera_transform.translation += delta_pos;
} }
void Camera::mouse_orientation(entt::registry &registry, MouseCursorInput const &mouse_cursor_input) void Camera::mouse_orientation(entt::registry &registry)
{ {
auto camera_view = registry.view<Camera, Transform>(); auto camera_view = registry.view<Camera, Transform>();
auto camera_entity = camera_view.front(); auto camera_entity = camera_view.front();
auto [camera, camera_transform] = camera_view.get(camera_entity); auto [camera, camera_transform] = camera_view.get(camera_entity);
auto [deltaX, deltaY] = mouse_cursor_input; auto const& mouse_cursor_input = registry.ctx().at<Input::MouseCursor>();
auto [deltaX, deltaY] = mouse_cursor_input.cursor_movement;
if (std::abs(deltaX) < std::numeric_limits<double>::epsilon() && if (std::abs(deltaX) < std::numeric_limits<double>::epsilon() &&
std::abs(deltaY) < std::numeric_limits<double>::epsilon()) { std::abs(deltaY) < std::numeric_limits<double>::epsilon()) {
@@ -108,8 +112,10 @@ void Camera::mouse_orientation(entt::registry &registry, MouseCursorInput const
glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0)); glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0));
} }
void Camera::aspect_ratio_update(entt::registry &registry, float aspect_ratio) void Camera::aspect_ratio_update(entt::registry &registry)
{ {
float aspect_ratio = registry.ctx().at<Window::Descriptor>().aspect_ratio;
auto camera_view = registry.view<Camera>(); auto camera_view = registry.view<Camera>();
auto camera_entity = camera_view.front(); auto camera_entity = camera_view.front();
auto [camera] = camera_view.get(camera_entity); auto [camera] = camera_view.get(camera_entity);

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "input.h"
#include "transform.h" #include "transform.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -49,9 +48,7 @@ struct Camera
[[nodiscard]] static auto view_matrix(GlobalTransform const &transform) -> glm::mat4; [[nodiscard]] static auto view_matrix(GlobalTransform const &transform) -> glm::mat4;
[[nodiscard]] static auto front_vector(GlobalTransform const &transform) -> glm::vec3; [[nodiscard]] static auto front_vector(GlobalTransform const &transform) -> glm::vec3;
static void keyboard_movement(entt::registry &registry, static void keyboard_movement(entt::registry &registry);
KeyInput const &key_input, static void mouse_orientation(entt::registry &registry);
std::chrono::duration<float> delta_time); static void aspect_ratio_update(entt::registry &registry);
static void mouse_orientation(entt::registry &registry, MouseCursorInput const &mouse_cursor_input);
static void aspect_ratio_update(entt::registry &registry, float aspect_ratio);
}; };

21
src/input.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "input.h"
void Input::handle_keyboard_input(entt::registry &registry, Key const &key_input)
{
registry.ctx().erase<Key>();
registry.ctx().emplace<Key>(key_input);
}
void Input::handle_mouse_button_input(entt::registry &registry,
MouseButton const &mouse_button_input)
{
registry.ctx().erase<MouseButton>();
registry.ctx().emplace<MouseButton>(mouse_button_input);
}
void Input::handle_mouse_cursor_input(entt::registry &registry,
MouseCursor const &mouse_cursor_input)
{
registry.ctx().erase<MouseCursor>();
registry.ctx().emplace<MouseCursor>(mouse_cursor_input);
}

View File

@@ -1,8 +1,27 @@
#pragma once #pragma once
#include <entt/entt.hpp>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
using KeyInput = std::unordered_map<int, bool>; namespace Input {
using MouseButtonInput = std::unordered_map<int, bool>;
using MouseCursorInput = std::pair<double, double>; struct Key
{
std::unordered_map<int, bool> key_map;
};
struct MouseButton
{
std::unordered_map<int, bool> button_map;
};
struct MouseCursor
{
std::pair<double, double> cursor_movement;
};
void handle_keyboard_input(entt::registry &registry, Key const &key_input);
void handle_mouse_button_input(entt::registry &registry, MouseButton const &mouse_button_input);
void handle_mouse_cursor_input(entt::registry &registry, MouseCursor const &mouse_cursor_input);
}; // namespace Input

View File

@@ -7,6 +7,7 @@
#include "shader.h" #include "shader.h"
#include "transform.h" #include "transform.h"
#include "util/Log.h" #include "util/Log.h"
#include "Window.h"
Scene::Scene(entt::registry registry) : m_registry(std::move(registry)) 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}); PointLight{.intensity = PointLight::DEFAULT_INTENSITY});
} }
void Scene::update(std::chrono::duration<float> delta, void Scene::update()
KeyInput const &key_input,
MouseCursorInput const &mouse_cursor_input,
float aspect_ratio,
bool cursor_catched)
{ {
GlobalTransform::update(m_registry); GlobalTransform::update(m_registry);
Camera::aspect_ratio_update(m_registry, aspect_ratio); Camera::aspect_ratio_update(m_registry);
Camera::keyboard_movement(m_registry, key_input, delta); Camera::keyboard_movement(m_registry);
if (cursor_catched) {
Camera::mouse_orientation(m_registry, mouse_cursor_input); if (m_registry.ctx().at<Window::MouseCatched>().catched) {
Camera::mouse_orientation(m_registry);
} }
} }

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "input.h"
#include "gltf.h" #include "gltf.h"
#include <chrono> #include <chrono>
@@ -13,13 +12,8 @@ class Scene
public: public:
Scene(entt::registry registry); Scene(entt::registry registry);
void update(std::chrono::duration<float> delta_time, void update();
KeyInput const &key_input, auto registry() -> auto & { return m_registry; }
MouseCursorInput const &mouse_cursor_input,
float aspect_ratio,
bool cursor_catched);
auto registry() -> entt::registry & { return m_registry; }
private: private:
entt::registry m_registry; entt::registry m_registry;

12
src/time.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <chrono>
namespace Time {
struct Delta
{
std::chrono::duration<float> delta;
};
} // namespace Time