From f2f8ccc1c24ab372ffe5e932780eeb1c49a4d277 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 21 Feb 2020 05:10:13 +0100 Subject: Add third person camera (orbit camera) --- src/main.cpp | 75 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 24 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 04c1001..33488bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "../include/RenderBackend/OpenGL/Texture2D.hpp" #include "../include/Image.hpp" #include "../include/Triangle.hpp" +#include "../include/ThirdPersonCamera.hpp" #include "../include/model_loader/ObjModelLoader.hpp" @@ -25,7 +26,9 @@ static std::unique_ptr load_shader_from_file(const char *filepath, Shade static std::unique_ptr build_shader_program_from_shaders(const std::vector &shaders); struct Userdata { - float cam_dist; + ThirdPersonCamera *third_person_camera; + double prev_cursor_x; + double prev_cursor_y; }; static std::vector generate_sand() { @@ -54,8 +57,7 @@ static std::vector generate_sand() { static void create_sand(DeviceMemory *triangles, DeviceMemory *texcoords, Texture2D *texture); static DeviceMemory* load_model(const char *filepath); -int main() -{ +int main() { initGlfw(); glfwSetErrorCallback(glfwErrorHandler); GLFWwindow *window = createWindow(); @@ -115,15 +117,30 @@ int main() texture_coords.resize(0); Userdata userdata; - userdata.cam_dist = 3.0f; - glm::vec3 character_pos(0.0f, 0.0f, userdata.cam_dist); + ThirdPersonCamera third_person_camera; + userdata.third_person_camera = &third_person_camera; + glfwGetCursorPos(window, &userdata.prev_cursor_x, &userdata.prev_cursor_y); + + glm::vec3 character_pos(0.0f, 0.0f, 10.0f); auto t_start = std::chrono::high_resolution_clock::now(); glfwSetWindowUserPointer(window, &userdata); glfwSetScrollCallback(window, [](GLFWwindow *window, double xoffset, double yoffset){ Userdata *userdata = (Userdata*)glfwGetWindowUserPointer(window); - userdata->cam_dist += yoffset; + userdata->third_person_camera->zoom(-yoffset); + }); + + glfwSetCursorPosCallback(window, [](GLFWwindow *window, double xpos, double ypos) { + Userdata *userdata = (Userdata*)glfwGetWindowUserPointer(window); + double diff_x = xpos - userdata->prev_cursor_x; + double diff_y = ypos - userdata->prev_cursor_y; + userdata->prev_cursor_x = xpos; + userdata->prev_cursor_y = ypos; + if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_2) == GLFW_PRESS) { + userdata->third_person_camera->rotate_horizontal(diff_x * 0.005f); + userdata->third_person_camera->rotate_vertical(-diff_y * 0.005f); + } }); glEnable(GL_CULL_FACE); @@ -141,25 +158,34 @@ int main() t_start = t_now; time += time_delta; + glm::mat4 camera_matrix = third_person_camera.get_matrix(); + glm::vec3 camera_forward = third_person_camera.get_forward_vector(); + glm::vec3 camera_right = third_person_camera.get_right_vector(); + + sand_view_uniform->set(camera_matrix); + view_uniform->set(camera_matrix); + float move_speed = time_delta * 3.0f; - if(glfwGetKey(window, GLFW_KEY_W)) - character_pos.y -= move_speed; - if(glfwGetKey(window, GLFW_KEY_S)) - character_pos.y += move_speed; - if(glfwGetKey(window, GLFW_KEY_A)) - character_pos.x += move_speed; - if(glfwGetKey(window, GLFW_KEY_D)) - character_pos.x -= move_speed; - - character_pos.z = userdata.cam_dist; - - glm::mat4 view = glm::lookAt( - character_pos, - character_pos - glm::vec3(0.0f, 3.0f, 3.0f), - glm::vec3(0.0f, 0.0f, 1.0f) - ); - sand_view_uniform->set(view); - view_uniform->set(view); + glm::vec3 move_vec = glm::vec3(); + if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { + move_vec.x += camera_forward.x; + move_vec.y += camera_forward.y; + } + if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { + move_vec.x += -camera_forward.x; + move_vec.y += -camera_forward.y; + } + if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { + move_vec.x += -camera_right.x; + move_vec.y += -camera_right.y; + } + if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { + move_vec.x += camera_right.x; + move_vec.y += camera_right.y; + } + if(glm::length(move_vec) > 0.0f) + character_pos += (glm::normalize(move_vec) * move_speed); + third_person_camera.set_target_position(character_pos); glm::mat4 model = glm::mat4(1.0f); model = glm::rotate( @@ -284,6 +310,7 @@ GLFWwindow* createWindow() { exit(10); } + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_FALSE); glfwMakeContextCurrent(window); glfwSwapInterval(1); // 1 = enable vsync -- cgit v1.2.3