@vunk/plus 1.10.3 → 1.11.1

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.
Files changed (46) hide show
  1. package/components/agent-chat-provider/index.mjs +1 -1
  2. package/components/avatar/index.mjs +1 -1
  3. package/components/broadcasting-markdown/index.mjs +25 -16
  4. package/components/broadcasting-markdown/src/ctx.d.ts +7 -0
  5. package/components/broadcasting-markdown/src/index.vue.d.ts +84 -1
  6. package/components/bubble-list/index.mjs +4 -4
  7. package/components/bubble-templates/index.mjs +1 -1
  8. package/components/chat-independent/index.mjs +1 -1
  9. package/components/drawer/index.css +92 -92
  10. package/components/drawer/index.mjs +2 -2
  11. package/components/index2.mjs +64 -26444
  12. package/components/lottie-animation/index.mjs +1 -1
  13. package/components/metahuman-broadcasting/index.mjs +28 -3062
  14. package/components/metahuman-broadcasting/src/ctx.d.ts +4 -0
  15. package/components/metahuman-broadcasting/src/index.vue.d.ts +102 -9
  16. package/components/monaco-editor/index.mjs +1 -1
  17. package/components/monaco-environment/index.mjs +1 -1
  18. package/components/pixi-frame/index.mjs +1988 -7
  19. package/components/pixi-frame/src/bitmap.vue.d.ts +4 -5
  20. package/components/pixi-frame/src/index.vue.d.ts +4 -5
  21. package/components/recorder-button/index.mjs +1 -1
  22. package/components/routes-menu-content/index.mjs +3 -3
  23. package/components/scrollbar/index.mjs +3 -3
  24. package/components/sender/index.mjs +2 -2
  25. package/components/speech-button/index.mjs +3 -3
  26. package/components/table-columns/index.mjs +1 -1
  27. package/components/tables-v1/index.mjs +1 -1
  28. package/components/tables-v1-checkbox/index.mjs +1 -1
  29. package/components/text/index.mjs +1 -1
  30. package/components/typing-markdown/index.mjs +1 -1
  31. package/components/vditor/index.mjs +3 -3
  32. package/components/xgplayer/index.mjs +2 -2
  33. package/icons/end/index.mjs +1 -1
  34. package/icons/keyboard/index.mjs +1 -1
  35. package/icons/start/index.mjs +1 -1
  36. package/icons/voice/index.mjs +1 -1
  37. package/index.css +92 -92
  38. package/package.json +1 -1
  39. package/components/SharedSystems.mjs +0 -3413
  40. package/components/WebGLRenderer.mjs +0 -3631
  41. package/components/WebGPURenderer.mjs +0 -2143
  42. package/components/browserAll.mjs +0 -2960
  43. package/components/colorToUniform.mjs +0 -268
  44. package/components/index3.mjs +0 -78
  45. package/components/init.mjs +0 -4505
  46. package/components/webworkerAll.mjs +0 -10
@@ -1,3413 +0,0 @@
1
- import { q as Shader, G as GpuProgram, t as GlProgram, u as TextureMatrix, k as UniformGroup, M as Matrix, E as ExtensionType, e as extensions, v as DefaultBatcher, x as BigPool, y as getGlobalBounds, z as TexturePool, R as RendererType, F as Bounds, H as FilterEffect, I as Sprite, s as Texture, S as STENCIL_MODES, h as CLEAR, w as warn, J as getAttributeInfoFromFormat, K as unsafeEvalSupported, b as Buffer, B as BufferUsage, i as CanvasSource, L as uid$1, j as TextureSource, N as Rectangle, O as SystemRunner, a as EventEmitter, C as Container, Q as multiplyColors, V as UPDATE_COLOR, W as UPDATE_BLEND, X as UPDATE_VISIBLE, Y as Color, Z as getLocalBounds, P as Point, c as BindGroup, T as Ticker, D as DOMAdapter, _ as VERSION, $ as deprecation, a0 as v8_0_0, a1 as RendererInitHook } from './index2.mjs';
2
- import { S as State, B as BatchableSprite, c as color32BitToUniform } from './colorToUniform.mjs';
3
-
4
- const _Filter = class _Filter extends Shader {
5
- /**
6
- * @param options - The optional parameters of this filter.
7
- */
8
- constructor(options) {
9
- options = { ..._Filter.defaultOptions, ...options };
10
- super(options);
11
- /** If enabled is true the filter is applied, if false it will not. */
12
- this.enabled = true;
13
- /**
14
- * The gpu state the filter requires to render.
15
- * @internal
16
- */
17
- this._state = State.for2d();
18
- this.blendMode = options.blendMode;
19
- this.padding = options.padding;
20
- if (typeof options.antialias === "boolean") {
21
- this.antialias = options.antialias ? "on" : "off";
22
- } else {
23
- this.antialias = options.antialias;
24
- }
25
- this.resolution = options.resolution;
26
- this.blendRequired = options.blendRequired;
27
- this.clipToViewport = options.clipToViewport;
28
- this.addResource("uTexture", 0, 1);
29
- }
30
- /**
31
- * Applies the filter
32
- * @param filterManager - The renderer to retrieve the filter from
33
- * @param input - The input render target.
34
- * @param output - The target to output to.
35
- * @param clearMode - Should the output be cleared before rendering to it
36
- */
37
- apply(filterManager, input, output, clearMode) {
38
- filterManager.applyFilter(this, input, output, clearMode);
39
- }
40
- /**
41
- * Get the blend mode of the filter.
42
- * @default "normal"
43
- */
44
- get blendMode() {
45
- return this._state.blendMode;
46
- }
47
- /** Sets the blend mode of the filter. */
48
- set blendMode(value) {
49
- this._state.blendMode = value;
50
- }
51
- /**
52
- * A short hand function to create a filter based of a vertex and fragment shader src.
53
- * @param options
54
- * @returns A shiny new PixiJS filter!
55
- */
56
- static from(options) {
57
- const { gpu, gl, ...rest } = options;
58
- let gpuProgram;
59
- let glProgram;
60
- if (gpu) {
61
- gpuProgram = GpuProgram.from(gpu);
62
- }
63
- if (gl) {
64
- glProgram = GlProgram.from(gl);
65
- }
66
- return new _Filter({
67
- gpuProgram,
68
- glProgram,
69
- ...rest
70
- });
71
- }
72
- };
73
- /** The default filter settings */
74
- _Filter.defaultOptions = {
75
- blendMode: "normal",
76
- resolution: 1,
77
- padding: 0,
78
- antialias: "off",
79
- blendRequired: false,
80
- clipToViewport: true
81
- };
82
- let Filter = _Filter;
83
-
84
- var fragment = "in vec2 vMaskCoord;\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uMaskTexture;\n\nuniform float uAlpha;\nuniform vec4 uMaskClamp;\nuniform float uInverse;\n\nout vec4 finalColor;\n\nvoid main(void)\n{\n float clip = step(3.5,\n step(uMaskClamp.x, vMaskCoord.x) +\n step(uMaskClamp.y, vMaskCoord.y) +\n step(vMaskCoord.x, uMaskClamp.z) +\n step(vMaskCoord.y, uMaskClamp.w));\n\n // TODO look into why this is needed\n float npmAlpha = uAlpha;\n vec4 original = texture(uTexture, vTextureCoord);\n vec4 masky = texture(uMaskTexture, vMaskCoord);\n float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);\n\n float a = alphaMul * masky.r * npmAlpha * clip;\n\n if (uInverse == 1.0) {\n a = 1.0 - a;\n }\n\n finalColor = original * a;\n}\n";
85
-
86
- var vertex = "in vec2 aPosition;\n\nout vec2 vTextureCoord;\nout vec2 vMaskCoord;\n\n\nuniform vec4 uInputSize;\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\nuniform mat3 uFilterMatrix;\n\nvec4 filterVertexPosition( vec2 aPosition )\n{\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n \n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( vec2 aPosition )\n{\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\n}\n\nvec2 getFilterCoord( vec2 aPosition )\n{\n return ( uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy;\n} \n\nvoid main(void)\n{\n gl_Position = filterVertexPosition(aPosition);\n vTextureCoord = filterTextureCoord(aPosition);\n vMaskCoord = getFilterCoord(aPosition);\n}\n";
87
-
88
- var source = "struct GlobalFilterUniforms {\n uInputSize:vec4<f32>,\n uInputPixel:vec4<f32>,\n uInputClamp:vec4<f32>,\n uOutputFrame:vec4<f32>,\n uGlobalFrame:vec4<f32>,\n uOutputTexture:vec4<f32>,\n};\n\nstruct MaskUniforms {\n uFilterMatrix:mat3x3<f32>,\n uMaskClamp:vec4<f32>,\n uAlpha:f32,\n uInverse:f32,\n};\n\n@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d<f32>;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var<uniform> filterUniforms : MaskUniforms;\n@group(1) @binding(1) var uMaskTexture: texture_2d<f32>;\n\nstruct VSOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv : vec2<f32>,\n @location(1) filterUv : vec2<f32>,\n};\n\nfn filterVertexPosition(aPosition:vec2<f32>) -> vec4<f32>\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2<f32> ) -> vec2<f32>\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2<f32> ) -> vec2<f32>\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw);\n}\n\nfn getFilterCoord(aPosition:vec2<f32> ) -> vec2<f32>\n{\n return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy;\n}\n\nfn getSize() -> vec2<f32>\n{\n return gfu.uGlobalFrame.zw;\n}\n\n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2<f32>,\n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition),\n getFilterCoord(aPosition)\n );\n}\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2<f32>,\n @location(1) filterUv: vec2<f32>,\n @builtin(position) position: vec4<f32>\n) -> @location(0) vec4<f32> {\n\n var maskClamp = filterUniforms.uMaskClamp;\n var uAlpha = filterUniforms.uAlpha;\n\n var clip = step(3.5,\n step(maskClamp.x, filterUv.x) +\n step(maskClamp.y, filterUv.y) +\n step(filterUv.x, maskClamp.z) +\n step(filterUv.y, maskClamp.w));\n\n var mask = textureSample(uMaskTexture, uSampler, filterUv);\n var source = textureSample(uTexture, uSampler, uv);\n var alphaMul = 1.0 - uAlpha * (1.0 - mask.a);\n\n var a: f32 = alphaMul * mask.r * uAlpha * clip;\n\n if (filterUniforms.uInverse == 1.0) {\n a = 1.0 - a;\n }\n\n return source * a;\n}\n";
89
-
90
- class MaskFilter extends Filter {
91
- constructor(options) {
92
- const { sprite, ...rest } = options;
93
- const textureMatrix = new TextureMatrix(sprite.texture);
94
- const filterUniforms = new UniformGroup({
95
- uFilterMatrix: { value: new Matrix(), type: "mat3x3<f32>" },
96
- uMaskClamp: { value: textureMatrix.uClampFrame, type: "vec4<f32>" },
97
- uAlpha: { value: 1, type: "f32" },
98
- uInverse: { value: options.inverse ? 1 : 0, type: "f32" }
99
- });
100
- const gpuProgram = GpuProgram.from({
101
- vertex: {
102
- source,
103
- entryPoint: "mainVertex"
104
- },
105
- fragment: {
106
- source,
107
- entryPoint: "mainFragment"
108
- }
109
- });
110
- const glProgram = GlProgram.from({
111
- vertex,
112
- fragment,
113
- name: "mask-filter"
114
- });
115
- super({
116
- ...rest,
117
- gpuProgram,
118
- glProgram,
119
- resources: {
120
- filterUniforms,
121
- uMaskTexture: sprite.texture.source
122
- }
123
- });
124
- this.sprite = sprite;
125
- this._textureMatrix = textureMatrix;
126
- }
127
- set inverse(value) {
128
- this.resources.filterUniforms.uniforms.uInverse = value ? 1 : 0;
129
- }
130
- get inverse() {
131
- return this.resources.filterUniforms.uniforms.uInverse === 1;
132
- }
133
- apply(filterManager, input, output, clearMode) {
134
- this._textureMatrix.texture = this.sprite.texture;
135
- filterManager.calculateSpriteMatrix(
136
- this.resources.filterUniforms.uniforms.uFilterMatrix,
137
- this.sprite
138
- ).prepend(this._textureMatrix.mapCoord);
139
- this.resources.uMaskTexture = this.sprite.texture.source;
140
- filterManager.applyFilter(this, input, output, clearMode);
141
- }
142
- }
143
-
144
- const _BatcherPipe = class _BatcherPipe {
145
- constructor(renderer, adaptor) {
146
- this.state = State.for2d();
147
- this._batchersByInstructionSet = /* @__PURE__ */ Object.create(null);
148
- /** A record of all active batchers, keyed by their names */
149
- this._activeBatches = /* @__PURE__ */ Object.create(null);
150
- this.renderer = renderer;
151
- this._adaptor = adaptor;
152
- this._adaptor.init?.(this);
153
- }
154
- static getBatcher(name) {
155
- return new this._availableBatchers[name]();
156
- }
157
- buildStart(instructionSet) {
158
- let batchers = this._batchersByInstructionSet[instructionSet.uid];
159
- if (!batchers) {
160
- batchers = this._batchersByInstructionSet[instructionSet.uid] = /* @__PURE__ */ Object.create(null);
161
- batchers.default || (batchers.default = new DefaultBatcher({
162
- maxTextures: this.renderer.limits.maxBatchableTextures
163
- }));
164
- }
165
- this._activeBatches = batchers;
166
- this._activeBatch = this._activeBatches.default;
167
- for (const i in this._activeBatches) {
168
- this._activeBatches[i].begin();
169
- }
170
- }
171
- addToBatch(batchableObject, instructionSet) {
172
- if (this._activeBatch.name !== batchableObject.batcherName) {
173
- this._activeBatch.break(instructionSet);
174
- let batch = this._activeBatches[batchableObject.batcherName];
175
- if (!batch) {
176
- batch = this._activeBatches[batchableObject.batcherName] = _BatcherPipe.getBatcher(batchableObject.batcherName);
177
- batch.begin();
178
- }
179
- this._activeBatch = batch;
180
- }
181
- this._activeBatch.add(batchableObject);
182
- }
183
- break(instructionSet) {
184
- this._activeBatch.break(instructionSet);
185
- }
186
- buildEnd(instructionSet) {
187
- this._activeBatch.break(instructionSet);
188
- const batches = this._activeBatches;
189
- for (const i in batches) {
190
- const batch = batches[i];
191
- const geometry = batch.geometry;
192
- geometry.indexBuffer.setDataWithSize(batch.indexBuffer, batch.indexSize, true);
193
- geometry.buffers[0].setDataWithSize(batch.attributeBuffer.float32View, batch.attributeSize, false);
194
- }
195
- }
196
- upload(instructionSet) {
197
- const batchers = this._batchersByInstructionSet[instructionSet.uid];
198
- for (const i in batchers) {
199
- const batcher = batchers[i];
200
- const geometry = batcher.geometry;
201
- if (batcher.dirty) {
202
- batcher.dirty = false;
203
- geometry.buffers[0].update(batcher.attributeSize * 4);
204
- }
205
- }
206
- }
207
- execute(batch) {
208
- if (batch.action === "startBatch") {
209
- const batcher = batch.batcher;
210
- const geometry = batcher.geometry;
211
- const shader = batcher.shader;
212
- this._adaptor.start(this, geometry, shader);
213
- }
214
- this._adaptor.execute(this, batch);
215
- }
216
- destroy() {
217
- this.state = null;
218
- this.renderer = null;
219
- this._adaptor = null;
220
- for (const i in this._activeBatches) {
221
- this._activeBatches[i].destroy();
222
- }
223
- this._activeBatches = null;
224
- }
225
- };
226
- /** @ignore */
227
- _BatcherPipe.extension = {
228
- type: [
229
- ExtensionType.WebGLPipes,
230
- ExtensionType.WebGPUPipes,
231
- ExtensionType.CanvasPipes
232
- ],
233
- name: "batch"
234
- };
235
- _BatcherPipe._availableBatchers = /* @__PURE__ */ Object.create(null);
236
- let BatcherPipe = _BatcherPipe;
237
- extensions.handleByMap(ExtensionType.Batcher, BatcherPipe._availableBatchers);
238
- extensions.add(DefaultBatcher);
239
-
240
- const textureBit = {
241
- name: "texture-bit",
242
- vertex: {
243
- header: (
244
- /* wgsl */
245
- `
246
-
247
- struct TextureUniforms {
248
- uTextureMatrix:mat3x3<f32>,
249
- }
250
-
251
- @group(2) @binding(2) var<uniform> textureUniforms : TextureUniforms;
252
- `
253
- ),
254
- main: (
255
- /* wgsl */
256
- `
257
- uv = (textureUniforms.uTextureMatrix * vec3(uv, 1.0)).xy;
258
- `
259
- )
260
- },
261
- fragment: {
262
- header: (
263
- /* wgsl */
264
- `
265
- @group(2) @binding(0) var uTexture: texture_2d<f32>;
266
- @group(2) @binding(1) var uSampler: sampler;
267
-
268
-
269
- `
270
- ),
271
- main: (
272
- /* wgsl */
273
- `
274
- outColor = textureSample(uTexture, uSampler, vUV);
275
- `
276
- )
277
- }
278
- };
279
- const textureBitGl = {
280
- name: "texture-bit",
281
- vertex: {
282
- header: (
283
- /* glsl */
284
- `
285
- uniform mat3 uTextureMatrix;
286
- `
287
- ),
288
- main: (
289
- /* glsl */
290
- `
291
- uv = (uTextureMatrix * vec3(uv, 1.0)).xy;
292
- `
293
- )
294
- },
295
- fragment: {
296
- header: (
297
- /* glsl */
298
- `
299
- uniform sampler2D uTexture;
300
-
301
-
302
- `
303
- ),
304
- main: (
305
- /* glsl */
306
- `
307
- outColor = texture(uTexture, vUV);
308
- `
309
- )
310
- }
311
- };
312
-
313
- const tempBounds$1 = new Bounds();
314
- class AlphaMaskEffect extends FilterEffect {
315
- constructor() {
316
- super();
317
- this.filters = [new MaskFilter({
318
- sprite: new Sprite(Texture.EMPTY),
319
- inverse: false,
320
- resolution: "inherit",
321
- antialias: "inherit"
322
- })];
323
- }
324
- get sprite() {
325
- return this.filters[0].sprite;
326
- }
327
- set sprite(value) {
328
- this.filters[0].sprite = value;
329
- }
330
- get inverse() {
331
- return this.filters[0].inverse;
332
- }
333
- set inverse(value) {
334
- this.filters[0].inverse = value;
335
- }
336
- }
337
- class AlphaMaskPipe {
338
- constructor(renderer) {
339
- this._activeMaskStage = [];
340
- this._renderer = renderer;
341
- }
342
- push(mask, maskedContainer, instructionSet) {
343
- const renderer = this._renderer;
344
- renderer.renderPipes.batch.break(instructionSet);
345
- instructionSet.add({
346
- renderPipeId: "alphaMask",
347
- action: "pushMaskBegin",
348
- mask,
349
- inverse: maskedContainer._maskOptions.inverse,
350
- canBundle: false,
351
- maskedContainer
352
- });
353
- mask.inverse = maskedContainer._maskOptions.inverse;
354
- if (mask.renderMaskToTexture) {
355
- const maskContainer = mask.mask;
356
- maskContainer.includeInBuild = true;
357
- maskContainer.collectRenderables(
358
- instructionSet,
359
- renderer,
360
- null
361
- );
362
- maskContainer.includeInBuild = false;
363
- }
364
- renderer.renderPipes.batch.break(instructionSet);
365
- instructionSet.add({
366
- renderPipeId: "alphaMask",
367
- action: "pushMaskEnd",
368
- mask,
369
- maskedContainer,
370
- inverse: maskedContainer._maskOptions.inverse,
371
- canBundle: false
372
- });
373
- }
374
- pop(mask, _maskedContainer, instructionSet) {
375
- const renderer = this._renderer;
376
- renderer.renderPipes.batch.break(instructionSet);
377
- instructionSet.add({
378
- renderPipeId: "alphaMask",
379
- action: "popMaskEnd",
380
- mask,
381
- inverse: _maskedContainer._maskOptions.inverse,
382
- canBundle: false
383
- });
384
- }
385
- execute(instruction) {
386
- const renderer = this._renderer;
387
- const renderMask = instruction.mask.renderMaskToTexture;
388
- if (instruction.action === "pushMaskBegin") {
389
- const filterEffect = BigPool.get(AlphaMaskEffect);
390
- filterEffect.inverse = instruction.inverse;
391
- if (renderMask) {
392
- instruction.mask.mask.measurable = true;
393
- const bounds = getGlobalBounds(instruction.mask.mask, true, tempBounds$1);
394
- instruction.mask.mask.measurable = false;
395
- bounds.ceil();
396
- const colorTextureSource = renderer.renderTarget.renderTarget.colorTexture.source;
397
- const filterTexture = TexturePool.getOptimalTexture(
398
- bounds.width,
399
- bounds.height,
400
- colorTextureSource._resolution,
401
- colorTextureSource.antialias
402
- );
403
- renderer.renderTarget.push(filterTexture, true);
404
- renderer.globalUniforms.push({
405
- offset: bounds,
406
- worldColor: 4294967295
407
- });
408
- const sprite = filterEffect.sprite;
409
- sprite.texture = filterTexture;
410
- sprite.worldTransform.tx = bounds.minX;
411
- sprite.worldTransform.ty = bounds.minY;
412
- this._activeMaskStage.push({
413
- filterEffect,
414
- maskedContainer: instruction.maskedContainer,
415
- filterTexture
416
- });
417
- } else {
418
- filterEffect.sprite = instruction.mask.mask;
419
- this._activeMaskStage.push({
420
- filterEffect,
421
- maskedContainer: instruction.maskedContainer
422
- });
423
- }
424
- } else if (instruction.action === "pushMaskEnd") {
425
- const maskData = this._activeMaskStage[this._activeMaskStage.length - 1];
426
- if (renderMask) {
427
- if (renderer.type === RendererType.WEBGL) {
428
- renderer.renderTarget.finishRenderPass();
429
- }
430
- renderer.renderTarget.pop();
431
- renderer.globalUniforms.pop();
432
- }
433
- renderer.filter.push({
434
- renderPipeId: "filter",
435
- action: "pushFilter",
436
- container: maskData.maskedContainer,
437
- filterEffect: maskData.filterEffect,
438
- canBundle: false
439
- });
440
- } else if (instruction.action === "popMaskEnd") {
441
- renderer.filter.pop();
442
- const maskData = this._activeMaskStage.pop();
443
- if (renderMask) {
444
- TexturePool.returnTexture(maskData.filterTexture);
445
- }
446
- BigPool.return(maskData.filterEffect);
447
- }
448
- }
449
- destroy() {
450
- this._renderer = null;
451
- this._activeMaskStage = null;
452
- }
453
- }
454
- /** @ignore */
455
- AlphaMaskPipe.extension = {
456
- type: [
457
- ExtensionType.WebGLPipes,
458
- ExtensionType.WebGPUPipes,
459
- ExtensionType.CanvasPipes
460
- ],
461
- name: "alphaMask"
462
- };
463
-
464
- class ColorMaskPipe {
465
- constructor(renderer) {
466
- this._colorStack = [];
467
- this._colorStackIndex = 0;
468
- this._currentColor = 0;
469
- this._renderer = renderer;
470
- }
471
- buildStart() {
472
- this._colorStack[0] = 15;
473
- this._colorStackIndex = 1;
474
- this._currentColor = 15;
475
- }
476
- push(mask, _container, instructionSet) {
477
- const renderer = this._renderer;
478
- renderer.renderPipes.batch.break(instructionSet);
479
- const colorStack = this._colorStack;
480
- colorStack[this._colorStackIndex] = colorStack[this._colorStackIndex - 1] & mask.mask;
481
- const currentColor = this._colorStack[this._colorStackIndex];
482
- if (currentColor !== this._currentColor) {
483
- this._currentColor = currentColor;
484
- instructionSet.add({
485
- renderPipeId: "colorMask",
486
- colorMask: currentColor,
487
- canBundle: false
488
- });
489
- }
490
- this._colorStackIndex++;
491
- }
492
- pop(_mask, _container, instructionSet) {
493
- const renderer = this._renderer;
494
- renderer.renderPipes.batch.break(instructionSet);
495
- const colorStack = this._colorStack;
496
- this._colorStackIndex--;
497
- const currentColor = colorStack[this._colorStackIndex - 1];
498
- if (currentColor !== this._currentColor) {
499
- this._currentColor = currentColor;
500
- instructionSet.add({
501
- renderPipeId: "colorMask",
502
- colorMask: currentColor,
503
- canBundle: false
504
- });
505
- }
506
- }
507
- execute(instruction) {
508
- const renderer = this._renderer;
509
- renderer.colorMask.setMask(instruction.colorMask);
510
- }
511
- destroy() {
512
- this._colorStack = null;
513
- }
514
- }
515
- /** @ignore */
516
- ColorMaskPipe.extension = {
517
- type: [
518
- ExtensionType.WebGLPipes,
519
- ExtensionType.WebGPUPipes,
520
- ExtensionType.CanvasPipes
521
- ],
522
- name: "colorMask"
523
- };
524
-
525
- class StencilMaskPipe {
526
- constructor(renderer) {
527
- // used when building and also when executing..
528
- this._maskStackHash = {};
529
- this._maskHash = /* @__PURE__ */ new WeakMap();
530
- this._renderer = renderer;
531
- }
532
- push(mask, _container, instructionSet) {
533
- var _a;
534
- const effect = mask;
535
- const renderer = this._renderer;
536
- renderer.renderPipes.batch.break(instructionSet);
537
- renderer.renderPipes.blendMode.setBlendMode(effect.mask, "none", instructionSet);
538
- instructionSet.add({
539
- renderPipeId: "stencilMask",
540
- action: "pushMaskBegin",
541
- mask,
542
- inverse: _container._maskOptions.inverse,
543
- canBundle: false
544
- });
545
- const maskContainer = effect.mask;
546
- maskContainer.includeInBuild = true;
547
- if (!this._maskHash.has(effect)) {
548
- this._maskHash.set(effect, {
549
- instructionsStart: 0,
550
- instructionsLength: 0
551
- });
552
- }
553
- const maskData = this._maskHash.get(effect);
554
- maskData.instructionsStart = instructionSet.instructionSize;
555
- maskContainer.collectRenderables(
556
- instructionSet,
557
- renderer,
558
- null
559
- );
560
- maskContainer.includeInBuild = false;
561
- renderer.renderPipes.batch.break(instructionSet);
562
- instructionSet.add({
563
- renderPipeId: "stencilMask",
564
- action: "pushMaskEnd",
565
- mask,
566
- inverse: _container._maskOptions.inverse,
567
- canBundle: false
568
- });
569
- const instructionsLength = instructionSet.instructionSize - maskData.instructionsStart - 1;
570
- maskData.instructionsLength = instructionsLength;
571
- const renderTargetUid = renderer.renderTarget.renderTarget.uid;
572
- (_a = this._maskStackHash)[renderTargetUid] ?? (_a[renderTargetUid] = 0);
573
- }
574
- pop(mask, _container, instructionSet) {
575
- const effect = mask;
576
- const renderer = this._renderer;
577
- renderer.renderPipes.batch.break(instructionSet);
578
- renderer.renderPipes.blendMode.setBlendMode(effect.mask, "none", instructionSet);
579
- instructionSet.add({
580
- renderPipeId: "stencilMask",
581
- action: "popMaskBegin",
582
- inverse: _container._maskOptions.inverse,
583
- canBundle: false
584
- });
585
- const maskData = this._maskHash.get(mask);
586
- for (let i = 0; i < maskData.instructionsLength; i++) {
587
- instructionSet.instructions[instructionSet.instructionSize++] = instructionSet.instructions[maskData.instructionsStart++];
588
- }
589
- instructionSet.add({
590
- renderPipeId: "stencilMask",
591
- action: "popMaskEnd",
592
- canBundle: false
593
- });
594
- }
595
- execute(instruction) {
596
- var _a;
597
- const renderer = this._renderer;
598
- const renderTargetUid = renderer.renderTarget.renderTarget.uid;
599
- let maskStackIndex = (_a = this._maskStackHash)[renderTargetUid] ?? (_a[renderTargetUid] = 0);
600
- if (instruction.action === "pushMaskBegin") {
601
- renderer.renderTarget.ensureDepthStencil();
602
- renderer.stencil.setStencilMode(STENCIL_MODES.RENDERING_MASK_ADD, maskStackIndex);
603
- maskStackIndex++;
604
- renderer.colorMask.setMask(0);
605
- } else if (instruction.action === "pushMaskEnd") {
606
- if (instruction.inverse) {
607
- renderer.stencil.setStencilMode(STENCIL_MODES.INVERSE_MASK_ACTIVE, maskStackIndex);
608
- } else {
609
- renderer.stencil.setStencilMode(STENCIL_MODES.MASK_ACTIVE, maskStackIndex);
610
- }
611
- renderer.colorMask.setMask(15);
612
- } else if (instruction.action === "popMaskBegin") {
613
- renderer.colorMask.setMask(0);
614
- if (maskStackIndex !== 0) {
615
- renderer.stencil.setStencilMode(STENCIL_MODES.RENDERING_MASK_REMOVE, maskStackIndex);
616
- } else {
617
- renderer.renderTarget.clear(null, CLEAR.STENCIL);
618
- renderer.stencil.setStencilMode(STENCIL_MODES.DISABLED, maskStackIndex);
619
- }
620
- maskStackIndex--;
621
- } else if (instruction.action === "popMaskEnd") {
622
- if (instruction.inverse) {
623
- renderer.stencil.setStencilMode(STENCIL_MODES.INVERSE_MASK_ACTIVE, maskStackIndex);
624
- } else {
625
- renderer.stencil.setStencilMode(STENCIL_MODES.MASK_ACTIVE, maskStackIndex);
626
- }
627
- renderer.colorMask.setMask(15);
628
- }
629
- this._maskStackHash[renderTargetUid] = maskStackIndex;
630
- }
631
- destroy() {
632
- this._renderer = null;
633
- this._maskStackHash = null;
634
- this._maskHash = null;
635
- }
636
- }
637
- StencilMaskPipe.extension = {
638
- type: [
639
- ExtensionType.WebGLPipes,
640
- ExtensionType.WebGPUPipes,
641
- ExtensionType.CanvasPipes
642
- ],
643
- name: "stencilMask"
644
- };
645
-
646
- function ensureAttributes(geometry, extractedData) {
647
- for (const i in geometry.attributes) {
648
- const attribute = geometry.attributes[i];
649
- const attributeData = extractedData[i];
650
- if (attributeData) {
651
- attribute.format ?? (attribute.format = attributeData.format);
652
- attribute.offset ?? (attribute.offset = attributeData.offset);
653
- attribute.instance ?? (attribute.instance = attributeData.instance);
654
- } else {
655
- warn(`Attribute ${i} is not present in the shader, but is present in the geometry. Unable to infer attribute details.`);
656
- }
657
- }
658
- ensureStartAndStride(geometry);
659
- }
660
- function ensureStartAndStride(geometry) {
661
- const { buffers, attributes } = geometry;
662
- const tempStride = {};
663
- const tempStart = {};
664
- for (const j in buffers) {
665
- const buffer = buffers[j];
666
- tempStride[buffer.uid] = 0;
667
- tempStart[buffer.uid] = 0;
668
- }
669
- for (const j in attributes) {
670
- const attribute = attributes[j];
671
- tempStride[attribute.buffer.uid] += getAttributeInfoFromFormat(attribute.format).stride;
672
- }
673
- for (const j in attributes) {
674
- const attribute = attributes[j];
675
- attribute.stride ?? (attribute.stride = tempStride[attribute.buffer.uid]);
676
- attribute.start ?? (attribute.start = tempStart[attribute.buffer.uid]);
677
- tempStart[attribute.buffer.uid] += getAttributeInfoFromFormat(attribute.format).stride;
678
- }
679
- }
680
-
681
- const GpuStencilModesToPixi = [];
682
- GpuStencilModesToPixi[STENCIL_MODES.NONE] = void 0;
683
- GpuStencilModesToPixi[STENCIL_MODES.DISABLED] = {
684
- stencilWriteMask: 0,
685
- stencilReadMask: 0
686
- };
687
- GpuStencilModesToPixi[STENCIL_MODES.RENDERING_MASK_ADD] = {
688
- stencilFront: {
689
- compare: "equal",
690
- passOp: "increment-clamp"
691
- },
692
- stencilBack: {
693
- compare: "equal",
694
- passOp: "increment-clamp"
695
- }
696
- };
697
- GpuStencilModesToPixi[STENCIL_MODES.RENDERING_MASK_REMOVE] = {
698
- stencilFront: {
699
- compare: "equal",
700
- passOp: "decrement-clamp"
701
- },
702
- stencilBack: {
703
- compare: "equal",
704
- passOp: "decrement-clamp"
705
- }
706
- };
707
- GpuStencilModesToPixi[STENCIL_MODES.MASK_ACTIVE] = {
708
- stencilWriteMask: 0,
709
- stencilFront: {
710
- compare: "equal",
711
- passOp: "keep"
712
- },
713
- stencilBack: {
714
- compare: "equal",
715
- passOp: "keep"
716
- }
717
- };
718
- GpuStencilModesToPixi[STENCIL_MODES.INVERSE_MASK_ACTIVE] = {
719
- stencilWriteMask: 0,
720
- stencilFront: {
721
- compare: "not-equal",
722
- passOp: "keep"
723
- },
724
- stencilBack: {
725
- compare: "not-equal",
726
- passOp: "keep"
727
- }
728
- };
729
-
730
- class UboSystem {
731
- constructor(adaptor) {
732
- /** Cache of uniform buffer layouts and sync functions, so we don't have to re-create them */
733
- this._syncFunctionHash = /* @__PURE__ */ Object.create(null);
734
- this._adaptor = adaptor;
735
- this._systemCheck();
736
- }
737
- /**
738
- * Overridable function by `pixi.js/unsafe-eval` to silence
739
- * throwing an error if platform doesn't support unsafe-evals.
740
- * @private
741
- */
742
- _systemCheck() {
743
- if (!unsafeEvalSupported()) {
744
- throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support.");
745
- }
746
- }
747
- ensureUniformGroup(uniformGroup) {
748
- const uniformData = this.getUniformGroupData(uniformGroup);
749
- uniformGroup.buffer || (uniformGroup.buffer = new Buffer({
750
- data: new Float32Array(uniformData.layout.size / 4),
751
- usage: BufferUsage.UNIFORM | BufferUsage.COPY_DST
752
- }));
753
- }
754
- getUniformGroupData(uniformGroup) {
755
- return this._syncFunctionHash[uniformGroup._signature] || this._initUniformGroup(uniformGroup);
756
- }
757
- _initUniformGroup(uniformGroup) {
758
- const uniformGroupSignature = uniformGroup._signature;
759
- let uniformData = this._syncFunctionHash[uniformGroupSignature];
760
- if (!uniformData) {
761
- const elements = Object.keys(uniformGroup.uniformStructures).map((i) => uniformGroup.uniformStructures[i]);
762
- const layout = this._adaptor.createUboElements(elements);
763
- const syncFunction = this._generateUboSync(layout.uboElements);
764
- uniformData = this._syncFunctionHash[uniformGroupSignature] = {
765
- layout,
766
- syncFunction
767
- };
768
- }
769
- return this._syncFunctionHash[uniformGroupSignature];
770
- }
771
- _generateUboSync(uboElements) {
772
- return this._adaptor.generateUboSync(uboElements);
773
- }
774
- syncUniformGroup(uniformGroup, data, offset) {
775
- const uniformGroupData = this.getUniformGroupData(uniformGroup);
776
- uniformGroup.buffer || (uniformGroup.buffer = new Buffer({
777
- data: new Float32Array(uniformGroupData.layout.size / 4),
778
- usage: BufferUsage.UNIFORM | BufferUsage.COPY_DST
779
- }));
780
- let dataInt32 = null;
781
- if (!data) {
782
- data = uniformGroup.buffer.data;
783
- dataInt32 = uniformGroup.buffer.dataInt32;
784
- }
785
- offset || (offset = 0);
786
- uniformGroupData.syncFunction(uniformGroup.uniforms, data, dataInt32, offset);
787
- return true;
788
- }
789
- updateUniformGroup(uniformGroup) {
790
- if (uniformGroup.isStatic && !uniformGroup._dirtyId)
791
- return false;
792
- uniformGroup._dirtyId = 0;
793
- const synced = this.syncUniformGroup(uniformGroup);
794
- uniformGroup.buffer.update();
795
- return synced;
796
- }
797
- destroy() {
798
- this._syncFunctionHash = null;
799
- }
800
- }
801
-
802
- const uniformParsers = [
803
- // uploading pixi matrix object to mat3
804
- {
805
- type: "mat3x3<f32>",
806
- test: (data) => {
807
- const value = data.value;
808
- return value.a !== void 0;
809
- },
810
- ubo: `
811
- var matrix = uv[name].toArray(true);
812
- data[offset] = matrix[0];
813
- data[offset + 1] = matrix[1];
814
- data[offset + 2] = matrix[2];
815
- data[offset + 4] = matrix[3];
816
- data[offset + 5] = matrix[4];
817
- data[offset + 6] = matrix[5];
818
- data[offset + 8] = matrix[6];
819
- data[offset + 9] = matrix[7];
820
- data[offset + 10] = matrix[8];
821
- `,
822
- uniform: `
823
- gl.uniformMatrix3fv(ud[name].location, false, uv[name].toArray(true));
824
- `
825
- },
826
- // uploading a pixi rectangle as a vec4
827
- {
828
- type: "vec4<f32>",
829
- test: (data) => data.type === "vec4<f32>" && data.size === 1 && data.value.width !== void 0,
830
- ubo: `
831
- v = uv[name];
832
- data[offset] = v.x;
833
- data[offset + 1] = v.y;
834
- data[offset + 2] = v.width;
835
- data[offset + 3] = v.height;
836
- `,
837
- uniform: `
838
- cv = ud[name].value;
839
- v = uv[name];
840
- if (cv[0] !== v.x || cv[1] !== v.y || cv[2] !== v.width || cv[3] !== v.height) {
841
- cv[0] = v.x;
842
- cv[1] = v.y;
843
- cv[2] = v.width;
844
- cv[3] = v.height;
845
- gl.uniform4f(ud[name].location, v.x, v.y, v.width, v.height);
846
- }
847
- `
848
- },
849
- // uploading a pixi point as a vec2
850
- {
851
- type: "vec2<f32>",
852
- test: (data) => data.type === "vec2<f32>" && data.size === 1 && data.value.x !== void 0,
853
- ubo: `
854
- v = uv[name];
855
- data[offset] = v.x;
856
- data[offset + 1] = v.y;
857
- `,
858
- uniform: `
859
- cv = ud[name].value;
860
- v = uv[name];
861
- if (cv[0] !== v.x || cv[1] !== v.y) {
862
- cv[0] = v.x;
863
- cv[1] = v.y;
864
- gl.uniform2f(ud[name].location, v.x, v.y);
865
- }
866
- `
867
- },
868
- // uploading a pixi color as a vec4
869
- {
870
- type: "vec4<f32>",
871
- test: (data) => data.type === "vec4<f32>" && data.size === 1 && data.value.red !== void 0,
872
- ubo: `
873
- v = uv[name];
874
- data[offset] = v.red;
875
- data[offset + 1] = v.green;
876
- data[offset + 2] = v.blue;
877
- data[offset + 3] = v.alpha;
878
- `,
879
- uniform: `
880
- cv = ud[name].value;
881
- v = uv[name];
882
- if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue || cv[3] !== v.alpha) {
883
- cv[0] = v.red;
884
- cv[1] = v.green;
885
- cv[2] = v.blue;
886
- cv[3] = v.alpha;
887
- gl.uniform4f(ud[name].location, v.red, v.green, v.blue, v.alpha);
888
- }
889
- `
890
- },
891
- // uploading a pixi color as a vec3
892
- {
893
- type: "vec3<f32>",
894
- test: (data) => data.type === "vec3<f32>" && data.size === 1 && data.value.red !== void 0,
895
- ubo: `
896
- v = uv[name];
897
- data[offset] = v.red;
898
- data[offset + 1] = v.green;
899
- data[offset + 2] = v.blue;
900
- `,
901
- uniform: `
902
- cv = ud[name].value;
903
- v = uv[name];
904
- if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue) {
905
- cv[0] = v.red;
906
- cv[1] = v.green;
907
- cv[2] = v.blue;
908
- gl.uniform3f(ud[name].location, v.red, v.green, v.blue);
909
- }
910
- `
911
- }
912
- ];
913
-
914
- function createUboSyncFunction(uboElements, parserCode, arrayGenerationFunction, singleSettersMap) {
915
- const funcFragments = [`
916
- var v = null;
917
- var v2 = null;
918
- var t = 0;
919
- var index = 0;
920
- var name = null;
921
- var arrayOffset = null;
922
- `];
923
- let prev = 0;
924
- for (let i = 0; i < uboElements.length; i++) {
925
- const uboElement = uboElements[i];
926
- const name = uboElement.data.name;
927
- let parsed = false;
928
- let offset = 0;
929
- for (let j = 0; j < uniformParsers.length; j++) {
930
- const uniformParser = uniformParsers[j];
931
- if (uniformParser.test(uboElement.data)) {
932
- offset = uboElement.offset / 4;
933
- funcFragments.push(
934
- `name = "${name}";`,
935
- `offset += ${offset - prev};`,
936
- uniformParsers[j][parserCode] || uniformParsers[j].ubo
937
- );
938
- parsed = true;
939
- break;
940
- }
941
- }
942
- if (!parsed) {
943
- if (uboElement.data.size > 1) {
944
- offset = uboElement.offset / 4;
945
- funcFragments.push(arrayGenerationFunction(uboElement, offset - prev));
946
- } else {
947
- const template = singleSettersMap[uboElement.data.type];
948
- offset = uboElement.offset / 4;
949
- funcFragments.push(
950
- /* wgsl */
951
- `
952
- v = uv.${name};
953
- offset += ${offset - prev};
954
- ${template};
955
- `
956
- );
957
- }
958
- }
959
- prev = offset;
960
- }
961
- const fragmentSrc = funcFragments.join("\n");
962
- return new Function(
963
- "uv",
964
- "data",
965
- "dataInt32",
966
- "offset",
967
- fragmentSrc
968
- );
969
- }
970
-
971
- function loopMatrix(col, row) {
972
- const total = col * row;
973
- return `
974
- for (let i = 0; i < ${total}; i++) {
975
- data[offset + (((i / ${col})|0) * 4) + (i % ${col})] = v[i];
976
- }
977
- `;
978
- }
979
- const uboSyncFunctionsSTD40 = {
980
- f32: `
981
- data[offset] = v;`,
982
- i32: `
983
- dataInt32[offset] = v;`,
984
- "vec2<f32>": `
985
- data[offset] = v[0];
986
- data[offset + 1] = v[1];`,
987
- "vec3<f32>": `
988
- data[offset] = v[0];
989
- data[offset + 1] = v[1];
990
- data[offset + 2] = v[2];`,
991
- "vec4<f32>": `
992
- data[offset] = v[0];
993
- data[offset + 1] = v[1];
994
- data[offset + 2] = v[2];
995
- data[offset + 3] = v[3];`,
996
- "vec2<i32>": `
997
- dataInt32[offset] = v[0];
998
- dataInt32[offset + 1] = v[1];`,
999
- "vec3<i32>": `
1000
- dataInt32[offset] = v[0];
1001
- dataInt32[offset + 1] = v[1];
1002
- dataInt32[offset + 2] = v[2];`,
1003
- "vec4<i32>": `
1004
- dataInt32[offset] = v[0];
1005
- dataInt32[offset + 1] = v[1];
1006
- dataInt32[offset + 2] = v[2];
1007
- dataInt32[offset + 3] = v[3];`,
1008
- "mat2x2<f32>": `
1009
- data[offset] = v[0];
1010
- data[offset + 1] = v[1];
1011
- data[offset + 4] = v[2];
1012
- data[offset + 5] = v[3];`,
1013
- "mat3x3<f32>": `
1014
- data[offset] = v[0];
1015
- data[offset + 1] = v[1];
1016
- data[offset + 2] = v[2];
1017
- data[offset + 4] = v[3];
1018
- data[offset + 5] = v[4];
1019
- data[offset + 6] = v[5];
1020
- data[offset + 8] = v[6];
1021
- data[offset + 9] = v[7];
1022
- data[offset + 10] = v[8];`,
1023
- "mat4x4<f32>": `
1024
- for (let i = 0; i < 16; i++) {
1025
- data[offset + i] = v[i];
1026
- }`,
1027
- "mat3x2<f32>": loopMatrix(3, 2),
1028
- "mat4x2<f32>": loopMatrix(4, 2),
1029
- "mat2x3<f32>": loopMatrix(2, 3),
1030
- "mat4x3<f32>": loopMatrix(4, 3),
1031
- "mat2x4<f32>": loopMatrix(2, 4),
1032
- "mat3x4<f32>": loopMatrix(3, 4)
1033
- };
1034
- const uboSyncFunctionsWGSL = {
1035
- ...uboSyncFunctionsSTD40,
1036
- "mat2x2<f32>": `
1037
- data[offset] = v[0];
1038
- data[offset + 1] = v[1];
1039
- data[offset + 2] = v[2];
1040
- data[offset + 3] = v[3];
1041
- `
1042
- };
1043
-
1044
- function calculateProjection(pm, x, y, width, height, flipY) {
1045
- const sign = flipY ? 1 : -1;
1046
- pm.identity();
1047
- pm.a = 1 / width * 2;
1048
- pm.d = sign * (1 / height * 2);
1049
- pm.tx = -1 - x * pm.a;
1050
- pm.ty = -sign - y * pm.d;
1051
- return pm;
1052
- }
1053
-
1054
- const canvasCache = /* @__PURE__ */ new Map();
1055
- function getCanvasTexture(canvas, options) {
1056
- if (!canvasCache.has(canvas)) {
1057
- const texture = new Texture({
1058
- source: new CanvasSource({
1059
- resource: canvas,
1060
- ...options
1061
- })
1062
- });
1063
- const onDestroy = () => {
1064
- if (canvasCache.get(canvas) === texture) {
1065
- canvasCache.delete(canvas);
1066
- }
1067
- };
1068
- texture.once("destroy", onDestroy);
1069
- texture.source.once("destroy", onDestroy);
1070
- canvasCache.set(canvas, texture);
1071
- }
1072
- return canvasCache.get(canvas);
1073
- }
1074
-
1075
- function isRenderingToScreen(renderTarget) {
1076
- const resource = renderTarget.colorTexture.source.resource;
1077
- return globalThis.HTMLCanvasElement && resource instanceof HTMLCanvasElement && document.body.contains(resource);
1078
- }
1079
-
1080
- const _RenderTarget = class _RenderTarget {
1081
- /**
1082
- * @param [descriptor] - Options for creating a render target.
1083
- */
1084
- constructor(descriptor = {}) {
1085
- /** unique id for this render target */
1086
- this.uid = uid$1("renderTarget");
1087
- /**
1088
- * An array of textures that can be written to by the GPU - mostly this has one texture in Pixi, but you could
1089
- * write to multiple if required! (eg deferred lighting)
1090
- */
1091
- this.colorTextures = [];
1092
- this.dirtyId = 0;
1093
- this.isRoot = false;
1094
- this._size = new Float32Array(2);
1095
- /** if true, then when the render target is destroyed, it will destroy all the textures that were created for it. */
1096
- this._managedColorTextures = false;
1097
- descriptor = { ..._RenderTarget.defaultOptions, ...descriptor };
1098
- this.stencil = descriptor.stencil;
1099
- this.depth = descriptor.depth;
1100
- this.isRoot = descriptor.isRoot;
1101
- if (typeof descriptor.colorTextures === "number") {
1102
- this._managedColorTextures = true;
1103
- for (let i = 0; i < descriptor.colorTextures; i++) {
1104
- this.colorTextures.push(
1105
- new TextureSource({
1106
- width: descriptor.width,
1107
- height: descriptor.height,
1108
- resolution: descriptor.resolution,
1109
- antialias: descriptor.antialias
1110
- })
1111
- );
1112
- }
1113
- } else {
1114
- this.colorTextures = [...descriptor.colorTextures.map((texture) => texture.source)];
1115
- const colorSource = this.colorTexture.source;
1116
- this.resize(colorSource.width, colorSource.height, colorSource._resolution);
1117
- }
1118
- this.colorTexture.source.on("resize", this.onSourceResize, this);
1119
- if (descriptor.depthStencilTexture || this.stencil) {
1120
- if (descriptor.depthStencilTexture instanceof Texture || descriptor.depthStencilTexture instanceof TextureSource) {
1121
- this.depthStencilTexture = descriptor.depthStencilTexture.source;
1122
- } else {
1123
- this.ensureDepthStencilTexture();
1124
- }
1125
- }
1126
- }
1127
- get size() {
1128
- const _size = this._size;
1129
- _size[0] = this.pixelWidth;
1130
- _size[1] = this.pixelHeight;
1131
- return _size;
1132
- }
1133
- get width() {
1134
- return this.colorTexture.source.width;
1135
- }
1136
- get height() {
1137
- return this.colorTexture.source.height;
1138
- }
1139
- get pixelWidth() {
1140
- return this.colorTexture.source.pixelWidth;
1141
- }
1142
- get pixelHeight() {
1143
- return this.colorTexture.source.pixelHeight;
1144
- }
1145
- get resolution() {
1146
- return this.colorTexture.source._resolution;
1147
- }
1148
- get colorTexture() {
1149
- return this.colorTextures[0];
1150
- }
1151
- onSourceResize(source) {
1152
- this.resize(source.width, source.height, source._resolution, true);
1153
- }
1154
- /**
1155
- * This will ensure a depthStencil texture is created for this render target.
1156
- * Most likely called by the mask system to make sure we have stencil buffer added.
1157
- * @internal
1158
- */
1159
- ensureDepthStencilTexture() {
1160
- if (!this.depthStencilTexture) {
1161
- this.depthStencilTexture = new TextureSource({
1162
- width: this.width,
1163
- height: this.height,
1164
- resolution: this.resolution,
1165
- format: "depth24plus-stencil8",
1166
- autoGenerateMipmaps: false,
1167
- antialias: false,
1168
- mipLevelCount: 1
1169
- // sampleCount: handled by the render target system..
1170
- });
1171
- }
1172
- }
1173
- resize(width, height, resolution = this.resolution, skipColorTexture = false) {
1174
- this.dirtyId++;
1175
- this.colorTextures.forEach((colorTexture, i) => {
1176
- if (skipColorTexture && i === 0)
1177
- return;
1178
- colorTexture.source.resize(width, height, resolution);
1179
- });
1180
- if (this.depthStencilTexture) {
1181
- this.depthStencilTexture.source.resize(width, height, resolution);
1182
- }
1183
- }
1184
- destroy() {
1185
- this.colorTexture.source.off("resize", this.onSourceResize, this);
1186
- if (this._managedColorTextures) {
1187
- this.colorTextures.forEach((texture) => {
1188
- texture.destroy();
1189
- });
1190
- }
1191
- if (this.depthStencilTexture) {
1192
- this.depthStencilTexture.destroy();
1193
- delete this.depthStencilTexture;
1194
- }
1195
- }
1196
- };
1197
- /** The default options for a render target */
1198
- _RenderTarget.defaultOptions = {
1199
- /** the width of the RenderTarget */
1200
- width: 0,
1201
- /** the height of the RenderTarget */
1202
- height: 0,
1203
- /** the resolution of the RenderTarget */
1204
- resolution: 1,
1205
- /** an array of textures, or a number indicating how many color textures there should be */
1206
- colorTextures: 1,
1207
- /** should this render target have a stencil buffer? */
1208
- stencil: false,
1209
- /** should this render target have a depth buffer? */
1210
- depth: false,
1211
- /** should this render target be antialiased? */
1212
- antialias: false,
1213
- // save on perf by default!
1214
- /** is this a root element, true if this is gl context owners render target */
1215
- isRoot: false
1216
- };
1217
- let RenderTarget = _RenderTarget;
1218
-
1219
- class RenderTargetSystem {
1220
- constructor(renderer) {
1221
- /** This is the root viewport for the render pass*/
1222
- this.rootViewPort = new Rectangle();
1223
- /** the current viewport that the gpu is using */
1224
- this.viewport = new Rectangle();
1225
- /**
1226
- * a runner that lets systems know if the active render target has changed.
1227
- * Eg the Stencil System needs to know so it can manage the stencil buffer
1228
- */
1229
- this.onRenderTargetChange = new SystemRunner("onRenderTargetChange");
1230
- /** the projection matrix that is used by the shaders based on the active render target and the viewport */
1231
- this.projectionMatrix = new Matrix();
1232
- /** the default clear color for render targets */
1233
- this.defaultClearColor = [0, 0, 0, 0];
1234
- /**
1235
- * a hash that stores the render target for a given render surface. When you pass in a texture source,
1236
- * a render target is created for it. This map stores and makes it easy to retrieve the render target
1237
- */
1238
- this._renderSurfaceToRenderTargetHash = /* @__PURE__ */ new Map();
1239
- /** A hash that stores a gpu render target for a given render target. */
1240
- this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null);
1241
- /**
1242
- * A stack that stores the render target and frame that is currently being rendered to.
1243
- * When push is called, the current render target is stored in this stack.
1244
- * When pop is called, the previous render target is restored.
1245
- */
1246
- this._renderTargetStack = [];
1247
- this._renderer = renderer;
1248
- renderer.renderableGC.addManagedHash(this, "_gpuRenderTargetHash");
1249
- }
1250
- /** called when dev wants to finish a render pass */
1251
- finishRenderPass() {
1252
- this.adaptor.finishRenderPass(this.renderTarget);
1253
- }
1254
- /**
1255
- * called when the renderer starts to render a scene.
1256
- * @param options
1257
- * @param options.target - the render target to render to
1258
- * @param options.clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111
1259
- * @param options.clearColor - the color to clear to
1260
- * @param options.frame - the frame to render to
1261
- */
1262
- renderStart({
1263
- target,
1264
- clear,
1265
- clearColor,
1266
- frame
1267
- }) {
1268
- this._renderTargetStack.length = 0;
1269
- this.push(
1270
- target,
1271
- clear,
1272
- clearColor,
1273
- frame
1274
- );
1275
- this.rootViewPort.copyFrom(this.viewport);
1276
- this.rootRenderTarget = this.renderTarget;
1277
- this.renderingToScreen = isRenderingToScreen(this.rootRenderTarget);
1278
- this.adaptor.prerender?.(this.rootRenderTarget);
1279
- }
1280
- postrender() {
1281
- this.adaptor.postrender?.(this.rootRenderTarget);
1282
- }
1283
- /**
1284
- * Binding a render surface! This is the main function of the render target system.
1285
- * It will take the RenderSurface (which can be a texture, canvas, or render target) and bind it to the renderer.
1286
- * Once bound all draw calls will be rendered to the render surface.
1287
- *
1288
- * If a frame is not provide and the render surface is a texture, the frame of the texture will be used.
1289
- * @param renderSurface - the render surface to bind
1290
- * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111
1291
- * @param clearColor - the color to clear to
1292
- * @param frame - the frame to render to
1293
- * @returns the render target that was bound
1294
- */
1295
- bind(renderSurface, clear = true, clearColor, frame) {
1296
- const renderTarget = this.getRenderTarget(renderSurface);
1297
- const didChange = this.renderTarget !== renderTarget;
1298
- this.renderTarget = renderTarget;
1299
- this.renderSurface = renderSurface;
1300
- const gpuRenderTarget = this.getGpuRenderTarget(renderTarget);
1301
- if (renderTarget.pixelWidth !== gpuRenderTarget.width || renderTarget.pixelHeight !== gpuRenderTarget.height) {
1302
- this.adaptor.resizeGpuRenderTarget(renderTarget);
1303
- gpuRenderTarget.width = renderTarget.pixelWidth;
1304
- gpuRenderTarget.height = renderTarget.pixelHeight;
1305
- }
1306
- const source = renderTarget.colorTexture;
1307
- const viewport = this.viewport;
1308
- const pixelWidth = source.pixelWidth;
1309
- const pixelHeight = source.pixelHeight;
1310
- if (!frame && renderSurface instanceof Texture) {
1311
- frame = renderSurface.frame;
1312
- }
1313
- if (frame) {
1314
- const resolution = source._resolution;
1315
- viewport.x = frame.x * resolution + 0.5 | 0;
1316
- viewport.y = frame.y * resolution + 0.5 | 0;
1317
- viewport.width = frame.width * resolution + 0.5 | 0;
1318
- viewport.height = frame.height * resolution + 0.5 | 0;
1319
- } else {
1320
- viewport.x = 0;
1321
- viewport.y = 0;
1322
- viewport.width = pixelWidth;
1323
- viewport.height = pixelHeight;
1324
- }
1325
- calculateProjection(
1326
- this.projectionMatrix,
1327
- 0,
1328
- 0,
1329
- viewport.width / source.resolution,
1330
- viewport.height / source.resolution,
1331
- !renderTarget.isRoot
1332
- );
1333
- this.adaptor.startRenderPass(renderTarget, clear, clearColor, viewport);
1334
- if (didChange) {
1335
- this.onRenderTargetChange.emit(renderTarget);
1336
- }
1337
- return renderTarget;
1338
- }
1339
- clear(target, clear = CLEAR.ALL, clearColor) {
1340
- if (!clear)
1341
- return;
1342
- if (target) {
1343
- target = this.getRenderTarget(target);
1344
- }
1345
- this.adaptor.clear(
1346
- target || this.renderTarget,
1347
- clear,
1348
- clearColor,
1349
- this.viewport
1350
- );
1351
- }
1352
- contextChange() {
1353
- this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null);
1354
- }
1355
- /**
1356
- * Push a render surface to the renderer. This will bind the render surface to the renderer,
1357
- * @param renderSurface - the render surface to push
1358
- * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111
1359
- * @param clearColor - the color to clear to
1360
- * @param frame - the frame to use when rendering to the render surface
1361
- */
1362
- push(renderSurface, clear = CLEAR.ALL, clearColor, frame) {
1363
- const renderTarget = this.bind(renderSurface, clear, clearColor, frame);
1364
- this._renderTargetStack.push({
1365
- renderTarget,
1366
- frame
1367
- });
1368
- return renderTarget;
1369
- }
1370
- /** Pops the current render target from the renderer and restores the previous render target. */
1371
- pop() {
1372
- this._renderTargetStack.pop();
1373
- const currentRenderTargetData = this._renderTargetStack[this._renderTargetStack.length - 1];
1374
- this.bind(currentRenderTargetData.renderTarget, false, null, currentRenderTargetData.frame);
1375
- }
1376
- /**
1377
- * Gets the render target from the provide render surface. Eg if its a texture,
1378
- * it will return the render target for the texture.
1379
- * If its a render target, it will return the same render target.
1380
- * @param renderSurface - the render surface to get the render target for
1381
- * @returns the render target for the render surface
1382
- */
1383
- getRenderTarget(renderSurface) {
1384
- if (renderSurface.isTexture) {
1385
- renderSurface = renderSurface.source;
1386
- }
1387
- return this._renderSurfaceToRenderTargetHash.get(renderSurface) ?? this._initRenderTarget(renderSurface);
1388
- }
1389
- /**
1390
- * Copies a render surface to another texture.
1391
- *
1392
- * NOTE:
1393
- * for sourceRenderSurfaceTexture, The render target must be something that is written too by the renderer
1394
- *
1395
- * The following is not valid:
1396
- * @example
1397
- * const canvas = document.createElement('canvas')
1398
- * canvas.width = 200;
1399
- * canvas.height = 200;
1400
- *
1401
- * const ctx = canvas2.getContext('2d')!
1402
- * ctx.fillStyle = 'red'
1403
- * ctx.fillRect(0, 0, 200, 200);
1404
- *
1405
- * const texture = RenderTexture.create({
1406
- * width: 200,
1407
- * height: 200,
1408
- * })
1409
- * const renderTarget = renderer.renderTarget.getRenderTarget(canvas2);
1410
- *
1411
- * renderer.renderTarget.copyToTexture(renderTarget,texture, {x:0,y:0},{width:200,height:200},{x:0,y:0});
1412
- *
1413
- * The best way to copy a canvas is to create a texture from it. Then render with that.
1414
- *
1415
- * Parsing in a RenderTarget canvas context (with a 2d context)
1416
- * @param sourceRenderSurfaceTexture - the render surface to copy from
1417
- * @param destinationTexture - the texture to copy to
1418
- * @param originSrc - the origin of the copy
1419
- * @param originSrc.x - the x origin of the copy
1420
- * @param originSrc.y - the y origin of the copy
1421
- * @param size - the size of the copy
1422
- * @param size.width - the width of the copy
1423
- * @param size.height - the height of the copy
1424
- * @param originDest - the destination origin (top left to paste from!)
1425
- * @param originDest.x - the x origin of the paste
1426
- * @param originDest.y - the y origin of the paste
1427
- */
1428
- copyToTexture(sourceRenderSurfaceTexture, destinationTexture, originSrc, size, originDest) {
1429
- if (originSrc.x < 0) {
1430
- size.width += originSrc.x;
1431
- originDest.x -= originSrc.x;
1432
- originSrc.x = 0;
1433
- }
1434
- if (originSrc.y < 0) {
1435
- size.height += originSrc.y;
1436
- originDest.y -= originSrc.y;
1437
- originSrc.y = 0;
1438
- }
1439
- const { pixelWidth, pixelHeight } = sourceRenderSurfaceTexture;
1440
- size.width = Math.min(size.width, pixelWidth - originSrc.x);
1441
- size.height = Math.min(size.height, pixelHeight - originSrc.y);
1442
- return this.adaptor.copyToTexture(
1443
- sourceRenderSurfaceTexture,
1444
- destinationTexture,
1445
- originSrc,
1446
- size,
1447
- originDest
1448
- );
1449
- }
1450
- /**
1451
- * ensures that we have a depth stencil buffer available to render to
1452
- * This is used by the mask system to make sure we have a stencil buffer.
1453
- */
1454
- ensureDepthStencil() {
1455
- if (!this.renderTarget.stencil) {
1456
- this.renderTarget.stencil = true;
1457
- this.adaptor.startRenderPass(this.renderTarget, false, null, this.viewport);
1458
- }
1459
- }
1460
- /** nukes the render target system */
1461
- destroy() {
1462
- this._renderer = null;
1463
- this._renderSurfaceToRenderTargetHash.forEach((renderTarget, key) => {
1464
- if (renderTarget !== key) {
1465
- renderTarget.destroy();
1466
- }
1467
- });
1468
- this._renderSurfaceToRenderTargetHash.clear();
1469
- this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null);
1470
- }
1471
- _initRenderTarget(renderSurface) {
1472
- let renderTarget = null;
1473
- if (CanvasSource.test(renderSurface)) {
1474
- renderSurface = getCanvasTexture(renderSurface).source;
1475
- }
1476
- if (renderSurface instanceof RenderTarget) {
1477
- renderTarget = renderSurface;
1478
- } else if (renderSurface instanceof TextureSource) {
1479
- renderTarget = new RenderTarget({
1480
- colorTextures: [renderSurface]
1481
- });
1482
- if (renderSurface.source instanceof CanvasSource) {
1483
- renderTarget.isRoot = true;
1484
- }
1485
- renderSurface.once("destroy", () => {
1486
- renderTarget.destroy();
1487
- this._renderSurfaceToRenderTargetHash.delete(renderSurface);
1488
- const gpuRenderTarget = this._gpuRenderTargetHash[renderTarget.uid];
1489
- if (gpuRenderTarget) {
1490
- this._gpuRenderTargetHash[renderTarget.uid] = null;
1491
- this.adaptor.destroyGpuRenderTarget(gpuRenderTarget);
1492
- }
1493
- });
1494
- }
1495
- this._renderSurfaceToRenderTargetHash.set(renderSurface, renderTarget);
1496
- return renderTarget;
1497
- }
1498
- getGpuRenderTarget(renderTarget) {
1499
- return this._gpuRenderTargetHash[renderTarget.uid] || (this._gpuRenderTargetHash[renderTarget.uid] = this.adaptor.initGpuRenderTarget(renderTarget));
1500
- }
1501
- resetState() {
1502
- this.renderTarget = null;
1503
- this.renderSurface = null;
1504
- }
1505
- }
1506
-
1507
- class BufferResource extends EventEmitter {
1508
- /**
1509
- * Create a new Buffer Resource.
1510
- * @param options - The options for the buffer resource
1511
- * @param options.buffer - The underlying buffer that this resource is using
1512
- * @param options.offset - The offset of the buffer this resource is using.
1513
- * If not provided, then it will use the offset of the buffer.
1514
- * @param options.size - The size of the buffer this resource is using.
1515
- * If not provided, then it will use the size of the buffer.
1516
- */
1517
- constructor({ buffer, offset, size }) {
1518
- super();
1519
- /**
1520
- * emits when the underlying buffer has changed shape (i.e. resized)
1521
- * letting the renderer know that it needs to discard the old buffer on the GPU and create a new one
1522
- * @event change
1523
- */
1524
- /** a unique id for this uniform group used through the renderer */
1525
- this.uid = uid$1("buffer");
1526
- /**
1527
- * a resource type, used to identify how to handle it when its in a bind group / shader resource
1528
- * @internal
1529
- */
1530
- this._resourceType = "bufferResource";
1531
- /**
1532
- * used internally to know if a uniform group was used in the last render pass
1533
- * @internal
1534
- */
1535
- this._touched = 0;
1536
- /**
1537
- * the resource id used internally by the renderer to build bind group keys
1538
- * @internal
1539
- */
1540
- this._resourceId = uid$1("resource");
1541
- /**
1542
- * A cheeky hint to the GL renderer to let it know this is a BufferResource
1543
- * @internal
1544
- */
1545
- this._bufferResource = true;
1546
- /**
1547
- * Has the Buffer resource been destroyed?
1548
- * @readonly
1549
- */
1550
- this.destroyed = false;
1551
- this.buffer = buffer;
1552
- this.offset = offset | 0;
1553
- this.size = size;
1554
- this.buffer.on("change", this.onBufferChange, this);
1555
- }
1556
- onBufferChange() {
1557
- this._resourceId = uid$1("resource");
1558
- this.emit("change", this);
1559
- }
1560
- /**
1561
- * Destroys this resource. Make sure the underlying buffer is not used anywhere else
1562
- * if you want to destroy it as well, or code will explode
1563
- * @param destroyBuffer - Should the underlying buffer be destroyed as well?
1564
- */
1565
- destroy(destroyBuffer = false) {
1566
- this.destroyed = true;
1567
- if (destroyBuffer) {
1568
- this.buffer.destroy();
1569
- }
1570
- this.emit("change", this);
1571
- this.buffer = null;
1572
- }
1573
- }
1574
-
1575
- class CustomRenderPipe {
1576
- constructor(renderer) {
1577
- this._renderer = renderer;
1578
- }
1579
- updateRenderable() {
1580
- }
1581
- destroyRenderable() {
1582
- }
1583
- validateRenderable() {
1584
- return false;
1585
- }
1586
- addRenderable(container, instructionSet) {
1587
- this._renderer.renderPipes.batch.break(instructionSet);
1588
- instructionSet.add(container);
1589
- }
1590
- execute(container) {
1591
- if (!container.isRenderable)
1592
- return;
1593
- container.render(this._renderer);
1594
- }
1595
- destroy() {
1596
- this._renderer = null;
1597
- }
1598
- }
1599
- CustomRenderPipe.extension = {
1600
- type: [
1601
- ExtensionType.WebGLPipes,
1602
- ExtensionType.WebGPUPipes,
1603
- ExtensionType.CanvasPipes
1604
- ],
1605
- name: "customRender"
1606
- };
1607
-
1608
- function executeInstructions(renderGroup, renderer) {
1609
- const instructionSet = renderGroup.instructionSet;
1610
- const instructions = instructionSet.instructions;
1611
- for (let i = 0; i < instructionSet.instructionSize; i++) {
1612
- const instruction = instructions[i];
1613
- renderer[instruction.renderPipeId].execute(instruction);
1614
- }
1615
- }
1616
-
1617
- const tempMatrix$1 = new Matrix();
1618
- class RenderGroupPipe {
1619
- constructor(renderer) {
1620
- this._renderer = renderer;
1621
- }
1622
- addRenderGroup(renderGroup, instructionSet) {
1623
- if (renderGroup.isCachedAsTexture) {
1624
- this._addRenderableCacheAsTexture(renderGroup, instructionSet);
1625
- } else {
1626
- this._addRenderableDirect(renderGroup, instructionSet);
1627
- }
1628
- }
1629
- execute(renderGroup) {
1630
- if (!renderGroup.isRenderable)
1631
- return;
1632
- if (renderGroup.isCachedAsTexture) {
1633
- this._executeCacheAsTexture(renderGroup);
1634
- } else {
1635
- this._executeDirect(renderGroup);
1636
- }
1637
- }
1638
- destroy() {
1639
- this._renderer = null;
1640
- }
1641
- _addRenderableDirect(renderGroup, instructionSet) {
1642
- this._renderer.renderPipes.batch.break(instructionSet);
1643
- if (renderGroup._batchableRenderGroup) {
1644
- BigPool.return(renderGroup._batchableRenderGroup);
1645
- renderGroup._batchableRenderGroup = null;
1646
- }
1647
- instructionSet.add(renderGroup);
1648
- }
1649
- _addRenderableCacheAsTexture(renderGroup, instructionSet) {
1650
- const batchableRenderGroup = renderGroup._batchableRenderGroup ?? (renderGroup._batchableRenderGroup = BigPool.get(BatchableSprite));
1651
- batchableRenderGroup.renderable = renderGroup.root;
1652
- batchableRenderGroup.transform = renderGroup.root.relativeGroupTransform;
1653
- batchableRenderGroup.texture = renderGroup.texture;
1654
- batchableRenderGroup.bounds = renderGroup._textureBounds;
1655
- instructionSet.add(renderGroup);
1656
- this._renderer.renderPipes.batch.addToBatch(batchableRenderGroup, instructionSet);
1657
- }
1658
- _executeCacheAsTexture(renderGroup) {
1659
- if (renderGroup.textureNeedsUpdate) {
1660
- renderGroup.textureNeedsUpdate = false;
1661
- const worldTransformMatrix = tempMatrix$1.identity().translate(
1662
- -renderGroup._textureBounds.x,
1663
- -renderGroup._textureBounds.y
1664
- );
1665
- this._renderer.renderTarget.push(renderGroup.texture, true, null, renderGroup.texture.frame);
1666
- this._renderer.globalUniforms.push({
1667
- worldTransformMatrix,
1668
- worldColor: 4294967295
1669
- });
1670
- executeInstructions(renderGroup, this._renderer.renderPipes);
1671
- this._renderer.renderTarget.finishRenderPass();
1672
- this._renderer.renderTarget.pop();
1673
- this._renderer.globalUniforms.pop();
1674
- }
1675
- renderGroup._batchableRenderGroup._batcher.updateElement(renderGroup._batchableRenderGroup);
1676
- renderGroup._batchableRenderGroup._batcher.geometry.buffers[0].update();
1677
- }
1678
- _executeDirect(renderGroup) {
1679
- this._renderer.globalUniforms.push({
1680
- worldTransformMatrix: renderGroup.inverseParentTextureTransform,
1681
- worldColor: renderGroup.worldColorAlpha
1682
- });
1683
- executeInstructions(renderGroup, this._renderer.renderPipes);
1684
- this._renderer.globalUniforms.pop();
1685
- }
1686
- }
1687
- RenderGroupPipe.extension = {
1688
- type: [
1689
- ExtensionType.WebGLPipes,
1690
- ExtensionType.WebGPUPipes,
1691
- ExtensionType.CanvasPipes
1692
- ],
1693
- name: "renderGroup"
1694
- };
1695
-
1696
- function clearList(list, index) {
1697
- index || (index = 0);
1698
- for (let j = index; j < list.length; j++) {
1699
- if (list[j]) {
1700
- list[j] = null;
1701
- } else {
1702
- break;
1703
- }
1704
- }
1705
- }
1706
-
1707
- const tempContainer = new Container();
1708
- const UPDATE_BLEND_COLOR_VISIBLE = UPDATE_VISIBLE | UPDATE_COLOR | UPDATE_BLEND;
1709
- function updateRenderGroupTransforms(renderGroup, updateChildRenderGroups = false) {
1710
- updateRenderGroupTransform(renderGroup);
1711
- const childrenToUpdate = renderGroup.childrenToUpdate;
1712
- const updateTick = renderGroup.updateTick++;
1713
- for (const j in childrenToUpdate) {
1714
- const renderGroupDepth = Number(j);
1715
- const childrenAtDepth = childrenToUpdate[j];
1716
- const list = childrenAtDepth.list;
1717
- const index = childrenAtDepth.index;
1718
- for (let i = 0; i < index; i++) {
1719
- const child = list[i];
1720
- if (child.parentRenderGroup === renderGroup && child.relativeRenderGroupDepth === renderGroupDepth) {
1721
- updateTransformAndChildren(child, updateTick, 0);
1722
- }
1723
- }
1724
- clearList(list, index);
1725
- childrenAtDepth.index = 0;
1726
- }
1727
- if (updateChildRenderGroups) {
1728
- for (let i = 0; i < renderGroup.renderGroupChildren.length; i++) {
1729
- updateRenderGroupTransforms(renderGroup.renderGroupChildren[i], updateChildRenderGroups);
1730
- }
1731
- }
1732
- }
1733
- function updateRenderGroupTransform(renderGroup) {
1734
- const root = renderGroup.root;
1735
- let worldAlpha;
1736
- if (renderGroup.renderGroupParent) {
1737
- const renderGroupParent = renderGroup.renderGroupParent;
1738
- renderGroup.worldTransform.appendFrom(
1739
- root.relativeGroupTransform,
1740
- renderGroupParent.worldTransform
1741
- );
1742
- renderGroup.worldColor = multiplyColors(
1743
- root.groupColor,
1744
- renderGroupParent.worldColor
1745
- );
1746
- worldAlpha = root.groupAlpha * renderGroupParent.worldAlpha;
1747
- } else {
1748
- renderGroup.worldTransform.copyFrom(root.localTransform);
1749
- renderGroup.worldColor = root.localColor;
1750
- worldAlpha = root.localAlpha;
1751
- }
1752
- worldAlpha = worldAlpha < 0 ? 0 : worldAlpha > 1 ? 1 : worldAlpha;
1753
- renderGroup.worldAlpha = worldAlpha;
1754
- renderGroup.worldColorAlpha = renderGroup.worldColor + ((worldAlpha * 255 | 0) << 24);
1755
- }
1756
- function updateTransformAndChildren(container, updateTick, updateFlags) {
1757
- if (updateTick === container.updateTick)
1758
- return;
1759
- container.updateTick = updateTick;
1760
- container.didChange = false;
1761
- const localTransform = container.localTransform;
1762
- container.updateLocalTransform();
1763
- const parent = container.parent;
1764
- if (parent && !parent.renderGroup) {
1765
- updateFlags |= container._updateFlags;
1766
- container.relativeGroupTransform.appendFrom(
1767
- localTransform,
1768
- parent.relativeGroupTransform
1769
- );
1770
- if (updateFlags & UPDATE_BLEND_COLOR_VISIBLE) {
1771
- updateColorBlendVisibility(container, parent, updateFlags);
1772
- }
1773
- } else {
1774
- updateFlags = container._updateFlags;
1775
- container.relativeGroupTransform.copyFrom(localTransform);
1776
- if (updateFlags & UPDATE_BLEND_COLOR_VISIBLE) {
1777
- updateColorBlendVisibility(container, tempContainer, updateFlags);
1778
- }
1779
- }
1780
- if (!container.renderGroup) {
1781
- const children = container.children;
1782
- const length = children.length;
1783
- for (let i = 0; i < length; i++) {
1784
- updateTransformAndChildren(children[i], updateTick, updateFlags);
1785
- }
1786
- const renderGroup = container.parentRenderGroup;
1787
- const renderable = container;
1788
- if (renderable.renderPipeId && !renderGroup.structureDidChange) {
1789
- renderGroup.updateRenderable(renderable);
1790
- }
1791
- }
1792
- }
1793
- function updateColorBlendVisibility(container, parent, updateFlags) {
1794
- if (updateFlags & UPDATE_COLOR) {
1795
- container.groupColor = multiplyColors(
1796
- container.localColor,
1797
- parent.groupColor
1798
- );
1799
- let groupAlpha = container.localAlpha * parent.groupAlpha;
1800
- groupAlpha = groupAlpha < 0 ? 0 : groupAlpha > 1 ? 1 : groupAlpha;
1801
- container.groupAlpha = groupAlpha;
1802
- container.groupColorAlpha = container.groupColor + ((groupAlpha * 255 | 0) << 24);
1803
- }
1804
- if (updateFlags & UPDATE_BLEND) {
1805
- container.groupBlendMode = container.localBlendMode === "inherit" ? parent.groupBlendMode : container.localBlendMode;
1806
- }
1807
- if (updateFlags & UPDATE_VISIBLE) {
1808
- container.globalDisplayStatus = container.localDisplayStatus & parent.globalDisplayStatus;
1809
- }
1810
- container._updateFlags = 0;
1811
- }
1812
-
1813
- function validateRenderables(renderGroup, renderPipes) {
1814
- const { list, index } = renderGroup.childrenRenderablesToUpdate;
1815
- let rebuildRequired = false;
1816
- for (let i = 0; i < index; i++) {
1817
- const container = list[i];
1818
- const renderable = container;
1819
- const pipe = renderPipes[renderable.renderPipeId];
1820
- rebuildRequired = pipe.validateRenderable(container);
1821
- if (rebuildRequired) {
1822
- break;
1823
- }
1824
- }
1825
- renderGroup.structureDidChange = rebuildRequired;
1826
- return rebuildRequired;
1827
- }
1828
-
1829
- const tempMatrix = new Matrix();
1830
- class RenderGroupSystem {
1831
- constructor(renderer) {
1832
- this._renderer = renderer;
1833
- }
1834
- render({ container, transform }) {
1835
- const parent = container.parent;
1836
- const renderGroupParent = container.renderGroup.renderGroupParent;
1837
- container.parent = null;
1838
- container.renderGroup.renderGroupParent = null;
1839
- const renderer = this._renderer;
1840
- let originalLocalTransform = tempMatrix;
1841
- if (transform) {
1842
- originalLocalTransform = originalLocalTransform.copyFrom(container.renderGroup.localTransform);
1843
- container.renderGroup.localTransform.copyFrom(transform);
1844
- }
1845
- const renderPipes = renderer.renderPipes;
1846
- this._updateCachedRenderGroups(container.renderGroup, null);
1847
- this._updateRenderGroups(container.renderGroup);
1848
- renderer.globalUniforms.start({
1849
- worldTransformMatrix: transform ? container.renderGroup.localTransform : container.renderGroup.worldTransform,
1850
- worldColor: container.renderGroup.worldColorAlpha
1851
- });
1852
- executeInstructions(container.renderGroup, renderPipes);
1853
- if (renderPipes.uniformBatch) {
1854
- renderPipes.uniformBatch.renderEnd();
1855
- }
1856
- if (transform) {
1857
- container.renderGroup.localTransform.copyFrom(originalLocalTransform);
1858
- }
1859
- container.parent = parent;
1860
- container.renderGroup.renderGroupParent = renderGroupParent;
1861
- }
1862
- destroy() {
1863
- this._renderer = null;
1864
- }
1865
- _updateCachedRenderGroups(renderGroup, closestCacheAsTexture) {
1866
- if (renderGroup.isCachedAsTexture) {
1867
- if (!renderGroup.updateCacheTexture)
1868
- return;
1869
- closestCacheAsTexture = renderGroup;
1870
- }
1871
- renderGroup._parentCacheAsTextureRenderGroup = closestCacheAsTexture;
1872
- for (let i = renderGroup.renderGroupChildren.length - 1; i >= 0; i--) {
1873
- this._updateCachedRenderGroups(renderGroup.renderGroupChildren[i], closestCacheAsTexture);
1874
- }
1875
- renderGroup.invalidateMatrices();
1876
- if (renderGroup.isCachedAsTexture) {
1877
- if (renderGroup.textureNeedsUpdate) {
1878
- const bounds = renderGroup.root.getLocalBounds();
1879
- bounds.ceil();
1880
- const lastTexture = renderGroup.texture;
1881
- if (renderGroup.texture) {
1882
- TexturePool.returnTexture(renderGroup.texture);
1883
- }
1884
- const renderer = this._renderer;
1885
- const resolution = renderGroup.textureOptions.resolution || renderer.view.resolution;
1886
- const antialias = renderGroup.textureOptions.antialias ?? renderer.view.antialias;
1887
- renderGroup.texture = TexturePool.getOptimalTexture(
1888
- bounds.width,
1889
- bounds.height,
1890
- resolution,
1891
- antialias
1892
- );
1893
- renderGroup._textureBounds || (renderGroup._textureBounds = new Bounds());
1894
- renderGroup._textureBounds.copyFrom(bounds);
1895
- if (lastTexture !== renderGroup.texture) {
1896
- if (renderGroup.renderGroupParent) {
1897
- renderGroup.renderGroupParent.structureDidChange = true;
1898
- }
1899
- }
1900
- }
1901
- } else if (renderGroup.texture) {
1902
- TexturePool.returnTexture(renderGroup.texture);
1903
- renderGroup.texture = null;
1904
- }
1905
- }
1906
- _updateRenderGroups(renderGroup) {
1907
- const renderer = this._renderer;
1908
- const renderPipes = renderer.renderPipes;
1909
- renderGroup.runOnRender(renderer);
1910
- renderGroup.instructionSet.renderPipes = renderPipes;
1911
- if (!renderGroup.structureDidChange) {
1912
- validateRenderables(renderGroup, renderPipes);
1913
- } else {
1914
- clearList(renderGroup.childrenRenderablesToUpdate.list, 0);
1915
- }
1916
- updateRenderGroupTransforms(renderGroup);
1917
- if (renderGroup.structureDidChange) {
1918
- renderGroup.structureDidChange = false;
1919
- this._buildInstructions(renderGroup, renderer);
1920
- } else {
1921
- this._updateRenderables(renderGroup);
1922
- }
1923
- renderGroup.childrenRenderablesToUpdate.index = 0;
1924
- renderer.renderPipes.batch.upload(renderGroup.instructionSet);
1925
- if (renderGroup.isCachedAsTexture && !renderGroup.textureNeedsUpdate)
1926
- return;
1927
- for (let i = 0; i < renderGroup.renderGroupChildren.length; i++) {
1928
- this._updateRenderGroups(renderGroup.renderGroupChildren[i]);
1929
- }
1930
- }
1931
- _updateRenderables(renderGroup) {
1932
- const { list, index } = renderGroup.childrenRenderablesToUpdate;
1933
- for (let i = 0; i < index; i++) {
1934
- const container = list[i];
1935
- if (container.didViewUpdate) {
1936
- renderGroup.updateRenderable(container);
1937
- }
1938
- }
1939
- clearList(list, index);
1940
- }
1941
- _buildInstructions(renderGroup, rendererOrPipes) {
1942
- const root = renderGroup.root;
1943
- const instructionSet = renderGroup.instructionSet;
1944
- instructionSet.reset();
1945
- const renderer = rendererOrPipes.renderPipes ? rendererOrPipes : rendererOrPipes.batch.renderer;
1946
- const renderPipes = renderer.renderPipes;
1947
- renderPipes.batch.buildStart(instructionSet);
1948
- renderPipes.blendMode.buildStart();
1949
- renderPipes.colorMask.buildStart();
1950
- if (root.sortableChildren) {
1951
- root.sortChildren();
1952
- }
1953
- root.collectRenderablesWithEffects(instructionSet, renderer, null);
1954
- renderPipes.batch.buildEnd(instructionSet);
1955
- renderPipes.blendMode.buildEnd(instructionSet);
1956
- }
1957
- }
1958
- /** @ignore */
1959
- RenderGroupSystem.extension = {
1960
- type: [
1961
- ExtensionType.WebGLSystem,
1962
- ExtensionType.WebGPUSystem,
1963
- ExtensionType.CanvasSystem
1964
- ],
1965
- name: "renderGroup"
1966
- };
1967
-
1968
- class SpritePipe {
1969
- constructor(renderer) {
1970
- this._renderer = renderer;
1971
- }
1972
- addRenderable(sprite, instructionSet) {
1973
- const gpuSprite = this._getGpuSprite(sprite);
1974
- if (sprite.didViewUpdate)
1975
- this._updateBatchableSprite(sprite, gpuSprite);
1976
- this._renderer.renderPipes.batch.addToBatch(gpuSprite, instructionSet);
1977
- }
1978
- updateRenderable(sprite) {
1979
- const gpuSprite = this._getGpuSprite(sprite);
1980
- if (sprite.didViewUpdate)
1981
- this._updateBatchableSprite(sprite, gpuSprite);
1982
- gpuSprite._batcher.updateElement(gpuSprite);
1983
- }
1984
- validateRenderable(sprite) {
1985
- const gpuSprite = this._getGpuSprite(sprite);
1986
- return !gpuSprite._batcher.checkAndUpdateTexture(
1987
- gpuSprite,
1988
- sprite._texture
1989
- );
1990
- }
1991
- _updateBatchableSprite(sprite, batchableSprite) {
1992
- batchableSprite.bounds = sprite.visualBounds;
1993
- batchableSprite.texture = sprite._texture;
1994
- }
1995
- _getGpuSprite(sprite) {
1996
- return sprite._gpuData[this._renderer.uid] || this._initGPUSprite(sprite);
1997
- }
1998
- _initGPUSprite(sprite) {
1999
- const batchableSprite = new BatchableSprite();
2000
- batchableSprite.renderable = sprite;
2001
- batchableSprite.transform = sprite.groupTransform;
2002
- batchableSprite.texture = sprite._texture;
2003
- batchableSprite.bounds = sprite.visualBounds;
2004
- batchableSprite.roundPixels = this._renderer._roundPixels | sprite._roundPixels;
2005
- sprite._gpuData[this._renderer.uid] = batchableSprite;
2006
- return batchableSprite;
2007
- }
2008
- destroy() {
2009
- this._renderer = null;
2010
- }
2011
- }
2012
- /** @ignore */
2013
- SpritePipe.extension = {
2014
- type: [
2015
- ExtensionType.WebGLPipes,
2016
- ExtensionType.WebGPUPipes,
2017
- ExtensionType.CanvasPipes
2018
- ],
2019
- name: "sprite"
2020
- };
2021
-
2022
- const _BackgroundSystem = class _BackgroundSystem {
2023
- constructor() {
2024
- this.clearBeforeRender = true;
2025
- this._backgroundColor = new Color(0);
2026
- this.color = this._backgroundColor;
2027
- this.alpha = 1;
2028
- }
2029
- /**
2030
- * initiates the background system
2031
- * @param options - the options for the background colors
2032
- */
2033
- init(options) {
2034
- options = { ..._BackgroundSystem.defaultOptions, ...options };
2035
- this.clearBeforeRender = options.clearBeforeRender;
2036
- this.color = options.background || options.backgroundColor || this._backgroundColor;
2037
- this.alpha = options.backgroundAlpha;
2038
- this._backgroundColor.setAlpha(options.backgroundAlpha);
2039
- }
2040
- /** The background color to fill if not transparent */
2041
- get color() {
2042
- return this._backgroundColor;
2043
- }
2044
- set color(value) {
2045
- const incoming = Color.shared.setValue(value);
2046
- if (incoming.alpha < 1 && this._backgroundColor.alpha === 1) {
2047
- warn(
2048
- "Cannot set a transparent background on an opaque canvas. To enable transparency, set backgroundAlpha < 1 when initializing your Application."
2049
- );
2050
- }
2051
- this._backgroundColor.setValue(value);
2052
- }
2053
- /** The background color alpha. Setting this to 0 will make the canvas transparent. */
2054
- get alpha() {
2055
- return this._backgroundColor.alpha;
2056
- }
2057
- set alpha(value) {
2058
- this._backgroundColor.setAlpha(value);
2059
- }
2060
- /** The background color as an [R, G, B, A] array. */
2061
- get colorRgba() {
2062
- return this._backgroundColor.toArray();
2063
- }
2064
- /**
2065
- * destroys the background system
2066
- * @internal
2067
- */
2068
- destroy() {
2069
- }
2070
- };
2071
- /** @ignore */
2072
- _BackgroundSystem.extension = {
2073
- type: [
2074
- ExtensionType.WebGLSystem,
2075
- ExtensionType.WebGPUSystem,
2076
- ExtensionType.CanvasSystem
2077
- ],
2078
- name: "background",
2079
- priority: 0
2080
- };
2081
- /** default options used by the system */
2082
- _BackgroundSystem.defaultOptions = {
2083
- /**
2084
- * {@link WebGLOptions.backgroundAlpha}
2085
- * @default 1
2086
- */
2087
- backgroundAlpha: 1,
2088
- /**
2089
- * {@link WebGLOptions.backgroundColor}
2090
- * @default 0x000000
2091
- */
2092
- backgroundColor: 0,
2093
- /**
2094
- * {@link WebGLOptions.clearBeforeRender}
2095
- * @default true
2096
- */
2097
- clearBeforeRender: true
2098
- };
2099
- let BackgroundSystem = _BackgroundSystem;
2100
-
2101
- const BLEND_MODE_FILTERS = {};
2102
- extensions.handle(ExtensionType.BlendMode, (value) => {
2103
- if (!value.name) {
2104
- throw new Error("BlendMode extension must have a name property");
2105
- }
2106
- BLEND_MODE_FILTERS[value.name] = value.ref;
2107
- }, (value) => {
2108
- delete BLEND_MODE_FILTERS[value.name];
2109
- });
2110
- class BlendModePipe {
2111
- constructor(renderer) {
2112
- this._isAdvanced = false;
2113
- this._filterHash = /* @__PURE__ */ Object.create(null);
2114
- this._renderer = renderer;
2115
- this._renderer.runners.prerender.add(this);
2116
- }
2117
- prerender() {
2118
- this._activeBlendMode = "normal";
2119
- this._isAdvanced = false;
2120
- }
2121
- /**
2122
- * This ensures that a blendMode switch is added to the instruction set if the blend mode has changed.
2123
- * @param renderable - The renderable we are adding to the instruction set
2124
- * @param blendMode - The blend mode of the renderable
2125
- * @param instructionSet - The instruction set we are adding to
2126
- */
2127
- setBlendMode(renderable, blendMode, instructionSet) {
2128
- if (this._activeBlendMode === blendMode) {
2129
- if (this._isAdvanced)
2130
- this._renderableList.push(renderable);
2131
- return;
2132
- }
2133
- this._activeBlendMode = blendMode;
2134
- if (this._isAdvanced) {
2135
- this._endAdvancedBlendMode(instructionSet);
2136
- }
2137
- this._isAdvanced = !!BLEND_MODE_FILTERS[blendMode];
2138
- if (this._isAdvanced) {
2139
- this._beginAdvancedBlendMode(instructionSet);
2140
- this._renderableList.push(renderable);
2141
- }
2142
- }
2143
- _beginAdvancedBlendMode(instructionSet) {
2144
- this._renderer.renderPipes.batch.break(instructionSet);
2145
- const blendMode = this._activeBlendMode;
2146
- if (!BLEND_MODE_FILTERS[blendMode]) {
2147
- warn(`Unable to assign BlendMode: '${blendMode}'. You may want to include: import 'pixi.js/advanced-blend-modes'`);
2148
- return;
2149
- }
2150
- let filterEffect = this._filterHash[blendMode];
2151
- if (!filterEffect) {
2152
- filterEffect = this._filterHash[blendMode] = new FilterEffect();
2153
- filterEffect.filters = [new BLEND_MODE_FILTERS[blendMode]()];
2154
- }
2155
- const instruction = {
2156
- renderPipeId: "filter",
2157
- action: "pushFilter",
2158
- renderables: [],
2159
- filterEffect,
2160
- canBundle: false
2161
- };
2162
- this._renderableList = instruction.renderables;
2163
- instructionSet.add(instruction);
2164
- }
2165
- _endAdvancedBlendMode(instructionSet) {
2166
- this._renderableList = null;
2167
- this._renderer.renderPipes.batch.break(instructionSet);
2168
- instructionSet.add({
2169
- renderPipeId: "filter",
2170
- action: "popFilter",
2171
- canBundle: false
2172
- });
2173
- }
2174
- /**
2175
- * called when the instruction build process is starting this will reset internally to the default blend mode
2176
- * @internal
2177
- */
2178
- buildStart() {
2179
- this._isAdvanced = false;
2180
- }
2181
- /**
2182
- * called when the instruction build process is finished, ensuring that if there is an advanced blend mode
2183
- * active, we add the final render instructions added to the instruction set
2184
- * @param instructionSet - The instruction set we are adding to
2185
- * @internal
2186
- */
2187
- buildEnd(instructionSet) {
2188
- if (this._isAdvanced) {
2189
- this._endAdvancedBlendMode(instructionSet);
2190
- }
2191
- }
2192
- /** @internal */
2193
- destroy() {
2194
- this._renderer = null;
2195
- this._renderableList = null;
2196
- for (const i in this._filterHash) {
2197
- this._filterHash[i].destroy();
2198
- }
2199
- this._filterHash = null;
2200
- }
2201
- }
2202
- /** @ignore */
2203
- BlendModePipe.extension = {
2204
- type: [
2205
- ExtensionType.WebGLPipes,
2206
- ExtensionType.WebGPUPipes,
2207
- ExtensionType.CanvasPipes
2208
- ],
2209
- name: "blendMode"
2210
- };
2211
-
2212
- const imageTypes = {
2213
- png: "image/png",
2214
- jpg: "image/jpeg",
2215
- webp: "image/webp"
2216
- };
2217
- const _ExtractSystem = class _ExtractSystem {
2218
- /** @param renderer - The renderer this System works for. */
2219
- constructor(renderer) {
2220
- this._renderer = renderer;
2221
- }
2222
- _normalizeOptions(options, defaults = {}) {
2223
- if (options instanceof Container || options instanceof Texture) {
2224
- return {
2225
- target: options,
2226
- ...defaults
2227
- };
2228
- }
2229
- return {
2230
- ...defaults,
2231
- ...options
2232
- };
2233
- }
2234
- /**
2235
- * Creates an HTMLImageElement from a display object or texture.
2236
- * @param options - Options for creating the image, or the target to extract
2237
- * @returns Promise that resolves with the generated HTMLImageElement
2238
- * @example
2239
- * ```ts
2240
- * // Basic usage with a sprite
2241
- * const sprite = new Sprite(texture);
2242
- * const image = await renderer.extract.image(sprite);
2243
- * document.body.appendChild(image);
2244
- *
2245
- * // Advanced usage with options
2246
- * const image = await renderer.extract.image({
2247
- * target: container,
2248
- * format: 'webp',
2249
- * quality: 0.8,
2250
- * frame: new Rectangle(0, 0, 100, 100),
2251
- * resolution: 2,
2252
- * clearColor: '#ff0000',
2253
- * antialias: true
2254
- * });
2255
- *
2256
- * // Extract directly from a texture
2257
- * const texture = Texture.from('myTexture.png');
2258
- * const image = await renderer.extract.image(texture);
2259
- * ```
2260
- * @see {@link ExtractImageOptions} For detailed options
2261
- * @see {@link ExtractSystem.base64} For base64 string output
2262
- * @see {@link ExtractSystem.canvas} For canvas output
2263
- * @category rendering
2264
- */
2265
- async image(options) {
2266
- const image = new Image();
2267
- image.src = await this.base64(options);
2268
- return image;
2269
- }
2270
- /**
2271
- * Converts the target into a base64 encoded string.
2272
- *
2273
- * This method works by first creating
2274
- * a canvas using `Extract.canvas` and then converting it to a base64 string.
2275
- * @param options - The options for creating the base64 string, or the target to extract
2276
- * @returns Promise that resolves with the base64 encoded string
2277
- * @example
2278
- * ```ts
2279
- * // Basic usage with a sprite
2280
- * const sprite = new Sprite(texture);
2281
- * const base64 = await renderer.extract.base64(sprite);
2282
- * console.log(base64); // data:image/png;base64,...
2283
- *
2284
- * // Advanced usage with options
2285
- * const base64 = await renderer.extract.base64({
2286
- * target: container,
2287
- * format: 'webp',
2288
- * quality: 0.8,
2289
- * frame: new Rectangle(0, 0, 100, 100),
2290
- * resolution: 2
2291
- * });
2292
- * ```
2293
- * @throws Will throw an error if the platform doesn't support any of:
2294
- * - ICanvas.toDataURL
2295
- * - ICanvas.toBlob
2296
- * - ICanvas.convertToBlob
2297
- * @see {@link ExtractImageOptions} For detailed options
2298
- * @see {@link ExtractSystem.canvas} For canvas output
2299
- * @see {@link ExtractSystem.image} For HTMLImage output
2300
- * @category rendering
2301
- */
2302
- async base64(options) {
2303
- options = this._normalizeOptions(
2304
- options,
2305
- _ExtractSystem.defaultImageOptions
2306
- );
2307
- const { format, quality } = options;
2308
- const canvas = this.canvas(options);
2309
- if (canvas.toBlob !== void 0) {
2310
- return new Promise((resolve, reject) => {
2311
- canvas.toBlob((blob) => {
2312
- if (!blob) {
2313
- reject(new Error("ICanvas.toBlob failed!"));
2314
- return;
2315
- }
2316
- const reader = new FileReader();
2317
- reader.onload = () => resolve(reader.result);
2318
- reader.onerror = reject;
2319
- reader.readAsDataURL(blob);
2320
- }, imageTypes[format], quality);
2321
- });
2322
- }
2323
- if (canvas.toDataURL !== void 0) {
2324
- return canvas.toDataURL(imageTypes[format], quality);
2325
- }
2326
- if (canvas.convertToBlob !== void 0) {
2327
- const blob = await canvas.convertToBlob({ type: imageTypes[format], quality });
2328
- return new Promise((resolve, reject) => {
2329
- const reader = new FileReader();
2330
- reader.onload = () => resolve(reader.result);
2331
- reader.onerror = reject;
2332
- reader.readAsDataURL(blob);
2333
- });
2334
- }
2335
- throw new Error("Extract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented");
2336
- }
2337
- /**
2338
- * Creates a Canvas element, renders the target to it and returns it.
2339
- * This method is useful for creating static images or when you need direct canvas access.
2340
- * @param options - The options for creating the canvas, or the target to extract
2341
- * @returns A Canvas element with the texture rendered on
2342
- * @example
2343
- * ```ts
2344
- * // Basic canvas extraction from a sprite
2345
- * const sprite = new Sprite(texture);
2346
- * const canvas = renderer.extract.canvas(sprite);
2347
- * document.body.appendChild(canvas);
2348
- *
2349
- * // Extract with custom region
2350
- * const canvas = renderer.extract.canvas({
2351
- * target: container,
2352
- * frame: new Rectangle(0, 0, 100, 100)
2353
- * });
2354
- *
2355
- * // Extract with high resolution
2356
- * const canvas = renderer.extract.canvas({
2357
- * target: sprite,
2358
- * resolution: 2,
2359
- * clearColor: '#ff0000'
2360
- * });
2361
- *
2362
- * // Extract directly from a texture
2363
- * const texture = Texture.from('myTexture.png');
2364
- * const canvas = renderer.extract.canvas(texture);
2365
- *
2366
- * // Extract with anti-aliasing
2367
- * const canvas = renderer.extract.canvas({
2368
- * target: graphics,
2369
- * antialias: true
2370
- * });
2371
- * ```
2372
- * @see {@link ExtractOptions} For detailed options
2373
- * @see {@link ExtractSystem.image} For HTMLImage output
2374
- * @see {@link ExtractSystem.pixels} For raw pixel data
2375
- * @category rendering
2376
- */
2377
- canvas(options) {
2378
- options = this._normalizeOptions(options);
2379
- const target = options.target;
2380
- const renderer = this._renderer;
2381
- if (target instanceof Texture) {
2382
- return renderer.texture.generateCanvas(target);
2383
- }
2384
- const texture = renderer.textureGenerator.generateTexture(options);
2385
- const canvas = renderer.texture.generateCanvas(texture);
2386
- texture.destroy(true);
2387
- return canvas;
2388
- }
2389
- /**
2390
- * Returns a one-dimensional array containing the pixel data of the entire texture in RGBA order,
2391
- * with integer values between 0 and 255 (inclusive).
2392
- * > [!NOE] The returned array is a flat Uint8Array where every 4 values represent RGBA
2393
- * @param options - The options for extracting the image, or the target to extract
2394
- * @returns One-dimensional Uint8Array containing the pixel data in RGBA format
2395
- * @example
2396
- * ```ts
2397
- * // Basic pixel extraction
2398
- * const sprite = new Sprite(texture);
2399
- * const pixels = renderer.extract.pixels(sprite);
2400
- * console.log(pixels[0], pixels[1], pixels[2], pixels[3]); // R,G,B,A values
2401
- *
2402
- * // Extract with custom region
2403
- * const pixels = renderer.extract.pixels({
2404
- * target: sprite,
2405
- * frame: new Rectangle(0, 0, 100, 100)
2406
- * });
2407
- *
2408
- * // Extract with high resolution
2409
- * const pixels = renderer.extract.pixels({
2410
- * target: sprite,
2411
- * resolution: 2
2412
- * });
2413
- * ```
2414
- * @see {@link ExtractOptions} For detailed options
2415
- * @see {@link ExtractSystem.canvas} For canvas output
2416
- * @see {@link ExtractSystem.image} For image output
2417
- * @category rendering
2418
- */
2419
- pixels(options) {
2420
- options = this._normalizeOptions(options);
2421
- const target = options.target;
2422
- const renderer = this._renderer;
2423
- const texture = target instanceof Texture ? target : renderer.textureGenerator.generateTexture(options);
2424
- const pixelInfo = renderer.texture.getPixels(texture);
2425
- if (target instanceof Container) {
2426
- texture.destroy(true);
2427
- }
2428
- return pixelInfo;
2429
- }
2430
- /**
2431
- * Creates a texture from a display object or existing texture.
2432
- *
2433
- * This is useful for creating
2434
- * reusable textures from rendered content or making copies of existing textures.
2435
- * > [!NOTE] The returned texture should be destroyed when no longer needed
2436
- * @param options - The options for creating the texture, or the target to extract
2437
- * @returns A new texture containing the extracted content
2438
- * @example
2439
- * ```ts
2440
- * // Basic texture extraction from a sprite
2441
- * const sprite = new Sprite(texture);
2442
- * const extractedTexture = renderer.extract.texture(sprite);
2443
- *
2444
- * // Extract with custom region
2445
- * const regionTexture = renderer.extract.texture({
2446
- * target: container,
2447
- * frame: new Rectangle(0, 0, 100, 100)
2448
- * });
2449
- *
2450
- * // Extract with high resolution
2451
- * const hiResTexture = renderer.extract.texture({
2452
- * target: sprite,
2453
- * resolution: 2,
2454
- * clearColor: '#ff0000'
2455
- * });
2456
- *
2457
- * // Create a new sprite from extracted texture
2458
- * const newSprite = new Sprite(
2459
- * renderer.extract.texture({
2460
- * target: graphics,
2461
- * antialias: true
2462
- * })
2463
- * );
2464
- *
2465
- * // Clean up when done
2466
- * extractedTexture.destroy(true);
2467
- * ```
2468
- * @see {@link ExtractOptions} For detailed options
2469
- * @see {@link Texture} For texture management
2470
- * @see {@link GenerateTextureSystem} For texture generation
2471
- * @category rendering
2472
- */
2473
- texture(options) {
2474
- options = this._normalizeOptions(options);
2475
- if (options.target instanceof Texture)
2476
- return options.target;
2477
- return this._renderer.textureGenerator.generateTexture(options);
2478
- }
2479
- /**
2480
- * Extracts and downloads content from the renderer as an image file.
2481
- * This is a convenient way to save screenshots or export rendered content.
2482
- * > [!NOTE] The download will use PNG format regardless of the filename extension
2483
- * @param options - The options for downloading and extracting the image, or the target to extract
2484
- * @example
2485
- * ```ts
2486
- * // Basic download with default filename
2487
- * const sprite = new Sprite(texture);
2488
- * renderer.extract.download(sprite); // Downloads as 'image.png'
2489
- *
2490
- * // Download with custom filename
2491
- * renderer.extract.download({
2492
- * target: sprite,
2493
- * filename: 'screenshot.png'
2494
- * });
2495
- *
2496
- * // Download with custom region
2497
- * renderer.extract.download({
2498
- * target: container,
2499
- * filename: 'region.png',
2500
- * frame: new Rectangle(0, 0, 100, 100)
2501
- * });
2502
- *
2503
- * // Download with high resolution and background
2504
- * renderer.extract.download({
2505
- * target: stage,
2506
- * filename: 'hd-screenshot.png',
2507
- * resolution: 2,
2508
- * clearColor: '#ff0000'
2509
- * });
2510
- *
2511
- * // Download with anti-aliasing
2512
- * renderer.extract.download({
2513
- * target: graphics,
2514
- * filename: 'smooth.png',
2515
- * antialias: true
2516
- * });
2517
- * ```
2518
- * @see {@link ExtractDownloadOptions} For detailed options
2519
- * @see {@link ExtractSystem.image} For creating images without download
2520
- * @see {@link ExtractSystem.canvas} For canvas output
2521
- * @category rendering
2522
- */
2523
- download(options) {
2524
- options = this._normalizeOptions(options);
2525
- const canvas = this.canvas(options);
2526
- const link = document.createElement("a");
2527
- link.download = options.filename ?? "image.png";
2528
- link.href = canvas.toDataURL("image/png");
2529
- document.body.appendChild(link);
2530
- link.click();
2531
- document.body.removeChild(link);
2532
- }
2533
- /**
2534
- * Logs the target to the console as an image. This is a useful way to debug what's happening in the renderer.
2535
- * The image will be displayed in the browser's console using CSS background images.
2536
- * @param options - The options for logging the image, or the target to log
2537
- * @param options.width - The width of the logged image preview in the console (in pixels)
2538
- * @example
2539
- * ```ts
2540
- * // Basic usage
2541
- * const sprite = new Sprite(texture);
2542
- * renderer.extract.log(sprite);
2543
- * ```
2544
- * @see {@link ExtractSystem.canvas} For getting raw canvas output
2545
- * @see {@link ExtractSystem.pixels} For raw pixel data
2546
- * @category rendering
2547
- * @advanced
2548
- */
2549
- log(options) {
2550
- const width = options.width ?? 200;
2551
- options = this._normalizeOptions(options);
2552
- const canvas = this.canvas(options);
2553
- const base64 = canvas.toDataURL();
2554
- console.log(`[Pixi Texture] ${canvas.width}px ${canvas.height}px`);
2555
- const style = [
2556
- "font-size: 1px;",
2557
- `padding: ${width}px ${300}px;`,
2558
- `background: url(${base64}) no-repeat;`,
2559
- "background-size: contain;"
2560
- ].join(" ");
2561
- console.log("%c ", style);
2562
- }
2563
- destroy() {
2564
- this._renderer = null;
2565
- }
2566
- };
2567
- /** @ignore */
2568
- _ExtractSystem.extension = {
2569
- type: [
2570
- ExtensionType.WebGLSystem,
2571
- ExtensionType.WebGPUSystem
2572
- ],
2573
- name: "extract"
2574
- };
2575
- /**
2576
- * Default options for image extraction.
2577
- * @example
2578
- * ```ts
2579
- * // Customize default options
2580
- * ExtractSystem.defaultImageOptions.format = 'webp';
2581
- * ExtractSystem.defaultImageOptions.quality = 0.8;
2582
- *
2583
- * // Use defaults
2584
- * const image = await renderer.extract.image(sprite);
2585
- * ```
2586
- */
2587
- _ExtractSystem.defaultImageOptions = {
2588
- format: "png",
2589
- quality: 1
2590
- };
2591
- let ExtractSystem = _ExtractSystem;
2592
-
2593
- class RenderTexture extends Texture {
2594
- static create(options) {
2595
- return new RenderTexture({
2596
- source: new TextureSource(options)
2597
- });
2598
- }
2599
- /**
2600
- * Resizes the render texture.
2601
- * @param width - The new width of the render texture.
2602
- * @param height - The new height of the render texture.
2603
- * @param resolution - The new resolution of the render texture.
2604
- * @returns This texture.
2605
- */
2606
- resize(width, height, resolution) {
2607
- this.source.resize(width, height, resolution);
2608
- return this;
2609
- }
2610
- }
2611
-
2612
- const tempRect = new Rectangle();
2613
- const tempBounds = new Bounds();
2614
- const noColor = [0, 0, 0, 0];
2615
- class GenerateTextureSystem {
2616
- constructor(renderer) {
2617
- this._renderer = renderer;
2618
- }
2619
- /**
2620
- * Creates a texture from a display object that can be used for creating sprites and other textures.
2621
- * This is particularly useful for optimizing performance when a complex container needs to be reused.
2622
- * @param options - Generate texture options or a container to convert to texture
2623
- * @returns A new RenderTexture containing the rendered display object
2624
- * @example
2625
- * ```ts
2626
- * // Basic usage with a container
2627
- * const container = new Container();
2628
- * container.addChild(
2629
- * new Graphics()
2630
- * .circle(0, 0, 50)
2631
- * .fill('red')
2632
- * );
2633
- *
2634
- * const texture = renderer.textureGenerator.generateTexture(container);
2635
- *
2636
- * // Advanced usage with options
2637
- * const texture = renderer.textureGenerator.generateTexture({
2638
- * target: container,
2639
- * frame: new Rectangle(0, 0, 100, 100), // Specific region
2640
- * resolution: 2, // High DPI
2641
- * clearColor: '#ff0000', // Red background
2642
- * antialias: true // Smooth edges
2643
- * });
2644
- *
2645
- * // Create a sprite from the generated texture
2646
- * const sprite = new Sprite(texture);
2647
- *
2648
- * // Clean up when done
2649
- * texture.destroy(true);
2650
- * ```
2651
- * @see {@link GenerateTextureOptions} For detailed texture generation options
2652
- * @see {@link RenderTexture} For the type of texture created
2653
- * @category rendering
2654
- */
2655
- generateTexture(options) {
2656
- if (options instanceof Container) {
2657
- options = {
2658
- target: options,
2659
- frame: void 0,
2660
- textureSourceOptions: {},
2661
- resolution: void 0
2662
- };
2663
- }
2664
- const resolution = options.resolution || this._renderer.resolution;
2665
- const antialias = options.antialias || this._renderer.view.antialias;
2666
- const container = options.target;
2667
- let clearColor = options.clearColor;
2668
- if (clearColor) {
2669
- const isRGBAArray = Array.isArray(clearColor) && clearColor.length === 4;
2670
- clearColor = isRGBAArray ? clearColor : Color.shared.setValue(clearColor).toArray();
2671
- } else {
2672
- clearColor = noColor;
2673
- }
2674
- const region = options.frame?.copyTo(tempRect) || getLocalBounds(container, tempBounds).rectangle;
2675
- region.width = Math.max(region.width, 1 / resolution) | 0;
2676
- region.height = Math.max(region.height, 1 / resolution) | 0;
2677
- const target = RenderTexture.create({
2678
- ...options.textureSourceOptions,
2679
- width: region.width,
2680
- height: region.height,
2681
- resolution,
2682
- antialias
2683
- });
2684
- const transform = Matrix.shared.translate(-region.x, -region.y);
2685
- this._renderer.render({
2686
- container,
2687
- transform,
2688
- target,
2689
- clearColor
2690
- });
2691
- target.source.updateMipmaps();
2692
- return target;
2693
- }
2694
- destroy() {
2695
- this._renderer = null;
2696
- }
2697
- }
2698
- /** @ignore */
2699
- GenerateTextureSystem.extension = {
2700
- type: [
2701
- ExtensionType.WebGLSystem,
2702
- ExtensionType.WebGPUSystem
2703
- ],
2704
- name: "textureGenerator"
2705
- };
2706
-
2707
- class GlobalUniformSystem {
2708
- constructor(renderer) {
2709
- this._stackIndex = 0;
2710
- this._globalUniformDataStack = [];
2711
- this._uniformsPool = [];
2712
- this._activeUniforms = [];
2713
- this._bindGroupPool = [];
2714
- this._activeBindGroups = [];
2715
- this._renderer = renderer;
2716
- }
2717
- reset() {
2718
- this._stackIndex = 0;
2719
- for (let i = 0; i < this._activeUniforms.length; i++) {
2720
- this._uniformsPool.push(this._activeUniforms[i]);
2721
- }
2722
- for (let i = 0; i < this._activeBindGroups.length; i++) {
2723
- this._bindGroupPool.push(this._activeBindGroups[i]);
2724
- }
2725
- this._activeUniforms.length = 0;
2726
- this._activeBindGroups.length = 0;
2727
- }
2728
- start(options) {
2729
- this.reset();
2730
- this.push(options);
2731
- }
2732
- bind({
2733
- size,
2734
- projectionMatrix,
2735
- worldTransformMatrix,
2736
- worldColor,
2737
- offset
2738
- }) {
2739
- const renderTarget = this._renderer.renderTarget.renderTarget;
2740
- const currentGlobalUniformData = this._stackIndex ? this._globalUniformDataStack[this._stackIndex - 1] : {
2741
- projectionData: renderTarget,
2742
- worldTransformMatrix: new Matrix(),
2743
- worldColor: 4294967295,
2744
- offset: new Point()
2745
- };
2746
- const globalUniformData = {
2747
- projectionMatrix: projectionMatrix || this._renderer.renderTarget.projectionMatrix,
2748
- resolution: size || renderTarget.size,
2749
- worldTransformMatrix: worldTransformMatrix || currentGlobalUniformData.worldTransformMatrix,
2750
- worldColor: worldColor || currentGlobalUniformData.worldColor,
2751
- offset: offset || currentGlobalUniformData.offset,
2752
- bindGroup: null
2753
- };
2754
- const uniformGroup = this._uniformsPool.pop() || this._createUniforms();
2755
- this._activeUniforms.push(uniformGroup);
2756
- const uniforms = uniformGroup.uniforms;
2757
- uniforms.uProjectionMatrix = globalUniformData.projectionMatrix;
2758
- uniforms.uResolution = globalUniformData.resolution;
2759
- uniforms.uWorldTransformMatrix.copyFrom(globalUniformData.worldTransformMatrix);
2760
- uniforms.uWorldTransformMatrix.tx -= globalUniformData.offset.x;
2761
- uniforms.uWorldTransformMatrix.ty -= globalUniformData.offset.y;
2762
- color32BitToUniform(
2763
- globalUniformData.worldColor,
2764
- uniforms.uWorldColorAlpha,
2765
- 0
2766
- );
2767
- uniformGroup.update();
2768
- let bindGroup;
2769
- if (this._renderer.renderPipes.uniformBatch) {
2770
- bindGroup = this._renderer.renderPipes.uniformBatch.getUniformBindGroup(uniformGroup, false);
2771
- } else {
2772
- bindGroup = this._bindGroupPool.pop() || new BindGroup();
2773
- this._activeBindGroups.push(bindGroup);
2774
- bindGroup.setResource(uniformGroup, 0);
2775
- }
2776
- globalUniformData.bindGroup = bindGroup;
2777
- this._currentGlobalUniformData = globalUniformData;
2778
- }
2779
- push(options) {
2780
- this.bind(options);
2781
- this._globalUniformDataStack[this._stackIndex++] = this._currentGlobalUniformData;
2782
- }
2783
- pop() {
2784
- this._currentGlobalUniformData = this._globalUniformDataStack[--this._stackIndex - 1];
2785
- if (this._renderer.type === RendererType.WEBGL) {
2786
- this._currentGlobalUniformData.bindGroup.resources[0].update();
2787
- }
2788
- }
2789
- get bindGroup() {
2790
- return this._currentGlobalUniformData.bindGroup;
2791
- }
2792
- get globalUniformData() {
2793
- return this._currentGlobalUniformData;
2794
- }
2795
- get uniformGroup() {
2796
- return this._currentGlobalUniformData.bindGroup.resources[0];
2797
- }
2798
- _createUniforms() {
2799
- const globalUniforms = new UniformGroup({
2800
- uProjectionMatrix: { value: new Matrix(), type: "mat3x3<f32>" },
2801
- uWorldTransformMatrix: { value: new Matrix(), type: "mat3x3<f32>" },
2802
- // TODO - someone smart - set this to be a unorm8x4 rather than a vec4<f32>
2803
- uWorldColorAlpha: { value: new Float32Array(4), type: "vec4<f32>" },
2804
- uResolution: { value: [0, 0], type: "vec2<f32>" }
2805
- }, {
2806
- isStatic: true
2807
- });
2808
- return globalUniforms;
2809
- }
2810
- destroy() {
2811
- this._renderer = null;
2812
- }
2813
- }
2814
- /** @ignore */
2815
- GlobalUniformSystem.extension = {
2816
- type: [
2817
- ExtensionType.WebGLSystem,
2818
- ExtensionType.WebGPUSystem,
2819
- ExtensionType.CanvasSystem
2820
- ],
2821
- name: "globalUniforms"
2822
- };
2823
-
2824
- let uid = 1;
2825
- class SchedulerSystem {
2826
- constructor() {
2827
- this._tasks = [];
2828
- /** a small off set to apply to the repeat schedules. This is just to make sure they run at slightly different times */
2829
- this._offset = 0;
2830
- }
2831
- /** Initializes the scheduler system and starts the ticker. */
2832
- init() {
2833
- Ticker.system.add(this._update, this);
2834
- }
2835
- /**
2836
- * Schedules a repeating task.
2837
- * @param func - The function to execute.
2838
- * @param duration - The interval duration in milliseconds.
2839
- * @param useOffset - this will spread out tasks so that they do not all run at the same time
2840
- * @returns The unique identifier for the scheduled task.
2841
- */
2842
- repeat(func, duration, useOffset = true) {
2843
- const id = uid++;
2844
- let offset = 0;
2845
- if (useOffset) {
2846
- this._offset += 1e3;
2847
- offset = this._offset;
2848
- }
2849
- this._tasks.push({
2850
- func,
2851
- duration,
2852
- start: performance.now(),
2853
- offset,
2854
- last: performance.now(),
2855
- repeat: true,
2856
- id
2857
- });
2858
- return id;
2859
- }
2860
- /**
2861
- * Cancels a scheduled task.
2862
- * @param id - The unique identifier of the task to cancel.
2863
- */
2864
- cancel(id) {
2865
- for (let i = 0; i < this._tasks.length; i++) {
2866
- if (this._tasks[i].id === id) {
2867
- this._tasks.splice(i, 1);
2868
- return;
2869
- }
2870
- }
2871
- }
2872
- /**
2873
- * Updates and executes the scheduled tasks.
2874
- * @private
2875
- */
2876
- _update() {
2877
- const now = performance.now();
2878
- for (let i = 0; i < this._tasks.length; i++) {
2879
- const task = this._tasks[i];
2880
- if (now - task.offset - task.last >= task.duration) {
2881
- const elapsed = now - task.start;
2882
- task.func(elapsed);
2883
- task.last = now;
2884
- }
2885
- }
2886
- }
2887
- /**
2888
- * Destroys the scheduler system and removes all tasks.
2889
- * @internal
2890
- */
2891
- destroy() {
2892
- Ticker.system.remove(this._update, this);
2893
- this._tasks.length = 0;
2894
- }
2895
- }
2896
- /** @ignore */
2897
- SchedulerSystem.extension = {
2898
- type: [
2899
- ExtensionType.WebGLSystem,
2900
- ExtensionType.WebGPUSystem,
2901
- ExtensionType.CanvasSystem
2902
- ],
2903
- name: "scheduler",
2904
- priority: 0
2905
- };
2906
-
2907
- let saidHello = false;
2908
- function sayHello(type) {
2909
- if (saidHello) {
2910
- return;
2911
- }
2912
- if (DOMAdapter.get().getNavigator().userAgent.toLowerCase().indexOf("chrome") > -1) {
2913
- const args = [
2914
- `%c %c %c %c %c PixiJS %c v${VERSION} (${type}) http://www.pixijs.com/
2915
-
2916
- `,
2917
- "background: #E72264; padding:5px 0;",
2918
- "background: #6CA2EA; padding:5px 0;",
2919
- "background: #B5D33D; padding:5px 0;",
2920
- "background: #FED23F; padding:5px 0;",
2921
- "color: #FFFFFF; background: #E72264; padding:5px 0;",
2922
- "color: #E72264; background: #FFFFFF; padding:5px 0;"
2923
- ];
2924
- globalThis.console.log(...args);
2925
- } else if (globalThis.console) {
2926
- globalThis.console.log(`PixiJS ${VERSION} - ${type} - http://www.pixijs.com/`);
2927
- }
2928
- saidHello = true;
2929
- }
2930
-
2931
- class HelloSystem {
2932
- constructor(renderer) {
2933
- this._renderer = renderer;
2934
- }
2935
- /**
2936
- * It all starts here! This initiates every system, passing in the options for any system by name.
2937
- * @param options - the config for the renderer and all its systems
2938
- */
2939
- init(options) {
2940
- if (options.hello) {
2941
- let name = this._renderer.name;
2942
- if (this._renderer.type === RendererType.WEBGL) {
2943
- name += ` ${this._renderer.context.webGLVersion}`;
2944
- }
2945
- sayHello(name);
2946
- }
2947
- }
2948
- }
2949
- /** @ignore */
2950
- HelloSystem.extension = {
2951
- type: [
2952
- ExtensionType.WebGLSystem,
2953
- ExtensionType.WebGPUSystem,
2954
- ExtensionType.CanvasSystem
2955
- ],
2956
- name: "hello",
2957
- priority: -2
2958
- };
2959
- /** The default options for the system. */
2960
- HelloSystem.defaultOptions = {
2961
- /** {@link WebGLOptions.hello} */
2962
- hello: false
2963
- };
2964
-
2965
- function cleanHash(hash) {
2966
- let clean = false;
2967
- for (const i in hash) {
2968
- if (hash[i] == void 0) {
2969
- clean = true;
2970
- break;
2971
- }
2972
- }
2973
- if (!clean)
2974
- return hash;
2975
- const cleanHash2 = /* @__PURE__ */ Object.create(null);
2976
- for (const i in hash) {
2977
- const value = hash[i];
2978
- if (value) {
2979
- cleanHash2[i] = value;
2980
- }
2981
- }
2982
- return cleanHash2;
2983
- }
2984
- function cleanArray(arr) {
2985
- let offset = 0;
2986
- for (let i = 0; i < arr.length; i++) {
2987
- if (arr[i] == void 0) {
2988
- offset++;
2989
- } else {
2990
- arr[i - offset] = arr[i];
2991
- }
2992
- }
2993
- arr.length -= offset;
2994
- return arr;
2995
- }
2996
-
2997
- let renderableGCTick = 0;
2998
- const _RenderableGCSystem = class _RenderableGCSystem {
2999
- /**
3000
- * Creates a new RenderableGCSystem instance.
3001
- * @param renderer - The renderer this garbage collection system works for
3002
- */
3003
- constructor(renderer) {
3004
- /** Array of renderables being tracked for garbage collection */
3005
- this._managedRenderables = [];
3006
- /** Array of hash objects being tracked for cleanup */
3007
- this._managedHashes = [];
3008
- /** Array of arrays being tracked for cleanup */
3009
- this._managedArrays = [];
3010
- this._renderer = renderer;
3011
- }
3012
- /**
3013
- * Initializes the garbage collection system with the provided options.
3014
- * @param options - Configuration options for the renderer
3015
- */
3016
- init(options) {
3017
- options = { ..._RenderableGCSystem.defaultOptions, ...options };
3018
- this.maxUnusedTime = options.renderableGCMaxUnusedTime;
3019
- this._frequency = options.renderableGCFrequency;
3020
- this.enabled = options.renderableGCActive;
3021
- }
3022
- /**
3023
- * Gets whether the garbage collection system is currently enabled.
3024
- * @returns True if GC is enabled, false otherwise
3025
- */
3026
- get enabled() {
3027
- return !!this._handler;
3028
- }
3029
- /**
3030
- * Enables or disables the garbage collection system.
3031
- * When enabled, schedules periodic cleanup of resources.
3032
- * When disabled, cancels all scheduled cleanups.
3033
- */
3034
- set enabled(value) {
3035
- if (this.enabled === value)
3036
- return;
3037
- if (value) {
3038
- this._handler = this._renderer.scheduler.repeat(
3039
- () => this.run(),
3040
- this._frequency,
3041
- false
3042
- );
3043
- this._hashHandler = this._renderer.scheduler.repeat(
3044
- () => {
3045
- for (const hash of this._managedHashes) {
3046
- hash.context[hash.hash] = cleanHash(hash.context[hash.hash]);
3047
- }
3048
- },
3049
- this._frequency
3050
- );
3051
- this._arrayHandler = this._renderer.scheduler.repeat(
3052
- () => {
3053
- for (const array of this._managedArrays) {
3054
- cleanArray(array.context[array.hash]);
3055
- }
3056
- },
3057
- this._frequency
3058
- );
3059
- } else {
3060
- this._renderer.scheduler.cancel(this._handler);
3061
- this._renderer.scheduler.cancel(this._hashHandler);
3062
- this._renderer.scheduler.cancel(this._arrayHandler);
3063
- }
3064
- }
3065
- /**
3066
- * Adds a hash table to be managed by the garbage collector.
3067
- * @param context - The object containing the hash table
3068
- * @param hash - The property name of the hash table
3069
- */
3070
- addManagedHash(context, hash) {
3071
- this._managedHashes.push({ context, hash });
3072
- }
3073
- /**
3074
- * Adds an array to be managed by the garbage collector.
3075
- * @param context - The object containing the array
3076
- * @param hash - The property name of the array
3077
- */
3078
- addManagedArray(context, hash) {
3079
- this._managedArrays.push({ context, hash });
3080
- }
3081
- /**
3082
- * Updates the GC timestamp and tracking before rendering.
3083
- * @param options - The render options
3084
- * @param options.container - The container to render
3085
- */
3086
- prerender({
3087
- container
3088
- }) {
3089
- this._now = performance.now();
3090
- container.renderGroup.gcTick = renderableGCTick++;
3091
- this._updateInstructionGCTick(container.renderGroup, container.renderGroup.gcTick);
3092
- }
3093
- /**
3094
- * Starts tracking a renderable for garbage collection.
3095
- * @param renderable - The renderable to track
3096
- */
3097
- addRenderable(renderable) {
3098
- if (!this.enabled)
3099
- return;
3100
- if (renderable._lastUsed === -1) {
3101
- this._managedRenderables.push(renderable);
3102
- renderable.once("destroyed", this._removeRenderable, this);
3103
- }
3104
- renderable._lastUsed = this._now;
3105
- }
3106
- /**
3107
- * Performs garbage collection by cleaning up unused renderables.
3108
- * Removes renderables that haven't been used for longer than maxUnusedTime.
3109
- */
3110
- run() {
3111
- const now = this._now;
3112
- const managedRenderables = this._managedRenderables;
3113
- const renderPipes = this._renderer.renderPipes;
3114
- let offset = 0;
3115
- for (let i = 0; i < managedRenderables.length; i++) {
3116
- const renderable = managedRenderables[i];
3117
- if (renderable === null) {
3118
- offset++;
3119
- continue;
3120
- }
3121
- const renderGroup = renderable.renderGroup ?? renderable.parentRenderGroup;
3122
- const currentTick = renderGroup?.instructionSet?.gcTick ?? -1;
3123
- if ((renderGroup?.gcTick ?? 0) === currentTick) {
3124
- renderable._lastUsed = now;
3125
- }
3126
- if (now - renderable._lastUsed > this.maxUnusedTime) {
3127
- if (!renderable.destroyed) {
3128
- const rp = renderPipes;
3129
- if (renderGroup)
3130
- renderGroup.structureDidChange = true;
3131
- rp[renderable.renderPipeId].destroyRenderable(renderable);
3132
- }
3133
- renderable._lastUsed = -1;
3134
- offset++;
3135
- renderable.off("destroyed", this._removeRenderable, this);
3136
- } else {
3137
- managedRenderables[i - offset] = renderable;
3138
- }
3139
- }
3140
- managedRenderables.length -= offset;
3141
- }
3142
- /** Cleans up the garbage collection system. Disables GC and removes all tracked resources. */
3143
- destroy() {
3144
- this.enabled = false;
3145
- this._renderer = null;
3146
- this._managedRenderables.length = 0;
3147
- this._managedHashes.length = 0;
3148
- this._managedArrays.length = 0;
3149
- }
3150
- /**
3151
- * Removes a renderable from being tracked when it's destroyed.
3152
- * @param renderable - The renderable to stop tracking
3153
- */
3154
- _removeRenderable(renderable) {
3155
- const index = this._managedRenderables.indexOf(renderable);
3156
- if (index >= 0) {
3157
- renderable.off("destroyed", this._removeRenderable, this);
3158
- this._managedRenderables[index] = null;
3159
- }
3160
- }
3161
- /**
3162
- * Updates the GC tick counter for a render group and its children.
3163
- * @param renderGroup - The render group to update
3164
- * @param gcTick - The new tick value
3165
- */
3166
- _updateInstructionGCTick(renderGroup, gcTick) {
3167
- renderGroup.instructionSet.gcTick = gcTick;
3168
- for (const child of renderGroup.renderGroupChildren) {
3169
- this._updateInstructionGCTick(child, gcTick);
3170
- }
3171
- }
3172
- };
3173
- /**
3174
- * Extension metadata for registering this system with the renderer.
3175
- * @ignore
3176
- */
3177
- _RenderableGCSystem.extension = {
3178
- type: [
3179
- ExtensionType.WebGLSystem,
3180
- ExtensionType.WebGPUSystem
3181
- ],
3182
- name: "renderableGC",
3183
- priority: 0
3184
- };
3185
- /**
3186
- * Default configuration options for the garbage collection system.
3187
- * These can be overridden when initializing the renderer.
3188
- */
3189
- _RenderableGCSystem.defaultOptions = {
3190
- /** Enable/disable the garbage collector */
3191
- renderableGCActive: true,
3192
- /** Time in ms before an unused resource is collected (default 1 minute) */
3193
- renderableGCMaxUnusedTime: 6e4,
3194
- /** How often to run garbage collection in ms (default 30 seconds) */
3195
- renderableGCFrequency: 3e4
3196
- };
3197
- let RenderableGCSystem = _RenderableGCSystem;
3198
-
3199
- const _TextureGCSystem = class _TextureGCSystem {
3200
- /** @param renderer - The renderer this System works for. */
3201
- constructor(renderer) {
3202
- this._renderer = renderer;
3203
- this.count = 0;
3204
- this.checkCount = 0;
3205
- }
3206
- init(options) {
3207
- options = { ..._TextureGCSystem.defaultOptions, ...options };
3208
- this.checkCountMax = options.textureGCCheckCountMax;
3209
- this.maxIdle = options.textureGCAMaxIdle ?? options.textureGCMaxIdle;
3210
- this.active = options.textureGCActive;
3211
- }
3212
- /**
3213
- * Checks to see when the last time a texture was used.
3214
- * If the texture has not been used for a specified amount of time, it will be removed from the GPU.
3215
- */
3216
- postrender() {
3217
- if (!this._renderer.renderingToScreen) {
3218
- return;
3219
- }
3220
- this.count++;
3221
- if (!this.active)
3222
- return;
3223
- this.checkCount++;
3224
- if (this.checkCount > this.checkCountMax) {
3225
- this.checkCount = 0;
3226
- this.run();
3227
- }
3228
- }
3229
- /**
3230
- * Checks to see when the last time a texture was used.
3231
- * If the texture has not been used for a specified amount of time, it will be removed from the GPU.
3232
- */
3233
- run() {
3234
- const managedTextures = this._renderer.texture.managedTextures;
3235
- for (let i = 0; i < managedTextures.length; i++) {
3236
- const texture = managedTextures[i];
3237
- if (texture.autoGarbageCollect && texture.resource && texture._touched > -1 && this.count - texture._touched > this.maxIdle) {
3238
- texture._touched = -1;
3239
- texture.unload();
3240
- }
3241
- }
3242
- }
3243
- destroy() {
3244
- this._renderer = null;
3245
- }
3246
- };
3247
- /** @ignore */
3248
- _TextureGCSystem.extension = {
3249
- type: [
3250
- ExtensionType.WebGLSystem,
3251
- ExtensionType.WebGPUSystem
3252
- ],
3253
- name: "textureGC"
3254
- };
3255
- /** default options for the TextureGCSystem */
3256
- _TextureGCSystem.defaultOptions = {
3257
- /**
3258
- * If set to true, this will enable the garbage collector on the GPU.
3259
- * @default true
3260
- */
3261
- textureGCActive: true,
3262
- /**
3263
- * @deprecated since 8.3.0
3264
- * @see {@link TextureGCSystemOptions.textureGCMaxIdle}
3265
- */
3266
- textureGCAMaxIdle: null,
3267
- /**
3268
- * The maximum idle frames before a texture is destroyed by garbage collection.
3269
- * @default 60 * 60
3270
- */
3271
- textureGCMaxIdle: 60 * 60,
3272
- /**
3273
- * Frames between two garbage collections.
3274
- * @default 600
3275
- */
3276
- textureGCCheckCountMax: 600
3277
- };
3278
- let TextureGCSystem = _TextureGCSystem;
3279
-
3280
- const _ViewSystem = class _ViewSystem {
3281
- /**
3282
- * Whether CSS dimensions of canvas view should be resized to screen dimensions automatically.
3283
- * This is only supported for HTMLCanvasElement and will be ignored if the canvas is an OffscreenCanvas.
3284
- * @type {boolean}
3285
- */
3286
- get autoDensity() {
3287
- return this.texture.source.autoDensity;
3288
- }
3289
- set autoDensity(value) {
3290
- this.texture.source.autoDensity = value;
3291
- }
3292
- /** The resolution / device pixel ratio of the renderer. */
3293
- get resolution() {
3294
- return this.texture.source._resolution;
3295
- }
3296
- set resolution(value) {
3297
- this.texture.source.resize(
3298
- this.texture.source.width,
3299
- this.texture.source.height,
3300
- value
3301
- );
3302
- }
3303
- /**
3304
- * initiates the view system
3305
- * @param options - the options for the view
3306
- */
3307
- init(options) {
3308
- options = {
3309
- ..._ViewSystem.defaultOptions,
3310
- ...options
3311
- };
3312
- if (options.view) {
3313
- deprecation(v8_0_0, "ViewSystem.view has been renamed to ViewSystem.canvas");
3314
- options.canvas = options.view;
3315
- }
3316
- this.screen = new Rectangle(0, 0, options.width, options.height);
3317
- this.canvas = options.canvas || DOMAdapter.get().createCanvas();
3318
- this.antialias = !!options.antialias;
3319
- this.texture = getCanvasTexture(this.canvas, options);
3320
- this.renderTarget = new RenderTarget({
3321
- colorTextures: [this.texture],
3322
- depth: !!options.depth,
3323
- isRoot: true
3324
- });
3325
- this.texture.source.transparent = options.backgroundAlpha < 1;
3326
- this.resolution = options.resolution;
3327
- }
3328
- /**
3329
- * Resizes the screen and canvas to the specified dimensions.
3330
- * @param desiredScreenWidth - The new width of the screen.
3331
- * @param desiredScreenHeight - The new height of the screen.
3332
- * @param resolution
3333
- */
3334
- resize(desiredScreenWidth, desiredScreenHeight, resolution) {
3335
- this.texture.source.resize(desiredScreenWidth, desiredScreenHeight, resolution);
3336
- this.screen.width = this.texture.frame.width;
3337
- this.screen.height = this.texture.frame.height;
3338
- }
3339
- /**
3340
- * Destroys this System and optionally removes the canvas from the dom.
3341
- * @param {options | false} options - The options for destroying the view, or "false".
3342
- * @example
3343
- * viewSystem.destroy();
3344
- * viewSystem.destroy(true);
3345
- * viewSystem.destroy({ removeView: true });
3346
- */
3347
- destroy(options = false) {
3348
- const removeView = typeof options === "boolean" ? options : !!options?.removeView;
3349
- if (removeView && this.canvas.parentNode) {
3350
- this.canvas.parentNode.removeChild(this.canvas);
3351
- }
3352
- }
3353
- };
3354
- /** @ignore */
3355
- _ViewSystem.extension = {
3356
- type: [
3357
- ExtensionType.WebGLSystem,
3358
- ExtensionType.WebGPUSystem,
3359
- ExtensionType.CanvasSystem
3360
- ],
3361
- name: "view",
3362
- priority: 0
3363
- };
3364
- /** The default options for the view system. */
3365
- _ViewSystem.defaultOptions = {
3366
- /**
3367
- * {@link WebGLOptions.width}
3368
- * @default 800
3369
- */
3370
- width: 800,
3371
- /**
3372
- * {@link WebGLOptions.height}
3373
- * @default 600
3374
- */
3375
- height: 600,
3376
- /**
3377
- * {@link WebGLOptions.autoDensity}
3378
- * @default false
3379
- */
3380
- autoDensity: false,
3381
- /**
3382
- * {@link WebGLOptions.antialias}
3383
- * @default false
3384
- */
3385
- antialias: false
3386
- };
3387
- let ViewSystem = _ViewSystem;
3388
-
3389
- const SharedSystems = [
3390
- BackgroundSystem,
3391
- GlobalUniformSystem,
3392
- HelloSystem,
3393
- ViewSystem,
3394
- RenderGroupSystem,
3395
- TextureGCSystem,
3396
- GenerateTextureSystem,
3397
- ExtractSystem,
3398
- RendererInitHook,
3399
- RenderableGCSystem,
3400
- SchedulerSystem
3401
- ];
3402
- const SharedRenderPipes = [
3403
- BlendModePipe,
3404
- BatcherPipe,
3405
- SpritePipe,
3406
- RenderGroupPipe,
3407
- AlphaMaskPipe,
3408
- StencilMaskPipe,
3409
- ColorMaskPipe,
3410
- CustomRenderPipe
3411
- ];
3412
-
3413
- export { BufferResource as B, GpuStencilModesToPixi as G, RenderTargetSystem as R, SharedSystems as S, UboSystem as U, SharedRenderPipes as a, uboSyncFunctionsSTD40 as b, createUboSyncFunction as c, uniformParsers as d, ensureAttributes as e, textureBitGl as f, textureBit as t, uboSyncFunctionsWGSL as u };