Commit: 6906d1aa493bb3da7630a7f61914060b8e1886a2
Parent: cc1eb1cf3113d81c8432531acf2eedb3463c68b5
Author: Randy Palamar
Date: Mon, 18 Nov 2024 18:18:16 -0700
make all computations involving the glyph bitmap integer
I don't know why I thought this was OK in the fragment shader but
it is not. Glyphs were getting blurred when they shouldn't be.
This was especially noticeable on lower resolution displays.
Diffstat:
5 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/frag_render.glsl b/frag_render.glsl
@@ -16,10 +16,10 @@ layout(std430, binding = 0) readonly restrict buffer ssbo_cells {
};
layout(std140, binding = 0) uniform parameters {
- uvec2 cell_size;
- uvec2 term_size_in_cells;
- vec2 term_size_in_pixels;
- vec2 top_left_margin;
+ ivec2 cell_size;
+ ivec2 term_size_in_cells;
+ ivec2 term_size_in_pixels;
+ ivec2 top_left_margin;
uint margin_colour;
float blink_parameter;
@@ -42,21 +42,21 @@ layout(location = 3) uniform sampler2D u_bitmap_texture;
#define ATTR_INVISIBLE (1u << 4u)
#define ATTR_STRUCK (1u << 5u)
-vec2
+ivec2
unpack_glyph_position(uint glyph_position)
{
- vec2 result;
- result.x = glyph_position & 0xFFFFu;
- result.y = glyph_position >> 16u;
+ ivec2 result;
+ result.x = int(glyph_position & 0xFFFFu);
+ result.y = int(glyph_position >> 16u);
return result;
}
void main()
{
- vec2 pixel_coord = gl_FragCoord.xy - top_left_margin;
+ ivec2 pixel_coord = ivec2(gl_FragCoord.xy) - top_left_margin;
- uvec2 cell_index = uvec2(pixel_coord / cell_size);
- vec2 cell_pos = mod(pixel_coord, cell_size);
+ ivec2 cell_index = pixel_coord / cell_size;
+ ivec2 cell_pos = ivec2(mod(pixel_coord, cell_size));
vec3 result;
if (pixel_coord.x > 0 && cell_index.x < term_size_in_cells.x &&
@@ -68,9 +68,6 @@ void main()
vec3 fg = unpackUnorm4x8(cell.fg ^ reverse_video_mask).wzy;
vec3 bg = unpackUnorm4x8(cell.bg ^ reverse_video_mask).wzy;
- vec2 glyph_pos = unpack_glyph_position(cell.gpu_glyph) * cell_size;
- vec2 tex_coord = (glyph_pos + cell_pos) / vec2(textureSize(u_bitmap_texture, 0));
-
if ((attr & ATTR_FAINT) != 0) fg *= 0.5;
if ((attr & ATTR_BLINK) != 0) fg = mix(bg, fg, 0.5 * (1 + sin(blink_parameter)));
@@ -80,7 +77,8 @@ void main()
bg = tmp;
}
- vec4 smp = texture(u_bitmap_texture, tex_coord);
+ ivec2 glyph_pos = unpack_glyph_position(cell.gpu_glyph) * cell_size;
+ vec4 smp = texelFetch(u_bitmap_texture, glyph_pos + cell_pos, 0);
result = mix(bg, fg * smp.xyz, smp.a);
if (((attr & ATTR_UNDERLINED) != 0) &&
@@ -96,7 +94,9 @@ void main()
/* NOTE: set to true to see the glyph cache texture */
if (false) {
- vec4 smp = texture(u_bitmap_texture, pixel_coord / term_size_in_pixels);
+ /* NOTE: needs to use texture() since the cache texture
+ * may be different size than the window size */
+ vec4 smp = texture(u_bitmap_texture, gl_FragCoord.xy / vec2(term_size_in_pixels));
colour = smp;
} else {
colour = vec4(result, 1);
diff --git a/terminal.c b/terminal.c
@@ -8,8 +8,8 @@ static const u8 utf8overhangmask[32] = {
#define SPLIT_LONG 4096L
-static uv2
-initialize_framebuffer(Framebuffer *fb, uv2 term_size)
+static iv2
+initialize_framebuffer(Framebuffer *fb, iv2 term_size)
{
size cell_memory_size = sizeof(Cell) * term_size.h * term_size.w;
size rows_memory_size = sizeof(Row) * term_size.h;
diff --git a/test.c b/test.c
@@ -349,7 +349,7 @@ main(void)
ALT_BACKLOG_LINES);
/* TODO: should probably be some odd size */
- term.size = (uv2){.w = 80, .h = 24};
+ term.size = (iv2){.w = 80, .h = 24};
term.views[0].fb.backing_store = memory_block_from_arena(&memory, 2 * MEGABYTE);
term.views[1].fb.backing_store = memory_block_from_arena(&memory, 2 * MEGABYTE);
initialize_framebuffer(&term.views[0].fb, term.size);
diff --git a/util.h b/util.h
@@ -296,11 +296,11 @@ enum shader_stages {
};
typedef struct {
- uv2 cell_size;
- uv2 term_size_in_cells;
- v2 term_size_in_pixels;
+ iv2 cell_size;
+ iv2 term_size_in_cells;
+ iv2 term_size_in_pixels;
- v2 top_left_margin;
+ iv2 top_left_margin;
u32 margin_colour;
f32 blink_parameter;
@@ -418,7 +418,7 @@ typedef struct {
} FontDesc;
typedef struct {
- u32 h, w;
+ i32 h, w;
i32 baseline;
} FontInfo;
@@ -564,7 +564,7 @@ typedef struct Term {
iptr child;
- uv2 size;
+ iv2 size;
/* NOTE: scrolling region */
u32 top, bot;
diff --git a/vtgl.c b/vtgl.c
@@ -261,10 +261,10 @@ resize(Term *t, PlatformAPI *platform, iv2 window_size)
ws.w -= 2 * g_term_margin.w;
ws.h -= 2 * g_term_margin.h;
- uv2 old_size = t->size;
+ iv2 old_size = t->size;
v2 cs = get_cell_size(&t->fa);
- t->size.w = (u32)(ws.w / cs.w);
- t->size.h = (u32)(ws.h / cs.h);
+ t->size.w = (i32)(ws.w / cs.w);
+ t->size.h = (i32)(ws.h / cs.h);
if (t->size.w > ARRAY_COUNT(t->tabs) * 32) {
t->size.w = ARRAY_COUNT(t->tabs) * 32u;
@@ -275,7 +275,7 @@ resize(Term *t, PlatformAPI *platform, iv2 window_size)
t->error_stream.widx = 0;
}
- if (!equal_uv2(old_size, t->size)) {
+ if (!equal_iv2(old_size, t->size)) {
t->size = initialize_framebuffer(&t->views[0].fb, t->size);
initialize_framebuffer(&t->views[1].fb, t->size);
gl->flags |= NEEDS_FULL_REFILL;
@@ -292,12 +292,12 @@ resize(Term *t, PlatformAPI *platform, iv2 window_size)
platform->set_terminal_size(t->child, t->size.h, t->size.w, ws.w, ws.h);
ShaderParameters *sp = &gl->shader_parameters;
- sp->cell_size = (uv2){.w = cs.w, .h = cs.h};
+ sp->cell_size = (iv2){.w = cs.w, .h = cs.h};
sp->top_left_margin = g_term_margin;
sp->margin_colour = g_colours.data[g_colours.bgidx].rgba;
//sp->margin_colour = 0x7f003f00;
- sp->term_size_in_pixels = v2_from_iv2(gl->window_size);
+ sp->term_size_in_pixels = gl->window_size;
sp->term_size_in_cells = t->size;
gl->flags &= ~NEEDS_RESIZE;
@@ -1073,7 +1073,7 @@ DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize)
.y = cs.y * requested_cells.y + 2 * g_term_margin.y,
};
- t->size = (uv2){.x = 1, .y = 1};
+ t->size = (iv2){.x = 1, .y = 1};
initialize_framebuffer(&t->views[0].fb, t->size);
initialize_framebuffer(&t->views[1].fb, t->size);