diff --git a/include/blt/gfx/input.h b/include/blt/gfx/input.h index 1b48280..47be6d4 100644 --- a/include/blt/gfx/input.h +++ b/include/blt/gfx/input.h @@ -31,6 +31,7 @@ namespace blt::gfx double mouseLastX = 0, mouseLastY = 0; double deltaX = 0, deltaY = 0; double scroll = 0; + bool mouse_moved = false; private: KEY_STATE* key_state; MOUSE_STATE* mouse_state; diff --git a/include/blt/gfx/renderer/camera.h b/include/blt/gfx/renderer/camera.h new file mode 100644 index 0000000..df7915d --- /dev/null +++ b/include/blt/gfx/renderer/camera.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_WITH_GRAPHICS_CAMERA_H +#define BLT_WITH_GRAPHICS_CAMERA_H + +#include "blt/gfx/state.h" + +namespace blt::gfx +{ + + class first_person_camera + { + private: + blt::vec3 position_; + blt::vec3 rotation_; + blt::vec3 speed_ {50, 50, 50}; + public: + void update(); + + inline void speed(const blt::vec3& speed) + { + speed_ = speed; + } + + [[nodiscard]] inline const vec3& speed() const + { + return speed_; + } + + [[nodiscard]] inline const vec3& position() const + { + return position_; + } + + void update_view(matrix_state_manager& manager); + }; + +} + +#endif //BLT_WITH_GRAPHICS_CAMERA_H diff --git a/include/blt/gfx/window.h b/include/blt/gfx/window.h index 35075c2..3c4cd6f 100644 --- a/include/blt/gfx/window.h +++ b/include/blt/gfx/window.h @@ -64,6 +64,8 @@ namespace blt::gfx double getMouseDY(); + bool mouseMovedLastFrame(); + void lockCursor(); void unlockCursor(); diff --git a/src/blt/gfx/renderer/batch_2d_renderer.cpp b/src/blt/gfx/renderer/batch_2d_renderer.cpp index 06ba32b..9566043 100644 --- a/src/blt/gfx/renderer/batch_2d_renderer.cpp +++ b/src/blt/gfx/renderer/batch_2d_renderer.cpp @@ -96,7 +96,9 @@ namespace blt::gfx } blend_factors.second.clear(); } + colors.second.clear(); } + textures.second.clear(); } if (transparency) glDisable(GL_BLEND); diff --git a/src/blt/gfx/renderer/camera.cpp b/src/blt/gfx/renderer/camera.cpp new file mode 100644 index 0000000..b426fe6 --- /dev/null +++ b/src/blt/gfx/renderer/camera.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include + +void blt::gfx::first_person_camera::update() +{ + using namespace blt::gfx; + vec3 move_at; + + float speed_multi = 1; + + if (isKeyPressed(GLFW_KEY_LEFT_CONTROL)) + speed_multi = 10; + + if (isKeyPressed(GLFW_KEY_W)) + move_at[2] = -1; + else if (isKeyPressed(GLFW_KEY_S)) + move_at[2] = 1; + else + move_at[2] = 0; + + if (isKeyPressed(GLFW_KEY_A)) + move_at[0] = 1; + else if (isKeyPressed(GLFW_KEY_D)) + move_at[0] = -1; + else + move_at[0] = 0; + + if (isKeyPressed(GLFW_KEY_SPACE)) + move_at[1] = 1; + else if (isKeyPressed(GLFW_KEY_LEFT_SHIFT)) + move_at[1] = -1; + else + move_at[1] = 0; + + auto yawRads = blt::toRadians(rotation_.y()); + + vec3 direction; + direction[0] = -move_at.z() * std::sin(yawRads) + -move_at.x() * std::cos(yawRads); + direction[1] = move_at.y(); + direction[2] = move_at.z() * std::cos(yawRads) + -move_at.x() * std::sin(yawRads); + + position_ = position_ + (direction * speed_ * speed_multi * static_cast(getFrameDeltaSeconds())); + + // TODO; + const float sensitivity = 10; + + if (mouseMovedLastFrame() && isCursorLocked()) { + auto dYaw = getMouseDX() * sensitivity * getFrameDeltaSeconds(); + auto dPitch = getMouseDY() * sensitivity * getFrameDeltaSeconds(); + + rotation_[1] += static_cast(dYaw); + rotation_[0] += static_cast(dPitch); + } + + const float sSpeed = 100; + const float vertFact = 0.75; + if (isKeyPressed(GLFW_KEY_RIGHT)) + rotation_[1] += static_cast(sSpeed * getFrameDeltaSeconds()); + if (isKeyPressed(GLFW_KEY_LEFT)) + rotation_[1] -= static_cast(sSpeed * getFrameDeltaSeconds()); + if (isKeyPressed(GLFW_KEY_UP)) + rotation_[0] -= static_cast(sSpeed * getFrameDeltaSeconds() * vertFact); + if (isKeyPressed(GLFW_KEY_DOWN)) + rotation_[0] += static_cast(sSpeed * getFrameDeltaSeconds() * vertFact); + + if(rotation_[0] > 89.0f) + rotation_[0] = 89.0f; + if(rotation_[0] < -89.0f) + rotation_[0] = -89.0f; + + if (rotation_[1] < 0) + rotation_[1] = 360; + if (rotation_[1] > 360) + rotation_[1] = 0; +} + +void blt::gfx::first_person_camera::update_view(blt::gfx::matrix_state_manager& manager) +{ + blt::mat4x4 view; + view.rotateX(toRadians(rotation_.x())); + view.rotateY(toRadians(rotation_.y())); + view.rotateZ(toRadians(rotation_.z())); + view.translate(-position_); + manager.setView(view); +} diff --git a/src/blt/gfx/window.cpp b/src/blt/gfx/window.cpp index 0ff040a..9377b2b 100644 --- a/src/blt/gfx/window.cpp +++ b/src/blt/gfx/window.cpp @@ -81,6 +81,7 @@ namespace blt::gfx /* Setup mouse cursor callback */ glfwSetCursorPosCallback(window_state.window, [](GLFWwindow* window, double x, double y) { window_state.inputManager.updateMousePos(x, y); + window_state.inputManager.mouse_moved = true; }); /* Setup mouse scroll callback */ @@ -159,6 +160,7 @@ namespace blt::gfx ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); /* -- Update GLFW state -- */ + window_state.inputManager.mouse_moved = false; glfwSwapBuffers(window_state.window); glfwPollEvents(); @@ -325,4 +327,9 @@ namespace blt::gfx { return window_state.deltaTime; } + + bool mouseMovedLastFrame() + { + return window_state.inputManager.mouse_moved; + } } diff --git a/tests/src/main.cpp b/tests/src/main.cpp index e5d4246..8b355fb 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include #include @@ -9,41 +7,17 @@ #include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/batch_2d_renderer.h" +#include "blt/gfx/renderer/camera.h" blt::gfx::matrix_state_manager global_matrices; blt::gfx::resource_manager resources; blt::gfx::batch_renderer_2d renderer_2d(resources); +blt::gfx::first_person_camera camera; float x = 0, y = 0, z = 0; float bx = 500, by = 500; float mx = 0, my = -9.8; -void handle_input() -{ - using namespace blt::gfx; - float moveAtX = 0; - float moveAtZ = 0; - if (isKeyPressed(GLFW_KEY_W)) - moveAtX = 1; - else if (isKeyPressed(GLFW_KEY_S)) - moveAtX = -1; - else - moveAtX = 0; - if (isKeyPressed(GLFW_KEY_A)) - moveAtZ = 1; - else if (isKeyPressed(GLFW_KEY_D)) - moveAtZ = -1; - else - moveAtZ = 0; - const float speed = 270; - y -= static_cast(moveAtX * speed * getFrameDeltaSeconds()); - x += static_cast(moveAtZ * speed * getFrameDeltaSeconds()); - - blt::mat4x4 view; - view.translate(x, y, z); - global_matrices.setView(view); -} - void init() { using namespace blt::gfx; @@ -58,15 +32,17 @@ void init() void update(std::int32_t width, std::int32_t height) { - global_matrices.update_perspectives(width, height); + global_matrices.update_perspectives(width, height, 90, 0.1, 2000); ImGui::ShowDemoWindow(); - ImGui::SetNextWindowSize(ImVec2(150, 85)); + ImGui::SetNextWindowSize(ImVec2(200, 100)); ImGui::Begin("Debug Info Panel", nullptr, ImGuiWindowFlags_NoResize); ImGui::Text("%s FPS: %f", ICON_FA_WRENCH, 1.0e9 / static_cast(blt::gfx::getFrameDelta())); ImGui::Text("Draw Count: %zu", renderer_2d.draw_count()); + ImGui::Text("Position: %f %f %f", camera.position().x(), camera.position().y(), camera.position().z()); ImGui::End(); - handle_input(); + camera.update(); + camera.update_view(global_matrices); global_matrices.update();