diff --git a/default.css b/default.css index b9937ac..722971f 100644 --- a/default.css +++ b/default.css @@ -8,9 +8,19 @@ html, body { body .main { height: 100%; + position: relative; } .main #c { width: 100%; height: 100%; } + +.main #offscreen { + position: absolute; + top: -999px; + left: -999px; + width: 128px; + height: 128px; + z-index: 1; +} diff --git a/geometry.js b/geometry.js index 326c748..296e166 100644 --- a/geometry.js +++ b/geometry.js @@ -1,4 +1,5 @@ let colors = {}; +let rasterized = {}; function get_color(stage_name) { if (stage_name in config.predefined_colors) { @@ -18,7 +19,57 @@ function get_color(stage_name) { return colors[stage_name]; } +function rasterize_and_pack(text, cycles) { + // TODO: handle texture is full or stuff don't fit (unlikely) + + const key = text + '@' + cycles; + + if (key in rasterized) { + return rasterized[key]; + } + + const tiles_needed = cycles - 1 + 1; // stage name + count from one + if (tiles_needed > config.raster_texture_size / config.w - raster_tile.x) { + raster_tile.x = 0; + raster_tile.y += 1; + } + + const u = raster_tile.x * config.w / config.raster_texture_size; + const v = raster_tile.y * config.h / config.raster_texture_size; + + rasterize(text); + 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; + + 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; + } + + if (raster_tile.x === config.raster_texture_size / config.w) { + raster_tile.x = 0; + raster_tile.y += 1; + } + + rasterized[key] = [u, v]; + + return [u, v]; +} + function generate(trace_id) { + const before = performance.now(); + const result = { 'count': 0, }; @@ -26,6 +77,7 @@ function generate(trace_id) { const positions = []; const sizes = []; const colors = []; + const uvs = []; let instructions = {}; @@ -56,9 +108,12 @@ function generate(trace_id) { b = Math.max(50, b - 50); } + 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); + uvs.push(u, v); result.count++; @@ -70,9 +125,22 @@ function generate(trace_id) { ++y; } - result.pos = new Float32Array(positions); - result.size = new Float32Array(sizes); - result.color = new Uint8Array(colors); + if (false) { + result.pos = new Float32Array([0, 0]); + result.size = new Float32Array([config.raster_texture_size, config.raster_texture_size]); + result.color = new Uint8Array([0, 0, 0, 255]); + result.uv = new Float32Array([0, 0]); + result.count = 1; + } else { + result.pos = new Float32Array(positions); + result.size = new Float32Array(sizes); + result.color = new Uint8Array(colors); + result.uv = new Float32Array(uvs); + } + + const after = performance.now(); + + console.log(`Generated geometry in ${Math.round(after - before)}ms`); return result; } diff --git a/index.html b/index.html index a828e3f..9f42726 100644 --- a/index.html +++ b/index.html @@ -16,10 +16,12 @@ +