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);
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",

View File

@ -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);