Browse Source

Use position instead of offsetting in shader, fix ugly font rendering at 100% scale

master
A.Olokhtonov 2 months ago
parent
commit
07612b6162
  1. 27
      geometry.js
  2. BIN
      ibm_vga8.woff2
  3. 2
      index.html
  4. 5
      index.js
  5. 4
      input.js
  6. 9
      rasterizer.js
  7. 18
      render.js

27
geometry.js

@ -28,7 +28,10 @@ function rasterize_and_pack(text, cycles) {
return rasterized[key]; 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) { if (tiles_needed > config.raster_texture_size / config.w - raster_tile.x) {
raster_tile.x = 0; raster_tile.x = 0;
raster_tile.y += 1; raster_tile.y += 1;
@ -42,20 +45,12 @@ function rasterize_and_pack(text, cycles) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, gl.texSubImage2D(gl.TEXTURE_2D, 0,
raster_tile.x * config.w, raster_tile.y * config.h, raster_tile.x * config.w, raster_tile.y * config.h,
config.w, 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) { if (raster_tile.x === config.raster_texture_size / config.w) {
raster_tile.x = 0; raster_tile.x = 0;
@ -101,18 +96,20 @@ function generate(trace_id) {
} }
let [r, g, b] = get_color(stage.name); let [r, g, b] = get_color(stage.name);
let a = 255;
if (!instruction.retired) { if (!instruction.retired) {
r = Math.max(50, r - 50); r = Math.max(50, r - 50);
g = Math.max(50, g - 50); g = Math.max(50, g - 50);
b = Math.max(50, b - 50); b = Math.max(50, b - 50);
a = 100;
} }
const [u, v] = rasterize_and_pack(stage.name, stage_cycles); const [u, v] = rasterize_and_pack(stage.name, stage_cycles);
sizes.push(stage_cycles * config.w, 1 * config.h); sizes.push(stage_cycles * config.w + (stage_cycles - 1) * config.padding, 1 * config.h);
positions.push(config.w * stage.c, config.h * y); positions.push(config.w * stage.c + config.padding * (stage.c - 1), config.h * y + config.padding * (y - 1));
colors.push(r, g, b, 255); colors.push(r, g, b, a);
uvs.push(u, v); uvs.push(u, v);
result.count++; result.count++;

BIN
ibm_vga8.woff2

Binary file not shown.

2
index.html

@ -21,7 +21,7 @@
<body> <body>
<div class="main"> <div class="main">
<canvas id="c"></canvas> <canvas id="c"></canvas>
<canvas id="offscreen" width="128" height="128"></canvas> <canvas id="offscreen" width="32" height="32"></canvas>
</div> </div>
</body> </body>
</html> </html>

5
index.js

@ -3,7 +3,12 @@ document.addEventListener('DOMContentLoaded', main);
let traces = {}; let traces = {};
function main() { function main() {
const font = new FontFace('ibm8x16', 'url(ibm_vga8.woff2)');
document.fonts.add(font);
font.load();
document.fonts.ready.then(() => {
init_webgl(); init_webgl();
init_rasterizer(); init_rasterizer();
init_listeners(); init_listeners();
});
} }

4
input.js

@ -73,8 +73,8 @@ function jump_to_first_instruction() {
const trace = traces[Object.keys(traces)[0]].raw; const trace = traces[Object.keys(traces)[0]].raw;
if (Object.keys(trace).length > 0) { if (Object.keys(trace).length > 0) {
const first_instruction = trace[Object.keys(trace)[0]]; const first_instruction = trace[Object.keys(trace)[0]];
offset.x = -first_instruction.cycle * config.w; offset.x = -first_instruction.cycle * config.w + config.padding * 2;
offset.y = 0 * config.h; offset.y = config.padding * 2;
zoom_target = 1; zoom_target = 1;
zoom = 1; zoom = 1;
schedule_draw(); schedule_draw();

9
rasterizer.js

@ -4,12 +4,15 @@ let c2d = null;
function init_rasterizer() { function init_rasterizer() {
c2d = document.querySelector('#offscreen').getContext('2d'); c2d = document.querySelector('#offscreen').getContext('2d');
c2d.font = '14px monospace'; c2d.font = '16px ibm8x16';
c2d.fillStyle = 'white'; //c2d.font = '14px monospace';
c2d.textAlign = 'center';
c2d.textBaseline = 'middle';
c2d.fillStyle = '#eeeeee';
} }
function rasterize(text) { function rasterize(text) {
c2d.clearRect(0, 0, c2d.canvas.width, c2d.canvas.height); 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); //c2d.fillRect(0, 0, 32, 32);
} }

18
render.js

@ -6,6 +6,7 @@ let config = {
bytes_per_quad: 28, bytes_per_quad: 28,
w: 32, w: 32,
h: 32, h: 32,
padding: 2,
predefined_colors: { predefined_colors: {
'Np': [75, 62, 143], 'Np': [75, 62, 143],
@ -69,29 +70,30 @@ const tquad_vs_src = `#version 300 es
} }
vec2 cycles = a_size / u_tile; vec2 cycles = a_size / u_tile;
vec2 tt = u_textile / u_tile;
if (vertex_index == 0) { if (vertex_index == 0) {
// "top left" aka "p1" // "top left" aka "p1"
corner = a_pos + inset; corner = a_pos;
uv = a_uv; uv = a_uv;
} else if (vertex_index == 1 || vertex_index == 5) { } else if (vertex_index == 1 || vertex_index == 5) {
// "top right" aka "p2" // "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); uv = a_uv + vec2(u_textile.x * cycles.x, 0);
} else if (vertex_index == 2 || vertex_index == 4) { } else if (vertex_index == 2 || vertex_index == 4) {
// "bottom left" aka "p3" // "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); uv = a_uv + vec2(0, u_textile.y * cycles.y);
} else { } else {
// "bottom right" aka "p4" // "bottom right" aka "p4"
corner = a_pos + a_size - inset; corner = a_pos + a_size;
uv = a_uv + u_textile * cycles; uv = a_uv + u_textile * cycles;
} }
vec2 screen02 = (corner.xy * vec2(u_scale) + u_translation) / u_res * 2.0; vec2 screen02 = (corner.xy * vec2(u_scale) + u_translation) / u_res * 2.0;
screen02.y = 2.0 - screen02.y; screen02.y = 2.0 - screen02.y;
v_color = a_color; 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); 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; in vec2 v_uv;
uniform sampler2D u_texture; uniform sampler2D u_texture;
uniform float u_fade;
layout(location = 0) out vec4 FragColor; layout(location = 0) out vec4 FragColor;
void main() { void main() {
vec4 text = texture(u_texture, v_uv); 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) { if (quads.count > 0) {
const program = programs['quad']; const program = programs['quad'];
const fade = Math.max(0, Math.min(1.25 * zoom - 0.25, 1));
gl.useProgram(program.program); gl.useProgram(program.program);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_packed']); 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.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.uniform1i(program.locations['u_texture'], textures['raster']);
gl.uniform2f(program.locations['u_tile'], config.w, config.h); 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_pos']);
gl.enableVertexAttribArray(program.locations['a_size']); gl.enableVertexAttribArray(program.locations['a_size']);

Loading…
Cancel
Save