From 13e924538cc8f9c92150861333d7e4cbe0178860 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 24 Jan 2021 02:19:23 +0100 Subject: [PATCH] Finished camera update --- examples/debug/main.cpp | 50 ++++++----- include/camera.hpp | 194 ++++++++++++++++++++++++++++++++++++++++ include/openglu.hpp | 1 + src/camera.cpp | 124 +++++++++++++++++++++++++ 4 files changed, 346 insertions(+), 23 deletions(-) create mode 100644 include/camera.hpp create mode 100644 src/camera.cpp diff --git a/examples/debug/main.cpp b/examples/debug/main.cpp index 16d07bf..344e537 100644 --- a/examples/debug/main.cpp +++ b/examples/debug/main.cpp @@ -48,15 +48,30 @@ int main(int argc, char** argv) // Create vertices for square float vertices[] = { - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left - -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // front top right + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // front bottom right + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // front bottom left + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // front top left + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // back top right + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // back bottom right + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // back bottom left + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f // back top left }; unsigned int indices[] = { - 0, 1, 3, // first triangle - 1, 2, 3 // second triangle + 0, 1, 3, // front + 1, 2, 3, + 7, 4, 0, // top + 7, 0, 3, + 0, 4, 5, // right + 0, 5, 1, + 7, 3, 2, // right + 7, 2, 6, + 2, 1, 6, // bottom + 1, 6, 5, + 4, 7, 5, // back + 7, 6, 5 }; oglu::VertexAttribute topology[] = { @@ -71,11 +86,6 @@ int main(int argc, char** argv) square.Move(-0.6f, 0.0f, 0.0f); square2.Move(0.6f, 0.0f, 0.0f); - //square.GlobalRotate(45.0f, 0.0f, 0.0f); - //square.GlobalRotate(0.0f, 0.0f, 45.0f); - - //square.SetGlobalRotation(45.0f, 0.0f, 45.0f); - // Create a shader oglu::Shader shader; try @@ -92,11 +102,7 @@ int main(int argc, char** argv) oglu::Texture crate = oglu::MakeTexture("assets/crate.jpg"); oglu::Texture opengl = oglu::MakeTexture("assets/opengl.png"); - glm::mat4 view(1.0f); - view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f)); - - glm::mat4 projection(1.0f); - projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f); + oglu::Camera camera; // Window loop oglu::Enable(GL_DEPTH_TEST); @@ -108,17 +114,15 @@ int main(int argc, char** argv) oglu::ClearScreen(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, oglu::Color(0.29f, 0.13f, 0.23f)); - // view = glm::rotate(view, glm::radians(1.0f), glm::vec3(0.0f, 1.0f, 0.0f)); - - square.Pitch(6.0f); - square2.Pitch(-6.0f); + camera.SetPosition(4.0f * sinf(t), 3.0f * sinf(0.238f * t), 4.0f * cosf(t)); + camera.LookAt(0.0f, 0.0f, 0.0f); shader->Use(); shader->SetUniform("texture1", crate, 0); shader->SetUniform("texture2", opengl, 1); shader->SetUniform("model", square); - shader->SetUniformMatrix4fv("view", 1, GL_FALSE, glm::value_ptr(view)); - shader->SetUniformMatrix4fv("projection", 1, GL_FALSE, glm::value_ptr(projection)); + shader->SetUniformMatrix4fv("view", 1, GL_FALSE, glm::value_ptr(camera.GetMatrix())); + shader->SetUniformMatrix4fv("projection", 1, GL_FALSE, glm::value_ptr(camera.GetProjection())); square.Render(); @@ -128,7 +132,7 @@ int main(int argc, char** argv) glfwSwapBuffers(window); glfwPollEvents(); - t += 0.1f; + t += 0.05f; } glfwTerminate(); diff --git a/include/camera.hpp b/include/camera.hpp new file mode 100644 index 0000000..640bbfa --- /dev/null +++ b/include/camera.hpp @@ -0,0 +1,194 @@ +/*****************************************************************//** + * \file camera.hpp + * \brief A camera object + * + * \author Lauchmelder + * \date January 2021 + *********************************************************************/ +#ifndef CAMERA_HPP +#define CAMERA_HPP + +#include +#include + +namespace oglu +{ + class Transformable; + + /** + * @brief A class that simulates a camera in 3D space. + */ + class OGLU_API Camera + { + public: + /** + * @brief Create a default camera. + * + * Default settings: + * Position: (0, 0, 0) + * Looking at: Negative Z + * FOV: 45.0f + * AspectRatio: 1.0f + * zNear: 0.1f + * zFar: 100.0f + */ + Camera(); + + /** + * @brief Create a new camera. + * + * @param[in] fov FOV of the camera (in degrees) + * @param[in] aspectRatio of the camera + * @param[in] zNear Near clipping plane + * @param[in] zFar Far clipping plane + */ + Camera(float fov, float aspectRatio, float zNear, float zFar); + + /** + * Copy another camera. + * + * @param[in] other Camera to copy from + */ + Camera(const Camera& other); + + /** + * @brief Set the cameras position. + * + * @param[in] x New x position + * @param[in] y New y position + * @param[in] z New z position + */ + void SetPosition(float x, float y, float z); + + /** + * @brief Set the cameras position. + * + * @param[in] position The new position + */ + void SetPosition(const float* position); + + /** + * @brief Set the cameras position. + * + * @param[in] position The new position + */ + void SetPosition(const glm::vec3& position); + + /** + * @brief Offset the cameras position + * + * @param[in] x x offset + * @param[in] y y offset + * @param[in] z z offset + */ + void Move(float x, float y, float z); + + /** + * @brief Offset the cameras position + * + * @param[in] offset Offset + */ + void Move(const float* offset); + + /** + * @brief Offset the cameras position + * + * @param[in] offset Offset + */ + void Move(const glm::vec3& offset); + + /** + * @brief Have the camera face a target. + * + * Right now the camera cannot roll. @p worldUp is always positive Y + * + * @param[in] x x position of the target + * @param[in] y y position of the target + * @param[in] z z position of the target + */ + void LookAt(float x, float y, float z); + + /** + * @brief Have the camera face a target. + * + * Right now the camera cannot roll. @p worldUp is always positive Y + * + * @param[in] target Coordinates of the target + */ + void LookAt(const float* target); + + /** + * @brief Have the camera face a target. + * + * Right now the camera cannot roll. @p worldUp is always positive Y + * + * @param[in] target Coordinates of the target + */ + void LookAt(const glm::vec3& target); + + /** + * @brief Have the camera face a target. + * + * Right now the camera cannot roll. @p worldUp is always positive Y + * + * @param[in] target A target Transformable + */ + void LookAt(const Transformable& target); + + /** + * @brief Pan the camera. + * + * Panning is a rotation around the cameras local up axis. + * + * @param[in] angle Angle to rotate by + */ + void Pan(float angle); + + /** + * @brief Tilt the camera. + * + * Panning is a rotation around the cameras local right axis. + * + * @param[in] angle Angle to rotate by + */ + void Tilt(float angle); + + /** + * @brief Roll the camera (doesn't work). + * + * Panning is a rotation around the cameras local front axis. + * + * @param[in] angle Angle to rotate by + */ + void Roll(float angle); + + /** + * @brief Get the view matrix. + * + * @returns A 4x4 view matrix + */ + const glm::mat4& GetMatrix(); + + /** + * @brief Get the projection matrix. + * + * @returns A 4x4 projection matrix + */ + const glm::mat4& GetProjection(); + + private: + glm::mat4 projection; ///< The projection matrix + glm::mat4 transformation; ///< The view matrix + glm::vec3 position; ///< The cameras position + glm::vec3 front; ///< The cameras front vector + glm::vec3 right; ///< The cameras right vector + glm::vec3 up; ///< The cameras up vector + + float fov; ///< FOV of the camera + float aspectRatio; ///< Aspect ratio of the camera + float zNear; ///< Near clipping plane + float zFar; ///< Far clipping plane + }; +} + +#endif \ No newline at end of file diff --git a/include/openglu.hpp b/include/openglu.hpp index 51a5840..46c93bd 100644 --- a/include/openglu.hpp +++ b/include/openglu.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace oglu { diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..8958614 --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,124 @@ +#include "camera.hpp" + +#include +#include +#include +#include + +namespace oglu +{ + Camera::Camera() : + fov(45.0f), aspectRatio(1.0f), zNear(0.1f), zFar(100.0f), position(glm::vec3(0.0f)), transformation(glm::mat4(1.0f)) + { + projection = glm::perspective(fov, aspectRatio, zNear, zFar); + up = glm::vec3(0.0f, 1.0f, 0.0f); + LookAt(glm::vec3(0.0f, 0.0f, -1.0f)); + } + + Camera::Camera(float fov, float aspectRatio, float zNear, float zFar) : + fov(fov), aspectRatio(aspectRatio), zNear(zNear), zFar(zFar), position(glm::vec3(0.0f)), transformation(glm::mat4(1.0f)) + { + projection = glm::perspective(fov, aspectRatio, zNear, zFar); + up = glm::vec3(0.0f, 1.0f, 0.0f); + LookAt(glm::vec3(0.0f, 0.0f, -1.0f)); + } + + Camera::Camera(const Camera& other) : + fov(other.fov), aspectRatio(other.aspectRatio), + zNear(other.zNear), zFar(other.zFar), + projection(other.projection), transformation(other.transformation), + front(other.front), up(other.up), right(other.right), + position(other.position) + { + } + + void Camera::SetPosition(float x, float y, float z) + { + this->position = glm::vec3(x, y, z); + LookAt(this->position + front); + } + + void Camera::SetPosition(const float* position) + { + this->position = glm::make_vec3(position); + LookAt(this->position + front); + } + + void Camera::SetPosition(const glm::vec3& position) + { + this->position = position; + LookAt(this->position + front); + } + + void Camera::Move(float x, float y, float z) + { + this->position += glm::vec3(x, y, z); + LookAt(this->position + front); + } + + void Camera::Move(const float* position) + { + this->position += glm::make_vec3(position); + LookAt(this->position + front); + } + + void Camera::Move(const glm::vec3& position) + { + this->position += position; + LookAt(this->position + front); + } + + void Camera::LookAt(float x, float y, float z) + { + LookAt(glm::vec3(x, y, z)); + } + + void Camera::LookAt(const float* target) + { + LookAt(glm::make_vec3(target)); + } + + void Camera::LookAt(const glm::vec3& target) + { + front = glm::normalize(target - position); + transformation = glm::lookAt(position, position + front, glm::vec3(0.0f, 1.0f, 0.0f)); + right = glm::normalize(glm::cross(front, glm::vec3(0.0f, 1.0f, 0.0f))); + up = glm::normalize(glm::cross(right, front)); + } + + void Camera::LookAt(const Transformable& target) + { + LookAt(target.GetPosition()); + } + + void Camera::Pan(float angle) + { + front = glm::rotate(glm::angleAxis(glm::radians(angle), up), front); + transformation = glm::lookAt(position, position + front, glm::vec3(0.0f, 1.0f, 0.0f)); + right = glm::normalize(glm::cross(front, glm::vec3(0.0f, 1.0f, 0.0f))); + } + + void Camera::Tilt(float angle) + { + front = glm::rotate(glm::angleAxis(glm::radians(angle), right), front); + transformation = glm::lookAt(position, position + front, glm::vec3(0.0f, 1.0f, 0.0f)); + up = glm::normalize(glm::cross(right, front)); + } + + void Camera::Roll(float angle) + { + up = glm::rotate(glm::angleAxis(glm::radians(angle), front), front); + transformation = glm::lookAt(position, position + front, up); + right = glm::normalize(glm::cross(front, up)); + } + + const glm::mat4& Camera::GetMatrix() + { + return transformation; + } + + const glm::mat4& Camera::GetProjection() + { + return projection; + } +}