rendering.c: sprite rotation
This commit is contained in:
parent
687e42ddfd
commit
79bc261ccd
@ -11,6 +11,23 @@ static void ingame_tick(struct state *state) {
|
|||||||
world_drawdef(scn->world);
|
world_drawdef(scn->world);
|
||||||
player_calc(scn->player);
|
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",
|
unfurl_triangle("/assets/big-violet.png",
|
||||||
(t_fvec3){ -1, -1, 0 },
|
(t_fvec3){ -1, -1, 0 },
|
||||||
(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);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_ALWAYS);
|
glDepthFunc(GL_ALWAYS);
|
||||||
|
glDepthRange((double)batch_count / UINT16_MAX, 1.0);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
render_sprites(current, batch.size, false);
|
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 xr = (float)srcrect.x / (float)dims.w;
|
||||||
const float yr = (float)srcrect.y / (float)dims.h;
|
const float yr = (float)srcrect.y / (float)dims.h;
|
||||||
|
|
||||||
|
/* non-rotated case */
|
||||||
|
if (sprite.rotation == 0.0f) {
|
||||||
payload[i] = (struct sprite_primitive_payload) {
|
payload[i] = (struct sprite_primitive_payload) {
|
||||||
/* upper-left */
|
/* upper-left */
|
||||||
.v0 = {
|
.v0 = {
|
||||||
@ -174,6 +176,54 @@ static void render_sprites(const struct primitive_2d primitives[],
|
|||||||
.c2 = sprite.color,
|
.c2 = sprite.color,
|
||||||
.c3 = 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);
|
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) {
|
t_fvec2 fvec2_from_vec2(t_vec2 vec) {
|
||||||
return (t_fvec2) {
|
return (t_fvec2) {
|
||||||
.x = (float)vec.x,
|
.x = (float)vec.x,
|
||||||
|
47
src/util.h
47
src/util.h
@ -77,29 +77,6 @@ typedef struct color {
|
|||||||
} t_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) */
|
/* a point in some space (integer) */
|
||||||
typedef struct vec2 {
|
typedef struct vec2 {
|
||||||
int x, y;
|
int x, y;
|
||||||
@ -125,6 +102,30 @@ typedef struct shvec2 {
|
|||||||
} t_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 */
|
/* aren't macros to prevent double evaluation with side effects */
|
||||||
/* maybe could be inlined? i hope LTO will resolve this */
|
/* maybe could be inlined? i hope LTO will resolve this */
|
||||||
t_fvec2 fvec2_from_vec2(t_vec2 vec);
|
t_fvec2 fvec2_from_vec2(t_vec2 vec);
|
||||||
|
Loading…
Reference in New Issue
Block a user