From 07612b61622430961eb4372d80b779be50fb09ed Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Wed, 24 Jul 2024 10:54:40 +0300 Subject: [PATCH] Use position instead of offsetting in shader, fix ugly font rendering at 100% scale --- geometry.js | 29 +++++++++++++---------------- ibm_vga8.woff2 | Bin 0 -> 38000 bytes index.html | 2 +- index.js | 11 ++++++++--- input.js | 4 ++-- rasterizer.js | 9 ++++++--- render.js | 18 ++++++++++++------ 7 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 ibm_vga8.woff2 diff --git a/geometry.js b/geometry.js index 296e166..63a224e 100644 --- a/geometry.js +++ b/geometry.js @@ -28,7 +28,10 @@ function rasterize_and_pack(text, cycles) { return rasterized[key]; } - const tiles_needed = cycles - 1 + 1; // stage name + count from one + let cycles_total_padding = (cycles - 1) * config.padding; + let bonus_cells = Math.ceil(cycles_total_padding / config.w); + + const tiles_needed = cycles - 1 + 1 + bonus_cells; // stage name + count cycles from one if (tiles_needed > config.raster_texture_size / config.w - raster_tile.x) { raster_tile.x = 0; raster_tile.y += 1; @@ -42,20 +45,12 @@ function rasterize_and_pack(text, cycles) { gl.texSubImage2D(gl.TEXTURE_2D, 0, raster_tile.x * config.w, raster_tile.y * config.h, config.w, config.h, - gl.RGBA, gl.UNSIGNED_BYTE, c2d.canvas + gl.RGBA, gl.UNSIGNED_BYTE, + c2d.canvas ); - raster_tile.x += 1; - for (let i = 1; i <= cycles; ++i) { - rasterize(i); - gl.bindTexture(gl.TEXTURE_2D, textures['raster']); - gl.texSubImage2D(gl.TEXTURE_2D, 0, - raster_tile.x * config.w, raster_tile.y * config.h, - config.w, config.h, - gl.RGBA, gl.UNSIGNED_BYTE, c2d.canvas - ); - raster_tile.x += 1; - } + raster_tile.x += 1; + raster_tile.x += cycles + bonus_cells; if (raster_tile.x === config.raster_texture_size / config.w) { raster_tile.x = 0; @@ -101,18 +96,20 @@ function generate(trace_id) { } let [r, g, b] = get_color(stage.name); + let a = 255; if (!instruction.retired) { r = Math.max(50, r - 50); g = Math.max(50, g - 50); b = Math.max(50, b - 50); + a = 100; } const [u, v] = rasterize_and_pack(stage.name, stage_cycles); - sizes.push(stage_cycles * config.w, 1 * config.h); - positions.push(config.w * stage.c, config.h * y); - colors.push(r, g, b, 255); + sizes.push(stage_cycles * config.w + (stage_cycles - 1) * config.padding, 1 * config.h); + positions.push(config.w * stage.c + config.padding * (stage.c - 1), config.h * y + config.padding * (y - 1)); + colors.push(r, g, b, a); uvs.push(u, v); result.count++; diff --git a/ibm_vga8.woff2 b/ibm_vga8.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..489d4d249f1f5399e50c40ae37e1555adcc27103 GIT binary patch literal 38000 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 CM2OS? literal 0 HcmV?d00001 diff --git a/index.html b/index.html index 9f42726..b031251 100644 --- a/index.html +++ b/index.html @@ -21,7 +21,7 @@
- +
diff --git a/index.js b/index.js index b33fbd1..3ede6a4 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,12 @@ document.addEventListener('DOMContentLoaded', main); let traces = {}; function main() { - init_webgl(); - init_rasterizer(); - init_listeners(); + const font = new FontFace('ibm8x16', 'url(ibm_vga8.woff2)'); + document.fonts.add(font); + font.load(); + document.fonts.ready.then(() => { + init_webgl(); + init_rasterizer(); + init_listeners(); + }); } diff --git a/input.js b/input.js index 8becf9a..6446386 100644 --- a/input.js +++ b/input.js @@ -73,8 +73,8 @@ function jump_to_first_instruction() { const trace = traces[Object.keys(traces)[0]].raw; if (Object.keys(trace).length > 0) { const first_instruction = trace[Object.keys(trace)[0]]; - offset.x = -first_instruction.cycle * config.w; - offset.y = 0 * config.h; + offset.x = -first_instruction.cycle * config.w + config.padding * 2; + offset.y = config.padding * 2; zoom_target = 1; zoom = 1; schedule_draw(); diff --git a/rasterizer.js b/rasterizer.js index 79168c7..c3247a3 100644 --- a/rasterizer.js +++ b/rasterizer.js @@ -4,12 +4,15 @@ let c2d = null; function init_rasterizer() { c2d = document.querySelector('#offscreen').getContext('2d'); - c2d.font = '14px monospace'; - c2d.fillStyle = 'white'; + c2d.font = '16px ibm8x16'; + //c2d.font = '14px monospace'; + c2d.textAlign = 'center'; + c2d.textBaseline = 'middle'; + c2d.fillStyle = '#eeeeee'; } function rasterize(text) { c2d.clearRect(0, 0, c2d.canvas.width, c2d.canvas.height); - c2d.fillText(text, 0, 14); + c2d.fillText(text, config.w / 2, config.h / 2); //c2d.fillRect(0, 0, 32, 32); } diff --git a/render.js b/render.js index e9d7e5e..d2c41d2 100644 --- a/render.js +++ b/render.js @@ -6,6 +6,7 @@ let config = { bytes_per_quad: 28, w: 32, h: 32, + padding: 2, predefined_colors: { 'Np': [75, 62, 143], @@ -69,29 +70,30 @@ const tquad_vs_src = `#version 300 es } vec2 cycles = a_size / u_tile; + vec2 tt = u_textile / u_tile; if (vertex_index == 0) { // "top left" aka "p1" - corner = a_pos + inset; + corner = a_pos; uv = a_uv; } else if (vertex_index == 1 || vertex_index == 5) { // "top right" aka "p2" - corner = a_pos + vec2(a_size.x, 0) + vec2(-inset.x, inset.y); + corner = a_pos + vec2(a_size.x, 0); uv = a_uv + vec2(u_textile.x * cycles.x, 0); } else if (vertex_index == 2 || vertex_index == 4) { // "bottom left" aka "p3" - corner = a_pos + vec2(0, a_size.y) + vec2(inset.x, -inset.y); + corner = a_pos + vec2(0, a_size.y); uv = a_uv + vec2(0, u_textile.y * cycles.y); } else { // "bottom right" aka "p4" - corner = a_pos + a_size - inset; + corner = a_pos + a_size; uv = a_uv + u_textile * cycles; } vec2 screen02 = (corner.xy * vec2(u_scale) + u_translation) / u_res * 2.0; screen02.y = 2.0 - screen02.y; v_color = a_color; - v_uv = uv - u_textile * vec2(0.2); + v_uv = uv; gl_Position = vec4(screen02 - 1.0, 1.0, 1.0); } @@ -104,12 +106,14 @@ const tquad_fs_src = `#version 300 es in vec2 v_uv; uniform sampler2D u_texture; + uniform float u_fade; layout(location = 0) out vec4 FragColor; void main() { vec4 text = texture(u_texture, v_uv); - FragColor = vec4(text.rgb * text.a + v_color.rgb * (1.0 - text.a), 1.0); + text.a = min(min(text.a, v_color.a), u_fade); + FragColor = vec4(text.rgb * text.a + v_color.rgb, 1.0); } `; @@ -147,6 +151,7 @@ function draw(ts, animation) { if (quads.count > 0) { const program = programs['quad']; + const fade = Math.max(0, Math.min(1.25 * zoom - 0.25, 1)); gl.useProgram(program.program); gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_packed']); @@ -162,6 +167,7 @@ function draw(ts, animation) { gl.uniform2f(program.locations['u_textile'], config.w / config.raster_texture_size, config.h / config.raster_texture_size); gl.uniform1i(program.locations['u_texture'], textures['raster']); gl.uniform2f(program.locations['u_tile'], config.w, config.h); + gl.uniform1f(program.locations['u_fade'], fade); gl.enableVertexAttribArray(program.locations['a_pos']); gl.enableVertexAttribArray(program.locations['a_size']);