diff --git a/CMakeLists.txt b/CMakeLists.txt index 54f33a7..f20a22c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,8 @@ add_executable(${PROJECT_NAME} src/main.cpp src/Shader.cpp include/Shader.hpp include/IndexBuffer.hpp - libs/stb_image.hpp - include/Camera.hpp) + include/Camera.hpp + include/FPS_Camera.hpp) target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:_DEBUG>) diff --git a/include/Camera.hpp b/include/Camera.hpp index d7ca7a4..58f87d9 100644 --- a/include/Camera.hpp +++ b/include/Camera.hpp @@ -1,11 +1,11 @@ #pragma once #include "glm/glm.hpp" -#include "glm/ext/matrix_transform.hpp" #include "glm/gtc/matrix_transform.hpp" class Camera { -private: +protected: + glm::vec3 position; glm::mat4 projection; glm::mat4 view; glm::mat4 viewProj; @@ -14,6 +14,7 @@ public: Camera(float fov, float width, float height) { projection = glm::perspective(fov/2.0f, width/height, 0.1f, 1000.f); view = glm::mat4(1.0f); + position = glm::vec3(0.0f); update(); } @@ -21,11 +22,12 @@ public: return viewProj; } - void update() { + virtual void update() { viewProj = projection * view; } - void translate(glm::vec3 v) { + virtual void translate(glm::vec3 v) { + position += v; view = glm::translate(view, v*-1.0f); } }; \ No newline at end of file diff --git a/include/FPS_Camera.hpp b/include/FPS_Camera.hpp new file mode 100644 index 0000000..a8cf3bd --- /dev/null +++ b/include/FPS_Camera.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "Camera.hpp" + +class FPSCamera : public Camera { +protected: + float yaw; // rotation y-axis + float pitch; // rotating x-axis + glm::vec3 lookAt; + const float mouseSensitivity = 0.3f; + glm::vec3 up; + +public: + FPSCamera(float fov, float width, float height) : Camera(fov, width, height) { + up = glm::vec3(0.0f, 1.0f, 0.0f); + yaw = -90.0f; + pitch = 0.0f; + onMouseMoved(0.0f, 0.0f); + } + + void onMouseMoved(float xRel, float yRel) { + yaw += xRel * mouseSensitivity; + pitch -= yRel * mouseSensitivity; + if (pitch > 89.0f) pitch = 89.0f; + else if (pitch < -89.0f) pitch = -89.0f; + + glm::vec3 front; + front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw)); + front.y = sin(glm::radians(pitch)); + front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw)); + lookAt = glm::normalize(front); + + update(); + } + + void update() override { + view = glm::lookAt(position, position+lookAt, up); + viewProj = projection * view; + } + + void moveFront(float amount) { + translate(lookAt * amount); + update(); + } + + void moveSideways(float amount) { + translate(glm::normalize(glm::cross(lookAt, up)) * amount); + update(); + } + +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8002fbf..32ce773 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "Shader.hpp" #define STB_IMAGE_IMPLEMENTATION #include "Camera.hpp" +#include "FPS_Camera.hpp" #include "stb_image.hpp" #include "glm/glm.hpp" #include "glm/ext/matrix_transform.hpp" @@ -92,6 +93,7 @@ int main() { ); SDL_GLContext context = SDL_GL_CreateContext(window); + SDL_SetWindowRelativeMouseMode(window, true); GLenum err = glewInit(); if (err != GLEW_OK) { @@ -170,7 +172,7 @@ int main() { auto model = glm::mat4(1.0f); model = glm::scale(model, glm::vec3(1.2f)); - Camera camera(90.0f, 800.0f, 600.0f); + FPSCamera camera(90.0f, 800.0f, 600.0f); camera.translate(glm::vec3(0.0f, 0.0f, 5.0f)); camera.update(); @@ -182,6 +184,7 @@ int main() { //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); float time = 0.0f; + float cameraSpeed = 6.0f; bool running = true; SDL_Event e; @@ -211,6 +214,8 @@ int main() { case SDLK_D: btnD = false; break; default: break; } + } else if (e.type == SDL_EVENT_MOUSE_MOTION) { + camera.onMouseMoved(e.motion.xrel, e.motion.yrel); } } @@ -219,16 +224,16 @@ int main() { time += delta; if (btnW) { - camera.translate(glm::vec3(0.0f, 0.0f, -2.0f*delta)); + camera.moveFront(delta * cameraSpeed); } if (btnS) { - camera.translate(glm::vec3(0.0f, 0.0f, 2.0f*delta)); + camera.moveFront(- delta * cameraSpeed); } if (btnA) { - camera.translate(glm::vec3(-1.0f*delta, 0.0f, 0.0f)); + camera.moveSideways(- delta * cameraSpeed); } if (btnD) { - camera.translate(glm::vec3(1.0f*delta, 0.0f, 0.0f)); + camera.moveSideways(delta * cameraSpeed); } camera.update();