From bb8e6669e7a9fe7073e082eb4e8d5d3819a3db90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Pottier?= Date: Fri, 29 Dec 2023 15:35:21 +0100 Subject: [PATCH] camera class --- .github/workflows/macos-ci.yml | 2 + .github/workflows/ubuntu-ci.yml | 2 + .github/workflows/windows-ci.yml | 2 + include/Camera.hpp | 54 ++++++++++++++++++++++ src/Camera.cpp | 78 ++++++++++++++++++++++++++++++++ src/main.cpp | 63 ++++++++++---------------- 6 files changed, 163 insertions(+), 38 deletions(-) create mode 100644 include/Camera.hpp create mode 100644 src/Camera.cpp diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index 6709958..855dd82 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -1,5 +1,7 @@ name: MacOS build +on: [push] + jobs: macos-build: runs-on: macos-latest diff --git a/.github/workflows/ubuntu-ci.yml b/.github/workflows/ubuntu-ci.yml index 4683023..ea0f238 100644 --- a/.github/workflows/ubuntu-ci.yml +++ b/.github/workflows/ubuntu-ci.yml @@ -1,5 +1,7 @@ name: Ubuntu build +on: [push] + jobs: ubuntu-build: runs-on: ubuntu-latest diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 07d0092..8e5624b 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -1,5 +1,7 @@ name: Windows build +on: [push] + jobs: windows-build: runs-on: windows-latest diff --git a/include/Camera.hpp b/include/Camera.hpp new file mode 100644 index 0000000..e6d19d5 --- /dev/null +++ b/include/Camera.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include "glad/glad.h" +#include "glm/glm.hpp" +#include "glm/gtc/matrix_transform.hpp" + +#include + +enum CameraMovement { + FORWARD, + BACKWARD, + LEFT, + RIGHT +}; + +const float YAW = -90.0f; +const float PITCH = 0.0f; +const float SPEED = 2.5f; +const float SENSITIVITY = 0.1f; +const float ZOOM = 45.0f; + +class Camera { +public: + // Camera attributes + glm::vec3 position; + glm::vec3 front; + glm::vec3 up; + glm::vec3 right; + glm::vec3 worldUp; + + // Euler angles + float yaw; + float pitch; + + // Options + float movementSpeed; + float mouseSensitivity; + float zoom; + + // Constructor with vector + Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH); + + // Constructor with scalars + Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch); + + glm::mat4 getViewMatrix(); + + void processKeyboard(CameraMovement direction, float deltaTime); + void processMouseMovement(float xoffset, float yoffset, bool constrainPitch = true); + void processMouseScoll(float yoffset); + +private: + void updateCameraVectors(); +}; diff --git a/src/Camera.cpp b/src/Camera.cpp new file mode 100644 index 0000000..05b8706 --- /dev/null +++ b/src/Camera.cpp @@ -0,0 +1,78 @@ +#include "Camera.hpp" + +Camera::Camera(glm::vec3 position, glm::vec3 up, float yaw, float pitch) { + front = glm::vec3(0.0f, 0.0f, -1.0f); + movementSpeed = SPEED; + mouseSensitivity = SENSITIVITY; + zoom = ZOOM; + this->position = position; + worldUp = up; + this->yaw = yaw; + this->pitch = pitch; + updateCameraVectors(); +} + +Camera::Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) { + front = glm::vec3(0.0f, 0.0f, -1.0f); + movementSpeed = SPEED; + mouseSensitivity = SENSITIVITY; + zoom = ZOOM; + position = glm::vec3(posX, posY, posZ); + worldUp = glm::vec3(upX, upY, upZ); + this->yaw = yaw; + this->pitch = pitch; + updateCameraVectors(); +} + +glm::mat4 Camera::getViewMatrix() { + return glm::lookAt(position, position + front, up); +} + +void Camera::processKeyboard(CameraMovement direction, float deltaTime) { + float velocity = movementSpeed * deltaTime; + switch (direction) { + case FORWARD: + position += front * velocity; + break; + case BACKWARD: + position -= front * velocity; + break; + case LEFT: + position -= right * velocity; + break; + case RIGHT: + position += right * velocity; + break; + } +} + +void Camera::processMouseMovement(float xoffset, float yoffset, bool constrainPitch) { + xoffset *= mouseSensitivity; + yoffset *= mouseSensitivity; + + yaw += xoffset; + pitch += yoffset; + + if (constrainPitch) { + if (pitch > 89.0f) { pitch = 89.0f; } + if (pitch < -89.0f) { pitch = -89.0f; } + } + + updateCameraVectors(); +} + +void Camera::processMouseScoll(float yoffset) { + zoom -= yoffset; + if (zoom < 1.0f ) { zoom = 1.0f; } + if (zoom > 45.0f ) { zoom = 45.0f; } +} + +void Camera::updateCameraVectors() { + glm::vec3 tmpFront; + tmpFront.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); + tmpFront.y = sin(glm::radians(pitch)); + tmpFront.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); + front = glm::normalize(tmpFront); + right = glm::normalize(glm::cross(front, worldUp)); + up = glm::normalize(glm::cross(right, front)); +} diff --git a/src/main.cpp b/src/main.cpp index 2cdcbf1..e348049 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include "Menu.hpp" #include "Shader.hpp" +#include "Camera.hpp" // maybe not stay here /* TODO: REMOVE */ /* DEBUG */ @@ -24,39 +25,32 @@ #include #include -// camera -glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); -glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); -glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); - +// Camera +Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); +float lastX = 1280.0f / 2.0; +float lastY = 720.0 / 2.0; bool firstMouse = true; -float yaw = -90.0f; // yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right so we initially rotate a bit to the left. -float pitch = 0.0f; -float lastX = 800.0f / 2.0; -float lastY = 600.0 / 2.0; -float fov = 45.0f; // timing -float deltaTime = 0.0f; // time between current frame and last frame +float deltaTime = 0.0f; float lastFrame = 0.0f; void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); - float cameraSpeed = static_cast(2.5 * deltaTime); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) - cameraPos += cameraSpeed * cameraFront; + camera.processKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) - cameraPos -= cameraSpeed * cameraFront; + camera.processKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) - cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; + camera.processKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) - cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; + camera.processKeyboard(RIGHT, deltaTime); } /* DEBUG */ -void framebufferSizeCallback(GLFWwindow*, int width, int height) { +void framebufferSizeCallback(GLFWwindow* /*window*/, int width, int height) { glViewport(0, 0, width, height); } @@ -69,24 +63,15 @@ void mouseCallback(GLFWwindow* /*window*/, double xpos, double ypos) { float xoffset = xpos - lastX; float yoffset = lastY - ypos; + lastX = xpos; lastY = ypos; - float sensitivity = 0.1f; - xoffset *= sensitivity; - yoffset *= sensitivity; - - yaw += xoffset; - pitch += yoffset; - - if (pitch > 89.0f) { pitch = 89.0f; } - if (pitch < -89.0f) { pitch = -89.0f; } + camera.processMouseMovement(xoffset, yoffset); +} - glm::vec3 direction; - direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); - direction.y = sin(glm::radians(pitch)); - direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); - cameraFront = glm::normalize(direction); +void scrollCallback(GLFWwindow* /*window*/, double /*xoffset*/, double yoffset) { + camera.processMouseScoll(static_cast(yoffset)); } int main() { @@ -126,7 +111,11 @@ int main() { return -1; } glfwMakeContextCurrent(window); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); + glfwSetCursorPosCallback(window, mouseCallback); + glfwSetScrollCallback(window, scrollCallback); + // Initialize Glad if (!gladLoadGLLoader(reinterpret_cast(glfwGetProcAddress))) { @@ -139,8 +128,8 @@ int main() { } glEnable(GL_DEPTH_TEST); - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - glfwSetCursorPosCallback(window, mouseCallback); + // TODO: REMOVE + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Setup ImGui context IMGUI_CHECKVERSION(); @@ -298,9 +287,6 @@ int main() { testShader.use(); glUniform1i(glGetUniformLocation(testShader.id, "texture1"), 0); testShader.setInt("texture2", 1); - - glm::mat4 projection = glm::perspective(glm::radians(fov), 1280.0f / 720.0f, 0.1f, 100.0f); - testShader.setMat4("projection", projection); // TODO END // Main loop @@ -333,8 +319,9 @@ int main() { testShader.use(); - - glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); + glm::mat4 projection = glm::perspective(glm::radians(camera.zoom), 1280.0f / 720.0f, 0.1f, 100.0f); + testShader.setMat4("projection", projection); + glm::mat4 view = camera.getViewMatrix(); testShader.setMat4("view", view); glBindVertexArray(VAO);