Commit: 19d64a874f62f9f170c78bd45a5bf544241e10d2
Parent: 6b46e481b70f74a0f0515502262573d377c81a26
Author: Randy Palamar
Date: Thu, 17 Oct 2024 20:56:02 -0600
start moving cell style calculations to fragment shader
ideally most calculations in push_cell get moved to the shader.
this also sets the shader up for proper colour blending with
coloured glyphs.
Diffstat:
6 files changed, 52 insertions(+), 27 deletions(-)
diff --git a/debug.c b/debug.c
@@ -174,9 +174,12 @@ debug_init(Term *t, Arena a)
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++)
- rgba_bitmap[i * g->size.w + j] = (u32)(render_buf[i * g->size.w + j]) << 24;
+ 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);
@@ -209,7 +212,7 @@ debug_measure_text(Term *t, Font *f, s8 text, b32 monospaced)
}
static void
-debug_draw_text(Term *t, RenderPushBuffer *rpb, s8 text, v2 position, Colour colour, b32 monospaced)
+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++) {
@@ -218,7 +221,8 @@ debug_draw_text(Term *t, RenderPushBuffer *rpb, s8 text, v2 position, Colour col
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 = colour.rgba}, glyph_idx);
+ 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;
}
}
@@ -265,7 +269,10 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
r.pos.x = ws.w - 1.1 * max_text_width;
r.size.x = 1.1 * max_text_width;
- draw_rectangle(rpb, &t->gl, r, (Colour){.rgba = 0x222222ff});
+ Colour fg = {.rgba = 0x1e9e33ff};
+ Colour bg = {.rgba = 0x222222ff};
+
+ draw_rectangle(rpb, &t->gl, r, bg);
f32 line_pad = 5;
v2 txt_pos = {.x = (u32)(r.pos.x + 5), .y = ws.h};
@@ -275,7 +282,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
if (ts.w > max_text_width) max_text_width = ts.w;
}
@@ -287,14 +294,14 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
txt.len = snprintf((char *)txt.data, buf.len, fmts[i].line1, cycs[i], 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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
if (ts.w > max_text_width) max_text_width = ts.w;
txt.len = snprintf((char *)txt.data, buf.len, fmts[i].line2, (f32)cycs[i]/(f32)hits[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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
if (ts.w > max_text_width) max_text_width = ts.w;
}
@@ -305,7 +312,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
cycs[CC_RENDER_FRAMEBUFFER] / (f32)(t->size.w * t->size.h));
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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
if (ts.w > max_text_width) max_text_width = ts.w;
}
@@ -317,7 +324,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, s8("Glyph Cache Stats:"), txt_pos, fg, bg, 1);
static char *fmts[ARRAY_COUNT(glyph_stats.E)] = {
" Hits: %u",
@@ -329,7 +336,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
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, (Colour){.rgba = 0x1e9e33ff}, 1);
+ debug_draw_text(t, rpb, txt, txt_pos, fg, bg, 1);
if (ts.w > max_text_width) max_text_width = ts.w;
}
}
diff --git a/font.c b/font.c
@@ -172,7 +172,7 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, enum face_style style, CachedGlyph
u32 pixel = 0;
if (0 /* COLOURED */) {
} else {
- pixel = (u32)(render_buf[i * cg->g.size.w + j]) << 24;
+ pixel = render_buf[i * cg->g.size.w + j] << 24 | 0x00FFFFFF;
}
rgba_bitmap[i * cg->g.size.w + j] = pixel;
}
diff --git a/frag_render.glsl b/frag_render.glsl
@@ -1,4 +1,4 @@
-#version 460 core
+#version 400 core
out vec4 colour;
@@ -12,14 +12,34 @@ uniform int u_charmap[512];
uniform vec2 u_texscale[512];
uniform uvec2 u_texcolour[512];
+#define ATTR_MASK 0xFFu
+#define ATTR_FAINT (1u << 0u)
+#define ATTR_UNDERLINED (1u << 1u)
+#define ATTR_BLINK (1u << 2u)
+#define ATTR_INVERSE (1u << 3u)
+#define ATTR_INVISIBLE (1u << 4u)
+#define ATTR_STRUCK (1u << 5u)
+
void main()
{
- vec4 fg = unpackUnorm4x8(u_texcolour[fs_in.index].x).wzyx;
- vec4 bg = unpackUnorm4x8(u_texcolour[fs_in.index].y).wzyx;
+ uint attr = u_texcolour[fs_in.index].x & ATTR_MASK;
+ vec3 fg = unpackUnorm4x8(u_texcolour[fs_in.index].x).wzy;
+ vec3 bg = unpackUnorm4x8(u_texcolour[fs_in.index].y).wzy;
+
+ vec3 tex_coord = vec3(fs_in.tex_coord, u_charmap[fs_in.index]);
+ tex_coord.xy *= u_texscale[fs_in.index];
+
+ if ((attr & ATTR_INVERSE) != 0) {
+ vec3 tmp = fg;
+ fg = bg;
+ bg = tmp;
+ }
+
+ if ((attr & ATTR_FAINT) != 0) fg *= 0.5;
- vec3 tex_coord = vec3(fs_in.tex_coord, u_charmap[fs_in.index]);
- tex_coord.xy *= u_texscale[fs_in.index];
+ vec4 smp = texture(u_texslot, tex_coord);
+ float a = u_texscale[fs_in.index].x == 0 ? 0 : smp.a;
- float a = u_texscale[fs_in.index].x == 0 ? 0 : texture(u_texslot, tex_coord).a;
- colour = mix(bg, fg, a);
+ colour.xyz = mix(bg, fg * smp.xyz, a);
+ colour.a = 1;
}
diff --git a/util.h b/util.h
@@ -109,6 +109,7 @@ enum cell_attribute {
ATTR_WIDE = 1 << 8,
ATTR_WDUMMY = 1 << 9, /* NOTE: used to skip cells when copying */
};
+#define ATTR_SHADER_MASK (ATTR_FAINT|ATTR_UNDERLINED|ATTR_BLINK|ATTR_INVERSE|ATTR_INVISIBLE|ATTR_STRUCK)
typedef struct {
Colour fg, bg;
diff --git a/vert_render.glsl b/vert_render.glsl
@@ -1,4 +1,4 @@
-#version 460 core
+#version 400 core
in vec2 position;
diff --git a/vtgl.c b/vtgl.c
@@ -281,13 +281,10 @@ push_cell(RenderPushBuffer *rpb, GLCtx *gl, Arena a, FontAtlas *fa, Cell c, Rect
rpb->charmap[idx + 1] = depth_idx;
CellStyle cs = c.style;
- if (cs.attr & ATTR_FAINT) {
- if (cs.attr & ATTR_INVERSE) cs.bg.a = 0.5 * 255;
- else cs.fg.a = 0.5 * 255;
- }
- u32 fg = (cs.attr & ATTR_INVERSE)? cs.bg.rgba : cs.fg.rgba;
- u32 bg = (cs.attr & ATTR_INVERSE)? cs.fg.rgba : cs.bg.rgba;
+ u32 attr = (cs.attr & ATTR_SHADER_MASK) >> 2;
+ u32 fg = (cs.fg.rgba & 0xFFFFFF00) | attr;
+ u32 bg = (cs.bg.rgba & 0xFFFFFF00) | attr;
u32 rmask = (gl->mode & WIN_MODE_REVERSE)? REVERSE_VIDEO_MASK : 0;
rpb->texcolours[idx + 0].x = fg ^ rmask;