Commit: 841511e052f412d9738758c36f15d59b4973e431
Parent: 00951ccc0c8bc64084152eec08e0d52cdeed9197
Author: Randy Palamar
Date: Wed, 23 Oct 2024 06:29:37 -0600
re-add arbitrary text drawing
now everything goes through the font cache and callers can request
a specific font_id to try and match on. There could be a couple
issues with this but I plan on rasterizing glyphs directly on the
GPU soon so I will probably not worry about fixing them for now.
Also the font code now works fine with proportional fonts as well
(besides kerning which will be handled later).
Diffstat:
M | config.def.h | | | 16 | +++++++++++++--- |
M | debug.c | | | 85 | +------------------------------------------------------------------------------ |
M | font.c | | | 64 | ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
M | terminal.c | | | 4 | +++- |
M | test.c | | | 10 | ++++++---- |
M | util.h | | | 18 | +++++++++--------- |
M | vtgl.c | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
7 files changed, 169 insertions(+), 181 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -6,11 +6,21 @@ static FontDesc g_fonts[][FS_LAST] = {
[FS_ITALIC] = {.path = "/usr/share/fonts/gofont/Go-Mono-Italic.ttf", .height = 24},
[FS_BOLD_ITALIC] = {.path = "/usr/share/fonts/gofont/Go-Mono-Bold-Italic.ttf", .height = 24},
},
+ {
+ [FS_NORMAL] = {.path = "/usr/share/fonts/dejavu/DejaVuSans.ttf", .height = 28},
+ },
+ {
+ [FS_NORMAL] = {.path = "/usr/share/fonts/dejavu/DejaVuSans.ttf", .height = 22},
+ },
+ {
+ [FS_NORMAL] = {.path = "/usr/share/fonts/liberation-fonts/LiberationMono-Regular.ttf", .height = 16},
+ },
};
-#ifdef _DEBUG
-static FontDesc g_debug_font_desc = {.path = "/usr/share/fonts/gofont/Go-Mono-Bold.ttf", .height = 18};
-#endif
+/* NOTE: indices into the array above */
+static u32 g_ui_small_font_id = 2;
+static u32 g_ui_large_font_id = 3;
+static u32 g_ui_debug_font_id = 4;
/* NOTE: terminal margin in pixels */
static v2 g_term_margin = {.w = 8, .h = 8};
diff --git a/debug.c b/debug.c
@@ -138,91 +138,8 @@ dump_glyph_cache_to_file(FontAtlas *fa)
fclose(f);
}
-#define MAX_DEBUG_FONT_SIZE 32.0
static void
debug_init(Term *t, Arena a)
{
- Font *f = &t->debug_font;
- init_font(f, &g_debug_font_desc);
-
- glGenTextures(1, &t->debug_glyph_texture);
- glActiveTexture(GL_TEXTURE0 + 1);
- glBindTexture(GL_TEXTURE_2D_ARRAY, t->debug_glyph_texture);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, MAX_DEBUG_FONT_SIZE, MAX_DEBUG_FONT_SIZE,
- ARRAY_COUNT(t->debug_glyphs), 0, GL_RED, GL_UNSIGNED_BYTE, 0);
-
- /* NOTE: calculate glyph sizes and upload rendered glyph to GPU */
- f32 scale = f->stbtt_scale;
- for (u32 i = ' '; i < 0x7F; i++) {
- Arena tmp = a;
- i32 x0, y0, x1, y1;
- i32 glyph_idx = stbtt_FindGlyphIndex(&f->font_info, i);
- stbtt_GetGlyphBitmapBoxSubpixel(&f->font_info, glyph_idx, scale, scale, 0, 0,
- &x0, &y0, &x1, &y1);
- Glyph *g = t->debug_glyphs + i - ' ';
- g->size.w = x1 - x0;
- g->size.h = y1 - y0;
- g->delta.x = x0;
- g->delta.y = -y1;
-
- u8 *render_buf = alloc(&tmp, u8, g->size.w * g->size.h);
- stbtt_MakeGlyphBitmapSubpixel(tmp, &f->font_info, render_buf, g->size.w, g->size.h,
- g->size.w, scale, scale, 0, 0, glyph_idx);
-
- u32 *rgba_bitmap = alloc(&tmp, u32, g->size.w * g->size.h);
- for (u32 i = 0; i < g->size.h; i++) {
- for (u32 j = 0; j < g->size.w; j++) {
- u32 pixel = (render_buf[i * g->size.w + j] << 24) | 0x00FFFFFF;
- rgba_bitmap[i * g->size.w + j] = pixel;
- }
- }
-
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i - ' ', g->size.w, g->size.h, 1,
- GL_RGBA, GL_UNSIGNED_BYTE, rgba_bitmap);
- }
-
- glActiveTexture(GL_TEXTURE0);
-
- i32 x0, x1, y0, y1;
- stbtt_GetFontBoundingBox(&t->debug_font.font_info, &x0, &y0, &x1, &y1);
- t->debug_glyphs[0].size.w = scale * (x1 - x0) + 0.5;
-}
-
-static void draw_rectangle(RenderPushBuffer *rpb, GLCtx *gl, Rect r, Colour colour);
-static void push_char(RenderPushBuffer *rpb, GLCtx *gl, v2 vertscale, v2 vertoff, v2 texscale,
- uv2 colours, i32 char_idx);
-
-static v2
-debug_measure_text(Term *t, Font *f, s8 text, b32 monospaced)
-{
- v2 result = {0};
- f32 single_space_width = t->debug_glyphs[0].size.w;
- for (size i = 0; i < text.len; i++) {
- Glyph g = t->debug_glyphs[text.data[i] - ' '];
- /* TODO: should we consider offset characters in y? */
- if (g.size.h > result.y)
- result.y = g.size.h;
- result.x += monospaced? single_space_width : g.size.w;
- }
- return result;
-}
-
-static void
-debug_draw_text(Term *t, RenderPushBuffer *rpb, s8 text, v2 position, Colour fg, Colour bg, b32 monospaced)
-{
- f32 single_space_width = t->debug_glyphs[0].size.w;
- for (size i = 0; i < text.len; i++) {
- i32 glyph_idx = text.data[i] - ' ';
- Glyph g = t->debug_glyphs[glyph_idx];
- v2 texscale = {.x = g.size.w / MAX_DEBUG_FONT_SIZE, .y = g.size.h / MAX_DEBUG_FONT_SIZE};
- v2 vertscale = {.x = g.size.w, .y = g.size.h};
- v2 vertoff = {.x = position.x + g.delta.x, .y = position.y + g.delta.y};
- push_char(rpb, &t->gl, vertscale, vertoff, texscale,
- (uv2){.x = fg.rgba & 0xFFFFFF00, .y = bg.rgba & 0xFFFFFF00}, glyph_idx);
- position.x += monospaced? single_space_width : g.size.w;
- }
+ /* NOTE: this used to be useful but for now its not */
}
diff --git a/font.c b/font.c
@@ -31,6 +31,22 @@ unpack_gpu_tile_coord(u32 gpu_index)
}
static void
+cached_glyph_to_uv(FontAtlas *fa, CachedGlyph *cg, v2 *start, v2 *end, v2 scale)
+{
+ v2 cs = {.w = fa->info.w, .h = fa->info.h};
+ uv2 tile_coord = unpack_gpu_tile_coord(cg->gpu_tile_index);
+
+ f32 min_x = tile_coord.x * cs.w + cg->x0;
+ f32 max_x = min_x + cg->width;
+ f32 min_y = tile_coord.y * cs.h + fa->info.h + cg->y0 - fa->info.baseline;
+ f32 max_y = min_y + cg->height;
+
+ *start = (v2){.x = min_x * scale.x, .y = max_y * scale.y};
+ *end = (v2){.x = max_x * scale.x, .y = min_y * scale.y};
+}
+
+
+static void
recycle_cache(GlyphCache *gc)
{
CachedGlyph *sentinel = gc->glyphs + 0;
@@ -135,15 +151,17 @@ get_and_clear_glyph_cache_stats(GlyphCache *gc)
}
static u32 *
-render_glyph(Arena *a, FontAtlas *fa, u32 cp, enum face_style style, CachedGlyph **out_glyph)
+render_glyph(Arena *a, FontAtlas *fa, u32 cp, u32 font_id, enum face_style style, CachedGlyph **out_glyph)
{
BEGIN_TIMED_BLOCK();
GlyphCache *gc = &fa->glyph_cache;
u32 *rgba_bitmap = NULL;
/* NOTE: first check if glyph is in the cache and valid */
- /* NOTE: 8 MSB are not used for UTF8 so we can use that to store the style of the glyph */
- u32 packed_cp = cp | ((u32)(style) << 24);
+ /* NOTE: 8 MSB are not used for UTF8 so we can use that to store some extra info:
+ * bits 25,26: the style of the glyph
+ * bits 26-31: requested font_id (limited to first 32 fonts */
+ u32 packed_cp = cp | ((u32)style << 24) | (font_id << 26);
u32 idx = get_glyph_entry_index(&fa->glyph_cache, packed_cp);
CachedGlyph *cg = fa->glyph_cache.glyphs + idx;
@@ -155,27 +173,45 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, enum face_style style, CachedGlyph
i32 glyph_idx = 0;
i32 font_idx = 0;
- for (u32 i = 0; i < fa->nfonts; i++) {
- u32 test_style = style;
- if (!fa->fonts[i][test_style].buf)
- test_style = FS_NORMAL;
- glyph_idx = stbtt_FindGlyphIndex(&fa->fonts[i][test_style].font_info, cp);
- if (!glyph_idx)
- glyph_idx = stbtt_FindGlyphIndex(&fa->fonts[i][FS_NORMAL].font_info, cp);
- if (glyph_idx) {
- font_idx = i;
- break;
+
+ /* NOTE: first try the requested font id */
+ if (font_id < fa->nfonts && fa->fonts[font_id][style].buf) {
+ glyph_idx = stbtt_FindGlyphIndex(&fa->fonts[font_id][style].font_info, cp);
+ if (glyph_idx)
+ font_idx = font_id;
+ }
+
+ if (!glyph_idx) {
+ for (u32 i = 0; i < fa->nfonts; i++) {
+ u32 test_style = style;
+ if (!fa->fonts[i][test_style].buf)
+ test_style = FS_NORMAL;
+ glyph_idx = stbtt_FindGlyphIndex(&fa->fonts[i][test_style].font_info, cp);
+ if (!glyph_idx)
+ glyph_idx = stbtt_FindGlyphIndex(&fa->fonts[i][FS_NORMAL].font_info, cp);
+ if (glyph_idx) {
+ font_idx = i;
+ break;
+ }
}
}
Font *f = &fa->fonts[font_idx][style];
f32 scale = f->stbtt_scale;
- i32 x0, y0, x1, y1;
+ i32 x0, y0, x1, y1, advance, left_bearing;
stbtt_GetGlyphBitmapBoxSubpixel(&f->font_info, glyph_idx, scale, scale, 0, 0,
&x0, &y0, &x1, &y1);
i32 height = y1 - y0;
i32 width = x1 - x0;
+
+ stbtt_GetGlyphHMetrics(&f->font_info, glyph_idx, &advance, &left_bearing);
+ cg->advance = scale * advance;
+ cg->height = height;
+ cg->width = width;
+ cg->x0 = x0;
+ cg->y0 = y0;
+
u8 *render_buf = alloc(a, u8, width * height);
stbtt_MakeGlyphBitmapSubpixel(*a, &f->font_info, render_buf, width, height,
width, scale, scale, 0, 0, glyph_idx);
diff --git a/terminal.c b/terminal.c
@@ -1229,7 +1229,9 @@ push_line(Term *t, Line *line, Arena a)
if (line->has_unicode) {
/* TODO: this is obviously complete crap but wcwidth from libc doesn't
* actually work so we must check from the rendered glyph */
- get_gpu_glyph_index(t->arena_for_frame, &t->gl, &t->fa, cp, FS_NORMAL, &width);
+ CachedGlyph *cg;
+ get_gpu_glyph_index(t->arena_for_frame, &t->gl, &t->fa, cp, 0, 0, &cg);
+ width = cg->tile_count;
} else {
width = 1;
}
diff --git a/test.c b/test.c
@@ -15,7 +15,7 @@
void glfwSetWindowTitle(GLFWwindow *w, const char *s) {}
const char *glfwGetWindowTitle(GLFWwindow *w) { return "test"; }
-static void get_gpu_glyph_index(Arena, void *, void *, u32, u32, u32 *);
+static void get_gpu_glyph_index(Arena, void *, void *, u32, u32, u32, CachedGlyph **);
static GlyphCacheStats get_and_clear_glyph_cache_stats(void *p) { return (GlyphCacheStats){0}; }
static void init_font(void *a, void *b) {}
static void push_char(RenderPushBuffer *r, GLCtx *g, v2 vs, v2 vo, v2 ts, uv2 co, i32 ci) {}
@@ -29,11 +29,13 @@ KEYBIND_FN(zoom) { return 0; }
#include "debug.c"
static void
-get_gpu_glyph_index(Arena a, void *b, void *c, u32 cp, u32 d, u32 *width)
+get_gpu_glyph_index(Arena a, void *b, void *c, u32 cp, u32 d, u32 e, CachedGlyph **cg)
{
/* TODO: this is wrong but will have to do for these tests */
- *width = wcwidth(cp);
- ASSERT(*width != -1);
+ static CachedGlyph scg;
+ scg.tile_count = wcwidth(cp);
+ *cg = &scg;
+ ASSERT((char)scg.tile_count != -1);
}
#define ESC(a) s8("\x1B"#a)
diff --git a/util.h b/util.h
@@ -336,10 +336,16 @@ typedef struct {
typedef struct {
u32 cp;
u32 next_with_same_hash;
+ u32 prev;
+ u32 next;
u32 gpu_tile_index;
- u16 prev, next;
- u16 uploaded_to_gpu;
- u16 tile_count;
+ u8 tile_count;
+ u8 uploaded_to_gpu;
+ u16 advance;
+ i16 height;
+ i16 width;
+ i16 x0;
+ i16 y0;
} CachedGlyph;
typedef union {
@@ -447,12 +453,6 @@ typedef struct {
u32 tabs[32];
char saved_title[1024];
-
- #ifdef _DEBUG
- Font debug_font;
- Glyph debug_glyphs[0x7F - 0x20];
- u32 debug_glyph_texture;
- #endif
} Term;
static f32 dt_for_frame;
diff --git a/vtgl.c b/vtgl.c
@@ -8,7 +8,7 @@
#include "font.c"
/* TODO this should be removed */
-static u32 get_gpu_glyph_index(Arena, GLCtx *, FontAtlas *, u32, enum face_style, u32 *);
+static u32 get_gpu_glyph_index(Arena, GLCtx *, FontAtlas *, u32, u32, enum face_style, CachedGlyph **);
#include "terminal.c"
@@ -20,7 +20,7 @@ static void draw_debug_overlay(Term *, RenderPushBuffer *);
#define REVERSE_VIDEO_MASK (Colour){.r = 0xff, .g = 0xff, .b = 0xff}.rgba
static v4
-normalized_colour(Colour c)
+normalize_colour(Colour c)
{
return (v4){.r = c.r / 255.0f, .g = c.g / 255.0f, .b = c.b / 255.0f, .a = c.a / 255.0f};
}
@@ -30,7 +30,7 @@ clear_colour(b32 reverse)
{
Colour c = g_colours.data[g_colours.bgidx];
if (reverse) c.rgba ^= REVERSE_VIDEO_MASK;
- v4 cc = normalized_colour(c);
+ v4 cc = normalize_colour(c);
glClearColor(cc.r, cc.g, cc.b, cc.a);
glClear(GL_COLOR_BUFFER_BIT);
}
@@ -140,23 +140,24 @@ update_uniforms(Term *t, enum shader_stages stage)
}
static iv2
-get_gpu_texture_position(v2 cs, uv2 gpu_position)
+get_gpu_texture_position(v2 cs, u32 gpu_tile_index)
{
+ uv2 gpu_position = {.x = gpu_tile_index & 0xFFFF, .y = gpu_tile_index >> 16};
iv2 result = {.y = gpu_position.y * cs.y, .x = gpu_position.x * cs.x};
return result;
}
static u32
-get_gpu_glyph_index(Arena a, GLCtx *gl, FontAtlas *fa, u32 codepoint, enum face_style style, u32 *tiles)
+get_gpu_glyph_index(Arena a, GLCtx *gl, FontAtlas *fa, u32 codepoint, u32 font_id,
+ enum face_style style, CachedGlyph **out)
{
- CachedGlyph *cg;
- u32 *data = render_glyph(&a, fa, codepoint, style, &cg);
+ u32 *data = render_glyph(&a, fa, codepoint, font_id, style, out);
if (data) {
+ CachedGlyph *cg = *out;
cg->uploaded_to_gpu = 1;
- uv2 gpu_position = unpack_gpu_tile_coord(cg->gpu_tile_index);
v2 cell_size = get_cell_size(fa);
- iv2 glyph_position = get_gpu_texture_position(cell_size, gpu_position);
+ iv2 glyph_position = get_gpu_texture_position(cell_size, cg->gpu_tile_index);
ASSERT(glyph_position.x + cell_size.w * cg->tile_count < gl->glyph_bitmap_dim.x);
ASSERT(glyph_position.y + cell_size.h < gl->glyph_bitmap_dim.y);
@@ -164,9 +165,8 @@ get_gpu_glyph_index(Arena a, GLCtx *gl, FontAtlas *fa, u32 codepoint, enum face_
cell_size.w * cg->tile_count, cell_size.h,
GL_RGBA, GL_UNSIGNED_BYTE, data);
}
- ASSERT(cg->uploaded_to_gpu);
- *tiles = cg->tile_count;
- return cg->gpu_tile_index;
+ ASSERT((*out)->uploaded_to_gpu);
+ return (*out)->gpu_tile_index;
}
/* NOTE: this function assumes we are drawing quads */
@@ -220,7 +220,6 @@ push_rect_full(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, v2 min_tex_c
rpb->colours[idx + 1] = colour;
rpb->colours[idx + 2] = colour;
rpb->colours[idx + 3] = colour;
-
}
static void
@@ -245,40 +244,59 @@ push_rect(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour)
push_rect_full(rpb, gl, r, colour, (v2){0}, (v2){.x = max_x, .y = max_y});
}
-#if 0
-
-static void
-push_char(RenderPushBuffer *rpb, GLCtx *gl, v2 vertscale, v2 vertoff, v2 texscale,
- uv2 colours, i32 char_idx)
+static v2
+push_s8(RenderPushBuffer *rpb, Arena a, GLCtx *gl, FontAtlas *fa, v2 pos, v4 colour, u32 font_id, s8 s)
{
- u32 idx = get_render_push_buffer_idx(rpb, gl, 1);
- rpb->vertscales[idx] = vertscale;
- rpb->vertoffsets[idx] = vertoff;
- rpb->texscales[idx] = texscale;
- rpb->texcolours[idx] = colours;
- rpb->charmap[idx] = char_idx;
-}
+ CachedGlyph *cg;
+ v2 start, end, text_size = {0};
+ v2 scale = {.x = 1.0f / gl->glyph_bitmap_dim.x, .y = 1.0f / gl->glyph_bitmap_dim.y};
-static void
-push_empty_cell_rect(RenderPushBuffer *rpb, Term *t, u32 minrow, u32 maxrow, u32 mincol, u32 maxcol)
-{
- ASSERT(minrow <= maxrow && mincol <= maxcol);
- ASSERT(maxrow <= t->size.h && maxcol <= t->size.w);
+ while (s.len) {
+ u32 cp = get_utf8(&s);
+ if (cp == (u32)-1)
+ break;
+
+ get_gpu_glyph_index(a, gl, fa, cp, font_id, FS_NORMAL, &cg);
+ cached_glyph_to_uv(fa, cg, &start, &end, scale);
+
+ Rect r = {.pos = pos, .size = {.x = cg->width, .y = cg->height}};
+ r.pos.x += cg->x0;
+ r.pos.y -= (cg->height + cg->y0);
- v2 cs = get_cell_size(&t->fa);
- v2 size = {.x = (maxcol - mincol + 1) * cs.w, .y = (maxrow - minrow + 1) * cs.h};
- v2 pos = {.x = mincol * cs.w, .y = t->gl.window_size.h - cs.h * (maxrow + 1)};
+ push_rect_full(rpb, gl, r, colour, start, end);
- Colour colour = g_colours.data[g_colours.fgidx];
- push_char(rpb, &t->gl, size, pos, (v2){0}, (uv2){.y = colour.rgba}, 0);
+ text_size.x += cg->advance;
+ pos.x += cg->advance;
+ if (cg->height > text_size.y)
+ text_size.y = cg->height;
+ }
+ text_size.x -= cg->advance;
+ text_size.w += cg->width;
+
+ return text_size;
}
-static void
-draw_rectangle(RenderPushBuffer *rpb, GLCtx *gl, Rect r, Colour colour)
+static v2
+measure_text(Arena a, GLCtx *gl, FontAtlas *fa, u32 font_id, s8 text)
{
- push_char(rpb, gl, r.size, r.pos, (v2){0}, (uv2){.y = colour.rgba}, 0);
+ v2 result = {0};
+
+ CachedGlyph *cg;
+ u32 cp = 0;
+ while (text.len) {
+ cp = get_utf8(&text);
+ if (cp == (u32)-1)
+ break;
+ get_gpu_glyph_index(a, gl, fa, cp, font_id, FS_NORMAL, &cg);
+ if (cg->height > result.y)
+ result.y = cg->height;
+ result.x += cg->advance;
+ }
+ result.x -= cg->advance;
+ result.x += cg->width;
+
+ return result;
}
-#endif
/* TODO: this is outdated */
/* NOTE: In this program we render to an offscreen render target that is later drawn
@@ -298,9 +316,9 @@ render_framebuffer(Term *t, RenderCell *render_buf)
Cell *c = &tv->fb.rows[row][col];
RenderCell *rc = render_buf + (row * t->size.w + col);
- u32 tiles;
+ CachedGlyph *cg;
rc->gpu_glyph = get_gpu_glyph_index(t->arena_for_frame, &t->gl, &t->fa,
- c->cp, c->style.attr & FS_MASK, &tiles);
+ c->cp, 0, c->style.attr & FS_MASK, &cg);
u32 attr = (c->style.attr & ATTR_SHADER_MASK) >> 2;
u32 rmask = (t->gl.mode & WIN_MODE_REVERSE)? REVERSE_VIDEO_MASK : 0;
@@ -308,6 +326,7 @@ render_framebuffer(Term *t, RenderCell *render_buf)
rc->bg = ((c->style.bg.rgba & 0xFFFFFF00) | attr) ^ rmask;
/* TODO: there is probably a better way to do this */
+ u32 tiles = cg->tile_count;
if (tiles > 1) {
for (u32 i = 1; i < tiles; i++) {
rc[i].gpu_glyph = rc->gpu_glyph + i;
@@ -776,6 +795,8 @@ init_callbacks(GLCtx *gl)
DEBUG_EXPORT void
do_terminal(Term *t, f32 dt)
{
+ BEGIN_TIMED_BLOCK();
+
dt_for_frame = dt;
if (t->gl.flags & UPDATE_POST_UNIFORMS)
@@ -869,20 +890,20 @@ do_terminal(Term *t, f32 dt)
push_rect_textured(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
flush_render_push_buffer(rpb, &t->gl);
- #if 0
+ /* TODO: update debug info at the start of the frame so that this function can
+ * be properly included */
+ END_TIMED_BLOCK();
+
/* 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]);
- 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});
+ draw_debug_overlay(t, rpb);
flush_render_push_buffer(rpb, &t->gl);
- #endif
}
#ifdef _DEBUG
DebugRecord debug_records[__COUNTER__];
-#if 0
static void
draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
{
@@ -902,33 +923,34 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
if (!(t->gl.flags & DRAW_DEBUG_OVERLAY))
return;
- glUniform1i(t->gl.render.texslot, 1);
-
v2 ws = t->gl.window_size;
s8 buf = s8alloc(&t->arena_for_frame, 1024);
static GlyphCacheStats glyph_stats;
static Rect r;
static f32 max_text_width;
+ static f32 line_height;
r.pos.x = ws.w - (max_text_width + 20);
r.size.x = max_text_width + 20;
- Colour fg = {.rgba = 0x1e9e33ff};
- Colour bg = {.rgba = 0x090909ff};
+ v4 fg = normalize_colour((Colour){.rgba = 0x1e9e33ff});
+ v4 bg = normalize_colour((Colour){.rgba = 0x090909bf});
- draw_rectangle(rpb, &t->gl, r, bg);
+ push_rect(rpb, &t->gl, r, bg);
+ u32 font_id = g_ui_debug_font_id;
f32 line_pad = 5;
- v2 txt_pos = {.x = (u32)(r.pos.x + 5), .y = ws.h};
+ v2 txt_pos = {.x = r.pos.x, .y = ws.h - 20};
{
s8 txt = buf;
txt.len = snprintf((char *)txt.data, buf.len, "Render Time: %0.02f ms/f", dt_for_frame * 1e3);
- v2 ts = debug_measure_text(t, &t->debug_font, txt, 1);
- txt_pos.y = (u32)(txt_pos.y - ts.y - line_pad);
- debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
+ v2 ts = measure_text(t->arena_for_frame, &t->gl, &t->fa, font_id, txt);
+ txt_pos.y = (u32)(txt_pos.y - ts.h - line_pad);
+ push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
if (ts.w > max_text_width) max_text_width = ts.w;
+ if (ts.h > line_height) line_height = ts.h;
}
for (u32 i = 0; i < ARRAY_COUNT(debug_records); i++) {
@@ -941,21 +963,20 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
txt.len = snprintf((char *)txt.data, buf.len, "%29s: %5u %4s %11.02f cycs/hit",
dr->function_name, hits[i], hits[i] > 1? "hits" : "hit",
(f32)cycs[i]/(f32)hits[i]);
- v2 ts = debug_measure_text(t, &t->debug_font, txt, 1);
- txt_pos.y = (u32)(txt_pos.y - ts.y - line_pad);
- debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
+ txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
+ v2 ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
if (ts.w > max_text_width) max_text_width = ts.w;
+ if (ts.h > line_height) line_height = ts.h;
}
GlyphCacheStats new_glyph_stats = get_and_clear_glyph_cache_stats(&t->fa.glyph_cache);
if (new_glyph_stats.hit_count != 0)
glyph_stats = new_glyph_stats;
{
- v2 ts = debug_measure_text(t, &t->debug_font, s8("Glyph Cache Stats:"), 1);
- txt_pos.y = (u32)(txt_pos.y - ts.y - line_pad);
- txt_pos.y = (u32)(txt_pos.y - ts.y - line_pad);
- debug_draw_text(t, rpb, s8("Glyph Cache Stats:"), txt_pos, fg, bg, 1);
+ s8 header = s8("Glyph Cache Stats:");
+ txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
+ v2 ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, header);
/* TODO: This doesn't really work when we are redrawing on every frame */
static char *fmts[ARRAY_COUNT(glyph_stats.E)] = {
@@ -966,10 +987,11 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
for (u32 i = 0; i < ARRAY_COUNT(glyph_stats.E); i++) {
s8 txt = buf;
txt.len = snprintf((char *)txt.data, buf.len, fmts[i], glyph_stats.E[i]);
- ts = debug_measure_text(t, &t->debug_font, txt, 1);
- txt_pos.y = (u32)(txt_pos.y - ts.y - line_pad);
- debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
+ txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
+ ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
+
if (ts.w > max_text_width) max_text_width = ts.w;
+ if (ts.h > line_height) line_height = ts.h;
}
}
@@ -977,4 +999,3 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
r.size.h = ws.h - r.pos.y;
}
#endif
-#endif