@@ -13,11 +13,13 @@ const shaderSources = [
13
13
/**
14
14
* @param {object } param
15
15
* @param {HTMLCanvasElement } param.$world
16
+ * @param {number } [param.cellSize]
16
17
* @param {string } [param.glyphFont]
17
18
* @param {{glyph: string}[] } param.tiles
18
19
*/
19
20
export default async function demo ( {
20
21
$world,
22
+ cellSize = 64 ,
21
23
glyphFont = 'sans' ,
22
24
tiles,
23
25
} ) {
@@ -103,7 +105,6 @@ export default async function demo({
103
105
} ;
104
106
105
107
const uni = {
106
- sheetBounds : mustGetUniform ( 'sheetBounds' ) , // uvec2
107
108
sheet : mustGetUniform ( 'sheet' ) , // sampler2D
108
109
perspective : mustGetUniform ( 'perspective' ) , // mediump mat4
109
110
} ;
@@ -148,16 +149,17 @@ export default async function demo({
148
149
gl . blendFunc ( gl . ONE , gl . ONE_MINUS_SRC_ALPHA ) ;
149
150
150
151
// NOTE: must be a power of 2
151
- const tileSize = 128 ;
152
+ const tileSize = 256 ;
152
153
153
154
const sheetTex = gl . createTexture ( ) ;
154
155
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 ;
156
159
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 ) ;
161
163
162
164
let maxTileID = 0 ;
163
165
@@ -184,14 +186,11 @@ export default async function demo({
184
186
185
187
const { width, height } = $world ;
186
188
187
- // increase to "zoom out"
188
- const zoom = 1 ;
189
-
190
189
/// build world data
191
190
// NOTE: typically this isn't done per-frame, but this is a demo
192
191
{
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 ) ;
195
194
const N = ( W + 1 ) * H ;
196
195
197
196
if ( locData . length != 2 * N )
@@ -264,7 +263,7 @@ export default async function demo({
264
263
265
264
gl . enableVertexAttribArray ( attr . loc ) ;
266
265
gl . enableVertexAttribArray ( attr . tileID ) ;
267
- gl . vertexAttrib1f ( attr . size , tileSize / zoom ) ;
266
+ gl . vertexAttrib1f ( attr . size , cellSize ) ;
268
267
269
268
gl . bindBuffer ( gl . ARRAY_BUFFER , locBuffer )
270
269
gl . vertexAttribPointer ( attr . loc , 2 , gl . FLOAT , false , 0 , 0 ) ;
@@ -285,8 +284,8 @@ export default async function demo({
285
284
286
285
const glyphs = tiles . map ( ( { glyph } ) => glyph ) ;
287
286
288
- $sheet . width = tileSize * glyphs . length ;
289
- $sheet . height = tileSize ;
287
+ $sheet . width = tileSize ;
288
+ $sheet . height = tileSize * glyphs . length ;
290
289
291
290
// TODO this is necessary to stop topline clipping, but why...
292
291
const fontSize = tileSize * 0.9 ;
@@ -334,19 +333,22 @@ export default async function demo({
334
333
ctx . fillStyle = 'black' ;
335
334
ctx . fillText ( glyph , x + Math . floor ( widthRem / 2 ) , y ) ;
336
335
337
- x += tileSize ;
336
+ y += tileSize ;
338
337
maxTileID ++ ;
339
338
}
340
339
}
341
340
342
- gl . uniform2ui ( uni . sheetBounds ,
343
- Math . floor ( $sheet . width / tileSize ) ,
344
- Math . floor ( $sheet . height / tileSize ) ) ;
341
+ const haveLayers = $sheet . height / tileSize ;
345
342
346
343
gl . activeTexture ( sheetTexUnit ) ;
347
344
gl . bindTexture ( sheetTexTarget , sheetTex ) ;
348
345
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
+
350
352
gl . generateMipmap ( sheetTexTarget ) ;
351
353
352
354
gl . texParameteri ( sheetTexTarget , gl . TEXTURE_MIN_FILTER , gl . LINEAR_MIPMAP_LINEAR ) ;
0 commit comments