working camera

This commit is contained in:
veclav talica 2024-07-30 18:05:05 +03:00
parent 4a924cb2a9
commit ea29f2c5f0
4 changed files with 60 additions and 27 deletions

View File

@ -11,14 +11,14 @@ static void ingame_tick(struct state *state) {
world_drawdef(scn->world);
player_calc(scn->player);
static t_camera cam = { .pos = { 0 }, .target = { 0, 0, -1 }, .up = { 0, -1, 0 }, .fov = (float)M_PI_2 };
static t_camera cam = { .pos = { 0, 0, 1 }, .target = { 0, 0, -1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 };
if (input_is_action_pressed(&ctx.input, "player_left"))
cam.pos.x -= 0.01f;
if (input_is_action_pressed(&ctx.input, "player_right"))
cam.pos.x += 0.01f;
if (input_is_action_pressed(&ctx.input, "player_jump"))
cam.pos.z -= 0.01f;
cam.pos.z += 0.01f;
m_sprite(m_set(path, "/assets/light.png"),
m_set(rect, ((t_frect){ 48, 64, 64, 64 })),

View File

@ -1,27 +1,52 @@
#include "camera.h"
#include "context.h"
#include <math.h>
#define CAMERA_NEAR_Z 0.1f
#define CAMERA_FAR_Z 100.0f
t_matrix4 camera_look_at(const t_camera *const camera) {
/* from cglm */
const t_fvec3 f = m_vec_norm(m_vec_sub(camera->pos, camera->target));
const t_fvec3 r = m_vec_norm(m_vec_cross(f, camera->up));
const t_fvec3 u = m_vec_cross(f, r);
const t_fvec3 r = m_vec_norm(m_vec_cross(camera->target, camera->up));
const t_fvec3 u = m_vec_cross(r, camera->target);
t_matrix4 result;
result.row[0].x = r.x;
result.row[0].y = u.x;
result.row[0].z =-f.x;
result.row[0].z = -camera->target.x;
result.row[1].x = r.y;
result.row[1].y = u.y;
result.row[1].z =-f.y;
result.row[1].z = -camera->target.y;
result.row[2].x = r.z;
result.row[2].y = u.z;
result.row[2].z =-f.z;
result.row[2].z = -camera->target.z;
result.row[3].x = -m_vec_dot(r, camera->pos);
result.row[3].y = -m_vec_dot(u, camera->pos);
result.row[3].z = m_vec_dot(f, camera->pos);
result.row[3].z = m_vec_dot(camera->target, camera->pos);
result.row[0].w = result.row[1].w = result.row[2].w = 0.0f;
result.row[3].w = 1.0f;
return result;
}
t_matrix4 camera_perspective(const t_camera *const camera) {
/* from cglm */
t_matrix4 result = {0};
const float aspect = RENDER_BASE_RATIO;
const float f = 1.0f / tanf(camera->fov * 0.5f);
const float fn = 1.0f / (CAMERA_NEAR_Z - CAMERA_FAR_Z);
result.row[0].x = f / aspect;
result.row[1].y = f;
result.row[2].z = (CAMERA_NEAR_Z + CAMERA_FAR_Z) * fn;
result.row[2].w = -1.0f;
result.row[3].z = 2.0f * CAMERA_NEAR_Z * CAMERA_FAR_Z * fn;
return result;
}

View File

@ -3,13 +3,19 @@
#include "util.h"
/* TODO: make it cached */
/* for example, perspective matrix only needs recaluclation on FOV change */
/* first person camera class */
typedef struct camera {
t_fvec3 pos; /* eye position */
t_fvec3 target; /* target point */
t_fvec3 target; /* normalized target vector */
t_fvec3 up; /* normalized up vector */
float fov; /* field of view, in radians */
} t_camera;
t_matrix4 camera_look_at(const t_camera *camera);
t_matrix4 camera_perspective(const t_camera *const camera);
#endif

View File

@ -14,7 +14,8 @@
/* TODO: have a default initialized one */
static t_matrix4 camera_projection;
static t_matrix4 camera_projection_matrix;
static t_matrix4 camera_look_at_matrix;
void render_queue_clear(void) {
@ -164,10 +165,10 @@ void render(void) {
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&camera_projection.row[0].x);
glLoadMatrixf(&camera_projection_matrix.row[0].x);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(&camera_look_at_matrix.row[0].x);
render_space();
}
@ -189,7 +190,8 @@ void render(void) {
SDL_GL_SwapWindow(ctx.window);
}
void push_camera(const t_camera *const camera) {
void set_camera(const t_camera *const camera) {
/* TODO: skip recaulculating if it's the same? */
camera_projection = camera_look_at(camera);
camera_projection_matrix = camera_perspective(camera);
camera_look_at_matrix = camera_look_at(camera);
}