diff --git a/CMakeLists.txt b/CMakeLists.txt index b1d9f79..737cea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,6 @@ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(NBGL_BUILD_TEST ON) -add_executable(GraphicsTest main.cpp funcs.cpp Draw.cpp Shader.cpp Buffers.cpp ../libs/glad/src/glad.c) +add_executable(GraphicsTest main.cpp funcs.cpp Draw.cpp Shader.cpp Buffers.cpp Camera.cpp ../libs/glad/src/glad.c) target_link_libraries(GraphicsTest NBWindow glfw OpenGL::GL) diff --git a/Camera.cpp b/Camera.cpp new file mode 100644 index 0000000..d7ba071 --- /dev/null +++ b/Camera.cpp @@ -0,0 +1,114 @@ +#include "Camera.h" +namespace NB { + +// Camera class +Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type(CameraType::None) { + _pos = pos; + _tar = tar; + _world_up = glm::normalize(up); + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _proj = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); + _calcLook(); +} + +void Camera::_calcLook() { + _look = glm::lookAt(_pos, _tar, _world_up); +} + +glm::vec3 Camera::normCross(const Vec3& a, const Vec3& b) { + return glm::normalize(glm::cross(a, b)); +} + +glm::vec3 Camera::getPos() const { return _pos; } + +glm::vec3 Camera::getTarget() const { return _tar; } + +glm::vec3 Camera::getDirection() const { return _dir; } + +glm::vec3 Camera::getWorldUp() const { return _world_up; } + +glm::vec3 Camera::getUp() const { return _up; } + +glm::vec3 Camera::getRight() const { return _right; } + +glm::mat4 Camera::getLookMatrix() const { return _look; } + +glm::mat4 Camera::getProjectionMatrix() const { return _proj; } + +glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; } + +void Camera::setProjection(const Mat4& proj) { + _proj = proj; +} + +void Camera::setPos(const Vec3& pos) { + _pos = pos; + _calcLook(); +} + +void Camera::setTarget(const Vec3& tar) { + _tar = tar; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::setDirection(const Vec3& dir) { + setTarget(glm::normalize(dir)+_pos); +} + +void Camera::setWorldUp(const Vec3& up) { + _world_up = up; + _right = normCross(_dir, _up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::addPos(const Vec3& add) { + _pos += add; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::panPos(const Vec3& add) { + _tar += add; + addPos(add); +} + +void Camera::panPosRelative(const Vec3& add) { + panPos(add.x*_right + add.y*_up + add.z*_dir); +} + +void Camera::addTarget(const Vec3& add) { + _tar += add; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::roll(float ang) { + +} + +void Camera::pitch(float ang) { + Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _right); + _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); + _tar = _pos + _dir; + _calcLook(); +} + +void Camera::yaw(float ang) { + Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _up); + _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); + _right = Vec3(rot_mat * glm::vec4(_right, 1.0f)); + _tar = _pos + _dir; + _calcLook(); +} + +} \ No newline at end of file diff --git a/Draw.cpp b/Draw.cpp index 44dae67..a5a86f8 100644 --- a/Draw.cpp +++ b/Draw.cpp @@ -307,110 +307,4 @@ void DrawInstanceBuffer::draw() const { _VAO.unbind(); } -// Camera class -Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type(CameraType::None) { - _pos = pos; - _tar = tar; - _world_up = glm::normalize(up); - _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, _world_up); - _up = normCross(_right, _dir); - _proj = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); - _calcLook(); -} - -void Camera::_calcLook() { - _look = glm::lookAt(_pos, _tar, _world_up); -} - -glm::vec3 Camera::normCross(const Vec3& a, const Vec3& b) { - return glm::normalize(glm::cross(a, b)); -} - -glm::vec3 Camera::getPos() const { return _pos; } - -glm::vec3 Camera::getTarget() const { return _tar; } - -glm::vec3 Camera::getDirection() const { return _dir; } - -glm::vec3 Camera::getWorldUp() const { return _world_up; } - -glm::vec3 Camera::getUp() const { return _up; } - -glm::vec3 Camera::getRight() const { return _right; } - -glm::mat4 Camera::getLookMatrix() const { return _look; } - -glm::mat4 Camera::getProjectionMatrix() const { return _proj; } - -glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; } - -void Camera::setProjection(const Mat4& proj) { - _proj = proj; -} - -void Camera::setPos(const Vec3& pos) { - _pos = pos; - _calcLook(); -} - -void Camera::setTarget(const Vec3& tar) { - _tar = tar; - _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, _world_up); - _up = normCross(_right, _dir); - _calcLook(); -} - -void Camera::setDirection(const Vec3& dir) { - setTarget(glm::normalize(dir)+_pos); -} - -void Camera::setWorldUp(const Vec3& up) { - _world_up = up; - _right = normCross(_dir, _up); - _up = normCross(_right, _dir); - _calcLook(); -} - -void Camera::addPos(const Vec3& add) { - _pos += add; - _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, _world_up); - _up = normCross(_right, _dir); - _calcLook(); -} - -void Camera::panPos(const Vec3& add) { - _tar += add; - addPos(add); -} - -void Camera::addTarget(const Vec3& add) { - _tar += add; - _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, _world_up); - _up = normCross(_right, _dir); - _calcLook(); -} - -void Camera::roll(float ang) { - -} - -void Camera::pitch(float ang) { - Mat4 rot_mat = glm::rotate(_look, ang, _right); - _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); - _tar = _pos + _dir; - _calcLook(); -} - -void Camera::yaw(float ang) { - Mat4 rot_mat = glm::rotate(_look, ang, _up); - _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); - _right = Vec3(rot_mat * glm::vec4(_right, 1.0f)); - _tar = _pos + _dir; - _calcLook(); -} - -} +} \ No newline at end of file diff --git a/funcs.cpp b/funcs.cpp index c788e4a..016e93d 100644 --- a/funcs.cpp +++ b/funcs.cpp @@ -8,19 +8,38 @@ void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } + if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { + cam->yaw(1.0f*deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { + cam->yaw(-1.0f*deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { + cam->pitch(1.0f*deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { + cam->pitch(-1.0f*deltaTime); + } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { - cam->yaw(0.05f); + cam->panPosRelative(glm::vec3(-1.5f, 0.0f, 0.0f)*deltaTime); } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { - cam->yaw(-0.05f); + cam->panPosRelative(glm::vec3(1.5f, 0.0f, 0.0f)*deltaTime); } if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { - cam->pitch(0.05f); + cam->panPosRelative(glm::vec3(0.0f, 0.0f, 1.5f)*deltaTime); } if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { - cam->pitch(-0.05f); + cam->panPosRelative(glm::vec3(0.0f, 0.0f, -1.5f)*deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { + cam->panPosRelative(glm::vec3(0.0f, 1.5f, 0.0f)*deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { + cam->panPosRelative(glm::vec3(0.0f, -1.5f, 0.0f)*deltaTime); } if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) { + cam->setPos(glm::vec3(0.0f, 0.0f, -2.0f)); cam->setTarget(glm::vec3(0.0f, 0.0f, 0.0f)); cam->setWorldUp(glm::vec3(0.0f, 1.0f, 0.0f)); } diff --git a/include/Camera.h b/include/Camera.h new file mode 100644 index 0000000..433f48b --- /dev/null +++ b/include/Camera.h @@ -0,0 +1,71 @@ +#pragma once +#ifndef _NB_CAMERA +#define _NB_CAMERA + +#include +#include +#include +#include +#include + +namespace NB { + +class Camera { +public: + typedef glm::vec3 Vec3; + typedef glm::mat4 Mat4; + + enum CameraType : unsigned char { + None, + Orthographic, + Perspective + }; + + static Vec3 normCross(const Vec3&, const Vec3&); + + Camera( + const Vec3& pos=Vec3(1.0f, 0.0f, 0.0f), + const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f), + const Vec3& up =Vec3(0.0f, 1.0f, 0.0f) + ); + + Vec3 getPos() const; + Vec3 getTarget() const; + Vec3 getDirection() const; + Vec3 getWorldUp() const; + Vec3 getUp() const; + Vec3 getRight() const; + Mat4 getLookMatrix() const; + Mat4 getProjectionMatrix() const; + Mat4 getFlattenedMatrices() const; + + void setProjection(const Mat4&); + void setPos(const Vec3&); + void setTarget(const Vec3&); + void setDirection(const Vec3&); + void setWorldUp(const Vec3&); + void addPos(const Vec3&); + void panPos(const Vec3&); + void panPosRelative(const Vec3&); + void addTarget(const Vec3&); + void roll(float); + void pitch(float); + void yaw(float); + +protected: + Vec3 _pos; + Vec3 _tar; + Vec3 _dir; + Vec3 _world_up; + Vec3 _up; + Vec3 _right; + Mat4 _look; + Mat4 _proj; + const CameraType _camera_type; + + void _calcLook(); + +}; + +} +#endif // _NB_CAMERA \ No newline at end of file diff --git a/include/Draw.h b/include/Draw.h index 89fb78e..7b1345d 100644 --- a/include/Draw.h +++ b/include/Draw.h @@ -5,9 +5,6 @@ #include #include -#include -#include -#include #include #include #include @@ -84,61 +81,5 @@ private: }; -class Camera { -public: - typedef glm::vec3 Vec3; - typedef glm::mat4 Mat4; - - enum CameraType : unsigned char { - None, - Orthographic, - Perspective - }; - - static Vec3 normCross(const Vec3&, const Vec3&); - - Camera( - const Vec3& pos=Vec3(1.0f, 0.0f, 0.0f), - const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f), - const Vec3& up =Vec3(0.0f, 1.0f, 0.0f) - ); - - Vec3 getPos() const; - Vec3 getTarget() const; - Vec3 getDirection() const; - Vec3 getWorldUp() const; - Vec3 getUp() const; - Vec3 getRight() const; - Mat4 getLookMatrix() const; - Mat4 getProjectionMatrix() const; - Mat4 getFlattenedMatrices() const; - - void setProjection(const Mat4&); - void setPos(const Vec3&); - void setTarget(const Vec3&); - void setDirection(const Vec3&); - void setWorldUp(const Vec3&); - void addPos(const Vec3&); - void panPos(const Vec3&); - void addTarget(const Vec3&); - void roll(float); - void pitch(float); - void yaw(float); - -protected: - Vec3 _pos; - Vec3 _tar; - Vec3 _dir; - Vec3 _world_up; - Vec3 _up; - Vec3 _right; - Mat4 _look; - Mat4 _proj; - const CameraType _camera_type; - - void _calcLook(); - -}; - } #endif \ No newline at end of file diff --git a/include/funcs.h b/include/funcs.h index 89db972..828afd7 100644 --- a/include/funcs.h +++ b/include/funcs.h @@ -5,8 +5,10 @@ #include #include #include "Draw.h" +#include "Camera.h" extern NB::Camera* cam; +extern float deltaTime; void framebuffer_size_callback(GLFWwindow*, int, int); diff --git a/main.cpp b/main.cpp index 0e4d8de..12f6f20 100644 --- a/main.cpp +++ b/main.cpp @@ -10,10 +10,13 @@ #include #include -#include "Draw.h" #include "Buffers.h" +#include "Draw.h" +#include "Camera.h" NB::Camera* cam; +float deltaTime = 0.0f; +float lastFrame = 0.0f; int main() { NB::Window myWindow(800, 600, "Howdy Naif!"); @@ -49,27 +52,30 @@ int main() { myCube.generateVBO(NB::vectorToRaw(vert_data)); myCube.generateEBO(elmt_data); - NB::Camera myCam(glm::vec3(0.0f, 0.0f, 1.0f)); + NB::Camera myCam(glm::vec3(0.0f, 0.0f, -2.0f)); cam = &myCam; + myCam.setProjection(glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f)); glm::mat4 lookMat; // Window loop GLenum err; + glEnable(GL_CULL_FACE); while(!glfwWindowShouldClose(window)) { + deltaTime = glfwGetTime() - lastFrame; + lastFrame = glfwGetTime(); NB_GL_DEBUG_THROW("nothing", "during"); // Input checking processInput(window); - + // Rendering Loop myShader.use(); - lookMat = myCam.getLookMatrix(); + lookMat = myCam.getFlattenedMatrices(); myShader.setMat4("look", lookMat); glClearColor(0.2f, 0.4f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); myCube.draw(); // Events and buffer swap -// myDrawing.draw(); glfwPollEvents(); glfwSwapBuffers(window); } diff --git a/shaders/vert.vs b/shaders/vert.vs index 1c00e02..a55ca7a 100644 --- a/shaders/vert.vs +++ b/shaders/vert.vs @@ -2,8 +2,10 @@ layout (location=0) in vec3 vPos; layout (location=1) in vec3 vColor; +uniform mat4 look; + out vec3 vertColor; void main() { vertColor = vColor; - gl_Position = vec4(vPos, 1.0); + gl_Position = look * vec4(vPos, 1.0); } \ No newline at end of file