Skip to content

Commit 3b67a4b

Browse files
committed
WIP gldemo switch to OffscreenCanvas
1 parent 471179f commit 3b67a4b

File tree

4 files changed

+4185
-4292
lines changed

4 files changed

+4185
-4292
lines changed

cube/gldemo.html

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@
99
</head>
1010

1111
<body>
12-
<div style="height: 80%">
13-
<canvas id="world"></canvas>
14-
</div>
15-
<div style="height: 20%">
16-
<canvas id="sheet" data-font="monospace" data-glyphs="🧚🍵🫖⛵"></canvas>
17-
</div>
12+
<canvas id="world"></canvas>
1813
<script type="module">
1914
import demo from './gldemo.js';
2015

21-
// TODO use an (experimental) OffscreenCanvas for the sheet
22-
const $sheet = document.querySelector('canvas#sheet');
23-
2416
const $world = document.querySelector('canvas#world');
25-
if ($sheet && $world) demo({$sheet, $world});
17+
if ($world) demo({
18+
$world,
19+
glyphFont: 'monospace',
20+
tiles: [
21+
{glyph: '🧚'},
22+
{glyph: '🍵'},
23+
{glyph: '🫖'},
24+
{glyph: '⛵'}
25+
]
26+
});
2627
</script>
2728
</body>
2829

cube/gldemo.js

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ const shaderSources = [
1313
/**
1414
* @param {object} param
1515
* @param {HTMLCanvasElement} param.$world
16-
* @param {HTMLCanvasElement} param.$sheet
16+
* @param {string} [param.glyphFont]
17+
* @param {{glyph: string}[]} param.tiles
1718
*/
1819
export default async function demo({
1920
$world,
20-
$sheet,
21+
glyphFont = 'sans',
22+
tiles,
2123
}) {
2224
const gl = (() => {
2325
const gl = $world.getContext('webgl2');
@@ -145,6 +147,9 @@ export default async function demo({
145147
// If you actually want to work with pre-multiplied alpha textures then you probably want
146148
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
147149

150+
// NOTE: must be a power of 2
151+
const tileSize = 128;
152+
148153
const sheetTex = gl.createTexture();
149154
const sheetTexUnit = gl.TEXTURE0;
150155
const sheetTexTarget = gl.TEXTURE_2D;
@@ -154,7 +159,6 @@ export default async function demo({
154159
// The biggest immediate difference would be less concern around translating
155160
// texel coordinates (the divide-by-sheetBounds in the fragment shader.)
156161

157-
let tileSize = 0;
158162
let maxTileID = 0;
159163

160164
const perspective = mat4.identity(new Float32Array(16));
@@ -166,7 +170,7 @@ export default async function demo({
166170
let locData = new Float32Array(0)
167171
let tileData = new Uint16Array(0);
168172

169-
sizeToParent($sheet, drawSheet);
173+
drawSheet();
170174
sizeToParent($world);
171175

172176
/** @returns {Promise<number>} */
@@ -276,35 +280,13 @@ export default async function demo({
276280

277281
}
278282

279-
function updateSheetTex() {
280-
gl.uniform2ui(uni.sheetBounds,
281-
Math.floor($sheet.width / tileSize),
282-
Math.floor($sheet.height / tileSize));
283-
284-
gl.activeTexture(sheetTexUnit);
285-
gl.bindTexture(sheetTexTarget, sheetTex);
286-
287-
gl.texImage2D(sheetTexTarget, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, $sheet);
288-
gl.generateMipmap(sheetTexTarget);
289-
290-
gl.texParameteri(sheetTexTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
291-
gl.texParameteri(sheetTexTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
292-
293-
gl.texParameteri(sheetTexTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
294-
gl.texParameteri(sheetTexTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
295-
}
296-
297283
function drawSheet() {
298-
const sheetText = $sheet.dataset['glyphs'] || '...';
299-
const sheetFont = $sheet.dataset['font'] || 'sans';
284+
const $sheet = new OffscreenCanvas(tileSize, tileSize * tiles.length);
300285

301-
const glyphs = Array.from(sheetText);
286+
const glyphs = tiles.map(({ glyph }) => glyph);
302287

303-
// NOTE: we round the sheet size down to a power of 2 because GL mipmap
304-
// generation requires texture to be such size
305-
$sheet.height = Math.pow(2, Math.floor(Math.log($sheet.height) / Math.log(2)));
306-
tileSize = $sheet.height;
307288
$sheet.width = tileSize * glyphs.length;
289+
$sheet.height = tileSize;
308290

309291
// TODO this is necessary to stop topline clipping, but why...
310292
const fontSize = tileSize * 0.9;
@@ -318,7 +300,7 @@ export default async function demo({
318300
for (let adjust = 0; adjust <= fontSize; adjust++) {
319301
if (adjust == fontSize)
320302
throw new Error(`unable to find a usable font adjustment for fontSize:${fontSize}`);
321-
ctx.font = `${fontSize - adjust}px ${sheetFont}`;
303+
ctx.font = `${fontSize - adjust}px ${glyphFont}`;
322304
const metrics = glyphs
323305
.map(glyph => ctx.measureText(glyph))
324306
.map(({
@@ -341,7 +323,7 @@ export default async function demo({
341323
// lay down glyphs in a 1d strip
342324
ctx.textBaseline = 'bottom';
343325
let x = 0, y = tileSize;
344-
for (const glyph of sheetText) {
326+
for (const glyph of glyphs) {
345327
const {
346328
actualBoundingBoxLeft,
347329
actualBoundingBoxRight,
@@ -357,7 +339,21 @@ export default async function demo({
357339
}
358340
}
359341

360-
updateSheetTex();
342+
gl.uniform2ui(uni.sheetBounds,
343+
Math.floor($sheet.width / tileSize),
344+
Math.floor($sheet.height / tileSize));
345+
346+
gl.activeTexture(sheetTexUnit);
347+
gl.bindTexture(sheetTexTarget, sheetTex);
348+
349+
gl.texImage2D(sheetTexTarget, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, $sheet);
350+
gl.generateMipmap(sheetTexTarget);
351+
352+
gl.texParameteri(sheetTexTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
353+
gl.texParameteri(sheetTexTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
354+
355+
gl.texParameteri(sheetTexTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
356+
gl.texParameteri(sheetTexTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
361357
}
362358

363359
}

cube/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"devDependencies": {
2424
"@snowpack/plugin-optimize": "^0.2.13",
2525
"@snowpack/plugin-typescript": "^1.2.1",
26+
"@types/offscreencanvas": "^2019.7.0",
2627
"@types/snowpack-env": "^2.3.4",
2728
"@types/wicg-native-file-system": "^2020.6.0",
2829
"ava": "^4.2.0",

0 commit comments

Comments
 (0)