rendering.c: sprite constant color that isn't just white only

This commit is contained in:
veclav talica 2024-07-28 16:25:25 +03:00
parent 20e33fe30d
commit b9188d8d8a
2 changed files with 30 additions and 23 deletions

View File

@ -11,10 +11,11 @@ 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 = 64, .w = 64, .h = 64 }, (t_push_sprite_args){ for (size_t i = 100000; --i;)
.path = "/assets/light.png", push_sprite_ex((t_frect){ .x = 32, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){
.color = (t_color){255, 0, 0, 255}, .path = "/assets/light.png",
.blend = true }); .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){ push_sprite_ex((t_frect){ .x = 48, .y = 64, .w = 64, .h = 64 }, (t_push_sprite_args){
.path = "/assets/light.png", .path = "/assets/light.png",

View File

@ -101,17 +101,20 @@ void push_sprite_ex(t_frect rect, t_push_sprite_args args) {
static struct sprite_batch { static struct sprite_batch {
int atlas_id; int atlas_id;
size_t size; /* how many primitives are in current batch */ size_t size; /* how many primitives are in current batch */
bool blend; /* whether it's blended or not */ bool blend; /* whether it's blended or not */
bool colored; /* whether color inmformation is needed to be passed */ bool constant_colored; /* whether colored batch is uniformly colored */
} collect_sprite_batch(const struct primitive_2d *primitives, size_t len) { } collect_sprite_batch(const struct primitive_2d *primitives, size_t len) {
/* assumes that first primitive is already a sprite */ /* assumes that first primitive is already a sprite */
struct sprite_batch result = { struct sprite_batch batch = {
.atlas_id = .atlas_id =
textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key), textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key),
.blend = primitives[0].sprite.blend, .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 */ /* batch size is clamped so that reallocated short indices could be used */
if (len >= QUAD_ELEMENT_BUFFER_LENGTH) if (len >= QUAD_ELEMENT_BUFFER_LENGTH)
len = QUAD_ELEMENT_BUFFER_LENGTH; len = QUAD_ELEMENT_BUFFER_LENGTH;
@ -124,25 +127,25 @@ static struct sprite_batch {
break; break;
/* only collect the same blend modes */ /* only collect the same blend modes */
if (current->sprite.blend != result.blend) if (current->sprite.blend != batch.blend)
break; break;
/* only collect the same texture atlases */ /* only collect the same texture atlases */
if (textures_get_atlas_id(&ctx.texture_cache, current->sprite.texture_key) if (textures_get_atlas_id(&ctx.texture_cache, current->sprite.texture_key)
!= result.atlas_id) != batch.atlas_id)
break; break;
/* if all are effectively without modulation we can skip sending color data */ /* if all are modulated the same we can skip sending the color data */
if (!result.colored && (current->sprite.color.r != 255 || if (batch.constant_colored && (current->sprite.color.r != uniform_color.r ||
current->sprite.color.g != 255 || current->sprite.color.g != uniform_color.g ||
current->sprite.color.b != 255 || current->sprite.color.b != uniform_color.b ||
current->sprite.color.a != 255 )) current->sprite.color.a != uniform_color.a ))
result.colored = true; 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; size_t payload_size;
if (batch.colored) if (!batch.constant_colored)
payload_size = sizeof (struct sprite_primitive_payload); payload_size = sizeof (struct sprite_primitive_payload);
else else
payload_size = sizeof (struct sprite_primitive_payload_without_color); 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"); CRY("Rotation", "Unimplemented");
} }
if (batch.colored) if (!batch.constant_colored)
((struct sprite_primitive_payload *)payload)[i] = (struct sprite_primitive_payload) { ((struct sprite_primitive_payload *)payload)[i] = (struct sprite_primitive_payload) {
.v0 = v0, .v0 = v0,
.v1 = v1, .v1 = v1,
@ -272,7 +275,7 @@ static void render_sprites(const struct primitive_2d primitives[],
GLsizei voff; GLsizei voff;
GLsizei uvoff; GLsizei uvoff;
if (batch.colored) { if (!batch.constant_colored) {
off = offsetof(struct sprite_primitive_payload, v1); off = offsetof(struct sprite_primitive_payload, v1);
voff = offsetof(struct sprite_primitive_payload, v0); voff = offsetof(struct sprite_primitive_payload, v0);
uvoff = offsetof(struct sprite_primitive_payload, uv0); uvoff = offsetof(struct sprite_primitive_payload, uv0);
@ -296,14 +299,17 @@ static void render_sprites(const struct primitive_2d primitives[],
off, off,
(void *)(size_t)uvoff); (void *)(size_t)uvoff);
if (batch.colored) { if (!batch.constant_colored) {
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, glColorPointer(4,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
off, off,
(void *)offsetof(struct sprite_primitive_payload, c0)); (void *)offsetof(struct sprite_primitive_payload, c0));
} else } 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); textures_bind(&ctx.texture_cache, primitives->sprite.texture_key, GL_TEXTURE_2D);