From c13bf5994998966225e04024f57e6df3571c9338 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sat, 26 Sep 2020 16:47:00 -0700 Subject: [PATCH] Add camera class because I felt like it --- include/engine/camera.hpp | 95 ++++++++++++++++++++++++++++++++++++++ include/engine/object.hpp | 69 ++++++++++++++++++++++++++++ makefile | 2 +- src/engine/camera.cpp | 97 +++++++++++++++++++++++++++++++++++++++ src/engine/object.cpp | 66 ++++++++++++++++++++++++++ src/main.cpp | 8 +++- 6 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 include/engine/camera.hpp create mode 100644 include/engine/object.hpp create mode 100644 src/engine/camera.cpp create mode 100644 src/engine/object.cpp diff --git a/include/engine/camera.hpp b/include/engine/camera.hpp new file mode 100644 index 0000000..dfd62fc --- /dev/null +++ b/include/engine/camera.hpp @@ -0,0 +1,95 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef OUR_DICK_ENGINE_CAMERA_HPP +#define OUR_DICK_ENGINE_CAMERA_HPP + +#include "graphics/gl_include.hpp" //GLfloat +#include "math/math.hpp" +#include "object.hpp" + +namespace egn{ + + class camera_iface : public object + { + protected: + enum update{ + VIEW_UPDATE = 8, + PROJ_UPDATE = 16, + }; + protected: + math::mat4 m_projection_matrix; //camera-to-sceen matrix + math::mat4 m_view_matrix; //world-to-camera matrix + GLfloat m_near = 1; //near clipping plane in camera space + GLfloat m_far = 100; //far clipping plane in camera space + + public: + camera_iface() = default; + camera_iface(const math::mat4& proj, GLfloat n, GLfloat f); + camera_iface(const camera_iface&) = default; + camera_iface(camera_iface&&) = default; + virtual ~camera_iface() = default; + + camera_iface& operator=(const camera_iface&) = default; + camera_iface& operator=(camera_iface&&) = default; + + void set_position(const math::vec3& pos)override; + void set_orientation(const math::quaternion& distance)override; + + //getters + const math::mat4& get_projection_matrix(); + const math::mat4& get_view_matrix(); + GLfloat get_near_plane()const; + GLfloat get_far_plane()const; + + //setters + void set_near_plane(GLfloat n); + void set_far_plane(GLfloat f); + + protected: + void recalc_view_matrix(); + virtual void recalc_projection_matrix() = 0; + }; + + class ortho_camera : public camera_iface + { + protected: + GLfloat m_width, m_height; //width and height of the camera space box + + public: + ortho_camera(GLfloat w, GLfloat h, GLfloat n, GLfloat f); + ortho_camera(const ortho_camera&) = default; + ortho_camera(ortho_camera&&) = default; + ~ortho_camera() = default; + + ortho_camera& operator=(const ortho_camera&) = default; + ortho_camera& operator=(ortho_camera&&) = default; + + GLfloat get_projection_width()const; + GLfloat get_projection_height()const; + + void set_projection_width(GLfloat w); + void set_projection_height(GLfloat h); + + protected: + void recalc_projection_matrix()override; + }; + +} + +#endif diff --git a/include/engine/object.hpp b/include/engine/object.hpp new file mode 100644 index 0000000..50420cf --- /dev/null +++ b/include/engine/object.hpp @@ -0,0 +1,69 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef OUR_DICK_ENGINE_OBJECT_HPP +#define OUR_DICK_ENGINE_OBJECT_HPP + +#include "graphics/gl_include.hpp" //GLfloat +#include "math/math.hpp" + +namespace egn{ + + class object + { + protected: + enum update{ + NO_UPDATE, + SCALE_UPDATE = 1, + TRANSLATION_UPDATE = 2, + ROTATION_UPDATE = 4, + }; + protected: + math::vec3 m_position; //track current positon in world space + math::quaternion m_orientation; //track current model space rotation + math::vec3 m_scale{1.0f, 1.0f, 1.0f}; //track model space scale + math::mat4 m_model_matrix; //compile all the above info into a matrix + int m_update_flag = NO_UPDATE; //whether or not to update the matrix upon access + + public: + object() = default; + explicit object(const math::vec3& position); + object(const math::vec3& position, const math::quaternion& orientation); + object(const object&) = default; + object(object&&) = default; + virtual ~object() = default; + + object& operator=(const object&) = default; + object& operator=(object&&) = default; + + void translate(const math::vec3& distance); + void rotate(const math::quaternion& distance); + void scale(const math::vec3& distance); + + virtual void set_position(const math::vec3& pos); + virtual void set_orientation(const math::quaternion& orient); + virtual void set_scale(const math::vec3& scale); + const math::mat4& get_model_matrix(); + + protected: + void recalc_model_matrix(); + }; + +} + +#endif diff --git a/makefile b/makefile index 80b0513..a5658dd 100644 --- a/makefile +++ b/makefile @@ -19,7 +19,7 @@ ifeq ($(OS),Windows_NT) WINDOWS::=1 endif -SOURCE_DIRS::=src src/audio src/audio/impl src/graphics +SOURCE_DIRS::=src src/audio src/audio/impl src/graphics src/engine SOURCES::= OBJDIR::=obj DEPDIR::=$(OBJDIR)/dep diff --git a/src/engine/camera.cpp b/src/engine/camera.cpp new file mode 100644 index 0000000..4bfecc2 --- /dev/null +++ b/src/engine/camera.cpp @@ -0,0 +1,97 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#include "engine/camera.hpp" + +namespace egn{ + + camera_iface::camera_iface(const math::mat4& proj, GLfloat n, GLfloat f): + m_projection_matrix(proj), + m_near(n), m_far(f){} + + void camera_iface::set_position(const math::vec3& pos){ + object::set_position(pos); + m_update_flag |= VIEW_UPDATE; + } + void camera_iface::set_orientation(const math::quaternion& orient){ + object::set_orientation(orient); + m_update_flag |= VIEW_UPDATE; + } + const math::mat4& camera_iface::get_projection_matrix(){ + if(m_update_flag & PROJ_UPDATE){ + recalc_projection_matrix(); + m_update_flag ^= PROJ_UPDATE; + } + return m_projection_matrix; + } + const math::mat4& camera_iface::get_view_matrix(){ + if(m_update_flag & VIEW_UPDATE){ + recalc_view_matrix(); + m_update_flag ^= VIEW_UPDATE; + } + return m_view_matrix; + } + + GLfloat camera_iface::get_near_plane()const{ + return m_near; + } + GLfloat camera_iface::get_far_plane()const{ + return m_far; + } + void camera_iface::set_near_plane(GLfloat n){ + m_update_flag |= PROJ_UPDATE; + m_near = n; + } + void camera_iface::set_far_plane(GLfloat f){ + m_update_flag |= PROJ_UPDATE; + m_far = f; + } + + void camera_iface::recalc_view_matrix(){ + m_view_matrix = m_orientation.to_mat4(); + m_view_matrix[3][0] = -m_position[0]; + m_view_matrix[3][1] = -m_position[1]; + m_view_matrix[3][2] = -m_position[2]; + } + + + ortho_camera::ortho_camera(GLfloat w, GLfloat h, GLfloat n, GLfloat f): + camera_iface(math::ortho_projection(w, h, n, f), n, f), + m_width(w), + m_height(h){} + + GLfloat ortho_camera::get_projection_width()const{ + return m_width; + } + GLfloat ortho_camera::get_projection_height()const{ + return m_height; + } + void ortho_camera::set_projection_width(GLfloat w){ + m_update_flag |= PROJ_UPDATE; + m_width = w; + } + void ortho_camera::set_projection_height(GLfloat h){ + m_update_flag |= PROJ_UPDATE; + m_height = h; + } + + void ortho_camera::recalc_projection_matrix(){ + m_projection_matrix = math::ortho_projection(m_width, m_height, m_near, m_far); + } + +} diff --git a/src/engine/object.cpp b/src/engine/object.cpp new file mode 100644 index 0000000..5f46029 --- /dev/null +++ b/src/engine/object.cpp @@ -0,0 +1,66 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#include "engine/object.hpp" + +namespace egn{ + + object::object(const math::vec3& position): + m_position(position){} + object::object(const math::vec3& position, const math::quaternion& orientation): + m_position(position), + m_orientation(orientation){} + + void object::translate(const math::vec3& distance){ + set_position(m_position + distance); + } + void object::rotate(const math::quaternion& distance){ + set_orientation(m_orientation * distance); + } + void object::scale(const math::vec3& distance){ + set_scale(math::vec3{m_scale[0] * distance[0], + m_scale[1] * distance[1], + m_scale[2] * distance[2]}); + } + void object::set_position(const math::vec3& pos){ + m_update_flag |= TRANSLATION_UPDATE; + m_position = pos; + } + void object::set_orientation(const math::quaternion& orient){ + m_update_flag |= ROTATION_UPDATE; + m_orientation = orient; + } + void object::set_scale(const math::vec3& scale){ + m_update_flag |= SCALE_UPDATE; + m_scale = scale; + } + const math::mat4& object::get_model_matrix(){ + if(m_update_flag & (SCALE_UPDATE | ROTATION_UPDATE | TRANSLATION_UPDATE)){ + recalc_model_matrix(); + m_update_flag &= (~(SCALE_UPDATE | ROTATION_UPDATE | TRANSLATION_UPDATE)); + } + return m_model_matrix; + } + void object::recalc_model_matrix(){ + m_model_matrix = m_orientation.to_mat4(); + m_model_matrix[3][0] = m_position[0]; + m_model_matrix[3][1] = m_position[1]; + m_model_matrix[3][2] = m_position[2]; + } + +} diff --git a/src/main.cpp b/src/main.cpp index c74d454..5bf82a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,8 @@ #include "graphics/shader.hpp" #include "graphics/shader_program.hpp" +#include "engine/camera.hpp" + // 0 | 1 | 2 // --------- // 3 | 4 | 5 @@ -231,7 +233,7 @@ public: int main(){ const grid g; - const math::mat4 identity_mat = math::ortho_projection(10.0f, 10.0f, 0.1f, 100.0f); + egn::ortho_camera cam(10, 10, 1, 100); srand(time(NULL)); game_state gs = {}; @@ -252,7 +254,9 @@ int main(){ gfx::vao vao; //add our view-projection matrix in the glsl uniform variable - prog.set_uniform("vp_mat", identity_mat); + prog.set_uniform("vp_mat", cam.get_projection_matrix()*cam.get_view_matrix()); + auto mat = prog.get_uniform_mat4("vp_mat"); + math::dump_matrix(mat); //put the grid square positions for(size_t i = 0;i < 3;++i){