rendering.c: sprite rotation
This commit is contained in:
		| @@ -11,6 +11,23 @@ static void ingame_tick(struct state *state) { | ||||
|     world_drawdef(scn->world); | ||||
|     player_calc(scn->player); | ||||
|  | ||||
|     push_sprite_ex((t_frect){ .x = 32, .y = 32, .w = 64, .h = 64 }, (t_push_sprite_args){ | ||||
|         .path = "/assets/player/baron-walk.png", | ||||
|         .color = (t_color){255, 255, 255, 255}, | ||||
|         .rotation = (float)M_PI * 2 * (float)(ctx.tick_count % 64) / 64, | ||||
|         .blend = true }); | ||||
|  | ||||
|     push_sprite_ex((t_frect){ .x = 64, .y = 32, .w = 64, .h = 64 }, (t_push_sprite_args){ | ||||
|         .path = "/assets/player/baron-walk.png", | ||||
|         .color = (t_color){255, 255, 255, 255}, | ||||
|         .rotation = (float)M_PI / 64, | ||||
|         .blend = true }); | ||||
|  | ||||
|     push_sprite_ex((t_frect){ .x = 96, .y = 32, .w = 64, .h = 64 }, (t_push_sprite_args){ | ||||
|         .path = "/assets/player/baron-walk.png", | ||||
|         .color = (t_color){255, 255, 255, 255}, | ||||
|         .blend = true }); | ||||
|  | ||||
|     unfurl_triangle("/assets/big-violet.png", | ||||
|                     (t_fvec3){ -1, -1, 0 }, | ||||
|                     (t_fvec3){ 1, -1, 0 }, | ||||
|   | ||||
| @@ -90,6 +90,7 @@ static void render_2d(void) { | ||||
|                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
|                     glEnable(GL_DEPTH_TEST); | ||||
|                     glDepthFunc(GL_ALWAYS); | ||||
|                     glDepthRange((double)batch_count / UINT16_MAX, 1.0); | ||||
|                     glDisable(GL_ALPHA_TEST); | ||||
|  | ||||
|                     render_sprites(current, batch.size, false); | ||||
|   | ||||
| @@ -135,6 +135,8 @@ static void render_sprites(const struct primitive_2d primitives[], | ||||
| 	        const float xr = (float)srcrect.x / (float)dims.w; | ||||
| 	        const float yr = (float)srcrect.y / (float)dims.h; | ||||
|  | ||||
| 	        /* non-rotated case */ | ||||
| 	        if (sprite.rotation == 0.0f) { | ||||
| 	            payload[i] = (struct sprite_primitive_payload) { | ||||
| 	                /* upper-left */ | ||||
| 	                .v0 = { | ||||
| @@ -174,6 +176,54 @@ static void render_sprites(const struct primitive_2d primitives[], | ||||
| 	                .c2 = sprite.color, | ||||
| 	                .c3 = sprite.color, | ||||
| 	            }; | ||||
| 	        } else { | ||||
| 	        	/* rotated case */ | ||||
| 	        	const t_fvec2 c = frect_center(sprite.rect); | ||||
| 	        	const t_fvec2 d = { | ||||
| 	        		.x = (cosf(sprite.rotation + (float)M_PI_4) * sprite.rect.w) * (float)M_SQRT1_2, | ||||
| 	        		.y = (sinf(sprite.rotation + (float)M_PI_4) * sprite.rect.h) * (float)M_SQRT1_2, | ||||
| 	        	}; | ||||
|  | ||||
| 	            payload[i] = (struct sprite_primitive_payload) { | ||||
| 	                /* upper-left */ | ||||
| 	                .v0 = { | ||||
| 	                    c.x - d.x, | ||||
| 	                    c.y - d.y }, | ||||
| 	                .uv0 = { | ||||
| 	                    xr + wr * sprite.flip_x, | ||||
| 	                    yr + hr * sprite.flip_y, }, | ||||
|  | ||||
| 	                /* bottom-left */ | ||||
| 	                .v1 = { | ||||
| 	                    c.x - d.y, | ||||
| 	                    c.y + d.x }, | ||||
| 	                .uv1 = { | ||||
| 	                    xr + wr * sprite.flip_x, | ||||
| 	                    yr + hr * !sprite.flip_y, }, | ||||
|  | ||||
| 	                /* bottom-right */ | ||||
| 	                .v2 = { | ||||
| 	                    c.x + d.x, | ||||
| 	                    c.y + d.y }, | ||||
| 	                .uv2 = { | ||||
| 	                    xr + wr * !sprite.flip_x, | ||||
| 	                    yr + hr * !sprite.flip_y, }, | ||||
|  | ||||
| 	                /* upper-right */ | ||||
| 	                .v3 = { | ||||
| 	                    c.x + d.y, | ||||
| 	                    c.y - d.x }, | ||||
| 	                .uv3 = { | ||||
| 	                    xr + wr * !sprite.flip_x, | ||||
| 	                    yr + hr * sprite.flip_y, }, | ||||
|  | ||||
| 	                /* equal for all (flat shaded) */ | ||||
| 	                .c0 = sprite.color, | ||||
| 	                .c1 = sprite.color, | ||||
| 	                .c2 = sprite.color, | ||||
| 	                .c3 = sprite.color, | ||||
| 	            }; | ||||
| 	        } | ||||
|         } | ||||
|  | ||||
|         glUnmapBuffer(GL_ARRAY_BUFFER); | ||||
|   | ||||
| @@ -186,6 +186,14 @@ t_frect to_frect(t_rect rect) { | ||||
| } | ||||
|  | ||||
|  | ||||
| t_fvec2 frect_center(t_frect rect) { | ||||
|     return (t_fvec2){ | ||||
|         .x = rect.x + rect.w / 2, | ||||
|         .y = rect.y + rect.h / 2, | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| t_fvec2 fvec2_from_vec2(t_vec2 vec) { | ||||
|     return (t_fvec2) { | ||||
|         .x = (float)vec.x, | ||||
|   | ||||
							
								
								
									
										47
									
								
								src/util.h
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								src/util.h
									
									
									
									
									
								
							| @@ -77,29 +77,6 @@ typedef struct color { | ||||
| } t_color; | ||||
|  | ||||
|  | ||||
| /* a rectangle with the origin at the upper left (integer) */ | ||||
| typedef struct rect { | ||||
|     int x, y; | ||||
|     int w, h; | ||||
| } t_rect; | ||||
|  | ||||
|  | ||||
| bool intersect_rect(const t_rect *a, const t_rect *b, t_rect *result); | ||||
|  | ||||
|  | ||||
| /* a rectangle with the origin at the upper left (floating point) */ | ||||
| typedef struct frect { | ||||
|     float x, y; | ||||
|     float w, h; | ||||
| } t_frect; | ||||
|  | ||||
|  | ||||
| bool intersect_frect(const t_frect *a, const t_frect *b, t_frect *result); | ||||
|  | ||||
| /* TODO: generics and specials (see m_to_fvec2() for an example)*/ | ||||
| t_frect to_frect(t_rect rect); | ||||
|  | ||||
|  | ||||
| /* a point in some space (integer) */ | ||||
| typedef struct vec2 { | ||||
|     int x, y; | ||||
| @@ -125,6 +102,30 @@ typedef struct shvec2 { | ||||
| } t_shvec2; | ||||
|  | ||||
|  | ||||
| /* a rectangle with the origin at the upper left (integer) */ | ||||
| typedef struct rect { | ||||
|     int x, y; | ||||
|     int w, h; | ||||
| } t_rect; | ||||
|  | ||||
|  | ||||
| /* a rectangle with the origin at the upper left (floating point) */ | ||||
| typedef struct frect { | ||||
|     float x, y; | ||||
|     float w, h; | ||||
| } t_frect; | ||||
|  | ||||
|  | ||||
| bool intersect_rect(const t_rect *a, const t_rect *b, t_rect *result); | ||||
|  | ||||
| bool intersect_frect(const t_frect *a, const t_frect *b, t_frect *result); | ||||
|  | ||||
| /* TODO: generics and specials (see m_to_fvec2() for an example)*/ | ||||
| t_frect to_frect(t_rect rect); | ||||
|  | ||||
| t_fvec2 frect_center(t_frect rect); | ||||
|  | ||||
|  | ||||
| /* aren't macros to prevent double evaluation with side effects */ | ||||
| /* maybe could be inlined? i hope LTO will resolve this */ | ||||
| t_fvec2 fvec2_from_vec2(t_vec2 vec); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user