diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9367d30..fc223da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,6 @@ add_library(fever_engine Controller.cpp Window.cpp ShaderProgram.cpp - Camera.cpp Light.cpp Scene.cpp FrameBuffer.cpp diff --git a/src/Camera.cpp b/src/Camera.cpp deleted file mode 100644 index b5dccc8..0000000 --- a/src/Camera.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "Camera.h" - -#include -#include -#include - -Camera::Camera(float fov, float aspectRatio) : m_fov(fov) -{ - m_viewMatrix = glm::mat4(1.); - updateAspectRatio(aspectRatio); - updateVPM(); -} - -void Camera::updateVPM() -{ - m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix; -} - -void Camera::updateAspectRatio(float aspectRatio) -{ - m_projectionMatrix = glm::perspective(m_fov / 2.F, aspectRatio, .01F, 1000.F); - updateVPM(); -} - -void Camera::translate(glm::vec3 translateVector) -{ - m_position += translateVector; - m_viewMatrix = glm::translate(m_viewMatrix, translateVector * -1.F); -} - -void Camera::lookForward() -{ - m_viewMatrix = glm::lookAt(m_position, m_position + m_front_vec, UP_VEC); -} - -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.); - float deltaFactor = SPEED * deltaTime * (m_accellerate ? 5.0 : 1.0); - m_accellerate = false; - - for (auto const &[key, pressed] : key_input) { - if (key == GLFW_KEY_W && pressed) { - deltaPos += deltaFactor * glm::normalize(frontVecWithoutY); - } - if (key == GLFW_KEY_S && pressed) { - deltaPos -= deltaFactor * glm::normalize(frontVecWithoutY); - } - if (key == GLFW_KEY_A && pressed) { - deltaPos -= deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC)); - } - if (key == GLFW_KEY_D && pressed) { - deltaPos += deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC)); - } - if (key == GLFW_KEY_SPACE && pressed) { - deltaPos += deltaFactor * UP_VEC; - } - if (key == GLFW_KEY_LEFT_SHIFT && pressed) { - deltaPos -= deltaFactor * UP_VEC; - } - if (key == GLFW_KEY_LEFT_ALT && pressed) { - m_accellerate = true; - } - } - m_position += deltaPos; -} - -void Camera::updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input) -{ - auto [deltaX, deltaY] = mouse_cursor_input; - - if (std::abs(deltaX) < std::numeric_limits::epsilon() && std::abs(deltaY) < std::numeric_limits::epsilon()) { - return; - } - - m_yaw += static_cast(deltaX); - m_pitch += static_cast(deltaY); - - static constexpr float CLIP = 89.; - - if (m_pitch > CLIP) { - m_pitch = CLIP; - } - if (m_pitch < -CLIP) { - m_pitch = -CLIP; - } - - glm::vec3 direction; - direction.x = std::cos(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch)); - direction.y = std::sin(glm::radians(m_pitch)); - direction.z = std::sin(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch)); - m_front_vec = glm::normalize(direction); -} - -auto Camera::getViewProj() const -> glm::mat4 -{ - return m_viewProjectionMatrix; -} - -auto Camera::getPosition() const -> glm::vec3 -{ - return m_position; -} - diff --git a/src/Camera.h b/src/Camera.h deleted file mode 100644 index f1a5902..0000000 --- a/src/Camera.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "Window.h" - -#include - -class Camera -{ -public: - Camera(float fov, float aspectRatio); - - void updateVPM(); - void updateAspectRatio(float aspectRatio); - void updatePositionFromKeyboardInput(KeyInput const &key_input, float deltaTime); - void updateDirectionFromMouseInput(MouseCursorInput const &mouse_cursor_input); - - void translate(glm::vec3 translateVector); - void lookForward(); - - [[nodiscard]] auto getViewProj() const -> glm::mat4; - [[nodiscard]] auto getPosition() const -> glm::vec3; - -private: - glm::mat4 m_viewMatrix; - glm::mat4 m_projectionMatrix; - glm::mat4 m_viewProjectionMatrix; - - glm::vec3 m_position = glm::vec3(0., 0., 0.); - glm::vec3 m_front_vec = glm::vec3(0., 0., -1.); - - static constexpr glm::vec3 UP_VEC = glm::vec3(0., 1., 0.); - static constexpr float SPEED = .5; - static constexpr float DEFAULT_YAW = -90.; - - float m_pitch{}; - float m_yaw = DEFAULT_YAW; - - float m_fov; - - bool m_accellerate = false; -}; diff --git a/src/Controller.cpp b/src/Controller.cpp index 3fa6e4a..b51474f 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -1,5 +1,4 @@ #include "Controller.h" -#include "Camera.h" #include "FrameBuffer.h" #include "Helper.h" #include "Light.h" @@ -64,16 +63,6 @@ void Controller::run() limit_framerate(); // --- Update game --- - - // --- Render and buffer swap --- - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - m_postProcessFrameBuffer.bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // m_camera->lookForward(); - // m_camera->updateVPM(); - m_gameWindow->clear_mouse_cursor_input(); // MOVE DOWN AGAIN! glfwPollEvents(); @@ -83,9 +72,16 @@ void Controller::run() static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000; m_scene.update( std::chrono::microseconds(static_cast(m_deltaTime * MICROSECONDS_PER_SECOND)), - &defaultProgram, key_input,mouse_cursor_input, m_gameWindow->aspectRatio()); + // --- Render and buffer swap --- + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_postProcessFrameBuffer.bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_scene.draw(&defaultProgram); + Framebuffer::unbind(); m_postProcessFrameBuffer.drawOnEntireScreen(); @@ -145,5 +141,5 @@ void Controller::updateExposure(ShaderProgram &shaderProgram) const { shaderProgram.bind(); shaderProgram.setUniform("u_exposure", m_exposure); - shaderProgram.unbind(); + ShaderProgram::unbind(); } diff --git a/src/Scene.cpp b/src/Scene.cpp index d6909db..249c0ef 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -7,9 +7,6 @@ #include "transform.h" #include "util/Log.h" -#include -#include - using namespace entt::literals; // TODO: make scene initialization part of gltf loader as seen in bevy @@ -95,14 +92,13 @@ Scene::Scene() // Spawn the camera auto entity = m_registry.create(); m_registry.emplace(entity, "Camera"); - m_registry.emplace(entity, Transform{.translation = glm::vec3(0.0, 0.5, -2.0)}); + m_registry.emplace(entity, Transform{.translation = glm::vec3(0.0, 0.5, -1.0)}); m_registry.emplace(entity, GlobalTransform{}); m_registry.emplace(entity, - Camera{.projection = Camera::Perspective{.aspect_ratio = 1.6}}); + Camera{.projection = Camera::Perspective{}}); } void Scene::update(std::chrono::duration delta, - ShaderProgram *shaderprogram, KeyInput const &key_input, MouseCursorInput const &mouse_cursor_input, float aspect_ratio) @@ -142,114 +138,38 @@ void Scene::update(std::chrono::duration delta, } } - { - auto mesh_view = m_registry.view(); - auto camera_view = m_registry.view(); - auto camera_entity = camera_view.front(); - auto [camera, camera_transform] = camera_view.get(camera_entity); - glm::mat4 view_projection_matrix = - camera.projection_matrix() * Camera::view_matrix(camera_transform); + Camera::keyboard_movement(m_registry, key_input, delta); + Camera::mouse_orientation(m_registry, mouse_cursor_input); + Camera::aspect_ratio_update(m_registry, aspect_ratio); +} - for (auto [entity, mesh, material, transform] : mesh_view.each()) { - shaderprogram->bind(); +void Scene::draw(ShaderProgram *shaderprogram) const +{ + auto mesh_view = m_registry.view(); + auto camera_view = m_registry.view(); + auto camera_entity = camera_view.front(); + auto [camera, camera_transform] = camera_view.get(camera_entity); + glm::mat4 view_projection_matrix = + camera.projection_matrix() * Camera::view_matrix(camera_transform); - // Bind textures - material.bind(*shaderprogram); + for (auto [entity, mesh, material, transform] : mesh_view.each()) { + shaderprogram->bind(); - // Bind modelview matrix uniform - { - glm::mat4 modelViewProj = view_projection_matrix * transform.transform; - shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj); - shaderprogram->setUniform("u_modelMatrix", transform.transform); - shaderprogram->setUniform("u_viewPosition", camera_transform.position()); - } + // Bind textures + material.bind(*shaderprogram); - glBindVertexArray(mesh.vao); - glDrawElements(GL_TRIANGLES, mesh.indices_count, mesh.indices_type, nullptr); - glBindVertexArray(0); - - ShaderProgram::unbind(); - } - } - - // Camera keyboard update - { - auto camera_view = m_registry.view(); - auto camera_entity = camera_view.front(); - auto [camera, camera_transform, camera_global_transform] = camera_view.get(camera_entity); - - glm::vec3 front_vec = Camera::front_vector(camera_global_transform); - glm::vec3 front_vec_without_y = glm::vec3(front_vec.x, 0., front_vec.z); - glm::vec3 deltaPos = glm::vec3(0., 0., 0.); - // float deltaFactor = SPEED * deltaTime * (m_accellerate ? 5.0 : 1.0); - float delta_factor = 0.5 * delta.count(); - // m_accellerate = false; - - for (auto const &[key, pressed] : key_input) { - if (key == GLFW_KEY_W && pressed) { - deltaPos += delta_factor * glm::normalize(front_vec_without_y); - } - if (key == GLFW_KEY_S && pressed) { - deltaPos -= delta_factor * glm::normalize(front_vec_without_y); - } - if (key == GLFW_KEY_A && pressed) { - deltaPos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR)); - } - if (key == GLFW_KEY_D && pressed) { - deltaPos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR)); - } - if (key == GLFW_KEY_SPACE && pressed) { - deltaPos += delta_factor * Camera::UP_VECTOR; - } - if (key == GLFW_KEY_LEFT_SHIFT && pressed) { - deltaPos -= delta_factor * Camera::UP_VECTOR; - } - // if (key == GLFW_KEY_LEFT_ALT && pressed) { - // m_accellerate = true; - // } - } - camera_transform.translation += deltaPos; - } - - // Camera mouse update - { - auto camera_view = m_registry.view(); - auto camera_entity = camera_view.front(); - auto [camera, camera_transform] = camera_view.get(camera_entity); - - auto [deltaX, deltaY] = mouse_cursor_input; - - if (std::abs(deltaX) < std::numeric_limits::epsilon() && - std::abs(deltaY) < std::numeric_limits::epsilon()) { - return; + // Bind modelview matrix uniform + { + glm::mat4 modelViewProj = view_projection_matrix * transform.transform; + shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj); + shaderprogram->setUniform("u_modelMatrix", transform.transform); + shaderprogram->setUniform("u_viewPosition", camera_transform.position()); } - auto pitch = static_cast(deltaY); - auto yaw = static_cast(deltaX); - auto roll = 0.0F; + glBindVertexArray(mesh.vao); + glDrawElements(GL_TRIANGLES, mesh.indices_count, mesh.indices_type, nullptr); + glBindVertexArray(0); - // Orthographic projection currently unsupported - auto &camera_perspective = std::get(camera.projection); - - camera_perspective.pitch += glm::radians(pitch); - camera_perspective.yaw += glm::radians(yaw); - - static constexpr float PITCH_CLIP = glm::radians(89.); - camera_perspective.pitch = - std::clamp(static_cast(camera_perspective.pitch), -PITCH_CLIP, PITCH_CLIP); - - camera_transform.orientation = - glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0)); + ShaderProgram::unbind(); } - - // Camera aspect ratio update - { - auto camera_view = m_registry.view(); - auto camera_entity = camera_view.front(); - auto [camera] = camera_view.get(camera_entity); - - // Orthographic projection currently unsupported - auto &camera_perspective = std::get(camera.projection); - camera_perspective.aspect_ratio = aspect_ratio; - } -} \ No newline at end of file +} diff --git a/src/Scene.h b/src/Scene.h index 722afdd..20e4d6d 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -1,9 +1,9 @@ #pragma once +#include "Window.h" #include "gltf_loader.h" #include "material.h" #include "mesh.h" -#include "Window.h" #include #include @@ -15,8 +15,12 @@ class Scene public: Scene(); - void update(std::chrono::duration delta, - ShaderProgram *shaderprogram, KeyInput const &key_input,MouseCursorInput const &mouse_cursor_input, float aspect_ratio); + void update(std::chrono::duration delta_time, + KeyInput const &key_input, + MouseCursorInput const &mouse_cursor_input, + float aspect_ratio); + + void draw(ShaderProgram *shaderprogram) const; private: entt::registry m_registry; diff --git a/src/Window.h b/src/Window.h index 25e8e1d..fc7c60b 100644 --- a/src/Window.h +++ b/src/Window.h @@ -1,13 +1,11 @@ #pragma once +#include "input.h" + #include #include #include -using KeyInput = std::unordered_map; -using MouseButtonInput = std::unordered_map; -using MouseCursorInput = std::pair; - class GLFWwindow; class Window @@ -35,7 +33,7 @@ private: static void glfw_error_callback(int error, const char *description); static void framebuffer_size_callback(GLFWwindow *glfw_window, int width, int height); - static constexpr float MOUSE_SENSITIVITY = 0.15f; + static constexpr float MOUSE_SENSITIVITY = 0.15F; void set_catched_cursor(bool value); diff --git a/src/camera.cpp b/src/camera.cpp index 3d05882..46da2cc 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,7 @@ #include "camera.h" #include "util/Log.h" + +#include #include auto Camera::projection_matrix() const -> glm::mat4 @@ -26,3 +28,93 @@ 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) +{ + struct KeyboardMovementContext + { + bool accelerate{}; + }; + + auto &context = registry.ctx().emplace(); + + auto camera_view = registry.view(); + auto camera_entity = camera_view.front(); + auto [camera, camera_transform, camera_global_transform] = camera_view.get(camera_entity); + + glm::vec3 front_vec = front_vector(camera_global_transform); + 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; + + for (auto const &[key, pressed] : key_input) { + if (key == GLFW_KEY_W && pressed) { + delta_pos += delta_factor * glm::normalize(front_vec); + } + if (key == GLFW_KEY_S && pressed) { + delta_pos -= delta_factor * glm::normalize(front_vec); + } + if (key == GLFW_KEY_A && pressed) { + delta_pos -= delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR)); + } + if (key == GLFW_KEY_D && pressed) { + delta_pos += delta_factor * glm::normalize(glm::cross(front_vec, Camera::UP_VECTOR)); + } + if (key == GLFW_KEY_SPACE && pressed) { + delta_pos += delta_factor * UP_VECTOR; + } + if (key == GLFW_KEY_LEFT_SHIFT && pressed) { + delta_pos -= delta_factor * UP_VECTOR; + } + if (key == GLFW_KEY_LEFT_ALT && pressed) { + context.accelerate = true; + } + } + camera_transform.translation += delta_pos; +} + +void Camera::mouse_orientation(entt::registry ®istry, MouseCursorInput const &mouse_cursor_input) +{ + 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; + + if (std::abs(deltaX) < std::numeric_limits::epsilon() && + std::abs(deltaY) < std::numeric_limits::epsilon()) { + return; + } + + auto pitch = static_cast(deltaY); + auto yaw = static_cast(deltaX); + auto roll = 0.0F; + + // Orthographic projection currently unsupported + auto &camera_perspective = std::get(camera.projection); + + camera_perspective.pitch += glm::radians(pitch); + camera_perspective.yaw += glm::radians(yaw); + + static constexpr float PITCH_CLIP = glm::radians(89.); + camera_perspective.pitch = + std::clamp(static_cast(camera_perspective.pitch), -PITCH_CLIP, PITCH_CLIP); + + camera_transform.orientation = + glm::quat(glm::vec3(-camera_perspective.pitch, -camera_perspective.yaw, 0.0)); +} + +void Camera::aspect_ratio_update(entt::registry ®istry, float aspect_ratio) +{ + auto camera_view = registry.view(); + auto camera_entity = camera_view.front(); + auto [camera] = camera_view.get(camera_entity); + + // Orthographic projection currently unsupported + auto &camera_perspective = std::get(camera.projection); + camera_perspective.aspect_ratio = aspect_ratio; +} diff --git a/src/camera.h b/src/camera.h index ed5bd4e..d7ef1b3 100644 --- a/src/camera.h +++ b/src/camera.h @@ -1,7 +1,11 @@ #pragma once +#include "input.h" #include "transform.h" +#include +#include +#include #include #include @@ -13,10 +17,13 @@ struct Camera static constexpr glm::vec3 UP_VECTOR = glm::vec3(0.0, 1.0, 0.0); + static constexpr float SPEED = 0.5; + static constexpr float ACCELERATION = 5.0; + struct Perspective { float fov = DEFAULT_FOV; - float aspect_ratio; + float aspect_ratio{}; float near = DEFAULT_NEAR; float far = DEFAULT_FAR; @@ -39,4 +46,10 @@ struct Camera [[nodiscard]] auto projection_matrix() const -> glm::mat4; [[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); }; diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..146dfcf --- /dev/null +++ b/src/input.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +using KeyInput = std::unordered_map; +using MouseButtonInput = std::unordered_map; +using MouseCursorInput = std::pair;