vtgl

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

Commit: 21929b5877058ac6e5a807654cc38f540aebd57b
Parent: fe59fb7e4c7feb69019c40b6a89ebce965c5653e
Author: Randy Palamar
Date:   Wed, 21 Aug 2024 07:55:33 -0600

rectify who is in charge of handling the padding

This completes the window padding. Now we just have to handle cell padding.

Diffstat:
Mterminal.c | 11-----------
Mvtgl.c | 60+++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/terminal.c b/terminal.c @@ -29,17 +29,6 @@ set_window_title(GLFWwindow *win, Arena a, s8 title) glfwSetWindowTitle(win, s8_to_cstr(&a, title)); } -static v2 -get_cell_size(Term *t) -{ - /* TODO: Make padding configurable */ - v2 result = { - .w = t->fa.size.w + 0, - .h = t->fa.size.h + 8, - }; - return result; -} - static s8 consume(s8 raw, size count) { diff --git a/vtgl.c b/vtgl.c @@ -59,11 +59,28 @@ set_projection_matrix(GLCtx *gl) } static v2 -get_window_top_left(Term *t) +get_cell_size(Term *t) { + /* TODO: Make padding configurable */ v2 result = { - .x = g_term_pad.w, - .y = t->gl.window_size.h - g_term_pad.h, + .w = t->fa.size.w + 0, + .h = t->fa.size.h + 8, + }; + return result; +} + +static v2 +get_terminal_top_left(Term *t) +{ + v2 cs = get_cell_size(t); + v2 occupied_size = {.x = t->size.w * cs.w, .y = t->size.h * cs.h}; + v2 delta = { + .x = t->gl.window_size.w - 2 * g_term_pad.w - occupied_size.w, + .y = t->gl.window_size.h - 2 * g_term_pad.h - occupied_size.h + }; + v2 result = { + .x = g_term_pad.w + delta.x / 2, + .y = t->gl.window_size.h - g_term_pad.h - delta.y / 2 }; return result; } @@ -71,18 +88,19 @@ get_window_top_left(Term *t) static void resize(Term *t) { - v2 ws = t->gl.window_size; - v2 cs = get_cell_size(t); + v2 ws = t->gl.window_size; + ws.w -= 2 * g_term_pad.w; + ws.h -= 2 * g_term_pad.h; + + v2 cs = get_cell_size(t); t->size.w = (u32)(ws.w / cs.w); t->size.h = (u32)(ws.h / cs.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); os_set_term_size(t->child, t->size.h, t->size.w, ws.w, ws.h); t->gl.flags &= ~NEEDS_RESIZE; + /* TODO: check if we actually changed size */ t->gl.flags |= NEEDS_FULL_BLIT; } @@ -275,21 +293,25 @@ push_cell(RenderPushBuffer *rpb, GLCtx *gl, Cell c, Rect r, f32 font_text_dy) rpb->texcolours[idx + 1].y = (cs.attr & ATTR_INVERSE)? cs.fg.rgba : cs.bg.rgba; } +/* NOTE: In this program we render to an offscreen render target that is later drawn + * to the screen as a full window quad. Therefore render_framebuffer must take care + * to handle all necessary padding (window and cell). Outside of here everyone should + * simply care about the terminal in terms of rows and columns (t->size). */ static void render_framebuffer(Term *t, RenderPushBuffer *rpb) { - v2 tl = get_window_top_left(t); + v2 tl = get_terminal_top_left(t); v2 cs = get_cell_size(t); TermView *tv = t->views + t->view_idx; { - Rect cr = {.pos = {.y = tl.y - cs.h}, .size = cs}; + Rect cr = {.pos = {.x = tl.x, .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); cr.pos.x += cs.w; } - cr.pos.x = 0; + cr.pos.x = tl.x; cr.pos.y -= cs.h; } } @@ -300,7 +322,7 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb) { iv2 curs = t->cursor.pos; Rect cr = { - .pos = {.x = cs.w * curs.x, .y = tl.h - cs.h * (curs.y + 1)}, + .pos = {.x = tl.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]; @@ -313,7 +335,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 = tl.h - cs.h * (curs.y + 1)}, + .pos = {.x = tl.x + cs.w * curs.x, .y = tl.h - cs.h * (curs.y + 1)}, .size = cs, }; /* NOTE: do full rows first */ @@ -325,7 +347,7 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb) cr.pos.x += cs.w; } curs.x = 0; - cr.pos.x = 0; + cr.pos.x = tl.x; cr.pos.y -= cs.h; } /* NOTE: do the last row */ @@ -478,14 +500,14 @@ fb_callback(GLFWwindow *win, i32 w, i32 h) { Term *t = glfwGetWindowUserPointer(win); - 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); + t->gl.window_size = (v2){.w = w, .h = h}; + + glViewport(0, 0, w, h); + set_projection_matrix(&t->gl); glActiveTexture(GL_TEXTURE0 + t->gl.fb_tex_unit); glBindTexture(GL_TEXTURE_2D, t->gl.fb_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t->gl.window_size.w, t->gl.window_size.h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); t->gl.flags |= NEEDS_RESIZE; }