working camera
This commit is contained in:
parent
4a924cb2a9
commit
ea29f2c5f0
@ -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 })),
|
||||
|
59
src/camera.c
59
src/camera.c
@ -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[1].x = r.y;
|
||||
result.row[1].y = u.y;
|
||||
result.row[1].z =-f.y;
|
||||
result.row[2].x = r.z;
|
||||
result.row[2].y = u.z;
|
||||
result.row[2].z =-f.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[0].w = result.row[1].w = result.row[2].w = 0.0f;
|
||||
result.row[3].w = 1.0f;
|
||||
result.row[0].x = r.x;
|
||||
result.row[0].y = u.x;
|
||||
result.row[0].z = -camera->target.x;
|
||||
result.row[1].x = r.y;
|
||||
result.row[1].y = u.y;
|
||||
result.row[1].z = -camera->target.y;
|
||||
result.row[2].x = r.z;
|
||||
result.row[2].y = u.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(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;
|
||||
}
|
||||
|
12
src/camera.h
12
src/camera.h
@ -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 up; /* normalized up vector */
|
||||
t_fvec3 pos; /* eye position */
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user