/** * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "camera.h" #include "display/display.h" #include "assert/assert.h" #include "display/framebuffer/framebuffer.h" #include "display/screen/screen.h" void cameraInit(camera_t *camera) { cameraInitPerspective(camera); } void cameraInitPerspective(camera_t *camera) { assertNotNull(camera, "Not a camera component"); camera->projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE; camera->perspective.fov = glm_rad(45.0f); camera->nearClip = 0.1f; camera->farClip = 10000.0f; camera->viewType = CAMERA_VIEW_TYPE_LOOKAT; glm_vec3_copy((vec3){ 5.0f, 5.0f, 5.0f }, camera->lookat.position); glm_vec3_copy((vec3){ 0.0f, 1.0f, 0.0f }, camera->lookat.up); glm_vec3_copy((vec3){ 0.0f, 0.0f, 0.0f }, camera->lookat.target); } void cameraInitOrthographic(camera_t *camera) { assertNotNull(camera, "Not a camera component"); camera->projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC; camera->orthographic.left = 0.0f; camera->orthographic.right = SCREEN.width; camera->orthographic.top = SCREEN.height; camera->orthographic.bottom = 0.0f; camera->nearClip = 0.1f; camera->farClip = 1.0f; camera->viewType = CAMERA_VIEW_TYPE_2D; glm_vec2_copy((vec2){ 0.0f, 0.0f }, camera->_2d.position); camera->_2d.zoom = 1.0f; } void cameraGetProjectionMatrix(camera_t *camera, mat4 dest) { assertNotNull(camera, "Not a camera component"); assertNotNull(dest, "Destination matrix must not be null"); if( camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE || camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED ) { glm_mat4_identity(dest); glm_perspective( camera->perspective.fov, SCREEN.aspect, camera->nearClip, camera->farClip, dest ); if(camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED) { dest[1][1] *= -1.0f; } } else if(camera->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) { glm_mat4_identity(dest); glm_ortho( camera->orthographic.left, camera->orthographic.right, camera->orthographic.top, camera->orthographic.bottom, camera->nearClip, camera->farClip, dest ); } } void cameraGetViewMatrix(camera_t *camera, mat4 dest) { assertNotNull(camera, "Not a camera component"); assertNotNull(dest, "Destination matrix must not be null"); if(camera->viewType == CAMERA_VIEW_TYPE_MATRIX) { glm_mat4_ucopy(camera->view, dest); } else if(camera->viewType == CAMERA_VIEW_TYPE_LOOKAT) { glm_mat4_identity(dest); glm_lookat( camera->lookat.position, camera->lookat.target, camera->lookat.up, dest ); } else if(camera->viewType == CAMERA_VIEW_TYPE_2D) { glm_mat4_identity(dest); glm_lookat( (vec3){ camera->_2d.position[0], camera->_2d.position[1], 0.5f }, (vec3){ camera->_2d.position[0], camera->_2d.position[1], 0.0f }, (vec3){ 0.0f, 1.0f, 0.0f }, dest ); } else if(camera->viewType == CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT) { assertUnreachable("LOOKAT_PIXEL_PERFECT view type is not implemented yet"); } }