From e9baa0ebe3c26c96167d8f5fb2ed5ead9bba2f1c Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 1 Dec 2024 21:01:39 +0000 Subject: [PATCH] Add fly camera --- src/main.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/src/main.cc b/src/main.cc index 3f218df..7e4ab90 100644 --- a/src/main.cc +++ b/src/main.cc @@ -83,6 +83,9 @@ int main() { return EXIT_CODE_GLAD_LOADER_FAILED; } + SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); + // Set texture options glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -205,21 +208,33 @@ int main() { glm::vec3(-3.3f, 2.0f, -1.5f) }; - glm::vec3 camera_target = glm::vec3(0.0f, 0.0f, 0.0f); + const float camera_speed = 25.0f; + glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 4.0f); + glm::vec3 camera_forward = glm::vec3(0.0f); glm::vec3 world_up = glm::vec3(0.0f, 1.0f, 0.0f); + float yaw = -90.0f; + float pitch = 0.0f; + glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 100.0f); glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); - float ticks = 0; - float radius = 10.0f; - bool running = true; - SDL_Event event = {}; + const float sensitivity = 0.1f; + int last_mouse_x = WINDOW_HALF_WIDTH; + int last_mouse_y = WINDOW_HALF_HEIGHT; + uint32_t last_frame = SDL_GetTicks(); + float delta = 0.0f; + bool running = true; + SDL_Event event = {}; while (running) { + uint32_t ticks = SDL_GetTicks(); + delta = (ticks - last_frame) * 0.001f; + last_frame = ticks; + while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: @@ -232,6 +247,36 @@ int main() { texture_mix_factor += 0.1f; } else if (event.key.keysym.sym == SDLK_DOWN) { texture_mix_factor -= 0.1f; + } else if (event.key.keysym.sym == SDLK_w) { + camera_position += camera_speed * delta * camera_forward; + } else if (event.key.keysym.sym == SDLK_s) { + camera_position -= camera_speed * delta * camera_forward; + } else if (event.key.keysym.sym == SDLK_d) { + camera_position += camera_speed * delta * glm::normalize(glm::cross(camera_forward, world_up)); + } else if (event.key.keysym.sym == SDLK_a) { + camera_position -= camera_speed * delta * glm::normalize(glm::cross(camera_forward, world_up)); + } + break; + case SDL_MOUSEMOTION: { + float x_offset = event.motion.xrel; + float y_offset = -event.motion.yrel; + + last_mouse_x = last_mouse_x + event.motion.xrel; + last_mouse_y = last_mouse_y + event.motion.yrel; + + x_offset *= sensitivity; + y_offset *= sensitivity; + + yaw += x_offset; + pitch += y_offset; + + if(pitch > 89.0f) { + pitch = 89.0f; + } + + if(pitch < -89.0f) { + pitch = -89.0f; + } } break; case SDL_WINDOWEVENT: @@ -243,21 +288,22 @@ int main() { int w, h; SDL_GL_GetDrawableSize(wnd, &w, &h); glViewport(0, 0, w, h); + SDL_WarpMouseInWindow(wnd, (int)(w * 0.5f), (int)(h * 0.5f)); } break; } } - texture_mix_factor = texture_mix_factor < 0.0f ? 0.0f : texture_mix_factor > 1.0f ? 1.0f : texture_mix_factor; - ticks = (float)SDL_GetTicks() / 1000.0f; - float camera_x = sin(ticks) * radius; - float camera_z = cos(ticks) * radius; - glm::vec3 camera_position = glm::vec3(camera_x, 0.0f, camera_z); - view = glm::lookAt(camera_position, camera_target, world_up); + camera_forward.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); + camera_forward.y = sin(glm::radians(pitch)); + camera_forward.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); + camera_forward = glm::normalize(camera_forward); + + view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "view"), 1, GL_FALSE, glm::value_ptr(view)); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);