A 3D game engine from scratch.
at main 142 lines 3.9 kB view raw
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net> 2 3#include "cameras.hpp" 4#include "intrinsics.hpp" 5 6 7cameras::State *cameras::state = nullptr; 8 9 10cameras::Camera * 11cameras::get_main() 12{ 13 return &cameras::state->camera_main; 14} 15 16 17void 18cameras::update_matrices(Camera *camera) 19{ 20 WindowSize *window_size = core::get_window_size(); 21 if (window_size->width == 0 || window_size->height == 0) { 22 return; 23 } 24 25 if (camera->type == CameraType::perspective) { 26 update_matrices_perspective(camera, window_size->width, window_size->height); 27 } else if (camera->type == CameraType::ortho) { 28 update_matrices_ortho(camera, window_size->width, window_size->height); 29 } 30} 31 32 33void 34cameras::update_ui_matrices(Camera *camera) 35{ 36 WindowSize *window_size = core::get_window_size(); 37 camera->ui_projection = glm::ortho(0.0f, (f32)window_size->width, 38 0.0f, (f32)window_size->height); 39} 40 41 42void 43cameras::move_front_back(Camera *camera, f32 sign, f64 dt) 44{ 45 camera->position += (sign * camera->speed * (f32)dt) * camera->front; 46} 47 48 49void 50cameras::move_left_right(Camera *camera, f32 sign, f64 dt) 51{ 52 v3 direction = normalize(cross( 53 camera->front, camera->up 54 )); 55 camera->position += (sign * camera->speed * (f32)dt) * direction; 56} 57 58 59void 60cameras::move_up_down(Camera *camera, f32 sign, f64 dt) 61{ 62 camera->position += (sign * camera->speed * (f32)dt) * camera->up; 63} 64 65 66void 67cameras::update_mouse(Camera *camera, v2 mouse_offset) 68{ 69 camera->yaw += mouse_offset.x; 70 camera->pitch += mouse_offset.y; 71 72 if (camera->pitch > 89.0f) { 73 camera->pitch = 89.0f; 74 } else if (camera->pitch < -89.0f) { 75 camera->pitch = -89.0f; 76 } 77} 78 79 80void 81cameras::init( 82 cameras::State *cameras_state, 83 u32 window_width, 84 u32 window_height 85) { 86 cameras::state = cameras_state; 87 cameras::state->camera_main.type = CameraType::perspective; 88 cameras::state->camera_main.yaw = -45.0f; 89 cameras::state->camera_main.pitch = 0.0f; 90 cameras::state->camera_main.position = v3(-7.0f, 3.0f, 7.0f); 91 cameras::state->camera_main.front = v3(0.0f, 0.0f, 0.0f); 92 cameras::state->camera_main.up = v3(0.0f, 1.0f, 0.0f); 93 cameras::state->camera_main.speed = 5.0f; 94 cameras::state->camera_main.horizontal_fov = 60.0f; 95 cameras::state->camera_main.vertical_fov = 0.0f; // Filled in later 96 cameras::state->camera_main.near_clip_dist = 0.1f; 97 cameras::state->camera_main.far_clip_dist = 600.0f; 98 cameras::state->camera_main.exposure = 1.0f; 99 100 update_matrices(&cameras::state->camera_main); 101 update_ui_matrices(&cameras::state->camera_main); 102} 103 104 105void 106cameras::update_matrices_ortho( 107 Camera *camera, u32 window_width, u32 window_height 108) { 109 if (window_width == 0 || window_height == 0) { 110 return; 111 } 112 113 camera->view = glm::lookAt(camera->position, v3(0.0f, 0.0f, 0.0f), camera->up); 114 115 camera->projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 116 camera->near_clip_dist, camera->far_clip_dist); 117} 118 119 120void 121cameras::update_matrices_perspective( 122 Camera *camera, u32 window_width, u32 window_height 123) { 124 if (window_width == 0 || window_height == 0) { 125 return; 126 } 127 128 camera->front = normalize(v3( 129 cos(radians(camera->yaw)) * cos(radians(camera->pitch)), 130 -sin(radians(camera->pitch)), 131 sin(radians(camera->yaw)) * cos(radians(camera->pitch)))); 132 133 camera->view = glm::lookAt(camera->position, 134 camera->position + camera->front, camera->up); 135 136 camera->projection = glm::perspective(radians(camera->horizontal_fov), 137 (f32)window_width / (f32)window_height, 138 camera->near_clip_dist, camera->far_clip_dist); 139 // https://en.wikipedia.org/wiki/Field_of_view_in_video_games#Field_of_view_calculations 140 camera->vertical_fov = (f32)degrees(2 * 141 atan(tan(radians(camera->horizontal_fov) / 2) * window_height / window_width)); 142}