@vectojs/core 1.22.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -924,10 +924,11 @@ var FLOATS_PER_POINT = 7;
924
924
  var POINT_STRIDE = FLOATS_PER_POINT * 4;
925
925
  var VERTS_PER_QUAD = 4;
926
926
  var INDICES_PER_QUAD = 6;
927
- var FLOATS_PER_RECT_VERT = 6;
928
- var RECT_VERT_STRIDE = FLOATS_PER_RECT_VERT * 4;
929
- var FLOATS_PER_SPRITE_VERT = 8;
930
- var SPRITE_VERT_STRIDE = FLOATS_PER_SPRITE_VERT * 4;
927
+ var PACKED_QUAD_VERT_STRIDE = 16;
928
+ var PACKED_RECT_VERT_STRIDE = 12;
929
+ var PACKED_UV_OFFSET = 8;
930
+ var PACKED_TINT_OFFSET = 12;
931
+ var PACKED_RECT_TINT_OFFSET = 8;
931
932
  function buildQuadIndices(quads) {
932
933
  const out = new Uint32Array(quads * INDICES_PER_QUAD);
933
934
  for (let i = 0; i < quads; i++) {
@@ -942,6 +943,35 @@ function buildQuadIndices(quads) {
942
943
  }
943
944
  return out;
944
945
  }
946
+ function encodeUnorm(v, max) {
947
+ return v <= 0 ? 0 : v >= 1 ? max : v * max + 0.5 | 0;
948
+ }
949
+ var LITTLE_ENDIAN = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
950
+ function packTint(r, g, b, a) {
951
+ const ri = encodeUnorm(r, 255);
952
+ const gi = encodeUnorm(g, 255);
953
+ const bi = encodeUnorm(b, 255);
954
+ const ai = encodeUnorm(a, 255);
955
+ return LITTLE_ENDIAN ? ai << 24 | bi << 16 | gi << 8 | ri : ri << 24 | gi << 16 | bi << 8 | ai;
956
+ }
957
+ function createPackedBuffer(byteLength) {
958
+ const bytes = new ArrayBuffer(byteLength);
959
+ return {
960
+ bytes,
961
+ f32: new Float32Array(bytes),
962
+ u16: new Uint16Array(bytes),
963
+ u32: new Uint32Array(bytes),
964
+ u8: new Uint8Array(bytes)
965
+ };
966
+ }
967
+ function growPacked(buf, neededBytes) {
968
+ if (neededBytes <= buf.bytes.byteLength) return buf;
969
+ let cap = buf.bytes.byteLength;
970
+ while (cap < neededBytes) cap *= 2;
971
+ const grown = createPackedBuffer(cap);
972
+ grown.u8.set(buf.u8);
973
+ return grown;
974
+ }
945
975
  var POINT_VERT = `#version 300 es
946
976
  in vec2 a_pos;
947
977
  in float a_radius;
@@ -1069,7 +1099,7 @@ function link(gl, vsSrc, fsSrc) {
1069
1099
  }
1070
1100
  return program;
1071
1101
  }
1072
- function writeQuad(out, o, x, y, width, height, u0, v0, u1, v1, r, g, b, al, rotation) {
1102
+ function writeQuad(out, byteOffset, x, y, width, height, u0, v0, u1, v1, r, g, b, al, rotation) {
1073
1103
  let x1;
1074
1104
  let y1;
1075
1105
  let x2;
@@ -1097,40 +1127,39 @@ function writeQuad(out, o, x, y, width, height, u0, v0, u1, v1, r, g, b, al, rot
1097
1127
  x3 = x - hs;
1098
1128
  y3 = y + hc;
1099
1129
  }
1100
- out[o] = x;
1101
- out[o + 1] = y;
1102
- out[o + 2] = u0;
1103
- out[o + 3] = v0;
1104
- out[o + 4] = r;
1105
- out[o + 5] = g;
1106
- out[o + 6] = b;
1107
- out[o + 7] = al;
1108
- out[o + 8] = x1;
1109
- out[o + 9] = y1;
1110
- out[o + 10] = u1;
1111
- out[o + 11] = v0;
1112
- out[o + 12] = r;
1113
- out[o + 13] = g;
1114
- out[o + 14] = b;
1115
- out[o + 15] = al;
1116
- out[o + 16] = x2;
1117
- out[o + 17] = y2;
1118
- out[o + 18] = u1;
1119
- out[o + 19] = v1;
1120
- out[o + 20] = r;
1121
- out[o + 21] = g;
1122
- out[o + 22] = b;
1123
- out[o + 23] = al;
1124
- out[o + 24] = x3;
1125
- out[o + 25] = y3;
1126
- out[o + 26] = u0;
1127
- out[o + 27] = v1;
1128
- out[o + 28] = r;
1129
- out[o + 29] = g;
1130
- out[o + 30] = b;
1131
- out[o + 31] = al;
1130
+ const iu0 = encodeUnorm(u0, 65535);
1131
+ const iv0 = encodeUnorm(v0, 65535);
1132
+ const iu1 = encodeUnorm(u1, 65535);
1133
+ const iv1 = encodeUnorm(v1, 65535);
1134
+ const tint = packTint(r, g, b, al);
1135
+ const f32 = out.f32;
1136
+ const u16 = out.u16;
1137
+ const u32 = out.u32;
1138
+ const fi = byteOffset >> 2;
1139
+ const si = byteOffset + PACKED_UV_OFFSET >> 1;
1140
+ const ti = byteOffset + PACKED_TINT_OFFSET >> 2;
1141
+ f32[fi] = x;
1142
+ f32[fi + 1] = y;
1143
+ u16[si] = iu0;
1144
+ u16[si + 1] = iv0;
1145
+ u32[ti] = tint;
1146
+ f32[fi + 4] = x1;
1147
+ f32[fi + 5] = y1;
1148
+ u16[si + 8] = iu1;
1149
+ u16[si + 9] = iv0;
1150
+ u32[ti + 4] = tint;
1151
+ f32[fi + 8] = x2;
1152
+ f32[fi + 9] = y2;
1153
+ u16[si + 16] = iu1;
1154
+ u16[si + 17] = iv1;
1155
+ u32[ti + 8] = tint;
1156
+ f32[fi + 12] = x3;
1157
+ f32[fi + 13] = y3;
1158
+ u16[si + 24] = iu0;
1159
+ u16[si + 25] = iv1;
1160
+ u32[ti + 12] = tint;
1132
1161
  }
1133
- function writeRectQuad(out, o, x, y, width, height, r, g, b, al, rotation) {
1162
+ function writeRectQuad(out, byteOffset, x, y, width, height, r, g, b, al, rotation) {
1134
1163
  let x1;
1135
1164
  let y1;
1136
1165
  let x2;
@@ -1158,30 +1187,22 @@ function writeRectQuad(out, o, x, y, width, height, r, g, b, al, rotation) {
1158
1187
  x3 = x - hs;
1159
1188
  y3 = y + hc;
1160
1189
  }
1161
- out[o] = x;
1162
- out[o + 1] = y;
1163
- out[o + 2] = r;
1164
- out[o + 3] = g;
1165
- out[o + 4] = b;
1166
- out[o + 5] = al;
1167
- out[o + 6] = x1;
1168
- out[o + 7] = y1;
1169
- out[o + 8] = r;
1170
- out[o + 9] = g;
1171
- out[o + 10] = b;
1172
- out[o + 11] = al;
1173
- out[o + 12] = x2;
1174
- out[o + 13] = y2;
1175
- out[o + 14] = r;
1176
- out[o + 15] = g;
1177
- out[o + 16] = b;
1178
- out[o + 17] = al;
1179
- out[o + 18] = x3;
1180
- out[o + 19] = y3;
1181
- out[o + 20] = r;
1182
- out[o + 21] = g;
1183
- out[o + 22] = b;
1184
- out[o + 23] = al;
1190
+ const tint = packTint(r, g, b, al);
1191
+ const f32 = out.f32;
1192
+ const u32 = out.u32;
1193
+ const fi = byteOffset >> 2;
1194
+ f32[fi] = x;
1195
+ f32[fi + 1] = y;
1196
+ u32[fi + 2] = tint;
1197
+ f32[fi + 3] = x1;
1198
+ f32[fi + 4] = y1;
1199
+ u32[fi + 5] = tint;
1200
+ f32[fi + 6] = x2;
1201
+ f32[fi + 7] = y2;
1202
+ u32[fi + 8] = tint;
1203
+ f32[fi + 9] = x3;
1204
+ f32[fi + 10] = y3;
1205
+ u32[fi + 11] = tint;
1185
1206
  }
1186
1207
  function grow(data, needed) {
1187
1208
  if (needed <= data.length) return data;
@@ -1228,9 +1249,16 @@ function createWebGLPointRenderer(canvas) {
1228
1249
  gl.bindVertexArray(rectVAO);
1229
1250
  gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);
1230
1251
  gl.enableVertexAttribArray(rAPos);
1231
- gl.vertexAttribPointer(rAPos, 2, gl.FLOAT, false, RECT_VERT_STRIDE, 0);
1252
+ gl.vertexAttribPointer(rAPos, 2, gl.FLOAT, false, PACKED_RECT_VERT_STRIDE, 0);
1232
1253
  gl.enableVertexAttribArray(rAColor);
1233
- gl.vertexAttribPointer(rAColor, 4, gl.FLOAT, false, RECT_VERT_STRIDE, 8);
1254
+ gl.vertexAttribPointer(
1255
+ rAColor,
1256
+ 4,
1257
+ gl.UNSIGNED_BYTE,
1258
+ true,
1259
+ PACKED_RECT_VERT_STRIDE,
1260
+ PACKED_RECT_TINT_OFFSET
1261
+ );
1234
1262
  const sAPos = gl.getAttribLocation(spriteProgram, "a_pos");
1235
1263
  const sAUv = gl.getAttribLocation(spriteProgram, "a_uv");
1236
1264
  const sATint = gl.getAttribLocation(spriteProgram, "a_tint");
@@ -1241,11 +1269,25 @@ function createWebGLPointRenderer(canvas) {
1241
1269
  gl.bindVertexArray(spriteVAO);
1242
1270
  gl.bindBuffer(gl.ARRAY_BUFFER, spriteBuffer);
1243
1271
  gl.enableVertexAttribArray(sAPos);
1244
- gl.vertexAttribPointer(sAPos, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 0);
1272
+ gl.vertexAttribPointer(sAPos, 2, gl.FLOAT, false, PACKED_QUAD_VERT_STRIDE, 0);
1245
1273
  gl.enableVertexAttribArray(sAUv);
1246
- gl.vertexAttribPointer(sAUv, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 8);
1274
+ gl.vertexAttribPointer(
1275
+ sAUv,
1276
+ 2,
1277
+ gl.UNSIGNED_SHORT,
1278
+ true,
1279
+ PACKED_QUAD_VERT_STRIDE,
1280
+ PACKED_UV_OFFSET
1281
+ );
1247
1282
  gl.enableVertexAttribArray(sATint);
1248
- gl.vertexAttribPointer(sATint, 4, gl.FLOAT, false, SPRITE_VERT_STRIDE, 16);
1283
+ gl.vertexAttribPointer(
1284
+ sATint,
1285
+ 4,
1286
+ gl.UNSIGNED_BYTE,
1287
+ true,
1288
+ PACKED_QUAD_VERT_STRIDE,
1289
+ PACKED_TINT_OFFSET
1290
+ );
1249
1291
  const gAPos = gl.getAttribLocation(msdfProgram, "a_pos");
1250
1292
  const gAUv = gl.getAttribLocation(msdfProgram, "a_uv");
1251
1293
  const gATint = gl.getAttribLocation(msdfProgram, "a_tint");
@@ -1257,11 +1299,25 @@ function createWebGLPointRenderer(canvas) {
1257
1299
  gl.bindVertexArray(glyphVAO);
1258
1300
  gl.bindBuffer(gl.ARRAY_BUFFER, glyphBuffer);
1259
1301
  gl.enableVertexAttribArray(gAPos);
1260
- gl.vertexAttribPointer(gAPos, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 0);
1302
+ gl.vertexAttribPointer(gAPos, 2, gl.FLOAT, false, PACKED_QUAD_VERT_STRIDE, 0);
1261
1303
  gl.enableVertexAttribArray(gAUv);
1262
- gl.vertexAttribPointer(gAUv, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 8);
1304
+ gl.vertexAttribPointer(
1305
+ gAUv,
1306
+ 2,
1307
+ gl.UNSIGNED_SHORT,
1308
+ true,
1309
+ PACKED_QUAD_VERT_STRIDE,
1310
+ PACKED_UV_OFFSET
1311
+ );
1263
1312
  gl.enableVertexAttribArray(gATint);
1264
- gl.vertexAttribPointer(gATint, 4, gl.FLOAT, false, SPRITE_VERT_STRIDE, 16);
1313
+ gl.vertexAttribPointer(
1314
+ gATint,
1315
+ 4,
1316
+ gl.UNSIGNED_BYTE,
1317
+ true,
1318
+ PACKED_QUAD_VERT_STRIDE,
1319
+ PACKED_TINT_OFFSET
1320
+ );
1265
1321
  const cAPos = gl.getAttribLocation(circleQuadProgram, "a_pos");
1266
1322
  const cAUv = gl.getAttribLocation(circleQuadProgram, "a_uv");
1267
1323
  const cATint = gl.getAttribLocation(circleQuadProgram, "a_tint");
@@ -1271,11 +1327,25 @@ function createWebGLPointRenderer(canvas) {
1271
1327
  gl.bindVertexArray(circleQuadVAO);
1272
1328
  gl.bindBuffer(gl.ARRAY_BUFFER, circleQuadBuffer);
1273
1329
  gl.enableVertexAttribArray(cAPos);
1274
- gl.vertexAttribPointer(cAPos, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 0);
1330
+ gl.vertexAttribPointer(cAPos, 2, gl.FLOAT, false, PACKED_QUAD_VERT_STRIDE, 0);
1275
1331
  gl.enableVertexAttribArray(cAUv);
1276
- gl.vertexAttribPointer(cAUv, 2, gl.FLOAT, false, SPRITE_VERT_STRIDE, 8);
1332
+ gl.vertexAttribPointer(
1333
+ cAUv,
1334
+ 2,
1335
+ gl.UNSIGNED_SHORT,
1336
+ true,
1337
+ PACKED_QUAD_VERT_STRIDE,
1338
+ PACKED_UV_OFFSET
1339
+ );
1277
1340
  gl.enableVertexAttribArray(cATint);
1278
- gl.vertexAttribPointer(cATint, 4, gl.FLOAT, false, SPRITE_VERT_STRIDE, 16);
1341
+ gl.vertexAttribPointer(
1342
+ cATint,
1343
+ 4,
1344
+ gl.UNSIGNED_BYTE,
1345
+ true,
1346
+ PACKED_QUAD_VERT_STRIDE,
1347
+ PACKED_TINT_OFFSET
1348
+ );
1279
1349
  gl.bindVertexArray(null);
1280
1350
  const quadIndexBuffer = gl.createBuffer();
1281
1351
  let quadIndexCapacity = 0;
@@ -1285,7 +1355,6 @@ function createWebGLPointRenderer(canvas) {
1285
1355
  while (cap < quads) cap *= 2;
1286
1356
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, quadIndexBuffer);
1287
1357
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, buildQuadIndices(cap), gl.STATIC_DRAW);
1288
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
1289
1358
  quadIndexCapacity = cap;
1290
1359
  };
1291
1360
  for (const vao of [rectVAO, spriteVAO, glyphVAO, circleQuadVAO]) {
@@ -1300,11 +1369,11 @@ function createWebGLPointRenderer(canvas) {
1300
1369
  let distanceRange = 4;
1301
1370
  let pointData = new Float32Array(FLOATS_PER_POINT * 1024);
1302
1371
  let pointCount = 0;
1303
- let rectData = new Float32Array(FLOATS_PER_RECT_VERT * VERTS_PER_QUAD * 256);
1372
+ let rectData = createPackedBuffer(PACKED_RECT_VERT_STRIDE * VERTS_PER_QUAD * 256);
1304
1373
  let rectCount = 0;
1305
- let spriteData = new Float32Array(FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD * 256);
1374
+ let spriteData = createPackedBuffer(PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD * 256);
1306
1375
  let spriteCount = 0;
1307
- let glyphData = new Float32Array(FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD * 1024);
1376
+ let glyphData = createPackedBuffer(PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD * 1024);
1308
1377
  let glyphCount = 0;
1309
1378
  let frameDrawCalls = 0;
1310
1379
  let lastFrameDrawCalls = 0;
@@ -1312,7 +1381,7 @@ function createWebGLPointRenderer(canvas) {
1312
1381
  let atlasSwitches = 0;
1313
1382
  let circleQuadFallbacks = 0;
1314
1383
  let circlePoints = 0;
1315
- let circleQuadData = new Float32Array(FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD * 64);
1384
+ let circleQuadData = createPackedBuffer(PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD * 64);
1316
1385
  let circleQuadCount = 0;
1317
1386
  let logicalW = 0;
1318
1387
  let logicalH = 0;
@@ -1322,11 +1391,11 @@ function createWebGLPointRenderer(canvas) {
1322
1391
  const maxPointSize = pointSizeRange ? pointSizeRange[1] : Infinity;
1323
1392
  const drawGlyphs = () => {
1324
1393
  if (glyphCount === 0 || !msdfTexture) return;
1325
- const floats = glyphCount * VERTS_PER_QUAD * FLOATS_PER_SPRITE_VERT;
1394
+ const bytes = glyphCount * VERTS_PER_QUAD * PACKED_QUAD_VERT_STRIDE;
1326
1395
  gl.useProgram(msdfProgram);
1327
1396
  gl.bindVertexArray(glyphVAO);
1328
1397
  gl.bindBuffer(gl.ARRAY_BUFFER, glyphBuffer);
1329
- gl.bufferData(gl.ARRAY_BUFFER, glyphData.subarray(0, floats), gl.DYNAMIC_DRAW);
1398
+ gl.bufferData(gl.ARRAY_BUFFER, glyphData.u8.subarray(0, bytes), gl.DYNAMIC_DRAW);
1330
1399
  gl.activeTexture(gl.TEXTURE0);
1331
1400
  gl.bindTexture(gl.TEXTURE_2D, msdfTexture);
1332
1401
  gl.uniform1i(gUTex, 0);
@@ -1393,8 +1462,8 @@ function createWebGLPointRenderer(canvas) {
1393
1462
  },
1394
1463
  addSprite(x, y, width, height, u0, v0, u1, v1, color = "#ffffff", alpha = 1, rotation = 0) {
1395
1464
  if (!texture) return;
1396
- const stride = FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD;
1397
- spriteData = grow(spriteData, (spriteCount + 1) * stride);
1465
+ const stride = PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD;
1466
+ spriteData = growPacked(spriteData, (spriteCount + 1) * stride);
1398
1467
  const rgba = parseColorToRGBA(color);
1399
1468
  writeQuad(
1400
1469
  spriteData,
@@ -1438,8 +1507,8 @@ function createWebGLPointRenderer(canvas) {
1438
1507
  },
1439
1508
  addGlyph(x, y, width, height, u0, v0, u1, v1, color = "#ffffff", alpha = 1, rotation = 0) {
1440
1509
  if (!msdfTexture) return;
1441
- const stride = FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD;
1442
- glyphData = grow(glyphData, (glyphCount + 1) * stride);
1510
+ const stride = PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD;
1511
+ glyphData = growPacked(glyphData, (glyphCount + 1) * stride);
1443
1512
  const rgba = parseColorToRGBA(color);
1444
1513
  writeQuad(
1445
1514
  glyphData,
@@ -1464,8 +1533,8 @@ function createWebGLPointRenderer(canvas) {
1464
1533
  const needsQuad = logicalW > 0 && (x < radius || y < radius || x > logicalW - radius || y > logicalH - radius) || radius * 2 * dpr > maxPointSize;
1465
1534
  if (needsQuad) {
1466
1535
  circleQuadFallbacks++;
1467
- const stride = FLOATS_PER_SPRITE_VERT * VERTS_PER_QUAD;
1468
- circleQuadData = grow(circleQuadData, (circleQuadCount + 1) * stride);
1536
+ const stride = PACKED_QUAD_VERT_STRIDE * VERTS_PER_QUAD;
1537
+ circleQuadData = growPacked(circleQuadData, (circleQuadCount + 1) * stride);
1469
1538
  const rgba = parseColorToRGBA(color);
1470
1539
  const d = radius * 2;
1471
1540
  writeQuad(
@@ -1502,8 +1571,8 @@ function createWebGLPointRenderer(canvas) {
1502
1571
  pointCount++;
1503
1572
  },
1504
1573
  addRect(x, y, width, height, color, alpha = 1, rotation = 0) {
1505
- const stride = FLOATS_PER_RECT_VERT * VERTS_PER_QUAD;
1506
- rectData = grow(rectData, (rectCount + 1) * stride);
1574
+ const stride = PACKED_RECT_VERT_STRIDE * VERTS_PER_QUAD;
1575
+ rectData = growPacked(rectData, (rectCount + 1) * stride);
1507
1576
  const rgba = parseColorToRGBA(color);
1508
1577
  writeRectQuad(
1509
1578
  rectData,
@@ -1522,11 +1591,11 @@ function createWebGLPointRenderer(canvas) {
1522
1591
  },
1523
1592
  flush() {
1524
1593
  if (rectCount > 0) {
1525
- const floats = rectCount * VERTS_PER_QUAD * FLOATS_PER_RECT_VERT;
1594
+ const bytes = rectCount * VERTS_PER_QUAD * PACKED_RECT_VERT_STRIDE;
1526
1595
  gl.useProgram(rectProgram);
1527
1596
  gl.bindVertexArray(rectVAO);
1528
1597
  gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);
1529
- gl.bufferData(gl.ARRAY_BUFFER, rectData.subarray(0, floats), gl.DYNAMIC_DRAW);
1598
+ gl.bufferData(gl.ARRAY_BUFFER, rectData.u8.subarray(0, bytes), gl.DYNAMIC_DRAW);
1530
1599
  gl.uniform2f(rURes, logicalW, logicalH);
1531
1600
  ensureQuadIndices(rectCount);
1532
1601
  gl.drawElements(gl.TRIANGLES, rectCount * INDICES_PER_QUAD, gl.UNSIGNED_INT, 0);
@@ -1547,22 +1616,22 @@ function createWebGLPointRenderer(canvas) {
1547
1616
  frameDrawCalls++;
1548
1617
  }
1549
1618
  if (circleQuadCount > 0) {
1550
- const floats = circleQuadCount * VERTS_PER_QUAD * FLOATS_PER_SPRITE_VERT;
1619
+ const bytes = circleQuadCount * VERTS_PER_QUAD * PACKED_QUAD_VERT_STRIDE;
1551
1620
  gl.useProgram(circleQuadProgram);
1552
1621
  gl.bindVertexArray(circleQuadVAO);
1553
1622
  gl.bindBuffer(gl.ARRAY_BUFFER, circleQuadBuffer);
1554
- gl.bufferData(gl.ARRAY_BUFFER, circleQuadData.subarray(0, floats), gl.DYNAMIC_DRAW);
1623
+ gl.bufferData(gl.ARRAY_BUFFER, circleQuadData.u8.subarray(0, bytes), gl.DYNAMIC_DRAW);
1555
1624
  gl.uniform2f(cURes, logicalW, logicalH);
1556
1625
  ensureQuadIndices(circleQuadCount);
1557
1626
  gl.drawElements(gl.TRIANGLES, circleQuadCount * INDICES_PER_QUAD, gl.UNSIGNED_INT, 0);
1558
1627
  frameDrawCalls++;
1559
1628
  }
1560
1629
  if (spriteCount > 0 && texture) {
1561
- const floats = spriteCount * VERTS_PER_QUAD * FLOATS_PER_SPRITE_VERT;
1630
+ const bytes = spriteCount * VERTS_PER_QUAD * PACKED_QUAD_VERT_STRIDE;
1562
1631
  gl.useProgram(spriteProgram);
1563
1632
  gl.bindVertexArray(spriteVAO);
1564
1633
  gl.bindBuffer(gl.ARRAY_BUFFER, spriteBuffer);
1565
- gl.bufferData(gl.ARRAY_BUFFER, spriteData.subarray(0, floats), gl.DYNAMIC_DRAW);
1634
+ gl.bufferData(gl.ARRAY_BUFFER, spriteData.u8.subarray(0, bytes), gl.DYNAMIC_DRAW);
1566
1635
  gl.activeTexture(gl.TEXTURE0);
1567
1636
  gl.bindTexture(gl.TEXTURE_2D, texture);
1568
1637
  gl.uniform1i(sUTex, 0);