diff --git a/apps/testgame/player.c b/apps/testgame/player.c index d25302a..d6fde3b 100644 --- a/apps/testgame/player.c +++ b/apps/testgame/player.c @@ -243,13 +243,13 @@ struct player *player_create(struct world *world) { static void drawdef(struct player *player) { - push_sprite("/assets/player/baron-walk.png", - (t_frect) { - .x = player->rect.x + ((player->rect.w - player->sprite_w) / 2), - .y = player->rect.y - 8, - .w = player->sprite_w, - .h = player->sprite_h, - }); + m_sprite("/assets/player/baron-walk.png", + (t_frect) { + .x = player->rect.x + ((player->rect.w - player->sprite_w) / 2), + .y = player->rect.y - 8, + .w = player->sprite_w, + .h = player->sprite_h, + }); push_circle((t_fvec2) { 256, 128 }, 24, diff --git a/apps/testgame/scenes/ingame.c b/apps/testgame/scenes/ingame.c index 149b276..926d2fe 100644 --- a/apps/testgame/scenes/ingame.c +++ b/apps/testgame/scenes/ingame.c @@ -20,38 +20,27 @@ static void ingame_tick(struct state *state) { if (input_is_action_pressed(&ctx.input, "player_jump")) cam.pos.z -= 0.01f; - push_camera(&cam); + m_sprite(m_set(path, "/assets/light.png"), + m_set(rect, ((t_frect){ 48, 64, 64, 64 })), + m_opt(color, ((t_color){ 255, 0, 0, 255 }))); - push_sprite_ex((t_frect){ .x = 32, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){ - .path = "/assets/light.png", - .color = (t_color){255, 0, 0, 255}, }); + m_sprite(m_set(path, "/assets/light.png"), + m_set(rect, ((t_frect){ 64, 64, 64, 64 })), + m_opt(color, ((t_color){ 0, 255, 0, 255 }))); - push_sprite_ex((t_frect){ .x = 48, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){ - .path = "/assets/light.png", - .color = (t_color){0, 255, 0, 255}, }); + m_sprite(m_set(path, "/assets/light.png"), + m_set(rect, ((t_frect){ 80, 64, 64, 64 })), + m_opt(color, ((t_color){ 0, 0, 255, 255 }))); - push_sprite_ex((t_frect){ .x = 64, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){ - .path = "/assets/light.png", - .color = (t_color){0, 0, 255, 255}, }); + m_sprite(m_set(path, "/assets/player/baron-walk.png"), + m_set(rect, ((t_frect){ 32, 32, 64, 64 })), + m_opt(rotation, (float)M_PI * 2 * (float)(ctx.tick_count % 64) / 64 )); - 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, }); + m_sprite(m_set(path, "/assets/player/baron-walk.png"), + m_set(rect, ((t_frect){ 128, 32, 128, 64 })), + m_opt(rotation, (float)M_PI * 2 * (float)(ctx.tick_count % 64) / 64 )); - 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, }); - - 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}, }); - - push_sprite_ex((t_frect){ .x = 128, .y = 32, .w = 128, .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, }); + set_camera(&cam); unfurl_triangle("/assets/big-violet.png", (t_fvec3){ -1, -1, 0 }, diff --git a/apps/testgame/scenes/title.c b/apps/testgame/scenes/title.c index 268f29b..4571579 100644 --- a/apps/testgame/scenes/title.c +++ b/apps/testgame/scenes/title.c @@ -14,9 +14,8 @@ static void title_tick(struct state *state) { } - push_sprite("/assets/title.png", (t_frect) { - (RENDER_BASE_WIDTH / 2) - (320 / 2), 64, 320, 128 - }); + m_sprite("/assets/title.png", ((t_frect) { + (RENDER_BASE_WIDTH / 2) - (320 / 2), 64, 320, 128 })); } diff --git a/apps/testgame/world.c b/apps/testgame/world.c index 61ea2d1..3b2ea8c 100644 --- a/apps/testgame/world.c +++ b/apps/testgame/world.c @@ -105,7 +105,7 @@ void world_drawdef(struct world *world) { if (world->tiles[i].type == TILE_TYPE_VOID) continue; - push_sprite("/assets/white.png", to_frect(world->tiles[i].rect)); + m_sprite("/assets/white.png", to_frect(world->tiles[i].rect)); } drawdef_debug(world); diff --git a/src/rendering.h b/src/rendering.h index 059aaa5..48221b6 100644 --- a/src/rendering.h +++ b/src/rendering.h @@ -2,6 +2,7 @@ #define RENDERING_H #include "util.h" +#include "macros/option.h" #include "camera.h" #include @@ -10,10 +11,13 @@ typedef struct push_sprite_args { char *path; - t_color color; - float rotation; - bool flip_x; - bool flip_y; + t_frect rect; + + m_option_list( + t_color, color, + float, rotation, + bool, flip_x, + bool, flip_y ) } t_push_sprite_args; /* clears all render queues */ @@ -21,12 +25,9 @@ void render_queue_clear(void); /* pushes a sprite onto the sprite render queue */ /* this is a simplified version of push_sprite_ex for the most common case. */ -/* it assumes you want no color modulation, no rotation, no flip, layer 0, and alpha blending */ -void push_sprite(char *path, t_frect rect); - -/* pushes a sprite onto the sprite render queue */ -/* note that if args is zeroed out, the color will be transparent black */ -void push_sprite_ex(t_frect rect, t_push_sprite_args args); +/* it assumes you want no color modulation, no rotation, no flip */ +void push_sprite(t_push_sprite_args args); +#define m_sprite(...) (push_sprite((t_push_sprite_args){__VA_ARGS__})) /* pushes a filled rectangle onto the rectangle render queue */ void push_rectangle(t_frect rect, t_color color); @@ -65,7 +66,7 @@ void unfurl_triangle(const char *path, // t_frect uvs); /* pushes a camera state to be used for all future unfurl_* commands */ -void push_camera(const t_camera *camera); +void set_camera(const t_camera *camera); /* renders the background, then the primitives in all render queues */ void render(void); diff --git a/src/rendering/sprites.h b/src/rendering/sprites.h index 44ca2a3..35de913 100644 --- a/src/rendering/sprites.h +++ b/src/rendering/sprites.h @@ -61,33 +61,14 @@ struct sprite_primitive_payload_without_color { */ /* TODO: it might make sense to infer alpha channel presence / meaningfulness for textures in atlas */ /* so that they are rendered with no blend / batched in a way to reduce overdraw automatically */ -void push_sprite(char *path, t_frect rect) { +void push_sprite(const t_push_sprite_args args) { struct sprite_primitive sprite = { - .rect = rect, - .color = (t_color) { 255, 255, 255, 255 }, - .rotation = 0.0, - .texture_key = textures_get_key(&ctx.texture_cache, path), - .flip_x = false, - .flip_y = false, - }; - - struct primitive_2d primitive = { - .type = PRIMITIVE_2D_SPRITE, - .sprite = sprite, - }; - - arrput(ctx.render_queue_2d, primitive); -} - - -void push_sprite_ex(t_frect rect, t_push_sprite_args args) { - struct sprite_primitive sprite = { - .rect = rect, - .color = args.color, - .rotation = args.rotation, + .rect = args.rect, + .color = m_or(args, color, ((t_color) { 255, 255, 255, 255 })), + .rotation = m_or(args, rotation, 0.0f), .texture_key = textures_get_key(&ctx.texture_cache, args.path), - .flip_x = args.flip_x, - .flip_y = args.flip_y, + .flip_x = m_or(args, flip_x, false), + .flip_y = m_or(args, flip_y, false), }; struct primitive_2d primitive = {