automatic detenction of texture mode and batching based on it

This commit is contained in:
2024-07-28 23:59:23 +03:00
parent 945b1d21fe
commit 3edd692771
9 changed files with 89 additions and 30 deletions

View File

@ -68,7 +68,6 @@ void push_sprite(char *path, t_frect rect) {
.texture_key = textures_get_key(&ctx.texture_cache, path),
.flip_x = false,
.flip_y = false,
.blend = true,
};
struct primitive_2d primitive = {
@ -88,7 +87,6 @@ void push_sprite_ex(t_frect rect, t_push_sprite_args args) {
.texture_key = textures_get_key(&ctx.texture_cache, args.path),
.flip_x = args.flip_x,
.flip_y = args.flip_y,
.blend = args.blend,
};
struct primitive_2d primitive = {
@ -101,16 +99,16 @@ 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 */
int atlas_id;
enum texture_mode mode;
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 batch = {
.atlas_id =
textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key),
.blend = primitives[0].sprite.blend,
.mode = textures_get_mode(&ctx.texture_cache, primitives[0].sprite.texture_key),
.constant_colored = true,
};
@ -128,7 +126,8 @@ static struct sprite_batch {
break;
/* only collect the same blend modes */
if (current->sprite.blend != batch.blend)
const enum texture_mode mode = textures_get_mode(&ctx.texture_cache, current->sprite.texture_key);
if (mode != batch.mode)
break;
/* only collect the same texture atlases */
@ -156,13 +155,23 @@ static void render_sprites(const struct primitive_2d primitives[],
if (vertex_array == 0)
glGenBuffers(1, &vertex_array);
if (batch.blend) {
if (batch.mode == TEXTURE_MODE_GHOSTLY) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
} else if (batch.mode == TEXTURE_MODE_SEETHROUGH) {
glDisable(GL_BLEND);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_EQUAL, 1.0f);
} else {
glDisable(GL_BLEND);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
size_t payload_size;
@ -186,7 +195,8 @@ static void render_sprites(const struct primitive_2d primitives[],
void *const payload = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
for (size_t i = 0; i < batch.size; ++i) {
const size_t cur = !batch.blend ? batch.size - i - 1: i; /* render opaques front to back */
/* render opaques front to back */
const size_t cur = batch.mode == TEXTURE_MODE_GHOSTLY ? i : batch.size - i - 1;
const struct sprite_primitive sprite = primitives[cur].sprite;
const t_rect srcrect =