@swf2es/render 0.1.20 → 0.1.21
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.
- package/dist/filter-plan.d.ts +5 -2
- package/dist/filter-plan.d.ts.map +1 -1
- package/dist/filter-plan.js +9 -6
- package/dist/filter-plan.js.map +1 -1
- package/dist/filter-shaders.d.ts +1 -1
- package/dist/filter-shaders.d.ts.map +1 -1
- package/dist/filter-shaders.js +3 -3
- package/dist/webgl/atlas.d.ts +8 -1
- package/dist/webgl/atlas.d.ts.map +1 -1
- package/dist/webgl/atlas.js +17 -2
- package/dist/webgl/atlas.js.map +1 -1
- package/dist/webgl/draws.d.ts +6 -3
- package/dist/webgl/draws.d.ts.map +1 -1
- package/dist/webgl/draws.js +23 -8
- package/dist/webgl/draws.js.map +1 -1
- package/dist/webgl/filters.d.ts +10 -0
- package/dist/webgl/filters.d.ts.map +1 -1
- package/dist/webgl/filters.js +50 -1
- package/dist/webgl/filters.js.map +1 -1
- package/dist/webgl/glyph-tables.d.ts +44 -0
- package/dist/webgl/glyph-tables.d.ts.map +1 -0
- package/dist/webgl/glyph-tables.js +148 -0
- package/dist/webgl/glyph-tables.js.map +1 -0
- package/dist/webgl/programs.d.ts +17 -5
- package/dist/webgl/programs.d.ts.map +1 -1
- package/dist/webgl/programs.js +36 -17
- package/dist/webgl/programs.js.map +1 -1
- package/package.json +2 -2
- package/src/filter-plan.ts +9 -6
- package/src/filter-shaders.ts +3 -3
- package/src/webgl/atlas.ts +23 -4
- package/src/webgl/draws.ts +25 -7
- package/src/webgl/filters.ts +55 -0
- package/src/webgl/glyph-tables.ts +179 -0
- package/src/webgl/programs.ts +36 -17
package/dist/webgl/programs.js
CHANGED
|
@@ -19,6 +19,13 @@ export const TINT_AT = 7;
|
|
|
19
19
|
export const DRAW_AT = 8;
|
|
20
20
|
/** The most cutoff table entries a text's draw takes, as the player's text/saffron.ts builds them. */
|
|
21
21
|
export const TABLE_ENTRIES = 48;
|
|
22
|
+
/**
|
|
23
|
+
* Texels a text's slot in the glyph tables' texture (GlyphTables): its mode,
|
|
24
|
+
* then its table's entries; and texels a line of it. Powers of two, which
|
|
25
|
+
* the vertex shader splits a slot's texel into column and line with.
|
|
26
|
+
*/
|
|
27
|
+
export const TABLE_SLOT = 64;
|
|
28
|
+
export const TABLE_LINE = 1024;
|
|
22
29
|
/** Segments a row of the outlines' texture, as the player's text/saffron.ts stores them. */
|
|
23
30
|
export const OUTLINE_ROW = 1024;
|
|
24
31
|
/**
|
|
@@ -52,6 +59,8 @@ export const RUN_UNIT = FILL_UNIT + FILL_TEXTURES;
|
|
|
52
59
|
export const MERGED_UNIT = RUN_UNIT + 1;
|
|
53
60
|
/** The merged fills' rows a line of their integer texture: a power of two, as for RUN_MOST. */
|
|
54
61
|
export const MERGED_LINE = 1024;
|
|
62
|
+
/** The glyph tables' unit (GlyphTables), past the merged fills' rows. */
|
|
63
|
+
export const TABLE_UNIT = MERGED_UNIT + 1;
|
|
55
64
|
/**
|
|
56
65
|
* Places a vertex by its row's transform, on a quarter of a pixel of
|
|
57
66
|
* Flash's (uUnit of them a stage pixel, from the stage's origin) where it
|
|
@@ -268,11 +277,14 @@ void main(void) {
|
|
|
268
277
|
* pixels to Flash's, uUnit of them a stage pixel, on their grid from the
|
|
269
278
|
* stage's origin, a BitmapData's in a draw. A glyph's pen stands where its
|
|
270
279
|
* text's origin, at a whole pixel, puts it, snapped as its grid fits it
|
|
271
|
-
* (
|
|
272
|
-
* and its quad reaches out past its outline by the furthest
|
|
273
|
-
* colour is drawn under the row's colour transform, light or
|
|
274
|
-
* chooses its table.
|
|
275
|
-
*
|
|
280
|
+
* (its mode: gridFitType 0 none, 1 pixel, 2 subpixel, thickness,
|
|
281
|
+
* sharpness), and its quad reaches out past its outline by the furthest
|
|
282
|
+
* cutoff. Its colour is drawn under the row's colour transform, light or
|
|
283
|
+
* dark as adl chooses its table. The text's mode and tables are in its slot
|
|
284
|
+
* of uTables (uTable; GlyphTables), read by texelFetch: not a uniform array
|
|
285
|
+
* indexed by each glyph's table start, the access that hung Intel's GPUs
|
|
286
|
+
* in the fill program's run table. aOrigin: the pen, and its light and dark tables,
|
|
287
|
+
* each its first entry plus 64 times its entries; aGlyph: a corner of its
|
|
276
288
|
* outline's bounds and the way out from it; aRun: its segments, first and
|
|
277
289
|
* count, the pixels of a unit of its outline, and its size.
|
|
278
290
|
*/
|
|
@@ -287,8 +299,8 @@ uniform highp sampler2D uRows;
|
|
|
287
299
|
uniform int uRow;
|
|
288
300
|
uniform vec4 uView;
|
|
289
301
|
uniform float uUnit;
|
|
290
|
-
uniform
|
|
291
|
-
uniform
|
|
302
|
+
uniform highp sampler2D uTables;
|
|
303
|
+
uniform int uTable;
|
|
292
304
|
out vec2 vPixel;
|
|
293
305
|
flat out vec2 vPen;
|
|
294
306
|
flat out vec4 vToGlyph;
|
|
@@ -296,10 +308,16 @@ flat out vec4 vToPixel;
|
|
|
296
308
|
flat out vec4 vCut;
|
|
297
309
|
flat out vec4 vShown;
|
|
298
310
|
|
|
311
|
+
// Texel i of the text's slot: its mode, then its tables' entries.
|
|
312
|
+
vec4 slot(int i) {
|
|
313
|
+
int at = uTable * ${TABLE_SLOT} + i;
|
|
314
|
+
return texelFetch(uTables, ivec2(at & ${TABLE_LINE - 1}, at >> ${Math.log2(TABLE_LINE)}), 0);
|
|
315
|
+
}
|
|
316
|
+
|
|
299
317
|
// The cutoffs at ppem by the table of entries start to start + count, as text/csm.ts' cutoffs.
|
|
300
|
-
vec2 cutoffs(int start, int count, float ppem) {
|
|
301
|
-
vec4 first =
|
|
302
|
-
vec4 last =
|
|
318
|
+
vec2 cutoffs(vec4 mode, int start, int count, float ppem) {
|
|
319
|
+
vec4 first = slot(1 + start);
|
|
320
|
+
vec4 last = slot(start + count);
|
|
303
321
|
vec2 c = first.yz;
|
|
304
322
|
if (ppem >= last.x) {
|
|
305
323
|
c = last.yz;
|
|
@@ -309,9 +327,9 @@ vec2 cutoffs(int start, int count, float ppem) {
|
|
|
309
327
|
break;
|
|
310
328
|
}
|
|
311
329
|
|
|
312
|
-
vec4 b =
|
|
330
|
+
vec4 b = slot(1 + start + i);
|
|
313
331
|
if (ppem <= b.x) {
|
|
314
|
-
vec4 a =
|
|
332
|
+
vec4 a = slot(start + i);
|
|
315
333
|
c = mix(a.yz, b.yz, (ppem - a.x) / (b.x - a.x));
|
|
316
334
|
break;
|
|
317
335
|
}
|
|
@@ -319,8 +337,8 @@ vec2 cutoffs(int start, int count, float ppem) {
|
|
|
319
337
|
}
|
|
320
338
|
|
|
321
339
|
float unit = 0.0001 * ppem;
|
|
322
|
-
float t = clamp(
|
|
323
|
-
float s = clamp(
|
|
340
|
+
float t = clamp(mode.y, -200.0, 200.0);
|
|
341
|
+
float s = clamp(mode.z, -400.0, 400.0);
|
|
324
342
|
c -= unit * vec2(t + s * 0.5, t - s * 0.5);
|
|
325
343
|
if (c.x < c.y) {
|
|
326
344
|
c = vec2((c.x + c.y) * 0.5);
|
|
@@ -335,6 +353,7 @@ void main(void) {
|
|
|
335
353
|
vec4 t = texelFetch(uRows, at + ivec2(1, 0), 0);
|
|
336
354
|
vec4 mul = texelFetch(uRows, at + ivec2(2, 0), 0);
|
|
337
355
|
vec4 add = texelFetch(uRows, at + ivec2(3, 0), 0);
|
|
356
|
+
vec4 mode = slot(0);
|
|
338
357
|
// The text's pixels to Flash's.
|
|
339
358
|
mat2 linear = mat2(m.xy, m.zw) * uUnit;
|
|
340
359
|
vec2 origin = t.xy * uUnit;
|
|
@@ -342,9 +361,9 @@ void main(void) {
|
|
|
342
361
|
float across = max(abs(linear[0][1]), abs(linear[1][0]));
|
|
343
362
|
if (across > max(abs(linear[0][0]), abs(linear[1][1])) / 65536.0) {
|
|
344
363
|
// Turned or skewed: no grid.
|
|
345
|
-
} else if (
|
|
364
|
+
} else if (mode.x == 1.0) {
|
|
346
365
|
pen = vec2(roundEven(pen.x * 8.0) / 8.0 + 0.5, roundEven(pen.y));
|
|
347
|
-
} else if (
|
|
366
|
+
} else if (mode.x == 2.0) {
|
|
348
367
|
pen = vec2(roundEven(pen.x * 4.0) / 4.0 + 0.5, roundEven(pen.y));
|
|
349
368
|
} else {
|
|
350
369
|
pen = roundEven(pen * 4.0) / 4.0 + vec2(0.5, 0.0);
|
|
@@ -355,7 +374,7 @@ void main(void) {
|
|
|
355
374
|
vec4 shown = clamp(aColor * mul + add, 0.0, 1.0);
|
|
356
375
|
bool light = dot(floor(shown.rgb * 255.0 + 0.5), vec3(30.0, 59.0, 11.0)) > 20000.0;
|
|
357
376
|
int table = int(light ? aOrigin.z : aOrigin.w);
|
|
358
|
-
vec2 cut = cutoffs(table & 63, table >> 6, ppem);
|
|
377
|
+
vec2 cut = cutoffs(mode, table & 63, table >> 6, ppem);
|
|
359
378
|
mat2 toPixel = linear * aRun.z;
|
|
360
379
|
float margin = max(abs(cut.x), abs(cut.y)) + 1.0;
|
|
361
380
|
float det = determinant(toPixel);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/webgl/programs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,GAAG,EACH,KAAK,EACL,MAAM,EACN,UAAU,EACV,KAAK,EACL,SAAS,EACT,MAAM,EACN,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,aAAa,CAAC;AAErB,2CAA2C;AAC3C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAE5B;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AAC1B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AAC1B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AAC1B,oGAAoG;AACpG,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AAC1B,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;AACxB,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAEzB,sGAAsG;AACtG,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,4FAA4F;AAC5F,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE5B,qFAAqF;AACrF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;AAEhC,sGAAsG;AACtG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,0FAA0F;AAC1F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,uFAAuF;AACvF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,+DAA+D;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;AAClD,sEAAsE;AACtE,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,GAAG,CAAC,CAAC;AACxC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/webgl/programs.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swf2es/render",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "swf2es's own renderer: a scene list, a planner and a WebGL 2 backend (docs/renderer.md)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"swf",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"src"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@swf2es/context3d": "0.1.
|
|
36
|
+
"@swf2es/context3d": "0.1.21"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/src/filter-plan.ts
CHANGED
|
@@ -38,21 +38,24 @@ export const KERNEL_PASS = 10;
|
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* How a uniform's values are set: one to four floats, an array of vec4s, a
|
|
41
|
-
* 4 by 4 matrix, an array of ivec4s,
|
|
42
|
-
* the frame's it reads
|
|
41
|
+
* 4 by 4 matrix, an array of ivec4s, a sampler, its value the texture of
|
|
42
|
+
* the frame's it reads, or a sampler of a line of floats, its values, for a
|
|
43
|
+
* shader that reads them at a varying index (as a uniform array read so
|
|
44
|
+
* hangs some GPUs).
|
|
43
45
|
*/
|
|
44
46
|
export const FLOATS = 1;
|
|
45
47
|
export const VEC4S = 2;
|
|
46
48
|
export const MATRIX4 = 3;
|
|
47
49
|
export const IVEC4S = 4;
|
|
48
50
|
export const SAMPLER = 5;
|
|
51
|
+
export const FLOAT_LINE = 6;
|
|
49
52
|
|
|
50
53
|
/** A pass's blurred input (FilterPass.blurred): none read, or the pass's input itself. */
|
|
51
54
|
export const NO_BLUR = -2;
|
|
52
55
|
export const INPUT_BLUR = -1;
|
|
53
56
|
|
|
54
|
-
/** The most floats a convolution's matrix takes in its shader:
|
|
55
|
-
const CONVOLUTION_FLOATS =
|
|
57
|
+
/** The most floats a convolution's matrix takes in its shader: 15 by 15. */
|
|
58
|
+
const CONVOLUTION_FLOATS = 15 * 15;
|
|
56
59
|
|
|
57
60
|
/** One pass: a program drawn from slot `input` into slot `output`, its uniforms in its plan's. */
|
|
58
61
|
export interface FilterPass {
|
|
@@ -468,7 +471,7 @@ function colorMatrix(
|
|
|
468
471
|
return out;
|
|
469
472
|
}
|
|
470
473
|
|
|
471
|
-
/** A convolution's weights, its matrix by rows padded to the shader's
|
|
474
|
+
/** A convolution's weights, its matrix by rows padded to the shader's line. */
|
|
472
475
|
const weights = new Float32Array(CONVOLUTION_FLOATS);
|
|
473
476
|
|
|
474
477
|
function convolution(
|
|
@@ -485,7 +488,7 @@ function convolution(
|
|
|
485
488
|
weights.set(v.subarray(at + 12, at + 12 + Math.min(columns * rows, weights.length)));
|
|
486
489
|
const out = plan.slot(width, height);
|
|
487
490
|
plan.pass(CONVOLUTION_PASS, input, width, height, out, width, height);
|
|
488
|
-
plan.uniformFrom("
|
|
491
|
+
plan.uniformFrom("uWeights", FLOAT_LINE, weights, 0, weights.length);
|
|
489
492
|
plan.uniform("uSize", 2, columns, rows);
|
|
490
493
|
plan.uniformFrom("uEdge", FLOATS, v, at + 2, 4);
|
|
491
494
|
plan.uniform("uDivisor", 1, v[at + 6]);
|
package/src/filter-shaders.ts
CHANGED
|
@@ -312,7 +312,7 @@ export const CONVOLUTION = `in vec2 vTextureCoord;
|
|
|
312
312
|
out vec4 finalColor;
|
|
313
313
|
uniform sampler2D uTexture;
|
|
314
314
|
uniform highp vec4 uInputSize;
|
|
315
|
-
uniform
|
|
315
|
+
uniform highp sampler2D uWeights;
|
|
316
316
|
uniform vec2 uSize;
|
|
317
317
|
uniform vec4 uBox;
|
|
318
318
|
uniform vec4 uEdge;
|
|
@@ -342,10 +342,10 @@ void main(void) {
|
|
|
342
342
|
int cols = int(uSize.x);
|
|
343
343
|
int count = cols * int(uSize.y);
|
|
344
344
|
vec4 sum = vec4(0.0);
|
|
345
|
-
// One loop, its index alone indexing the weights, as GLSL ES 1 allows.
|
|
346
345
|
for (int k = 0; k < 225; k++) {
|
|
347
346
|
if (k >= count) { break; }
|
|
348
|
-
|
|
347
|
+
// From a texture: a uniform array indexed so is what hung Intel's GPUs in other programs.
|
|
348
|
+
float w = texelFetch(uWeights, ivec2(k, 0), 0).r;
|
|
349
349
|
if (w != 0.0) {
|
|
350
350
|
int j = k / cols;
|
|
351
351
|
vec2 at = vec2(float(k - j * cols), float(j)) - reach;
|
package/src/webgl/atlas.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GlState } from "@swf2es/context3d/device";
|
|
2
2
|
import { type Geometries, type GeometryData, GLYPH_FLOATS } from "../geometry.js";
|
|
3
|
+
import { GlyphTables } from "./glyph-tables.js";
|
|
3
4
|
import {
|
|
4
5
|
COLOR_AT,
|
|
5
6
|
DEPTH_AT,
|
|
@@ -67,13 +68,16 @@ function interleave(
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Where a geometry lies in the atlas, or the glyph atlas with its text's
|
|
73
|
+
* mode and table, and their slot in the glyph tables (-1 past their room).
|
|
74
|
+
*/
|
|
71
75
|
export interface Place {
|
|
72
76
|
vertexStart: number;
|
|
73
77
|
vertices: number;
|
|
74
78
|
indexStart: number;
|
|
75
79
|
indices: number;
|
|
76
|
-
glyphs: { mode: Float32Array; table: Float32Array } | null;
|
|
80
|
+
glyphs: { mode: Float32Array; table: Float32Array; slot: number } | null;
|
|
77
81
|
/** Its geometry's flat (GeometryData.flat). */
|
|
78
82
|
flat: boolean;
|
|
79
83
|
/** Small, unchanged geometries may be copied into a run's streaming buffer. */
|
|
@@ -122,10 +126,13 @@ export class GeometryAtlas {
|
|
|
122
126
|
live: 0,
|
|
123
127
|
holes: 0,
|
|
124
128
|
};
|
|
129
|
+
/** The texts' modes and tables, which the glyph program reads. */
|
|
130
|
+
readonly tables: GlyphTables;
|
|
125
131
|
|
|
126
132
|
constructor(gl: WebGL2RenderingContext, state: GlState) {
|
|
127
133
|
this.gl = gl;
|
|
128
134
|
this.state = state;
|
|
135
|
+
this.tables = new GlyphTables(gl, state);
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
/** The buffers and vertex arrays made, both atlases empty, as the context comes or comes back. */
|
|
@@ -177,6 +184,7 @@ export class GeometryAtlas {
|
|
|
177
184
|
this.stagedVertices = 0;
|
|
178
185
|
this.stagedIndexCount = 0;
|
|
179
186
|
this.places = [];
|
|
187
|
+
this.tables.setUp();
|
|
180
188
|
}
|
|
181
189
|
|
|
182
190
|
/**
|
|
@@ -254,7 +262,8 @@ export class GeometryAtlas {
|
|
|
254
262
|
const texts =
|
|
255
263
|
g.top + glyphVertices > g.capacity ||
|
|
256
264
|
g.indexTop + glyphIndices > g.indexCapacity ||
|
|
257
|
-
(g.holes > GLYPHS_LEAST && g.holes > g.live)
|
|
265
|
+
(g.holes > GLYPHS_LEAST && g.holes > g.live) ||
|
|
266
|
+
this.tables.full;
|
|
258
267
|
if (shapes) {
|
|
259
268
|
this.repack(geometries);
|
|
260
269
|
}
|
|
@@ -272,6 +281,7 @@ export class GeometryAtlas {
|
|
|
272
281
|
|
|
273
282
|
geometries.added.length = 0;
|
|
274
283
|
this.flush();
|
|
284
|
+
this.tables.upload();
|
|
275
285
|
}
|
|
276
286
|
|
|
277
287
|
/** Every live shape's geometry copied into new buffers, with room for twice what is live. */
|
|
@@ -336,12 +346,16 @@ export class GeometryAtlas {
|
|
|
336
346
|
g.indexTop = 0;
|
|
337
347
|
g.live = 0;
|
|
338
348
|
g.holes = 0;
|
|
349
|
+
// Only the live texts' tables kept.
|
|
350
|
+
this.tables.reset();
|
|
339
351
|
for (const id of ids) {
|
|
340
352
|
const data = geometries.get(id) as GeometryData;
|
|
341
353
|
if (data.glyphs) {
|
|
342
354
|
this.copyGlyphs(id, data);
|
|
343
355
|
}
|
|
344
356
|
}
|
|
357
|
+
|
|
358
|
+
this.tables.upload();
|
|
345
359
|
}
|
|
346
360
|
|
|
347
361
|
/** `data` copied in at the top of the atlas, its indices made absolute. */
|
|
@@ -483,7 +497,11 @@ export class GeometryAtlas {
|
|
|
483
497
|
vertices: count,
|
|
484
498
|
indexStart: g.indexTop,
|
|
485
499
|
indices: indices.length,
|
|
486
|
-
glyphs: {
|
|
500
|
+
glyphs: {
|
|
501
|
+
mode: glyphs.mode,
|
|
502
|
+
table: glyphs.table,
|
|
503
|
+
slot: this.tables.slot(glyphs.mode, glyphs.table),
|
|
504
|
+
},
|
|
487
505
|
flat: false,
|
|
488
506
|
batch: null,
|
|
489
507
|
};
|
|
@@ -501,5 +519,6 @@ export class GeometryAtlas {
|
|
|
501
519
|
gl.deleteVertexArray(this.glyphArray);
|
|
502
520
|
gl.deleteBuffer(this.glyphBuffer);
|
|
503
521
|
gl.deleteBuffer(this.glyphIndexBuffer);
|
|
522
|
+
this.tables.destroy();
|
|
504
523
|
}
|
|
505
524
|
}
|
package/src/webgl/draws.ts
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
RUN_MOST,
|
|
38
38
|
RUN_UNIT,
|
|
39
39
|
SNAP_BIT,
|
|
40
|
+
TABLE_UNIT,
|
|
40
41
|
TEXTURE_UNIT,
|
|
41
42
|
} from "./programs.js";
|
|
42
43
|
import { framebufferOf, type Open, type Target, type TargetPool } from "./targets.js";
|
|
@@ -166,15 +167,17 @@ export class Draws {
|
|
|
166
167
|
private meshMode = -1;
|
|
167
168
|
/**
|
|
168
169
|
* Advanced text's program (GeometryData.glyphs), where it takes its row, view, Flash's
|
|
169
|
-
* pixels a stage pixel
|
|
170
|
+
* pixels a stage pixel and its text's slot in the glyph tables (GlyphTables), and the row
|
|
171
|
+
* and slot told it last, -1 for none; its vertices are in an atlas of their own.
|
|
170
172
|
*/
|
|
171
173
|
private glyphProgram!: WebGLProgram;
|
|
172
174
|
private glyphRowLocation: WebGLUniformLocation | null = null;
|
|
173
175
|
private glyphViewLocation: WebGLUniformLocation | null = null;
|
|
174
176
|
private glyphUnitLocation: WebGLUniformLocation | null = null;
|
|
175
|
-
private glyphModeLocation: WebGLUniformLocation | null = null;
|
|
176
177
|
private glyphTableLocation: WebGLUniformLocation | null = null;
|
|
177
178
|
private glyphStale = true;
|
|
179
|
+
private glyphRow = -1;
|
|
180
|
+
private glyphTable = -1;
|
|
178
181
|
/** Flash's pixels a stage pixel: the target's pixels a stage pixel over those a pixel of Flash's. */
|
|
179
182
|
private unit = 1;
|
|
180
183
|
/**
|
|
@@ -279,12 +282,14 @@ export class Draws {
|
|
|
279
282
|
this.glyphRowLocation = gl.getUniformLocation(this.glyphProgram, "uRow");
|
|
280
283
|
this.glyphViewLocation = gl.getUniformLocation(this.glyphProgram, "uView");
|
|
281
284
|
this.glyphUnitLocation = gl.getUniformLocation(this.glyphProgram, "uUnit");
|
|
282
|
-
this.glyphModeLocation = gl.getUniformLocation(this.glyphProgram, "uMode");
|
|
283
285
|
this.glyphTableLocation = gl.getUniformLocation(this.glyphProgram, "uTable");
|
|
284
286
|
this.state.useProgram(this.glyphProgram);
|
|
285
287
|
gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uRows"), 0);
|
|
286
288
|
gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uSegments"), OUTLINE_UNIT);
|
|
289
|
+
gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uTables"), TABLE_UNIT);
|
|
287
290
|
this.glyphStale = true;
|
|
291
|
+
this.glyphRow = -1;
|
|
292
|
+
this.glyphTable = -1;
|
|
288
293
|
this.lastRow = -1;
|
|
289
294
|
}
|
|
290
295
|
|
|
@@ -846,7 +851,8 @@ export class Draws {
|
|
|
846
851
|
/**
|
|
847
852
|
* Entry `i`, advanced text's glyph quads (GeometryData.glyphs), drawn by the glyph
|
|
848
853
|
* program from its atlas, which is told the view as it changed, and its
|
|
849
|
-
* text's
|
|
854
|
+
* row and its text's slot in the glyph tables as they change; the glyph
|
|
855
|
+
* program left in use.
|
|
850
856
|
*/
|
|
851
857
|
private drawGlyphs(scene: SceneList, i: number, place: Place): void {
|
|
852
858
|
const gl = this.gl;
|
|
@@ -860,11 +866,23 @@ export class Draws {
|
|
|
860
866
|
this.glyphStale = false;
|
|
861
867
|
}
|
|
862
868
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
869
|
+
const row = scene.row[i];
|
|
870
|
+
if (row !== this.glyphRow) {
|
|
871
|
+
gl.uniform1i(this.glyphRowLocation, row);
|
|
872
|
+
this.glyphRow = row;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
const tables = this.atlas.tables;
|
|
876
|
+
const slot = glyphs.slot >= 0 ? glyphs.slot : tables.scratch(glyphs.mode, glyphs.table);
|
|
877
|
+
if (slot !== this.glyphTable) {
|
|
878
|
+
gl.uniform1i(this.glyphTableLocation, slot);
|
|
879
|
+
this.glyphTable = slot;
|
|
880
|
+
}
|
|
881
|
+
|
|
866
882
|
state.bindTexture(OUTLINE_UNIT, this.gpu.outlines);
|
|
867
883
|
state.bindSampler(OUTLINE_UNIT, null);
|
|
884
|
+
state.bindTexture(TABLE_UNIT, tables.texture);
|
|
885
|
+
state.bindSampler(TABLE_UNIT, null);
|
|
868
886
|
gl.drawElements(gl.TRIANGLES, place.indices, gl.UNSIGNED_INT, place.indexStart * 4);
|
|
869
887
|
}
|
|
870
888
|
|
package/src/webgl/filters.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
CONVOLUTION_PASS,
|
|
6
6
|
DISPLACE_PASS,
|
|
7
7
|
FilterPlan,
|
|
8
|
+
FLOAT_LINE,
|
|
8
9
|
FLOATS,
|
|
9
10
|
GLOW_PASS,
|
|
10
11
|
GRADIENT_PASS,
|
|
@@ -59,6 +60,8 @@ export interface FilterHost<T extends FilterTarget> {
|
|
|
59
60
|
const INPUT_UNIT = 4;
|
|
60
61
|
const BLURRED_UNIT = 5;
|
|
61
62
|
const EXTRA_UNIT = 6;
|
|
63
|
+
/** A pass's line of floats (FLOAT_LINE): a convolution's weights, which reads no gradient nor map. */
|
|
64
|
+
const LINE_UNIT = EXTRA_UNIT;
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* A triangle over the output's frame, the viewport, reading its input
|
|
@@ -146,6 +149,10 @@ export class FilterRunner<T extends FilterTarget> {
|
|
|
146
149
|
private readonly hasTexture = (id: number) => id >= 0 && this.host.texture(id) !== null;
|
|
147
150
|
/** The target's pixels a unit of its own, for the chain running. */
|
|
148
151
|
private resolution = 1;
|
|
152
|
+
/** The texture of a pass's line of floats (FLOAT_LINE), its width, and the floats' bits it holds. */
|
|
153
|
+
private line: WebGLTexture | null = null;
|
|
154
|
+
private lineWidth = 0;
|
|
155
|
+
private lineBits = new Uint32Array(0);
|
|
149
156
|
|
|
150
157
|
constructor(
|
|
151
158
|
gl: WebGL2RenderingContext,
|
|
@@ -356,6 +363,10 @@ export class FilterRunner<T extends FilterTarget> {
|
|
|
356
363
|
// As many as KERNEL_IMAGES, which the plan holds a kernel to.
|
|
357
364
|
this.kernels.bindImage(location, this.samplers++, values[at], this.host);
|
|
358
365
|
break;
|
|
366
|
+
case FLOAT_LINE:
|
|
367
|
+
gl.uniform1i(location, LINE_UNIT);
|
|
368
|
+
this.bindLine(values, at, count);
|
|
369
|
+
break;
|
|
359
370
|
case FLOATS:
|
|
360
371
|
this.set(
|
|
361
372
|
pass,
|
|
@@ -369,6 +380,45 @@ export class FilterRunner<T extends FilterTarget> {
|
|
|
369
380
|
}
|
|
370
381
|
}
|
|
371
382
|
|
|
383
|
+
/**
|
|
384
|
+
* `count` of `values` from `at` bound on LINE_UNIT as a line of floats,
|
|
385
|
+
* uploaded where they are not the ones it holds: a frame's filters alike
|
|
386
|
+
* take the same.
|
|
387
|
+
*/
|
|
388
|
+
private bindLine(values: Float32Array, at: number, count: number): void {
|
|
389
|
+
const gl = this.gl;
|
|
390
|
+
const bits = new Uint32Array(values.buffer, values.byteOffset + at * 4, count);
|
|
391
|
+
let same = this.line !== null && count === this.lineBits.length;
|
|
392
|
+
for (let k = 0; same && k < count; k++) {
|
|
393
|
+
same = bits[k] === this.lineBits[k];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (!same) {
|
|
397
|
+
if (!this.line || count > this.lineWidth) {
|
|
398
|
+
if (this.line) {
|
|
399
|
+
this.state.dropTexture(this.line);
|
|
400
|
+
gl.deleteTexture(this.line);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
this.line = gl.createTexture() as WebGLTexture;
|
|
404
|
+
this.lineWidth = count;
|
|
405
|
+
this.state.bindTexture(LINE_UNIT, this.line);
|
|
406
|
+
this.state.activeTexture(LINE_UNIT);
|
|
407
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, count, 1);
|
|
408
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
409
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
this.state.bindTexture(LINE_UNIT, this.line);
|
|
413
|
+
this.state.activeTexture(LINE_UNIT);
|
|
414
|
+
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, count, 1, gl.RED, gl.FLOAT, values, at);
|
|
415
|
+
this.lineBits = bits.slice();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
this.state.bindTexture(LINE_UNIT, this.line);
|
|
419
|
+
this.state.bindSampler(LINE_UNIT, null);
|
|
420
|
+
}
|
|
421
|
+
|
|
372
422
|
/** The pass of program `id` (filter-plan.ts), in use. */
|
|
373
423
|
private program(id: number): Pass {
|
|
374
424
|
switch (id) {
|
|
@@ -498,5 +548,10 @@ export class FilterRunner<T extends FilterTarget> {
|
|
|
498
548
|
}
|
|
499
549
|
|
|
500
550
|
this.passes.clear();
|
|
551
|
+
if (this.line) {
|
|
552
|
+
this.state.dropTexture(this.line);
|
|
553
|
+
this.gl.deleteTexture(this.line);
|
|
554
|
+
this.line = null;
|
|
555
|
+
}
|
|
501
556
|
}
|
|
502
557
|
}
|