Commit: 00951ccc0c8bc64084152eec08e0d52cdeed9197
Parent: dcf90db4c39ad0b3164b50b46dff5a44db85576a
Author: Randy Palamar
Date: Tue, 22 Oct 2024 20:11:57 -0600
combine default 1x1 texture with glyph cache texture
This way we can batch rectangle drawing and glyph bitmap drawing
for overlay fonts.
Diffstat:
4 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/font.c b/font.c
@@ -221,6 +221,8 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, enum face_style style, CachedGlyph
cg->gpu_tile_index = (tile_coord.y << 16) | (tile_coord.x & 0xFFFF);
}
+ /* NOTE: tile index 0,0 is reserved */
+ ASSERT(cg->gpu_tile_index);
ASSERT(tile_index);
for (u32 i = 0; i < cg->tile_count; i++)
@@ -258,6 +260,9 @@ font_atlas_update(FontAtlas *fa, iv2 glyph_bitmap_dim)
mem_clear(gc->occupied_tiles, 0, sizeof(*gc->occupied_tiles) * gc->cache_len);
get_and_clear_glyph_cache_stats(gc);
+ /* NOTE: reserve tile 0,0 */
+ gc->occupied_tiles[0] = 1;
+
Font *font = &fa->fonts[0][FS_BOLD];
if (!font) font = &fa->fonts[0][FS_NORMAL];
i32 x0, x1, y0, y1;
diff --git a/main.c b/main.c
@@ -177,10 +177,12 @@ init_window(Term *t, Arena arena, iv2 window_size)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * ARRAY_COUNT(rpb->positions) * sizeof(i32),
element_indices, GL_STATIC_DRAW);
- u32 white = 0xFFFFFFFF;
- t->gl.default_tex = gen_2D_texture((iv2){.x = 1, .y = 1}, GL_RGBA, GL_NEAREST, &white);
t->gl.glyph_bitmap_tex = gen_2D_texture(t->gl.glyph_bitmap_dim, GL_RGBA, GL_NEAREST, 0);
+ /* NOTE: set pixel 0,0 to white (tile 0,0 is reserved). We can use this texture for
+ * drawing glyphs from the font cache or for drawing plain rectangles */
+ u32 white = 0xFFFFFFFF;
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &white);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
diff --git a/util.h b/util.h
@@ -242,8 +242,6 @@ typedef struct {
u32 fb, fb_tex, fb_tex_unit;
- u32 default_tex;
-
u32 programs[SHADER_LAST];
#define X(name) i32 name;
struct { GL_POST_UNIFORMS } post;
diff --git a/vtgl.c b/vtgl.c
@@ -200,7 +200,7 @@ get_render_push_buffer_idx(RenderPushBuffer *rpb, GLCtx *gl, u32 count)
}
static void
-push_rect(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, b32 flip_texture)
+push_rect_full(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, v2 min_tex_coord, v2 max_tex_coord)
{
u32 idx = get_render_push_buffer_idx(rpb, gl, 4);
v2 start = r.pos;
@@ -211,23 +211,38 @@ push_rect(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, b32 flip_texture)
rpb->positions[idx + 2] = (v2){.x = start.x, .y = start.y};
rpb->positions[idx + 3] = (v2){.x = start.x, .y = end.y };
- /* TODO: cleanup */
- if (!flip_texture) {
- rpb->texture_coordinates[idx + 0] = (v2){.x = 1.0f, .y = 1.0f};
- rpb->texture_coordinates[idx + 1] = (v2){.x = 1.0f, .y = 0.0f};
- rpb->texture_coordinates[idx + 2] = (v2){.x = 0.0f, .y = 0.0f};
- rpb->texture_coordinates[idx + 3] = (v2){.x = 0.0f, .y = 1.0f};
- } else {
- rpb->texture_coordinates[idx + 0] = (v2){.x = 1.0f, .y = 0.0f};
- rpb->texture_coordinates[idx + 1] = (v2){.x = 1.0f, .y = 1.0f};
- rpb->texture_coordinates[idx + 2] = (v2){.x = 0.0f, .y = 1.0f};
- rpb->texture_coordinates[idx + 3] = (v2){.x = 0.0f, .y = 0.0f};
- }
+ rpb->texture_coordinates[idx + 0] = (v2){.x = max_tex_coord.x, .y = max_tex_coord.y};
+ rpb->texture_coordinates[idx + 1] = (v2){.x = max_tex_coord.x, .y = min_tex_coord.y};
+ rpb->texture_coordinates[idx + 2] = (v2){.x = min_tex_coord.x, .y = min_tex_coord.y};
+ rpb->texture_coordinates[idx + 3] = (v2){.x = min_tex_coord.x, .y = max_tex_coord.y};
rpb->colours[idx + 0] = colour;
rpb->colours[idx + 1] = colour;
rpb->colours[idx + 2] = colour;
rpb->colours[idx + 3] = colour;
+
+}
+
+static void
+push_rect_textured(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, b32 flip_texture)
+{
+ v2 min_tex_coord, max_tex_coord;
+ if (!flip_texture) {
+ max_tex_coord = (v2){.x = 1.0f, .y = 1.0f};
+ min_tex_coord = (v2){.x = 0.0f, .y = 0.0f};
+ } else {
+ max_tex_coord = (v2){.x = 1.0f, .y = 0.0f};
+ min_tex_coord = (v2){.x = 0.0f, .y = 1.0f};
+ }
+ push_rect_full(rpb, gl, r, colour, min_tex_coord, max_tex_coord);
+}
+
+static void
+push_rect(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour)
+{
+ f32 max_x = 1.0f / gl->glyph_bitmap_dim.x;
+ f32 max_y = 1.0f / gl->glyph_bitmap_dim.y;
+ push_rect_full(rpb, gl, r, colour, (v2){0}, (v2){.x = max_x, .y = max_y});
}
#if 0
@@ -835,7 +850,7 @@ do_terminal(Term *t, f32 dt)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, t->gl.render_shader_ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*sp), sp);
- push_rect(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 0);
+ push_rect_textured(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 0);
flush_render_push_buffer(rpb, &t->gl);
static f32 param = 0;
@@ -851,16 +866,15 @@ do_terminal(Term *t, f32 dt)
glUniform1i(t->gl.post.texslot, t->gl.fb_tex_unit);
glUniform1f(t->gl.post.param, param);
- push_rect(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
+ push_rect_textured(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
flush_render_push_buffer(rpb, &t->gl);
#if 0
/* NOTE: this happens at the end so that ui stuff doesn't go through the post
* processing/effects shader */
glUseProgram(t->gl.programs[SHADER_RECTS]);
- glBindTexture(GL_TEXTURE_2D, t->gl.default_tex);
- push_rect(rpb, &t->gl, (Rect){.size = {.w = 300, .h = 200}}, (v4){.r = 0.5, .a = 1}, 0);
- push_rect(rpb, &t->gl, (Rect){.pos = {.x = 300, .y = 200}, .size = {.w = 300, .h = 200}}, (v4){.g = 0.5, .a = 1}, 0);
+ push_rect(rpb, &t->gl, (Rect){.size = {.w = 300, .h = 200}}, (v4){.r = 0.5, .a = 1});
+ push_rect(rpb, &t->gl, (Rect){.pos = {.x = 300, .y = 200}, .size = {.w = 300, .h = 200}}, (v4){.g = 0.5, .a = 1});
flush_render_push_buffer(rpb, &t->gl);
#endif
}