vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: fe59fb7e4c7feb69019c40b6a89ebce965c5653e
Parent: 6a905a8a157d37e2c4dae7cab10d85cc2f50d93e
Author: Randy Palamar
Date:   Wed, 21 Aug 2024 06:46:58 -0600

first pass at whole window padding

There are still some things that should be cleaned up and rounding
errors to look for but this at stops us from drawing right on the edge.

Diffstat:
Mconfig.def.h | 3+++
Mvtgl.c | 69+++++++++++++++++++++++++++++++++++++--------------------------------
2 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -3,6 +3,9 @@ static char *g_fonts[] = { "monospace:style=Regular:pixelsize=16", }; +/* NOTE: terminal padding in pixels */ +static v2 g_term_pad = {.w = 8, .h = 8}; + static u8 g_tabstop = 8; static Colour base16_colours[16] = { diff --git a/vtgl.c b/vtgl.c @@ -58,6 +58,16 @@ set_projection_matrix(GLCtx *gl) glUniformMatrix4fv(gl->post.Pmat, 1, GL_TRUE, pmat); } +static v2 +get_window_top_left(Term *t) +{ + v2 result = { + .x = g_term_pad.w, + .y = t->gl.window_size.h - g_term_pad.h, + }; + return result; +} + static void resize(Term *t) { @@ -66,12 +76,8 @@ resize(Term *t) t->size.w = (u32)(ws.w / cs.w); t->size.h = (u32)(ws.h / cs.h); - /* TODO: Proper padding */ - //v2 ws = {.x = t->size.w * cs.w, .y = t->size.h * cs.h}; - //f32 xpad = (w - ws.w) / 2; - //f32 ypad = (h - ws.h) / 2; - //glViewport(xpad, ypad, ws.w, ws.h); - glViewport(0, 0, ws.w, ws.h); + glViewport(g_term_pad.w, g_term_pad.h, ws.w, ws.h); + set_projection_matrix(&t->gl); os_alloc_framebuffer(&t->views[0].fb, t->size.h, t->size.w); os_alloc_framebuffer(&t->views[1].fb, t->size.h, t->size.w); @@ -272,11 +278,12 @@ push_cell(RenderPushBuffer *rpb, GLCtx *gl, Cell c, Rect r, f32 font_text_dy) static void render_framebuffer(Term *t, RenderPushBuffer *rpb) { - v2 cs = get_cell_size(t); + v2 tl = get_window_top_left(t); + v2 cs = get_cell_size(t); TermView *tv = t->views + t->view_idx; { - Rect cr = {.pos = {.y = t->gl.window_size.h - cs.h}, .size = cs}; + Rect cr = {.pos = {.y = tl.y - cs.h}, .size = cs}; for (u32 r = 0; r < t->size.h; r++) { for (u32 c = 0; c < t->size.w; c++) { push_cell(rpb, &t->gl, tv->fb.rows[r][c], cr, t->fa.deltay); @@ -291,11 +298,9 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb) /* TODO: hide cursor doesn't get reset properly */ //if (!(t->gl.mode & WIN_MODE_HIDECURSOR)) { + iv2 curs = t->cursor.pos; Rect cr = { - .pos = { - .x = cs.w * t->cursor.pos.x, - .y = t->gl.window_size.h - cs.h * (t->cursor.pos.y + 1), - }, + .pos = {.x = cs.w * curs.x, .y = tl.h - cs.h * (curs.y + 1)}, .size = cs, }; Cell cursor = tv->fb.rows[t->cursor.pos.y][t->cursor.pos.x]; @@ -308,10 +313,7 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb) if (t->selection.end.x != -1) { iv2 curs = t->selection.start; Rect cr = { - .pos = { - .x = cs.w * curs.x, - .y = t->gl.window_size.h - cs.h * (curs.y + 1), - }, + .pos = {.x = cs.w * curs.x, .y = tl.h - cs.h * (curs.y + 1)}, .size = cs, }; /* NOTE: do full rows first */ @@ -475,13 +477,15 @@ static void fb_callback(GLFWwindow *win, i32 w, i32 h) { Term *t = glfwGetWindowUserPointer(win); - t->gl.window_size = (v2){.w = w, .h = h}; + + v2 cell_size = get_cell_size(t); + t->gl.window_size.w = MAX(cell_size.w, w - 2 * g_term_pad.w); + t->gl.window_size.h = MAX(cell_size.h, h - 2 * g_term_pad.h); glActiveTexture(GL_TEXTURE0 + t->gl.fb_tex_unit); glBindTexture(GL_TEXTURE_2D, t->gl.fb_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - set_projection_matrix(&t->gl); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t->gl.window_size.w, t->gl.window_size.h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); t->gl.flags |= NEEDS_RESIZE; } @@ -709,21 +713,22 @@ do_terminal(Term *t) render_framebuffer(t, rpb); v2 ws = t->gl.window_size; - v2 cell_size = get_cell_size(t); - v2 cursor_pos = { - .x = t->cursor.pos.x * cell_size.w, - .y = ws.h - cell_size.h * (t->cursor.pos.y + 1), - }; - v2 src_bl = {0}; - v2 src_tr = { .x = ws.w, .y = src_bl.y + ws.h }; + if (0) { + v2 cell_size = get_cell_size(t); + v2 cursor_pos = { + .x = t->cursor.pos.x * cell_size.w, + .y = ws.h - cell_size.h * (t->cursor.pos.y + 1), + }; - if (t->cursor.pos.y > t->size.h) { - src_tr.y = cursor_pos.y + ws.h; - src_bl.y = cursor_pos.y; - } + v2 src_bl = {0}; + v2 src_tr = { .x = ws.w, .y = src_bl.y + ws.h }; + + if (t->cursor.pos.y > t->size.h) { + src_tr.y = cursor_pos.y + ws.h; + src_bl.y = cursor_pos.y; + } - if (0) { s8 fps = s8alloc(&t->arena_for_frame, 64); fps.len = snprintf((char *)fps.data, fps.len, "Render Time: %0.02f ms/f", last_frame_time * 1e3); v2 ts = measure_text(&t->gl, fps, 1);