diff --git a/src/game/scenes/ingame.c b/src/game/scenes/ingame.c index 1296ab7..666b027 100644 --- a/src/game/scenes/ingame.c +++ b/src/game/scenes/ingame.c @@ -11,10 +11,11 @@ static void ingame_tick(struct state *state) { world_drawdef(scn->world); player_calc(scn->player); - 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}, - .blend = true }); + for (size_t i = 100000; --i;) + 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}, + .blend = false }); push_sprite_ex((t_frect){ .x = 48, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){ .path = "/assets/light.png", diff --git a/src/rendering/sprites.h b/src/rendering/sprites.h index 1ea3c98..72ef96d 100644 --- a/src/rendering/sprites.h +++ b/src/rendering/sprites.h @@ -101,17 +101,20 @@ void push_sprite_ex(t_frect rect, t_push_sprite_args args) { static struct sprite_batch { int atlas_id; - size_t size; /* how many primitives are in current batch */ - bool blend; /* whether it's blended or not */ - bool colored; /* whether color inmformation is needed to be passed */ + size_t size; /* how many primitives are in current batch */ + bool blend; /* whether it's blended or not */ + bool constant_colored; /* whether colored batch is uniformly colored */ } collect_sprite_batch(const struct primitive_2d *primitives, size_t len) { /* assumes that first primitive is already a sprite */ - struct sprite_batch result = { + struct sprite_batch batch = { .atlas_id = textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key), .blend = primitives[0].sprite.blend, + .constant_colored = true, }; + const t_color uniform_color = primitives[0].sprite.color; + /* batch size is clamped so that reallocated short indices could be used */ if (len >= QUAD_ELEMENT_BUFFER_LENGTH) len = QUAD_ELEMENT_BUFFER_LENGTH; @@ -124,25 +127,25 @@ static struct sprite_batch { break; /* only collect the same blend modes */ - if (current->sprite.blend != result.blend) + if (current->sprite.blend != batch.blend) break; /* only collect the same texture atlases */ if (textures_get_atlas_id(&ctx.texture_cache, current->sprite.texture_key) - != result.atlas_id) + != batch.atlas_id) break; - /* if all are effectively without modulation we can skip sending color data */ - if (!result.colored && (current->sprite.color.r != 255 || - current->sprite.color.g != 255 || - current->sprite.color.b != 255 || - current->sprite.color.a != 255 )) - result.colored = true; + /* if all are modulated the same we can skip sending the color data */ + if (batch.constant_colored && (current->sprite.color.r != uniform_color.r || + current->sprite.color.g != uniform_color.g || + current->sprite.color.b != uniform_color.b || + current->sprite.color.a != uniform_color.a )) + batch.constant_colored = false; - ++result.size; + ++batch.size; } - return result; + return batch; } @@ -165,7 +168,7 @@ static void render_sprites(const struct primitive_2d primitives[], } size_t payload_size; - if (batch.colored) + if (!batch.constant_colored) payload_size = sizeof (struct sprite_primitive_payload); else payload_size = sizeof (struct sprite_primitive_payload_without_color); @@ -233,7 +236,7 @@ static void render_sprites(const struct primitive_2d primitives[], CRY("Rotation", "Unimplemented"); } - if (batch.colored) + if (!batch.constant_colored) ((struct sprite_primitive_payload *)payload)[i] = (struct sprite_primitive_payload) { .v0 = v0, .v1 = v1, @@ -272,7 +275,7 @@ static void render_sprites(const struct primitive_2d primitives[], GLsizei voff; GLsizei uvoff; - if (batch.colored) { + if (!batch.constant_colored) { off = offsetof(struct sprite_primitive_payload, v1); voff = offsetof(struct sprite_primitive_payload, v0); uvoff = offsetof(struct sprite_primitive_payload, uv0); @@ -296,14 +299,17 @@ static void render_sprites(const struct primitive_2d primitives[], off, (void *)(size_t)uvoff); - if (batch.colored) { + if (!batch.constant_colored) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, off, (void *)offsetof(struct sprite_primitive_payload, c0)); } else - glColor4ub(255, 255, 255, 255); + glColor4ub(primitives[0].sprite.color.r, + primitives[0].sprite.color.g, + primitives[0].sprite.color.b, + primitives[0].sprite.color.a); textures_bind(&ctx.texture_cache, primitives->sprite.texture_key, GL_TEXTURE_2D);