@sadhaka/loom-engine 0.11.0 → 0.12.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.
- package/COMMERCIAL_LICENSE_TERMS.md +74 -0
- package/README.md +118 -6
- package/dist/engine.d.ts +6 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +35 -1
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/renderer/shaders/sprite-shader-source.d.ts +4 -0
- package/dist/renderer/shaders/sprite-shader-source.d.ts.map +1 -0
- package/dist/renderer/shaders/sprite-shader-source.js +83 -0
- package/dist/renderer/shaders/sprite-shader-source.js.map +1 -0
- package/dist/renderer/sprite-batcher.d.ts +30 -0
- package/dist/renderer/sprite-batcher.d.ts.map +1 -0
- package/dist/renderer/sprite-batcher.js +146 -0
- package/dist/renderer/sprite-batcher.js.map +1 -0
- package/dist/renderer/texture-atlas.d.ts +24 -0
- package/dist/renderer/texture-atlas.d.ts.map +1 -0
- package/dist/renderer/texture-atlas.js +173 -0
- package/dist/renderer/texture-atlas.js.map +1 -0
- package/dist/renderer/webgl2-device.d.ts +53 -0
- package/dist/renderer/webgl2-device.d.ts.map +1 -0
- package/dist/renderer/webgl2-device.js +596 -0
- package/dist/renderer/webgl2-device.js.map +1 -0
- package/package.json +11 -5
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// SpriteBatcher - per-frame instance accumulator for the WebGL2 path.
|
|
2
|
+
//
|
|
3
|
+
// Pure CPU-side: holds a growable Float32Array of per-instance data
|
|
4
|
+
// and tracks the current batch key (atlas + blend mode). submit()
|
|
5
|
+
// appends; if the batch key changes it flushes the current run via
|
|
6
|
+
// a handler the device wires up at construction. flush() also runs
|
|
7
|
+
// from endFrame to drain any pending instances.
|
|
8
|
+
//
|
|
9
|
+
// 12 floats per instance:
|
|
10
|
+
// [origin.x, origin.y, size.x, size.y,
|
|
11
|
+
// uv0.x, uv0.y, uv1.x, uv1.y,
|
|
12
|
+
// tint.r, tint.g, tint.b, tint.a]
|
|
13
|
+
//
|
|
14
|
+
// Why: a single drawArraysInstanced call covers the whole batch with
|
|
15
|
+
// one CPU->GPU upload of the instance buffer. Atlas swap forces a
|
|
16
|
+
// flush because the bound texture changes; blend-mode swap forces a
|
|
17
|
+
// flush because gl.blendFunc state changes.
|
|
18
|
+
//
|
|
19
|
+
// Submission order is preserved within a batch. Higher-level systems
|
|
20
|
+
// (SpriteRenderSystem) sort globally before submitting; the batcher
|
|
21
|
+
// trusts that order. Subsequent atlas batches reset the order chain
|
|
22
|
+
// but never mix across atlases - that is intentional, the cost is
|
|
23
|
+
// borne by the consumer (sort by atlas then by depth if global
|
|
24
|
+
// ordering across atlases matters).
|
|
25
|
+
export const FLOATS_PER_INSTANCE = 12;
|
|
26
|
+
const INITIAL_CAPACITY = 1024;
|
|
27
|
+
export class SpriteBatcher {
|
|
28
|
+
// Instance data buffer. Grows by doubling when capacity is hit.
|
|
29
|
+
// Backing typed-array stays referentially stable when count is
|
|
30
|
+
// below capacity to avoid per-frame allocation.
|
|
31
|
+
buffer;
|
|
32
|
+
capacity;
|
|
33
|
+
// Current run state.
|
|
34
|
+
count = 0;
|
|
35
|
+
currentAtlas = null;
|
|
36
|
+
currentBlend = 'alpha';
|
|
37
|
+
// Flush statistics. Reset at beginFrame; surfaced by getStats for
|
|
38
|
+
// tests + diagnostics.
|
|
39
|
+
flushCount = 0;
|
|
40
|
+
instanceTotal = 0;
|
|
41
|
+
flushHandler;
|
|
42
|
+
constructor(flushHandler, initialCapacity = INITIAL_CAPACITY) {
|
|
43
|
+
this.flushHandler = flushHandler;
|
|
44
|
+
this.capacity = Math.max(64, initialCapacity);
|
|
45
|
+
this.buffer = new Float32Array(this.capacity * FLOATS_PER_INSTANCE);
|
|
46
|
+
}
|
|
47
|
+
// Reset for a new frame. Counts go to zero; batch state cleared.
|
|
48
|
+
// Flushes any pending instances first as a safety net (endFrame
|
|
49
|
+
// should have done this, but we belt-and-suspenders to keep the
|
|
50
|
+
// device contract clean).
|
|
51
|
+
beginFrame() {
|
|
52
|
+
if (this.count > 0 && this.currentAtlas) {
|
|
53
|
+
this.flush();
|
|
54
|
+
}
|
|
55
|
+
this.count = 0;
|
|
56
|
+
this.currentAtlas = null;
|
|
57
|
+
this.currentBlend = 'alpha';
|
|
58
|
+
this.flushCount = 0;
|
|
59
|
+
this.instanceTotal = 0;
|
|
60
|
+
}
|
|
61
|
+
// Submit one instance to the batcher. Triggers flush if the
|
|
62
|
+
// (atlas, blendMode) key differs from the current batch.
|
|
63
|
+
submit(atlas, blendMode, originX, originY, sizeX, sizeY, u0, v0, u1, v1, tintR, tintG, tintB, tintA) {
|
|
64
|
+
if (atlas.released)
|
|
65
|
+
return;
|
|
66
|
+
if (this.currentAtlas !== atlas || this.currentBlend !== blendMode) {
|
|
67
|
+
// Atlas / blend change forces a batch break. Flush the current
|
|
68
|
+
// run before installing the new key.
|
|
69
|
+
if (this.count > 0 && this.currentAtlas) {
|
|
70
|
+
this.flush();
|
|
71
|
+
}
|
|
72
|
+
this.currentAtlas = atlas;
|
|
73
|
+
this.currentBlend = blendMode;
|
|
74
|
+
}
|
|
75
|
+
if (this.count >= this.capacity) {
|
|
76
|
+
this.grow();
|
|
77
|
+
}
|
|
78
|
+
var off = this.count * FLOATS_PER_INSTANCE;
|
|
79
|
+
var b = this.buffer;
|
|
80
|
+
b[off + 0] = originX;
|
|
81
|
+
b[off + 1] = originY;
|
|
82
|
+
b[off + 2] = sizeX;
|
|
83
|
+
b[off + 3] = sizeY;
|
|
84
|
+
b[off + 4] = u0;
|
|
85
|
+
b[off + 5] = v0;
|
|
86
|
+
b[off + 6] = u1;
|
|
87
|
+
b[off + 7] = v1;
|
|
88
|
+
b[off + 8] = tintR;
|
|
89
|
+
b[off + 9] = tintG;
|
|
90
|
+
b[off + 10] = tintB;
|
|
91
|
+
b[off + 11] = tintA;
|
|
92
|
+
this.count++;
|
|
93
|
+
}
|
|
94
|
+
// Flush the current run via the device-supplied handler. No-op if
|
|
95
|
+
// nothing pending or no atlas selected.
|
|
96
|
+
flush() {
|
|
97
|
+
if (this.count === 0 || !this.currentAtlas)
|
|
98
|
+
return;
|
|
99
|
+
var atlas = this.currentAtlas;
|
|
100
|
+
var blend = this.currentBlend;
|
|
101
|
+
var n = this.count;
|
|
102
|
+
this.flushHandler(atlas, blend, this.buffer, n);
|
|
103
|
+
this.flushCount++;
|
|
104
|
+
this.instanceTotal += n;
|
|
105
|
+
this.count = 0;
|
|
106
|
+
}
|
|
107
|
+
// Final drain - call from endFrame to push the last partial batch.
|
|
108
|
+
endFrame() {
|
|
109
|
+
if (this.count > 0 && this.currentAtlas) {
|
|
110
|
+
this.flush();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Diagnostics. Returned object is owned by the caller; we copy
|
|
114
|
+
// into it to avoid allocating per-frame.
|
|
115
|
+
getStats(out) {
|
|
116
|
+
out.flushCount = this.flushCount;
|
|
117
|
+
out.instanceTotal = this.instanceTotal;
|
|
118
|
+
out.capacity = this.capacity;
|
|
119
|
+
}
|
|
120
|
+
// Test-only inspection helpers. Not part of the public API but
|
|
121
|
+
// exported so the test file can assert internal state without
|
|
122
|
+
// brittle reflection.
|
|
123
|
+
_peekCount() {
|
|
124
|
+
return this.count;
|
|
125
|
+
}
|
|
126
|
+
_peekCurrentAtlas() {
|
|
127
|
+
return this.currentAtlas;
|
|
128
|
+
}
|
|
129
|
+
_peekCurrentBlend() {
|
|
130
|
+
return this.currentBlend;
|
|
131
|
+
}
|
|
132
|
+
_peekBuffer() {
|
|
133
|
+
return this.buffer;
|
|
134
|
+
}
|
|
135
|
+
// Grow by doubling. Float32Array does not resize in place; we
|
|
136
|
+
// allocate a new buffer and copy the live prefix. Triggered when
|
|
137
|
+
// submit overruns capacity.
|
|
138
|
+
grow() {
|
|
139
|
+
var next = this.capacity * 2;
|
|
140
|
+
var b = new Float32Array(next * FLOATS_PER_INSTANCE);
|
|
141
|
+
b.set(this.buffer.subarray(0, this.count * FLOATS_PER_INSTANCE));
|
|
142
|
+
this.buffer = b;
|
|
143
|
+
this.capacity = next;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=sprite-batcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprite-batcher.js","sourceRoot":"","sources":["../../src/renderer/sprite-batcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AtlasDescriptor } from './graphics-device.js';
|
|
2
|
+
export declare class TextureAtlas {
|
|
3
|
+
texture: WebGLTexture | null;
|
|
4
|
+
readonly width: number;
|
|
5
|
+
readonly height: number;
|
|
6
|
+
readonly uvRects: Float32Array;
|
|
7
|
+
readonly frameSizes: Float32Array;
|
|
8
|
+
readonly frameCount: number;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
private sourceImage;
|
|
11
|
+
released: boolean;
|
|
12
|
+
constructor(gl: WebGL2RenderingContext | null, desc: AtlasDescriptor);
|
|
13
|
+
upload(gl: WebGL2RenderingContext): void;
|
|
14
|
+
bind(gl: WebGL2RenderingContext): void;
|
|
15
|
+
handleContextLoss(): void;
|
|
16
|
+
dispose(gl: WebGL2RenderingContext | null): void;
|
|
17
|
+
lookupUVRect(frame: number, out: Float32Array, offset: number): boolean;
|
|
18
|
+
lookupFrameSize(frame: number, out: {
|
|
19
|
+
w: number;
|
|
20
|
+
h: number;
|
|
21
|
+
}): boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function makeParticleDiscAtlas(gl: WebGL2RenderingContext | null): TextureAtlas | null;
|
|
24
|
+
//# sourceMappingURL=texture-atlas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-atlas.d.ts","sourceRoot":"","sources":["../../src/renderer/texture-atlas.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,qBAAa,YAAY;IAGvB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IAKpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAI/B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;IAElC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAG5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAItB,OAAO,CAAC,WAAW,CAAqD;IAIxE,QAAQ,EAAE,OAAO,CAAS;gBAEd,EAAE,EAAE,sBAAsB,GAAG,IAAI,EAAE,IAAI,EAAE,eAAe;IAmCpE,MAAM,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI;IAkCxC,IAAI,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI;IAMtC,iBAAiB,IAAI,IAAI;IAIzB,OAAO,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI;IAWhD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAWvE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO;CAOvE;AASD,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,sBAAsB,GAAG,IAAI,GAChC,YAAY,GAAG,IAAI,CAqBrB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// TextureAtlas - GL texture wrapper for the WebGL2 backend.
|
|
2
|
+
//
|
|
3
|
+
// Wraps a single GL texture plus a frame-rect lookup table. The
|
|
4
|
+
// device passes an AtlasDescriptor at registerAtlas time; we upload
|
|
5
|
+
// the source image as a texture and pre-compute UV rects per frame
|
|
6
|
+
// so drawSprite/drawTile can look up by frame index without a divide
|
|
7
|
+
// in the hot path.
|
|
8
|
+
//
|
|
9
|
+
// Texture coordinates use UNPACK_FLIP_Y_WEBGL=true on upload so frame
|
|
10
|
+
// (x, y) - which the AtlasDescriptor specifies in top-left source
|
|
11
|
+
// pixel coords - maps directly to UVs of (x/W, y/H, (x+w)/W, (y+h)/H)
|
|
12
|
+
// in the GL texture. The shader uses the unit-quad vertex (0..1) as
|
|
13
|
+
// the mix factor between (u0, v0) and (u1, v1).
|
|
14
|
+
//
|
|
15
|
+
// Context-loss handling: the device watches the canvas for
|
|
16
|
+
// 'webglcontextlost' and calls handleContextLoss() on every atlas
|
|
17
|
+
// to mark them invalid. On 'webglcontextrestored' the device calls
|
|
18
|
+
// rehydrate(gl) which re-uploads the cached source image.
|
|
19
|
+
export class TextureAtlas {
|
|
20
|
+
// GL texture object. Null while the context is lost or before
|
|
21
|
+
// upload. drawSprite paths must check before binding.
|
|
22
|
+
texture = null;
|
|
23
|
+
// Atlas dimensions in pixels - cached because the descriptor's
|
|
24
|
+
// image may be reclaimed from layout flow but the dims do not
|
|
25
|
+
// change.
|
|
26
|
+
width;
|
|
27
|
+
height;
|
|
28
|
+
// Pre-computed UV rects. Layout: 4 floats per frame
|
|
29
|
+
// [u0, v0, u1, v1]. Indexed by frame number * 4. Storing as a
|
|
30
|
+
// single Float32Array keeps lookup branchless and cache-friendly
|
|
31
|
+
// when the batcher iterates many sprites.
|
|
32
|
+
uvRects;
|
|
33
|
+
// Pre-computed frame sizes in pixels. Layout: 2 floats per frame
|
|
34
|
+
// [w, h]. drawSprite multiplies by camera zoom.
|
|
35
|
+
frameSizes;
|
|
36
|
+
frameCount;
|
|
37
|
+
// Optional debug name for logging.
|
|
38
|
+
name;
|
|
39
|
+
// Source image kept for context-restore rehydrate. AtlasDescriptor
|
|
40
|
+
// owns the image lifetime; we hold a reference but never mutate.
|
|
41
|
+
sourceImage;
|
|
42
|
+
// Marker to skip use-after-release. releaseAtlas sets this; the
|
|
43
|
+
// device's draw paths bail out on released atlases.
|
|
44
|
+
released = false;
|
|
45
|
+
constructor(gl, desc) {
|
|
46
|
+
this.sourceImage = desc.image;
|
|
47
|
+
this.name = desc.name ?? 'unnamed';
|
|
48
|
+
// Image dimensions vary by source type; ImageBitmap, HTMLImage-
|
|
49
|
+
// Element and HTMLCanvasElement all expose width/height the same
|
|
50
|
+
// way.
|
|
51
|
+
this.width = desc.image.width;
|
|
52
|
+
this.height = desc.image.height;
|
|
53
|
+
this.frameCount = desc.frames.length;
|
|
54
|
+
this.uvRects = new Float32Array(this.frameCount * 4);
|
|
55
|
+
this.frameSizes = new Float32Array(this.frameCount * 2);
|
|
56
|
+
var W = this.width || 1;
|
|
57
|
+
var H = this.height || 1;
|
|
58
|
+
for (var i = 0; i < this.frameCount; i++) {
|
|
59
|
+
var f = desc.frames[i];
|
|
60
|
+
if (!f)
|
|
61
|
+
continue;
|
|
62
|
+
var base4 = i * 4;
|
|
63
|
+
var base2 = i * 2;
|
|
64
|
+
this.uvRects[base4 + 0] = f.x / W;
|
|
65
|
+
this.uvRects[base4 + 1] = f.y / H;
|
|
66
|
+
this.uvRects[base4 + 2] = (f.x + f.w) / W;
|
|
67
|
+
this.uvRects[base4 + 3] = (f.y + f.h) / H;
|
|
68
|
+
this.frameSizes[base2 + 0] = f.w;
|
|
69
|
+
this.frameSizes[base2 + 1] = f.h;
|
|
70
|
+
}
|
|
71
|
+
if (gl) {
|
|
72
|
+
this.upload(gl);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Upload source image to a GL texture. Used at construction and on
|
|
76
|
+
// context-restore. Idempotent: deletes any prior texture first.
|
|
77
|
+
upload(gl) {
|
|
78
|
+
if (this.released)
|
|
79
|
+
return;
|
|
80
|
+
if (this.texture) {
|
|
81
|
+
gl.deleteTexture(this.texture);
|
|
82
|
+
this.texture = null;
|
|
83
|
+
}
|
|
84
|
+
var tex = gl.createTexture();
|
|
85
|
+
if (!tex) {
|
|
86
|
+
// createTexture returns null only on context-lost; bail and
|
|
87
|
+
// leave this.texture null. The device will retry on restore.
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
91
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
92
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
93
|
+
// Pixel-art friendly defaults to match Canvas2DDevice's
|
|
94
|
+
// imageSmoothingEnabled = false. Consumers can override after
|
|
95
|
+
// registerAtlas via the returned handle if they need bilinear.
|
|
96
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
97
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
98
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
99
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
100
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.sourceImage);
|
|
101
|
+
this.texture = tex;
|
|
102
|
+
}
|
|
103
|
+
// Bind for sampling. Caller has the active texture unit set.
|
|
104
|
+
bind(gl) {
|
|
105
|
+
gl.bindTexture(gl.TEXTURE_2D, this.texture);
|
|
106
|
+
}
|
|
107
|
+
// Mark texture invalid - context lost. The GL object is already
|
|
108
|
+
// gone; we just clear the JS reference so subsequent draws skip.
|
|
109
|
+
handleContextLoss() {
|
|
110
|
+
this.texture = null;
|
|
111
|
+
}
|
|
112
|
+
dispose(gl) {
|
|
113
|
+
this.released = true;
|
|
114
|
+
if (gl && this.texture) {
|
|
115
|
+
gl.deleteTexture(this.texture);
|
|
116
|
+
}
|
|
117
|
+
this.texture = null;
|
|
118
|
+
}
|
|
119
|
+
// Look up the UV rect for a frame index. Returns false if the
|
|
120
|
+
// frame is out of range so the caller can skip the draw safely.
|
|
121
|
+
// out is filled with [u0, v0, u1, v1].
|
|
122
|
+
lookupUVRect(frame, out, offset) {
|
|
123
|
+
if (frame < 0 || frame >= this.frameCount)
|
|
124
|
+
return false;
|
|
125
|
+
var base = frame * 4;
|
|
126
|
+
out[offset + 0] = this.uvRects[base + 0] ?? 0;
|
|
127
|
+
out[offset + 1] = this.uvRects[base + 1] ?? 0;
|
|
128
|
+
out[offset + 2] = this.uvRects[base + 2] ?? 0;
|
|
129
|
+
out[offset + 3] = this.uvRects[base + 3] ?? 0;
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
// Look up the frame width/height in pixels.
|
|
133
|
+
lookupFrameSize(frame, out) {
|
|
134
|
+
if (frame < 0 || frame >= this.frameCount)
|
|
135
|
+
return false;
|
|
136
|
+
var base = frame * 2;
|
|
137
|
+
out.w = this.frameSizes[base + 0] ?? 0;
|
|
138
|
+
out.h = this.frameSizes[base + 1] ?? 0;
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Build a tiny built-in atlas containing a single soft-disc frame
|
|
143
|
+
// for drawParticle. 64 x 64 RGBA, white center fading to transparent
|
|
144
|
+
// edge. Returned wrapped in a TextureAtlas with one frame at index 0.
|
|
145
|
+
//
|
|
146
|
+
// Lazy-built on first drawParticle call. Headless / Node tests pass
|
|
147
|
+
// gl=null; the descriptor is still valid and the GL upload happens
|
|
148
|
+
// later when (if) the context is provided.
|
|
149
|
+
export function makeParticleDiscAtlas(gl) {
|
|
150
|
+
if (typeof document === 'undefined')
|
|
151
|
+
return null;
|
|
152
|
+
var size = 64;
|
|
153
|
+
var c = document.createElement('canvas');
|
|
154
|
+
c.width = size;
|
|
155
|
+
c.height = size;
|
|
156
|
+
var ctx = c.getContext('2d');
|
|
157
|
+
if (!ctx)
|
|
158
|
+
return null;
|
|
159
|
+
var center = size / 2;
|
|
160
|
+
var grad = ctx.createRadialGradient(center, center, 0, center, center, center);
|
|
161
|
+
grad.addColorStop(0, 'rgba(255,255,255,1)');
|
|
162
|
+
grad.addColorStop(1, 'rgba(255,255,255,0)');
|
|
163
|
+
ctx.fillStyle = grad;
|
|
164
|
+
ctx.beginPath();
|
|
165
|
+
ctx.arc(center, center, center, 0, Math.PI * 2);
|
|
166
|
+
ctx.fill();
|
|
167
|
+
return new TextureAtlas(gl, {
|
|
168
|
+
image: c,
|
|
169
|
+
frames: [{ x: 0, y: 0, w: size, h: size }],
|
|
170
|
+
name: 'particle-disc',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=texture-atlas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-atlas.js","sourceRoot":"","sources":["../../src/renderer/texture-atlas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ColorRGBA } from '../util/color.js';
|
|
2
|
+
import { type IGraphicsDevice, type AtlasHandle, type AtlasDescriptor, type TextStyle } from './graphics-device.js';
|
|
3
|
+
import { type CameraView } from './camera.js';
|
|
4
|
+
export declare class WebGL2Device implements IGraphicsDevice {
|
|
5
|
+
readonly canvas: HTMLCanvasElement;
|
|
6
|
+
readonly viewportWidth: number;
|
|
7
|
+
readonly viewportHeight: number;
|
|
8
|
+
private gl;
|
|
9
|
+
private program;
|
|
10
|
+
private vao;
|
|
11
|
+
private quadVBO;
|
|
12
|
+
private instanceVBO;
|
|
13
|
+
private instanceVBOBytes;
|
|
14
|
+
private atlases;
|
|
15
|
+
private nextAtlasHandle;
|
|
16
|
+
private camera;
|
|
17
|
+
private drawCallCount;
|
|
18
|
+
private batcher;
|
|
19
|
+
private particleAtlas;
|
|
20
|
+
private textCache;
|
|
21
|
+
private contextLost;
|
|
22
|
+
private boundOnLost;
|
|
23
|
+
private boundOnRestored;
|
|
24
|
+
private lastUpload;
|
|
25
|
+
constructor(canvas: HTMLCanvasElement, gl?: WebGL2RenderingContext);
|
|
26
|
+
private initGLResources;
|
|
27
|
+
private compileProgram;
|
|
28
|
+
private handleContextLoss;
|
|
29
|
+
private handleContextRestored;
|
|
30
|
+
beginFrame(): void;
|
|
31
|
+
endFrame(): void;
|
|
32
|
+
setCamera(cam: Readonly<CameraView>): void;
|
|
33
|
+
registerAtlas(desc: AtlasDescriptor): AtlasHandle;
|
|
34
|
+
releaseAtlas(handle: AtlasHandle): void;
|
|
35
|
+
drawSprite(worldX: number, worldY: number, worldZ: number, atlas: AtlasHandle, frame: number, tint?: Readonly<ColorRGBA>): void;
|
|
36
|
+
drawTile(tileX: number, tileY: number, atlas: AtlasHandle, frame: number): void;
|
|
37
|
+
drawText(worldX: number, worldY: number, text: string, style: TextStyle): void;
|
|
38
|
+
drawParticle(worldX: number, worldY: number, worldZ: number, size: number, color: Readonly<ColorRGBA>, additive: boolean): void;
|
|
39
|
+
getDrawCallCount(): number;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
getBatcherStats(): {
|
|
42
|
+
flushCount: number;
|
|
43
|
+
instanceTotal: number;
|
|
44
|
+
capacity: number;
|
|
45
|
+
};
|
|
46
|
+
_peekLastUpload(): {
|
|
47
|
+
count: number;
|
|
48
|
+
floats: number;
|
|
49
|
+
};
|
|
50
|
+
private executeFlush;
|
|
51
|
+
private getOrBakeText;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=webgl2-device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl2-device.d.ts","sourceRoot":"","sources":["../../src/renderer/webgl2-device.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAkDrB,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,GAAG,CAAuC;IAClD,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,WAAW,CAA4B;IAG/C,OAAO,CAAC,gBAAgB,CAAa;IAErC,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,eAAe,CAAa;IAEpC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,aAAa,CAAa;IAElC,OAAO,CAAC,OAAO,CAAgB;IAG/B,OAAO,CAAC,aAAa,CAA6B;IAKlD,OAAO,CAAC,SAAS,CAAwC;IAIzD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,eAAe,CAA6B;IAGpD,OAAO,CAAC,UAAU,CAA8D;gBAEpE,MAAM,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,sBAAsB;IAgDlE,OAAO,CAAC,eAAe;IAqDvB,OAAO,CAAC,cAAc;IA6CtB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,qBAAqB;IAa7B,UAAU,IAAI,IAAI;IA0BlB,QAAQ,IAAI,IAAI;IAOhB,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI;IAI1C,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW;IAOjD,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAOvC,UAAU,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,GACzB,IAAI;IAqCP,QAAQ,CACN,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,GACZ,IAAI;IA+BP,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GACf,IAAI;IA4CP,YAAY,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,QAAQ,EAAE,OAAO,GAChB,IAAI;IAkCP,gBAAgB,IAAI,MAAM;IAO1B,OAAO,IAAI,IAAI;IAkCf,eAAe,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAWlF,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAMpD,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,aAAa;CAiEtB"}
|