working camera
This commit is contained in:
		| @@ -11,14 +11,14 @@ static void ingame_tick(struct state *state) { | |||||||
|     world_drawdef(scn->world); |     world_drawdef(scn->world); | ||||||
|     player_calc(scn->player); |     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")) |     if (input_is_action_pressed(&ctx.input, "player_left")) | ||||||
|         cam.pos.x -= 0.01f; |         cam.pos.x -= 0.01f; | ||||||
|     if (input_is_action_pressed(&ctx.input, "player_right")) |     if (input_is_action_pressed(&ctx.input, "player_right")) | ||||||
|         cam.pos.x += 0.01f; |         cam.pos.x += 0.01f; | ||||||
|     if (input_is_action_pressed(&ctx.input, "player_jump")) |     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_sprite(m_set(path,  "/assets/light.png"), | ||||||
|              m_set(rect,  ((t_frect){ 48, 64, 64, 64 })), |              m_set(rect,  ((t_frect){ 48, 64, 64, 64 })), | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								src/camera.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								src/camera.c
									
									
									
									
									
								
							| @@ -1,27 +1,52 @@ | |||||||
| #include "camera.h" | #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) { | t_matrix4 camera_look_at(const t_camera *const camera) { | ||||||
|     /* from cglm */ |     /* 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(camera->target, camera->up)); | ||||||
|     const t_fvec3 r = m_vec_norm(m_vec_cross(f, camera->up)); |     const t_fvec3 u = m_vec_cross(r, camera->target); | ||||||
|     const t_fvec3 u = m_vec_cross(f, r); |  | ||||||
|  |  | ||||||
|     t_matrix4 result; |     t_matrix4 result; | ||||||
|  |  | ||||||
|     result.row[0].x =  r.x; |     result.row[0].x =  r.x; | ||||||
|     result.row[0].y =  u.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].x =  r.y; | ||||||
|     result.row[1].y =  u.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].x =  r.z; | ||||||
|     result.row[2].y =  u.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].x = -m_vec_dot(r, camera->pos); | ||||||
|     result.row[3].y = -m_vec_dot(u, 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[0].w =  result.row[1].w = result.row[2].w = 0.0f; | ||||||
|     result.row[3].w =  1.0f; |     result.row[3].w =  1.0f; | ||||||
|  |  | ||||||
|     return result; |     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; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -3,13 +3,19 @@ | |||||||
|  |  | ||||||
| #include "util.h" | #include "util.h" | ||||||
|  |  | ||||||
|  | /* TODO: make it cached */ | ||||||
|  | /*       for example, perspective matrix only needs recaluclation on FOV change */ | ||||||
|  |  | ||||||
| /* first person camera class */ | /* first person camera class */ | ||||||
| typedef struct camera { | typedef struct camera { | ||||||
|     t_fvec3 pos;        /* eye position */ |     t_fvec3 pos;        /* eye position */ | ||||||
| 	t_fvec3 target;		/* target point */ |     t_fvec3 target;     /* normalized target vector */ | ||||||
|     t_fvec3 up;         /* normalized up vector */ |     t_fvec3 up;         /* normalized up vector */ | ||||||
|  |     float fov;        /* field of view, in radians */ | ||||||
| } t_camera; | } t_camera; | ||||||
|  |  | ||||||
| t_matrix4 camera_look_at(const t_camera *camera); | t_matrix4 camera_look_at(const t_camera *camera); | ||||||
|  |  | ||||||
|  | t_matrix4 camera_perspective(const t_camera *const camera); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -14,7 +14,8 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| /* TODO: have a default initialized one */ | /* 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) { | void render_queue_clear(void) { | ||||||
| @@ -164,10 +165,10 @@ void render(void) { | |||||||
|  |  | ||||||
|     { |     { | ||||||
|         glMatrixMode(GL_PROJECTION); |         glMatrixMode(GL_PROJECTION); | ||||||
|         glLoadMatrixf(&camera_projection.row[0].x); |         glLoadMatrixf(&camera_projection_matrix.row[0].x); | ||||||
|  |  | ||||||
|         glMatrixMode(GL_MODELVIEW); |         glMatrixMode(GL_MODELVIEW); | ||||||
|         glLoadIdentity(); |         glLoadMatrixf(&camera_look_at_matrix.row[0].x); | ||||||
|  |  | ||||||
|         render_space(); |         render_space(); | ||||||
|     } |     } | ||||||
| @@ -189,7 +190,8 @@ void render(void) { | |||||||
|     SDL_GL_SwapWindow(ctx.window); |     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? */ |     /* 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); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user