From ee7f2e4006690df3c30fff96df19d7e87d931626 Mon Sep 17 00:00:00 2001 From: elipzer Date: Wed, 12 Sep 2018 09:46:55 -0400 Subject: [PATCH] 2D Camera Works. Working on 3D Camera. --- OpenGLEngine/Camera.h | 15 ++++---- OpenGLEngine/Camera2D.cpp | 18 ++++++---- OpenGLEngine/Camera2D.h | 2 ++ OpenGLEngine/Camera3D.cpp | 57 ++++++++++++++++++++++++++++-- OpenGLEngine/Camera3D.h | 23 ++++++++---- OpenGLEngine/MySimple2DScene.cpp | 1 + OpenGLEngine/MySimple3DScene.cpp | 1 + OpenGLEngine/MySimpleCubeScene.cpp | 4 ++- 8 files changed, 96 insertions(+), 25 deletions(-) diff --git a/OpenGLEngine/Camera.h b/OpenGLEngine/Camera.h index 369bfc0..006b6ae 100644 --- a/OpenGLEngine/Camera.h +++ b/OpenGLEngine/Camera.h @@ -6,21 +6,18 @@ using namespace glm; -class Camera : public Poseable +class Camera { public: - Camera( - const vec3& position, - const vec3& forward = vec3(0.0f, 0.0f, 1.0f), - const vec3& up = vec3(0.0f, 1.0f, 0.0f), - const vec3& right = vec3(1.0f, 0.0f, 0.0f) - ) : Poseable(position, forward, up, right), m_projection_matrix(1.0f) - {} + Camera() : m_view_matrix(1.0f), m_projection_matrix(1.0f) {} - mat4x4 get_world_to_view_matrix() const { return m_projection_matrix * m_orientation_matrix; } + mat4x4 get_world_to_view_matrix() const { return m_projection_matrix * m_view_matrix; } + + const mat4x4& get_view_matrix() const { return m_view_matrix; } const mat4x4& get_projection_matrix() const { return m_projection_matrix; } protected: + mat4x4 m_view_matrix; mat4x4 m_projection_matrix; }; \ No newline at end of file diff --git a/OpenGLEngine/Camera2D.cpp b/OpenGLEngine/Camera2D.cpp index 9673013..c91789a 100644 --- a/OpenGLEngine/Camera2D.cpp +++ b/OpenGLEngine/Camera2D.cpp @@ -6,7 +6,6 @@ Camera2D::Camera2D(const vec2& size, const vec2& position) : Camera2D(vec3(size.x, size.y, 2.0f), vec3(position.x, position.y, 0.0f)) {} Camera2D::Camera2D(const vec3& size, const vec3& position) - : Camera(position) { update_size(size); update_position(position); @@ -21,18 +20,23 @@ void Camera2D::update_size(const vec3& size) void Camera2D::update_position(const vec3& position) { m_position = position; - Poseable::update_position(-position); } -void Camera2D::translate(const vec2& position) +void Camera2D::translate(const vec2& translation) { - translate(vec3(position.x, position.y, 0.0f)); + translate(vec3(translation.x, translation.y, 0.0f)); } -void Camera2D::translate(const vec3& position) +void Camera2D::translate(const vec3& translation) { - m_position += position; - Poseable::translate(-position); + m_position += translation; +} + +void Camera2D::prerender() +{ + m_view_matrix[3][0] = -m_position.x; + m_view_matrix[3][1] = -m_position.y; + m_view_matrix[3][2] = -m_position.z; } void Camera2D::update_scale() diff --git a/OpenGLEngine/Camera2D.h b/OpenGLEngine/Camera2D.h index 6f77bc8..f4f1e1f 100644 --- a/OpenGLEngine/Camera2D.h +++ b/OpenGLEngine/Camera2D.h @@ -18,6 +18,8 @@ public: void translate(const vec2& translation); void translate(const vec3& translation); + void prerender(); + const vec3& get_size() const { return m_size; } const vec3& get_position() const { return m_position; } diff --git a/OpenGLEngine/Camera3D.cpp b/OpenGLEngine/Camera3D.cpp index 76d21ec..98a982e 100644 --- a/OpenGLEngine/Camera3D.cpp +++ b/OpenGLEngine/Camera3D.cpp @@ -12,9 +12,10 @@ Camera3D::Camera3D( const vec3& up, const vec3& right ) - : Camera(position, forward, up, right) { update_frustum(fov_y, aspect_ratio, znear, zfar); + update_position(position); + update_orientation(forward, up, right); } void Camera3D::update_frustum(float fov_y, float aspect_ratio, float znear, float zfar) @@ -22,8 +23,60 @@ void Camera3D::update_frustum(float fov_y, float aspect_ratio, float znear, floa m_projection_matrix = glm::perspective(fov_y, aspect_ratio, znear, zfar); } +void Camera3D::update_position(const vec3& position) +{ + m_position = position; +} + +void Camera3D::update_orientation(const vec3& forward, const vec3& up, const vec3& right) +{ + vec3 real_forward; + vec3 real_up; + vec3 real_right; + + if (right == vec3(0.0f)) + real_right = glm::normalize(glm::cross(forward, up)); + else + real_right = right; + + real_forward = glm::normalize(forward); + real_up = glm::cross(real_right, real_forward); + + m_forward = vec4(real_forward, 0.0f); + m_up = vec4(real_up, 0.0f); + m_right = vec4(real_right, 0.0f); +} + +void Camera3D::direct_update_orientation(const vec3& forward, const vec3& up, const vec3& right) +{ + m_forward = vec4(forward, 0.0f); + m_up = vec4(up, 0.0f); + m_right = vec4(right, 0.0f); +} + void Camera3D::translate(const vec3& translation) { m_position += translation; - Poseable::translate(-translation); +} + +void Camera3D::rotate(const vec3& axis, float angle) +{ + mat4 rotation = glm::rotate(mat4(1.0f), angle, axis); + m_forward = rotation * m_forward; + m_up = rotation * m_up; + m_right = rotation * m_right; +} + +void Camera3D::prerender() +{ + // This works but it is backwards. + m_view_matrix = glm::lookAt(m_position, m_position + vec3(m_forward), vec3(m_up)); + /* + m_view_matrix = mat4( + vec4(m_right.x, m_up.x, -m_forward.x, 0.0f), + vec4(m_right.y, m_up.y, -m_forward.y, 0.0f), + vec4(m_right.z, m_up.z, -m_forward.z, 0.0f), + vec4(glm::dot(vec3(m_right), -m_position), glm::dot(vec3(m_up), -m_position), glm::dot(vec3(m_forward), -m_position), 1.0f) + ); + */ } \ No newline at end of file diff --git a/OpenGLEngine/Camera3D.h b/OpenGLEngine/Camera3D.h index ced338e..fb1908a 100644 --- a/OpenGLEngine/Camera3D.h +++ b/OpenGLEngine/Camera3D.h @@ -9,8 +9,6 @@ using namespace glm; class Camera3D : public Camera { public: - // Creates a Camera3D. - // Will throw if direction, up, and right are not orthogonal Camera3D( float fov_y, float aspect_ratio, @@ -19,18 +17,31 @@ public: const vec3& position, const vec3& forward = vec3(0.0f, 0.0f, 1.0f), const vec3& up = vec3(0.0f, 1.0f, 0.0f), - const vec3& right = vec3(1.0f, 0.0f, 0.0f) + const vec3& right = vec3(0.0f) // Zero for auto-calculated ); void update_frustum(float fov_y, float aspect_ratio, float znear, float zfar); + void update_position(const vec3& position); + // Updates the orientation based on three vectors. + // If right is equal to zero it is calculated with glm::cross(forward, up). + // Then the true up is calculated with glm::cross(right, forward) + void update_orientation(const vec3& forward = vec3(0.0f, 0.0f, 1.0f), const vec3& up = vec3(0.0f, 1.0f, 0.0f), const vec3& right = vec3(0.0f)); + // Directly sets the forward, up, and right values. + void direct_update_orientation(const vec3& forward, const vec3& up, const vec3& right); void translate(const vec3& translation); + void rotate(const vec3& axis, float angle); + + void prerender(); const vec3& get_position() const { return m_position; } - vec3 get_forward() const { return vec3(m_orientation_matrix[2]); } - vec3 get_up() const { return vec3(m_orientation_matrix[1]); } - vec3 get_right() const { return vec3(m_orientation_matrix[0]); } + vec3 get_forward() const { return vec3(m_forward); } + vec3 get_up() const { return vec3(m_up); } + vec3 get_right() const { return vec3(m_right); } private: vec3 m_position; + vec4 m_forward; + vec4 m_up; + vec4 m_right; }; \ No newline at end of file diff --git a/OpenGLEngine/MySimple2DScene.cpp b/OpenGLEngine/MySimple2DScene.cpp index 6ba7c63..0afb21a 100644 --- a/OpenGLEngine/MySimple2DScene.cpp +++ b/OpenGLEngine/MySimple2DScene.cpp @@ -90,6 +90,7 @@ void MySimple2DScene::update(float delta_time, clock_t clock) m_camera.translate(camera_translation * delta_time * 100.0f); // TODO: Make a prerender function or move this to render + m_camera.prerender(); m_batch.prerender(); } diff --git a/OpenGLEngine/MySimple3DScene.cpp b/OpenGLEngine/MySimple3DScene.cpp index 792fa8e..27343cd 100644 --- a/OpenGLEngine/MySimple3DScene.cpp +++ b/OpenGLEngine/MySimple3DScene.cpp @@ -92,6 +92,7 @@ void MySimple3DScene::update(float delta_time, clock_t clock) m_camera.translate(camera_translation * delta_time); // TODO: Make a prerender function or move this to render + m_camera.prerender(); m_batch.prerender(); } diff --git a/OpenGLEngine/MySimpleCubeScene.cpp b/OpenGLEngine/MySimpleCubeScene.cpp index 4896789..554f7ba 100644 --- a/OpenGLEngine/MySimpleCubeScene.cpp +++ b/OpenGLEngine/MySimpleCubeScene.cpp @@ -19,7 +19,7 @@ MySimpleCubeScene::MySimpleCubeScene(Application& application) MySimpleShaderProgram::Vertex( 1.0f, -1.0f, 1.0f) ), DrawMode::DRAW_TRIANGLES), m_batch(&m_shape, 1), - m_camera((float)egm::TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)) + m_camera((float)egm::TAU_1_8, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)) {} MySimpleCubeScene::~MySimpleCubeScene() @@ -65,6 +65,7 @@ void MySimpleCubeScene::update(float delta_time, clock_t clock) color.a = 1.0f; Poseable& pose = m_batch.get_pose(0); + pose.rotate(glm::normalize(vec3(1.0f, 1.0f, 0.0f)), (float)egm::TAU_1_2 * delta_time); pose.update_position(vec3(3 * (float)cos(radians), 0.0f, 0.0f)); } @@ -80,6 +81,7 @@ void MySimpleCubeScene::update(float delta_time, clock_t clock) m_camera.translate(camera_translation * delta_time); // TODO: Make a prerender function or move this to render + m_camera.prerender(); m_batch.prerender(); }