rendering: use sprite batching techniques for rect primitives, unite their render path

This commit is contained in:
2024-10-14 11:46:07 +03:00
parent 82bad550e5
commit b295c5920c
10 changed files with 308 additions and 116 deletions

View File

@ -60,15 +60,18 @@ void draw_sprite_args(const DrawSpriteArgs args) {
}
struct SpriteBatch collect_sprite_batch(const Primitive2D primitives[], size_t len) {
/* assumes that first primitive is already a sprite */
struct QuadBatch collect_sprite_batch(const Primitive2D primitives[], size_t len) {
SDL_assert(primitives[0].type == PRIMITIVE_2D_SPRITE);
SDL_assert(primitives && len != 0);
const uint16_t texture_key_id = primitives[0].sprite.texture_key.id;
const int atlas_id = textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key);
struct SpriteBatch batch = {
struct QuadBatch batch = {
.mode = textures_get_mode(&ctx.texture_cache, primitives[0].sprite.texture_key),
.constant_colored = true,
.repeat = primitives[0].sprite.repeat,
.textured = true,
};
const uint32_t uniform_color = *(const uint32_t *)&primitives[0].sprite.color;
@ -116,9 +119,12 @@ struct SpriteBatch collect_sprite_batch(const Primitive2D primitives[], size_t l
/* assumes that orthogonal matrix setup is done already */
void render_sprites(const Primitive2D primitives[],
const struct SpriteBatch batch)
void render_sprite_batch(const Primitive2D primitives[],
const struct QuadBatch batch)
{
SDL_assert(primitives && batch.size != 0);
SDL_assert(primitives[0].type == PRIMITIVE_2D_SPRITE);
/* single vertex array is used for every batch with NULL glBufferData() trick at the end */
static VertexBuffer vertex_array = 0;
if (vertex_array == 0)
@ -131,10 +137,10 @@ void render_sprites(const Primitive2D primitives[],
/* vertex population over a vertex buffer builder interface */
{
VertexBufferBuilder payload = build_vertex_buffer(vertex_array, get_sprite_payload_size(batch) * batch.size);
VertexBufferBuilder payload = build_vertex_buffer(vertex_array, get_quad_payload_size(batch) * batch.size);
for (size_t i = 0; i < batch.size; ++i) {
/* render opaques front to back */
/* render opaques front to back, to gain benefit of an early z rejection */
const size_t cur = batch.mode == TEXTURE_MODE_GHOSTLY ? i : batch.size - i - 1;
const SpritePrimitive sprite = primitives[cur].sprite;
@ -233,9 +239,9 @@ void render_sprites(const Primitive2D primitives[],
v3 = (Vec2){ c.x + t.x * +h.x - t.y * -h.y, c.y + t.y * +h.x + t.x * -h.y };
}
push_sprite_payload_to_vertex_buffer_builder(batch, &payload, v0, v1, v2, v3, uv0, uv1, uv2, uv3, sprite.color);
push_quad_payload_to_vertex_buffer_builder(batch, &payload, v0, v1, v2, v3, uv0, uv1, uv2, uv3, sprite.color);
}
}
finally_render_sprites(primitives, batch, vertex_array);
finally_render_quads(primitives, batch, vertex_array);
}