@lightningjs/renderer 0.8.2 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/CoreNode.d.ts +27 -1
- package/dist/src/core/CoreNode.js +130 -5
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreShaderManager.d.ts +2 -0
- package/dist/src/core/CoreShaderManager.js +9 -0
- package/dist/src/core/CoreShaderManager.js.map +1 -1
- package/dist/src/core/CoreTextNode.js +20 -1
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +2 -0
- package/dist/src/core/CoreTextureManager.js +2 -0
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +3 -2
- package/dist/src/core/Stage.js +36 -10
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.d.ts +1 -0
- package/dist/src/core/TextureMemoryManager.js +3 -1
- package/dist/src/core/TextureMemoryManager.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.d.ts +2 -1
- package/dist/src/core/lib/ImageWorker.js +11 -7
- package/dist/src/core/lib/ImageWorker.js.map +1 -1
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +26 -1
- package/dist/src/core/lib/WebGlContextWrapper.js +37 -1
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/renderers/CoreRenderer.d.ts +32 -3
- package/dist/src/core/renderers/CoreRenderer.js +14 -2
- package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/canvas/CanvasCoreRenderer.d.ts +22 -0
- package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js +166 -0
- package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js.map +1 -0
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +17 -0
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +124 -0
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -0
- package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.d.ts +5 -0
- package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js +32 -0
- package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js.map +1 -0
- package/dist/src/core/renderers/canvas/internal/ColorUtils.d.ts +15 -0
- package/dist/src/core/renderers/canvas/internal/ColorUtils.js +45 -0
- package/dist/src/core/renderers/canvas/internal/ColorUtils.js.map +1 -0
- package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.d.ts +10 -0
- package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js +43 -0
- package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.d.ts +11 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js +51 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +11 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +22 -11
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +4 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +7 -2
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +18 -21
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +121 -41
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js +19 -4
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +4 -6
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js +6 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
- package/dist/src/core/text-rendering/TextRenderingUtils.d.ts +12 -0
- package/dist/src/core/text-rendering/TextRenderingUtils.js +14 -0
- package/dist/src/core/text-rendering/TextRenderingUtils.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +2 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +6 -3
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +2 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.js +3 -0
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/textures/RenderTexture.d.ts +28 -0
- package/dist/src/core/textures/RenderTexture.js +52 -0
- package/dist/src/core/textures/RenderTexture.js.map +1 -0
- package/dist/src/core/utils.d.ts +6 -1
- package/dist/src/core/utils.js +74 -82
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/main-api/INode.d.ts +9 -0
- package/dist/src/main-api/Inspector.js +7 -1
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/RendererMain.d.ts +4 -0
- package/dist/src/main-api/RendererMain.js +2 -0
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/render-drivers/main/MainCoreDriver.js +1 -0
- package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyNode.d.ts +3 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js +29 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.js +1 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
- package/dist/src/render-drivers/threadx/NodeStruct.js +9 -0
- package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
- package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
- package/dist/src/render-drivers/threadx/SharedNode.js +1 -0
- package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +2 -0
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +3 -0
- package/dist/src/render-drivers/threadx/ThreadXMainNode.js +7 -0
- package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +1 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +1 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +2 -0
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/render-drivers/utils.js +1 -1
- package/dist/src/render-drivers/utils.js.map +1 -1
- package/dist/src/utils.d.ts +12 -6
- package/dist/src/utils.js +19 -9
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/CoreNode.ts +164 -8
- package/src/core/CoreShaderManager.ts +13 -0
- package/src/core/CoreTextNode.ts +25 -0
- package/src/core/CoreTextureManager.ts +3 -0
- package/src/core/Stage.ts +44 -10
- package/src/core/TextureMemoryManager.ts +3 -1
- package/src/core/lib/ImageWorker.ts +13 -8
- package/src/core/lib/WebGlContextWrapper.ts +51 -1
- package/src/core/renderers/CoreRenderer.ts +46 -6
- package/src/core/renderers/canvas/CanvasCoreRenderer.ts +223 -0
- package/src/core/renderers/canvas/CanvasCoreTexture.ts +144 -0
- package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +37 -0
- package/src/core/renderers/canvas/internal/ColorUtils.ts +55 -0
- package/src/core/renderers/canvas/shaders/UnsupportedShader.ts +48 -0
- package/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.ts +79 -0
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +26 -24
- package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +4 -2
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +173 -70
- package/src/core/renderers/webgl/WebGlCoreShader.ts +29 -4
- package/src/core/renderers/webgl/shaders/DefaultShader.ts +4 -6
- package/src/core/renderers/webgl/shaders/SdfShader.ts +6 -1
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +10 -1
- package/src/core/text-rendering/renderers/TextRenderer.ts +3 -0
- package/src/core/textures/ImageTexture.ts +3 -0
- package/src/core/textures/RenderTexture.ts +81 -0
- package/src/core/utils.ts +101 -93
- package/src/main-api/INode.ts +11 -0
- package/src/main-api/Inspector.ts +6 -1
- package/src/main-api/RendererMain.ts +8 -0
- package/src/render-drivers/main/MainCoreDriver.ts +1 -0
- package/src/render-drivers/main/MainOnlyNode.ts +44 -0
- package/src/render-drivers/main/MainOnlyTextNode.ts +1 -0
- package/src/render-drivers/threadx/NodeStruct.ts +10 -0
- package/src/render-drivers/threadx/SharedNode.ts +2 -0
- package/src/render-drivers/threadx/ThreadXCoreDriver.ts +2 -0
- package/src/render-drivers/threadx/ThreadXMainNode.ts +9 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +1 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +1 -0
- package/src/render-drivers/threadx/worker/renderer.ts +2 -0
- package/src/render-drivers/utils.ts +1 -1
- package/src/utils.ts +21 -9
package/src/core/CoreNode.ts
CHANGED
|
@@ -37,6 +37,7 @@ import type {
|
|
|
37
37
|
TextureFreedEventHandler,
|
|
38
38
|
TextureLoadedEventHandler,
|
|
39
39
|
} from './textures/Texture.js';
|
|
40
|
+
import { RenderTexture } from './textures/RenderTexture.js';
|
|
40
41
|
import type {
|
|
41
42
|
Dimensions,
|
|
42
43
|
NodeTextureFailedPayload,
|
|
@@ -104,6 +105,7 @@ export interface CoreNodeProps {
|
|
|
104
105
|
pivotX: number;
|
|
105
106
|
pivotY: number;
|
|
106
107
|
rotation: number;
|
|
108
|
+
rtt: boolean;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
type ICoreNode = Omit<
|
|
@@ -212,6 +214,16 @@ export enum UpdateType {
|
|
|
212
214
|
*/
|
|
213
215
|
IsRenderable = 1024,
|
|
214
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Render Texture update
|
|
219
|
+
*/
|
|
220
|
+
RenderTexture = 2048,
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Track if parent has render texture
|
|
224
|
+
*/
|
|
225
|
+
ParentRenderTexture = 4096,
|
|
226
|
+
|
|
215
227
|
/**
|
|
216
228
|
* None
|
|
217
229
|
*/
|
|
@@ -220,7 +232,7 @@ export enum UpdateType {
|
|
|
220
232
|
/**
|
|
221
233
|
* All
|
|
222
234
|
*/
|
|
223
|
-
All =
|
|
235
|
+
All = 8191,
|
|
224
236
|
}
|
|
225
237
|
|
|
226
238
|
export class CoreNode extends EventEmitter implements ICoreNode {
|
|
@@ -252,6 +264,8 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
252
264
|
public premultipliedColorBl = 0;
|
|
253
265
|
public premultipliedColorBr = 0;
|
|
254
266
|
public calcZIndex = 0;
|
|
267
|
+
public hasRTTupdates = false;
|
|
268
|
+
public parentHasRenderTexture = false;
|
|
255
269
|
|
|
256
270
|
constructor(protected stage: Stage, props: CoreNodeProps) {
|
|
257
271
|
super();
|
|
@@ -261,6 +275,10 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
261
275
|
};
|
|
262
276
|
// Allow for parent to be processed appropriately
|
|
263
277
|
this.parent = props.parent;
|
|
278
|
+
|
|
279
|
+
// Allow for Render Texture to be processed appropriately
|
|
280
|
+
this.rtt = props.rtt;
|
|
281
|
+
|
|
264
282
|
this.updateScaleRotateTransform();
|
|
265
283
|
}
|
|
266
284
|
|
|
@@ -324,6 +342,13 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
324
342
|
// Texture was loaded. In case the RAF loop has already stopped, we request
|
|
325
343
|
// a render to ensure the texture is rendered.
|
|
326
344
|
this.stage.requestRender();
|
|
345
|
+
|
|
346
|
+
// If parent has a render texture, flag that we need to update
|
|
347
|
+
// @todo: Reserve type for RTT updates
|
|
348
|
+
if (this.parentHasRenderTexture) {
|
|
349
|
+
this.setRTTUpdates(1);
|
|
350
|
+
}
|
|
351
|
+
|
|
327
352
|
this.emit('loaded', {
|
|
328
353
|
type: 'texture',
|
|
329
354
|
dimensions,
|
|
@@ -373,6 +398,11 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
373
398
|
if (parent && !(parent.updateType & UpdateType.Children)) {
|
|
374
399
|
parent.setUpdateType(UpdateType.Children);
|
|
375
400
|
}
|
|
401
|
+
// If node is part of RTT texture
|
|
402
|
+
// Flag that we need to update
|
|
403
|
+
if (this.parentHasRenderTexture) {
|
|
404
|
+
this.setRTTUpdates(type);
|
|
405
|
+
}
|
|
376
406
|
}
|
|
377
407
|
|
|
378
408
|
sortChildren() {
|
|
@@ -421,16 +451,43 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
421
451
|
|
|
422
452
|
const parent = this.props.parent;
|
|
423
453
|
let childUpdateType = UpdateType.None;
|
|
454
|
+
|
|
455
|
+
if (this.updateType & UpdateType.ParentRenderTexture) {
|
|
456
|
+
let p = this.parent;
|
|
457
|
+
while (p) {
|
|
458
|
+
if (p.rtt) {
|
|
459
|
+
this.parentHasRenderTexture = true;
|
|
460
|
+
}
|
|
461
|
+
p = p.parent;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// If we have render texture updates and not already running a full update
|
|
466
|
+
if (
|
|
467
|
+
this.updateType ^ UpdateType.All &&
|
|
468
|
+
this.updateType & UpdateType.RenderTexture
|
|
469
|
+
) {
|
|
470
|
+
this.children.forEach((child) => {
|
|
471
|
+
child.setUpdateType(UpdateType.All);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
424
475
|
if (this.updateType & UpdateType.Global) {
|
|
425
476
|
assertTruthy(this.localTransform);
|
|
477
|
+
|
|
426
478
|
this.globalTransform = Matrix3d.copy(
|
|
427
479
|
parent?.globalTransform || this.localTransform,
|
|
428
480
|
this.globalTransform,
|
|
429
481
|
);
|
|
430
482
|
|
|
483
|
+
if (this.parentHasRenderTexture && this.props.parent?.rtt) {
|
|
484
|
+
this.globalTransform = Matrix3d.identity();
|
|
485
|
+
}
|
|
486
|
+
|
|
431
487
|
if (parent) {
|
|
432
488
|
this.globalTransform.multiply(this.localTransform);
|
|
433
489
|
}
|
|
490
|
+
|
|
434
491
|
this.calculateRenderCoords();
|
|
435
492
|
this.updateBoundingRect();
|
|
436
493
|
this.setUpdateType(
|
|
@@ -511,7 +568,11 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
511
568
|
parent.setUpdateType(UpdateType.ZIndexSortedChildren);
|
|
512
569
|
}
|
|
513
570
|
|
|
514
|
-
if (
|
|
571
|
+
if (
|
|
572
|
+
this.updateType & UpdateType.Children &&
|
|
573
|
+
this.children.length &&
|
|
574
|
+
!this.rtt
|
|
575
|
+
) {
|
|
515
576
|
this.children.forEach((child) => {
|
|
516
577
|
// Trigger the depenedent update types on the child
|
|
517
578
|
child.setUpdateType(childUpdateType);
|
|
@@ -755,7 +816,6 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
755
816
|
);
|
|
756
817
|
}
|
|
757
818
|
}
|
|
758
|
-
|
|
759
819
|
/**
|
|
760
820
|
* This function calculates the clipping rectangle for a node.
|
|
761
821
|
*
|
|
@@ -824,13 +884,30 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
824
884
|
this.props.texture = null;
|
|
825
885
|
this.props.shader = null;
|
|
826
886
|
|
|
887
|
+
if (this.rtt) {
|
|
888
|
+
this.stage.renderer.removeRTTNode(this);
|
|
889
|
+
}
|
|
890
|
+
|
|
827
891
|
this.removeAllListeners();
|
|
828
892
|
this.parent = null;
|
|
829
893
|
}
|
|
830
894
|
|
|
831
895
|
renderQuads(renderer: CoreRenderer): void {
|
|
832
|
-
const { width, height, texture, textureOptions, shader, shaderProps } =
|
|
896
|
+
const { width, height, texture, textureOptions, shader, shaderProps, rtt } =
|
|
833
897
|
this.props;
|
|
898
|
+
|
|
899
|
+
// Prevent quad rendering if parent has a render texture
|
|
900
|
+
// and renderer is not currently rendering to a texture
|
|
901
|
+
if (this.parentHasRenderTexture) {
|
|
902
|
+
if (!renderer.renderToTextureActive) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
// Prevent quad rendering if parent render texture is not the active render texture
|
|
906
|
+
if (this.parentRenderTexture !== renderer.activeRttNode) {
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
834
911
|
const {
|
|
835
912
|
premultipliedColorTl,
|
|
836
913
|
premultipliedColorTr,
|
|
@@ -863,10 +940,10 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
863
940
|
tb: gt.tb,
|
|
864
941
|
tc: gt.tc,
|
|
865
942
|
td: gt.td,
|
|
943
|
+
rtt,
|
|
944
|
+
parentHasRenderTexture: this.parentHasRenderTexture,
|
|
945
|
+
framebufferDimensions: this.framebufferDimensions,
|
|
866
946
|
});
|
|
867
|
-
|
|
868
|
-
// Calculate absolute X and Y based on all ancestors
|
|
869
|
-
// renderer.addQuad(absX, absY, w, h, color, texture, textureOptions, zIndex);
|
|
870
947
|
}
|
|
871
948
|
|
|
872
949
|
//#region Properties
|
|
@@ -915,6 +992,10 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
915
992
|
if (this.props.width !== value) {
|
|
916
993
|
this.props.width = value;
|
|
917
994
|
this.setUpdateType(UpdateType.Local);
|
|
995
|
+
|
|
996
|
+
if (this.props.rtt) {
|
|
997
|
+
this.setUpdateType(UpdateType.RenderTexture);
|
|
998
|
+
}
|
|
918
999
|
}
|
|
919
1000
|
}
|
|
920
1001
|
|
|
@@ -926,6 +1007,10 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
926
1007
|
if (this.props.height !== value) {
|
|
927
1008
|
this.props.height = value;
|
|
928
1009
|
this.setUpdateType(UpdateType.Local);
|
|
1010
|
+
|
|
1011
|
+
if (this.props.rtt) {
|
|
1012
|
+
this.setUpdateType(UpdateType.RenderTexture);
|
|
1013
|
+
}
|
|
929
1014
|
}
|
|
930
1015
|
}
|
|
931
1016
|
|
|
@@ -1235,9 +1320,80 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
1235
1320
|
newParent.setUpdateType(
|
|
1236
1321
|
UpdateType.Children | UpdateType.ZIndexSortedChildren,
|
|
1237
1322
|
);
|
|
1238
|
-
}
|
|
1239
1323
|
|
|
1324
|
+
if (newParent.rtt || newParent.parentHasRenderTexture) {
|
|
1325
|
+
this.setRTTUpdates(UpdateType.All);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1240
1328
|
this.updateScaleRotateTransform();
|
|
1241
1329
|
}
|
|
1330
|
+
|
|
1331
|
+
get rtt(): boolean {
|
|
1332
|
+
return this.props.rtt;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
set rtt(value: boolean) {
|
|
1336
|
+
if (!value) {
|
|
1337
|
+
if (this.props.rtt) {
|
|
1338
|
+
this.props.rtt = false;
|
|
1339
|
+
this.unloadTexture();
|
|
1340
|
+
this.setUpdateType(UpdateType.All);
|
|
1341
|
+
|
|
1342
|
+
this.children.forEach((child) => {
|
|
1343
|
+
child.parentHasRenderTexture = false;
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
this.stage.renderer?.removeRTTNode(this);
|
|
1347
|
+
}
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
this.props.rtt = true;
|
|
1352
|
+
this.hasRTTupdates = true;
|
|
1353
|
+
this.setUpdateType(UpdateType.All);
|
|
1354
|
+
|
|
1355
|
+
this.children.forEach((child) => {
|
|
1356
|
+
child.setUpdateType(UpdateType.All);
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
// Store RTT nodes in a separate list
|
|
1360
|
+
this.stage.renderer?.renderToTexture(this);
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
/**
|
|
1364
|
+
* Returns the framebuffer dimensions of the node.
|
|
1365
|
+
* If the node has a render texture, the dimensions are the same as the node's dimensions.
|
|
1366
|
+
* If the node does not have a render texture, the dimensions are inherited from the parent.
|
|
1367
|
+
* If the node parent has a render texture and the node is a render texture, the nodes dimensions are used.
|
|
1368
|
+
*/
|
|
1369
|
+
get framebufferDimensions(): Dimensions {
|
|
1370
|
+
if (this.parentHasRenderTexture && !this.rtt && this.parent) {
|
|
1371
|
+
return this.parent.framebufferDimensions;
|
|
1372
|
+
}
|
|
1373
|
+
return { width: this.width, height: this.height };
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/**
|
|
1377
|
+
* Returns the parent render texture node if it exists.
|
|
1378
|
+
*/
|
|
1379
|
+
get parentRenderTexture(): CoreNode | null {
|
|
1380
|
+
let parent = this.parent;
|
|
1381
|
+
while (parent) {
|
|
1382
|
+
if (parent.rtt) {
|
|
1383
|
+
return parent;
|
|
1384
|
+
}
|
|
1385
|
+
parent = parent.parent;
|
|
1386
|
+
}
|
|
1387
|
+
return null;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
get texture(): Texture | null {
|
|
1391
|
+
return this.props.texture;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
setRTTUpdates(type: number) {
|
|
1395
|
+
this.hasRTTupdates = true;
|
|
1396
|
+
this.parent?.setRTTUpdates(type);
|
|
1397
|
+
}
|
|
1242
1398
|
//#endregion Properties
|
|
1243
1399
|
}
|
|
@@ -61,6 +61,8 @@ import {
|
|
|
61
61
|
type RadialProgressEffectProps,
|
|
62
62
|
} from './renderers/webgl/shaders/effects/RadialProgressEffect.js';
|
|
63
63
|
import { HolePunchEffect } from './renderers/webgl/shaders/effects/HolePunchEffect.js';
|
|
64
|
+
import { WebGlCoreShader } from './renderers/webgl/WebGlCoreShader.js';
|
|
65
|
+
import { UnsupportedShader } from './renderers/canvas/shaders/UnsupportedShader.js';
|
|
64
66
|
|
|
65
67
|
export type { FadeOutEffectProps };
|
|
66
68
|
export type { LinearGradientEffectProps };
|
|
@@ -75,6 +77,7 @@ export interface ShaderMap {
|
|
|
75
77
|
RoundedRectangle: typeof RoundedRectangle;
|
|
76
78
|
DynamicShader: typeof DynamicShader;
|
|
77
79
|
SdfShader: typeof SdfShader;
|
|
80
|
+
UnsupportedShader: typeof UnsupportedShader;
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
export type ShaderNode<Type extends keyof ShaderMap> = {
|
|
@@ -170,6 +173,16 @@ export class CoreShaderManager {
|
|
|
170
173
|
throw new Error(`Shader type "${shType as string}" is not registered`);
|
|
171
174
|
}
|
|
172
175
|
|
|
176
|
+
if (
|
|
177
|
+
this.renderer.mode === 'canvas' &&
|
|
178
|
+
ShaderClass.prototype instanceof WebGlCoreShader
|
|
179
|
+
) {
|
|
180
|
+
return {
|
|
181
|
+
shader: new UnsupportedShader(shType) as InstanceType<ShaderMap[Type]>,
|
|
182
|
+
props: props as Record<string, unknown>,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
173
186
|
if (shType === 'DynamicShader') {
|
|
174
187
|
return this.loadDynamicShader(props!);
|
|
175
188
|
}
|
package/src/core/CoreTextNode.ts
CHANGED
|
@@ -34,6 +34,7 @@ import type {
|
|
|
34
34
|
} from '../common/CommonTypes.js';
|
|
35
35
|
import type { Rect, RectWithValid } from './lib/utils.js';
|
|
36
36
|
import { assertTruthy } from '../utils.js';
|
|
37
|
+
import { Matrix3d } from './lib/Matrix3d.js';
|
|
37
38
|
|
|
38
39
|
export interface CoreTextNodeProps extends CoreNodeProps, TrProps {
|
|
39
40
|
text: string;
|
|
@@ -354,11 +355,35 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
354
355
|
|
|
355
356
|
override renderQuads(renderer: CoreRenderer) {
|
|
356
357
|
assertTruthy(this.globalTransform);
|
|
358
|
+
|
|
359
|
+
// Prevent quad rendering if parent has a render texture
|
|
360
|
+
// and this node is not the render texture
|
|
361
|
+
if (this.parentHasRenderTexture) {
|
|
362
|
+
if (!renderer.renderToTextureActive) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// Prevent quad rendering if parent render texture is not the active render texture
|
|
366
|
+
if (this.parentRenderTexture !== renderer.activeRttNode) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (this.parentHasRenderTexture && this.props.parent?.rtt) {
|
|
372
|
+
this.globalTransform = Matrix3d.identity();
|
|
373
|
+
if (this.localTransform) {
|
|
374
|
+
this.globalTransform.multiply(this.localTransform);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
assertTruthy(this.globalTransform);
|
|
379
|
+
|
|
357
380
|
this.textRenderer.renderQuads(
|
|
358
381
|
this.trState,
|
|
359
382
|
this.globalTransform,
|
|
360
383
|
this.clippingRect,
|
|
361
384
|
this.worldAlpha,
|
|
385
|
+
this.parentHasRenderTexture,
|
|
386
|
+
this.framebufferDimensions,
|
|
362
387
|
);
|
|
363
388
|
}
|
|
364
389
|
|
|
@@ -25,6 +25,7 @@ import { ColorTexture } from './textures/ColorTexture.js';
|
|
|
25
25
|
import { ImageTexture } from './textures/ImageTexture.js';
|
|
26
26
|
import { NoiseTexture } from './textures/NoiseTexture.js';
|
|
27
27
|
import { SubTexture } from './textures/SubTexture.js';
|
|
28
|
+
import { RenderTexture } from './textures/RenderTexture.js';
|
|
28
29
|
import type { Texture } from './textures/Texture.js';
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -40,6 +41,7 @@ export interface TextureMap {
|
|
|
40
41
|
ImageTexture: typeof ImageTexture;
|
|
41
42
|
NoiseTexture: typeof NoiseTexture;
|
|
42
43
|
SubTexture: typeof SubTexture;
|
|
44
|
+
RenderTexture: typeof RenderTexture;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
export type ExtractProps<Type> = Type extends { z$__type__Props: infer Props }
|
|
@@ -173,6 +175,7 @@ export class CoreTextureManager {
|
|
|
173
175
|
this.registerTextureType('ColorTexture', ColorTexture);
|
|
174
176
|
this.registerTextureType('NoiseTexture', NoiseTexture);
|
|
175
177
|
this.registerTextureType('SubTexture', SubTexture);
|
|
178
|
+
this.registerTextureType('RenderTexture', RenderTexture);
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
registerTextureType<Type extends keyof TextureMap>(
|
package/src/core/Stage.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { startLoop, getTimeStamp } from './platform.js';
|
|
20
20
|
import { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js';
|
|
21
|
-
import { assertTruthy } from '../utils.js';
|
|
21
|
+
import { assertTruthy, setPremultiplyMode } from '../utils.js';
|
|
22
22
|
import { AnimationManager } from './animations/AnimationManager.js';
|
|
23
23
|
import { CoreNode } from './CoreNode.js';
|
|
24
24
|
import { CoreTextureManager } from './CoreTextureManager.js';
|
|
@@ -38,6 +38,11 @@ import type {
|
|
|
38
38
|
FrameTickPayload,
|
|
39
39
|
} from '../common/CommonTypes.js';
|
|
40
40
|
import { TextureMemoryManager } from './TextureMemoryManager.js';
|
|
41
|
+
import type {
|
|
42
|
+
CoreRenderer,
|
|
43
|
+
CoreRendererOptions,
|
|
44
|
+
} from './renderers/CoreRenderer.js';
|
|
45
|
+
import { CanvasCoreRenderer } from './renderers/canvas/CanvasCoreRenderer.js';
|
|
41
46
|
|
|
42
47
|
export interface StageOptions {
|
|
43
48
|
rootId: number;
|
|
@@ -52,6 +57,7 @@ export interface StageOptions {
|
|
|
52
57
|
fpsUpdateInterval: number;
|
|
53
58
|
enableContextSpy: boolean;
|
|
54
59
|
numImageWorkers: number;
|
|
60
|
+
renderMode: 'webgl' | 'canvas';
|
|
55
61
|
|
|
56
62
|
debug?: {
|
|
57
63
|
monitorTextureCache?: boolean;
|
|
@@ -79,7 +85,7 @@ export class Stage extends EventEmitter {
|
|
|
79
85
|
public readonly fontManager: TrFontManager;
|
|
80
86
|
public readonly textRenderers: Partial<TextRendererMap>;
|
|
81
87
|
public readonly shManager: CoreShaderManager;
|
|
82
|
-
public readonly renderer:
|
|
88
|
+
public readonly renderer: CoreRenderer;
|
|
83
89
|
public readonly root: CoreNode;
|
|
84
90
|
public readonly boundsMargin: [number, number, number, number];
|
|
85
91
|
|
|
@@ -110,6 +116,7 @@ export class Stage extends EventEmitter {
|
|
|
110
116
|
enableContextSpy,
|
|
111
117
|
numImageWorkers,
|
|
112
118
|
txMemByteThreshold,
|
|
119
|
+
renderMode,
|
|
113
120
|
} = options;
|
|
114
121
|
|
|
115
122
|
this.txManager = new CoreTextureManager(numImageWorkers);
|
|
@@ -135,7 +142,7 @@ export class Stage extends EventEmitter {
|
|
|
135
142
|
}, 1000);
|
|
136
143
|
}
|
|
137
144
|
|
|
138
|
-
|
|
145
|
+
const rendererOptions: CoreRendererOptions = {
|
|
139
146
|
stage: this,
|
|
140
147
|
canvas,
|
|
141
148
|
pixelRatio:
|
|
@@ -146,15 +153,27 @@ export class Stage extends EventEmitter {
|
|
|
146
153
|
txMemManager: this.txMemManager,
|
|
147
154
|
shManager: this.shManager,
|
|
148
155
|
contextSpy: this.contextSpy,
|
|
149
|
-
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (renderMode === 'canvas') {
|
|
159
|
+
this.renderer = new CanvasCoreRenderer(rendererOptions);
|
|
160
|
+
} else {
|
|
161
|
+
this.renderer = new WebGlCoreRenderer(rendererOptions);
|
|
162
|
+
}
|
|
163
|
+
setPremultiplyMode(renderMode);
|
|
150
164
|
|
|
151
165
|
// Must do this after renderer is created
|
|
152
166
|
this.txManager.renderer = this.renderer;
|
|
153
167
|
|
|
154
|
-
this.textRenderers =
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
168
|
+
this.textRenderers =
|
|
169
|
+
renderMode === 'webgl'
|
|
170
|
+
? {
|
|
171
|
+
canvas: new CanvasTextRenderer(this),
|
|
172
|
+
sdf: new SdfTextRenderer(this),
|
|
173
|
+
}
|
|
174
|
+
: {
|
|
175
|
+
canvas: new CanvasTextRenderer(this),
|
|
176
|
+
};
|
|
158
177
|
this.fontManager = new TrFontManager(this.textRenderers);
|
|
159
178
|
|
|
160
179
|
// create root node
|
|
@@ -192,6 +211,7 @@ export class Stage extends EventEmitter {
|
|
|
192
211
|
textureOptions: null,
|
|
193
212
|
shader: null,
|
|
194
213
|
shaderProps: null,
|
|
214
|
+
rtt: false,
|
|
195
215
|
});
|
|
196
216
|
|
|
197
217
|
this.root = rootNode;
|
|
@@ -237,17 +257,31 @@ export class Stage extends EventEmitter {
|
|
|
237
257
|
*/
|
|
238
258
|
drawFrame() {
|
|
239
259
|
const { renderer, renderRequested } = this;
|
|
260
|
+
assertTruthy(renderer);
|
|
240
261
|
|
|
241
262
|
// Update tree if needed
|
|
242
263
|
if (this.root.updateType !== 0) {
|
|
243
264
|
this.root.update(this.deltaTime, this.root.clippingRect);
|
|
244
265
|
}
|
|
245
266
|
|
|
246
|
-
//
|
|
247
|
-
renderer
|
|
267
|
+
// Reset render operations and clear the canvas
|
|
268
|
+
renderer.reset();
|
|
269
|
+
|
|
270
|
+
// Check if we need to garbage collect
|
|
271
|
+
if (renderer.txMemManager.gcRequested) {
|
|
272
|
+
renderer.txMemManager.gc();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// If we have RTT nodes draw them first
|
|
276
|
+
// So we can use them as textures in the main scene
|
|
277
|
+
if (renderer.rttNodes.length > 0) {
|
|
278
|
+
renderer.renderRTTNodes();
|
|
279
|
+
}
|
|
248
280
|
|
|
281
|
+
// Fill quads buffer
|
|
249
282
|
this.addQuads(this.root);
|
|
250
283
|
|
|
284
|
+
// Perform render pass
|
|
251
285
|
renderer?.render();
|
|
252
286
|
|
|
253
287
|
this.calculateFps();
|
|
@@ -22,6 +22,7 @@ export class TextureMemoryManager {
|
|
|
22
22
|
private memUsed = 0;
|
|
23
23
|
private textures: Map<CoreContextTexture, number> = new Map();
|
|
24
24
|
private threshold: number;
|
|
25
|
+
public gcRequested = false;
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* @param byteThreshold Number of texture bytes to trigger garbage collection
|
|
@@ -52,11 +53,12 @@ export class TextureMemoryManager {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
if (this.memUsed > this.threshold) {
|
|
55
|
-
this.
|
|
56
|
+
this.gcRequested = true;
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
gc() {
|
|
61
|
+
this.gcRequested = false;
|
|
60
62
|
this.textures.forEach((byteSize, ctxTexture) => {
|
|
61
63
|
if (!ctxTexture.renderable) {
|
|
62
64
|
ctxTexture.free();
|
|
@@ -23,9 +23,10 @@ type MessageCallback = [(value: any) => void, (reason: any) => void];
|
|
|
23
23
|
|
|
24
24
|
export class ImageWorkerManager {
|
|
25
25
|
imageWorkersEnabled = true;
|
|
26
|
-
messageManager: Record<
|
|
26
|
+
messageManager: Record<number, MessageCallback> = {};
|
|
27
27
|
workers: Worker[] = [];
|
|
28
28
|
workerIndex = 0;
|
|
29
|
+
nextId = 0;
|
|
29
30
|
|
|
30
31
|
constructor(numImageWorkers: number) {
|
|
31
32
|
this.workers = this.createWorkers(numImageWorkers);
|
|
@@ -35,15 +36,16 @@ export class ImageWorkerManager {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
private handleMessage(event: MessageEvent) {
|
|
38
|
-
const {
|
|
39
|
+
const { id, data, error } = event.data as {
|
|
40
|
+
id: number;
|
|
39
41
|
src: string;
|
|
40
42
|
data?: any;
|
|
41
43
|
error?: string;
|
|
42
44
|
};
|
|
43
|
-
const msg = this.messageManager[
|
|
45
|
+
const msg = this.messageManager[id];
|
|
44
46
|
if (msg) {
|
|
45
47
|
const [resolve, reject] = msg;
|
|
46
|
-
delete this.messageManager[
|
|
48
|
+
delete this.messageManager[id];
|
|
47
49
|
if (error) {
|
|
48
50
|
reject(new Error(error));
|
|
49
51
|
} else {
|
|
@@ -91,16 +93,17 @@ export class ImageWorkerManager {
|
|
|
91
93
|
});
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
self.onmessage =
|
|
96
|
+
self.onmessage = (event) => {
|
|
97
|
+
var id = event.data.id;
|
|
95
98
|
var src = event.data.src;
|
|
96
99
|
var premultiplyAlpha = event.data.premultiplyAlpha;
|
|
97
100
|
|
|
98
101
|
getImage(src, premultiplyAlpha)
|
|
99
102
|
.then(function(data) {
|
|
100
|
-
self.postMessage({
|
|
103
|
+
self.postMessage({ id: id, data: data }, [data.data]);
|
|
101
104
|
})
|
|
102
105
|
.catch(function(error) {
|
|
103
|
-
self.postMessage({
|
|
106
|
+
self.postMessage({ id: id, error: error.message });
|
|
104
107
|
});
|
|
105
108
|
};
|
|
106
109
|
`;
|
|
@@ -135,8 +138,10 @@ export class ImageWorkerManager {
|
|
|
135
138
|
try {
|
|
136
139
|
if (this.workers) {
|
|
137
140
|
const absoluteSrcUrl = this.convertUrlToAbsolute(src);
|
|
138
|
-
|
|
141
|
+
const id = this.nextId++;
|
|
142
|
+
this.messageManager[id] = [resolve, reject];
|
|
139
143
|
this.getNextWorker().postMessage({
|
|
144
|
+
id,
|
|
140
145
|
src: absoluteSrcUrl,
|
|
141
146
|
premultiplyAlpha,
|
|
142
147
|
});
|
|
@@ -75,6 +75,7 @@ export class WebGlContextWrapper {
|
|
|
75
75
|
public readonly RGBA;
|
|
76
76
|
public readonly UNSIGNED_BYTE;
|
|
77
77
|
public readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL;
|
|
78
|
+
public readonly UNPACK_FLIP_Y_WEBGL;
|
|
78
79
|
public readonly FLOAT;
|
|
79
80
|
public readonly TRIANGLES;
|
|
80
81
|
public readonly UNSIGNED_SHORT;
|
|
@@ -86,6 +87,7 @@ export class WebGlContextWrapper {
|
|
|
86
87
|
public readonly COMPILE_STATUS;
|
|
87
88
|
public readonly LINK_STATUS;
|
|
88
89
|
public readonly DYNAMIC_DRAW;
|
|
90
|
+
public readonly COLOR_ATTACHMENT0;
|
|
89
91
|
//#endregion WebGL Enums
|
|
90
92
|
|
|
91
93
|
constructor(private gl: WebGLRenderingContext | WebGL2RenderingContext) {
|
|
@@ -161,6 +163,7 @@ export class WebGlContextWrapper {
|
|
|
161
163
|
this.RGBA = gl.RGBA;
|
|
162
164
|
this.UNSIGNED_BYTE = gl.UNSIGNED_BYTE;
|
|
163
165
|
this.UNPACK_PREMULTIPLY_ALPHA_WEBGL = gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL;
|
|
166
|
+
this.UNPACK_FLIP_Y_WEBGL = gl.UNPACK_FLIP_Y_WEBGL;
|
|
164
167
|
this.FLOAT = gl.FLOAT;
|
|
165
168
|
this.TRIANGLES = gl.TRIANGLES;
|
|
166
169
|
this.UNSIGNED_SHORT = gl.UNSIGNED_SHORT;
|
|
@@ -175,6 +178,7 @@ export class WebGlContextWrapper {
|
|
|
175
178
|
this.COMPILE_STATUS = gl.COMPILE_STATUS;
|
|
176
179
|
this.LINK_STATUS = gl.LINK_STATUS;
|
|
177
180
|
this.DYNAMIC_DRAW = gl.DYNAMIC_DRAW;
|
|
181
|
+
this.COLOR_ATTACHMENT0 = gl.COLOR_ATTACHMENT0;
|
|
178
182
|
}
|
|
179
183
|
/**
|
|
180
184
|
* Returns true if the WebGL context is WebGL2
|
|
@@ -533,7 +537,7 @@ export class WebGlContextWrapper {
|
|
|
533
537
|
|
|
534
538
|
/**
|
|
535
539
|
* ```
|
|
536
|
-
* createBuffer();
|
|
540
|
+
* gl.createBuffer();
|
|
537
541
|
* ```
|
|
538
542
|
*
|
|
539
543
|
* @returns
|
|
@@ -543,6 +547,52 @@ export class WebGlContextWrapper {
|
|
|
543
547
|
return gl.createBuffer();
|
|
544
548
|
}
|
|
545
549
|
|
|
550
|
+
/**
|
|
551
|
+
* ```
|
|
552
|
+
* gl.createFramebuffer();
|
|
553
|
+
* ```
|
|
554
|
+
* @returns
|
|
555
|
+
*/
|
|
556
|
+
createFramebuffer() {
|
|
557
|
+
const { gl } = this;
|
|
558
|
+
return gl.createFramebuffer();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* ```
|
|
563
|
+
* gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
564
|
+
* ```
|
|
565
|
+
*
|
|
566
|
+
* @param framebuffer
|
|
567
|
+
*/
|
|
568
|
+
bindFramebuffer(framebuffer: WebGLFramebuffer | null) {
|
|
569
|
+
const { gl } = this;
|
|
570
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* ```
|
|
575
|
+
* gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
576
|
+
* ```
|
|
577
|
+
* @remarks
|
|
578
|
+
* **WebGL Difference**: Bind target is always `gl.FRAMEBUFFER` and textarget is always `gl.TEXTURE_2D`
|
|
579
|
+
*/
|
|
580
|
+
|
|
581
|
+
framebufferTexture2D(
|
|
582
|
+
attachment: GLenum,
|
|
583
|
+
texture: WebGLTexture | null,
|
|
584
|
+
level: GLint,
|
|
585
|
+
) {
|
|
586
|
+
const { gl } = this;
|
|
587
|
+
gl.framebufferTexture2D(
|
|
588
|
+
gl.FRAMEBUFFER,
|
|
589
|
+
attachment,
|
|
590
|
+
gl.TEXTURE_2D,
|
|
591
|
+
texture,
|
|
592
|
+
level,
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
|
|
546
596
|
/**
|
|
547
597
|
* ```
|
|
548
598
|
* gl.clear(gl.COLOR_BUFFER_BIT);
|