Skip to content

Commit 5c63a12

Browse files
committed
WIP gldemo switch to 2d array texture
1 parent 3b67a4b commit 5c63a12

File tree

3 files changed

+28
-34
lines changed

3 files changed

+28
-34
lines changed

cube/gldemo.frag.glsl

+4-8
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ precision highp float;
44
precision highp int;
55
precision highp sampler2DArray;
66

7-
uniform sampler2D sheet;
7+
uniform sampler2DArray sheet;
88

9-
uniform uvec2 sheetBounds;
10-
11-
in vec2 sheetAt;
9+
in float sheetLayer;
1210

1311
out lowp vec4 color;
1412

1513
void main(void) {
1614
mediump vec2 tileAt = gl_PointCoord;
17-
color = texture(sheet,
18-
(sheetAt + tileAt)
19-
/ vec2(float(sheetBounds.x), float(sheetBounds.y))
20-
);
15+
16+
color = texture(sheet, vec3(tileAt, sheetLayer));
2117
}

cube/gldemo.js

+22-20
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 {number} [param.cellSize]
1617
* @param {string} [param.glyphFont]
1718
* @param {{glyph: string}[]} param.tiles
1819
*/
1920
export default async function demo({
2021
$world,
22+
cellSize = 64,
2123
glyphFont = 'sans',
2224
tiles,
2325
}) {
@@ -103,7 +105,6 @@ export default async function demo({
103105
};
104106

105107
const uni = {
106-
sheetBounds: mustGetUniform('sheetBounds'), // uvec2
107108
sheet: mustGetUniform('sheet'), // sampler2D
108109
perspective: mustGetUniform('perspective'), // mediump mat4
109110
};
@@ -148,16 +149,17 @@ export default async function demo({
148149
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
149150

150151
// NOTE: must be a power of 2
151-
const tileSize = 128;
152+
const tileSize = 256;
152153

153154
const sheetTex = gl.createTexture();
154155
const sheetTexUnit = gl.TEXTURE0;
155-
const sheetTexTarget = gl.TEXTURE_2D;
156+
const sheetTexTarget = gl.TEXTURE_2D_ARRAY;
157+
const sheetMipLevels = 4;
158+
const sheetLayers = 2048;
156159

157-
// TODO we're using a classic gl.TEXTURE_2D atlas for now, but are probably
158-
// better suited by gl.TEXTURE_2D_ARRAY from webgl2.
159-
// The biggest immediate difference would be less concern around translating
160-
// texel coordinates (the divide-by-sheetBounds in the fragment shader.)
160+
gl.activeTexture(sheetTexUnit);
161+
gl.bindTexture(sheetTexTarget, sheetTex);
162+
gl.texStorage3D(sheetTexTarget, sheetMipLevels, gl.RGBA8, tileSize, tileSize, sheetLayers);
161163

162164
let maxTileID = 0;
163165

@@ -184,14 +186,11 @@ export default async function demo({
184186

185187
const { width, height } = $world;
186188

187-
// increase to "zoom out"
188-
const zoom = 1;
189-
190189
/// build world data
191190
// NOTE: typically this isn't done per-frame, but this is a demo
192191
{
193-
const W = Math.ceil(width / tileSize) * zoom;
194-
const H = Math.ceil(height / tileSize) * zoom;
192+
const W = Math.ceil(width / cellSize);
193+
const H = Math.ceil(height / cellSize);
195194
const N = (W + 1) * H;
196195

197196
if (locData.length != 2 * N)
@@ -264,7 +263,7 @@ export default async function demo({
264263

265264
gl.enableVertexAttribArray(attr.loc);
266265
gl.enableVertexAttribArray(attr.tileID);
267-
gl.vertexAttrib1f(attr.size, tileSize / zoom);
266+
gl.vertexAttrib1f(attr.size, cellSize);
268267

269268
gl.bindBuffer(gl.ARRAY_BUFFER, locBuffer)
270269
gl.vertexAttribPointer(attr.loc, 2, gl.FLOAT, false, 0, 0);
@@ -285,8 +284,8 @@ export default async function demo({
285284

286285
const glyphs = tiles.map(({ glyph }) => glyph);
287286

288-
$sheet.width = tileSize * glyphs.length;
289-
$sheet.height = tileSize;
287+
$sheet.width = tileSize;
288+
$sheet.height = tileSize * glyphs.length;
290289

291290
// TODO this is necessary to stop topline clipping, but why...
292291
const fontSize = tileSize * 0.9;
@@ -334,19 +333,22 @@ export default async function demo({
334333
ctx.fillStyle = 'black';
335334
ctx.fillText(glyph, x + Math.floor(widthRem / 2), y);
336335

337-
x += tileSize;
336+
y += tileSize;
338337
maxTileID++;
339338
}
340339
}
341340

342-
gl.uniform2ui(uni.sheetBounds,
343-
Math.floor($sheet.width / tileSize),
344-
Math.floor($sheet.height / tileSize));
341+
const haveLayers = $sheet.height / tileSize;
345342

346343
gl.activeTexture(sheetTexUnit);
347344
gl.bindTexture(sheetTexTarget, sheetTex);
348345

349-
gl.texImage2D(sheetTexTarget, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, $sheet);
346+
gl.texSubImage3D(
347+
sheetTexTarget, 0,
348+
0, 0, 0,
349+
tileSize, tileSize, haveLayers,
350+
gl.RGBA, gl.UNSIGNED_BYTE, $sheet);
351+
350352
gl.generateMipmap(sheetTexTarget);
351353

352354
gl.texParameteri(sheetTexTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);

cube/gldemo.vert.glsl

+2-6
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
precision highp float;
44
precision highp int;
55

6-
uniform uvec2 sheetBounds;
7-
86
uniform mat4 perspective;
97

108
in vec2 loc;
119
in float size;
1210
in uint tileID;
1311

14-
out vec2 sheetAt;
12+
out float sheetLayer;
1513

1614
void main(void) {
1715
gl_Position = perspective * vec4(
@@ -22,7 +20,5 @@ void main(void) {
2220

2321
gl_PointSize = size;
2422

25-
sheetAt = vec2(
26-
tileID % sheetBounds.x,
27-
tileID / sheetBounds.x);
23+
sheetLayer = float(tileID);
2824
}

0 commit comments

Comments
 (0)