working camera
This commit is contained in:
		| @@ -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); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user