@flighthq/displayobject-gl 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/glBitmap.d.ts +4 -0
- package/dist/glBitmap.d.ts.map +1 -0
- package/dist/glBitmap.js +106 -0
- package/dist/glBitmap.js.map +1 -0
- package/dist/glCache.d.ts +30 -0
- package/dist/glCache.d.ts.map +1 -0
- package/dist/glCache.js +185 -0
- package/dist/glCache.js.map +1 -0
- package/dist/glClip.d.ts +3 -0
- package/dist/glClip.d.ts.map +1 -0
- package/dist/glClip.js +46 -0
- package/dist/glClip.js.map +1 -0
- package/dist/glClipContours.d.ts +4 -0
- package/dist/glClipContours.d.ts.map +1 -0
- package/dist/glClipContours.js +148 -0
- package/dist/glClipContours.js.map +1 -0
- package/dist/glClipRectangle.d.ts +4 -0
- package/dist/glClipRectangle.d.ts.map +1 -0
- package/dist/glClipRectangle.js +68 -0
- package/dist/glClipRectangle.js.map +1 -0
- package/dist/glColorTransformMaterial.d.ts +4 -0
- package/dist/glColorTransformMaterial.d.ts.map +1 -0
- package/dist/glColorTransformMaterial.js +116 -0
- package/dist/glColorTransformMaterial.js.map +1 -0
- package/dist/glDefaultMaterial.d.ts +4 -0
- package/dist/glDefaultMaterial.d.ts.map +1 -0
- package/dist/glDefaultMaterial.js +20 -0
- package/dist/glDefaultMaterial.js.map +1 -0
- package/dist/glDisplayObject.d.ts +5 -0
- package/dist/glDisplayObject.d.ts.map +1 -0
- package/dist/glDisplayObject.js +41 -0
- package/dist/glDisplayObject.js.map +1 -0
- package/dist/glDisplayObjectRegistration.d.ts +25 -0
- package/dist/glDisplayObjectRegistration.d.ts.map +1 -0
- package/dist/glDisplayObjectRegistration.js +51 -0
- package/dist/glDisplayObjectRegistration.js.map +1 -0
- package/dist/glMaterials.d.ts +4 -0
- package/dist/glMaterials.d.ts.map +1 -0
- package/dist/glMaterials.js +97 -0
- package/dist/glMaterials.js.map +1 -0
- package/dist/glParticleEmitter.d.ts +4 -0
- package/dist/glParticleEmitter.d.ts.map +1 -0
- package/dist/glParticleEmitter.js +258 -0
- package/dist/glParticleEmitter.js.map +1 -0
- package/dist/glQuadBatch.d.ts +3 -0
- package/dist/glQuadBatch.d.ts.map +1 -0
- package/dist/glQuadBatch.js +88 -0
- package/dist/glQuadBatch.js.map +1 -0
- package/dist/glRichText.d.ts +9 -0
- package/dist/glRichText.d.ts.map +1 -0
- package/dist/glRichText.js +149 -0
- package/dist/glRichText.js.map +1 -0
- package/dist/glScale9Mapper.d.ts +3 -0
- package/dist/glScale9Mapper.d.ts.map +1 -0
- package/dist/glScale9Mapper.js +37 -0
- package/dist/glScale9Mapper.js.map +1 -0
- package/dist/glScale9Shape.d.ts +9 -0
- package/dist/glScale9Shape.d.ts.map +1 -0
- package/dist/glScale9Shape.js +118 -0
- package/dist/glScale9Shape.js.map +1 -0
- package/dist/glShape.d.ts +4 -0
- package/dist/glShape.d.ts.map +1 -0
- package/dist/glShape.js +125 -0
- package/dist/glShape.js.map +1 -0
- package/dist/glShapeMesh.d.ts +9 -0
- package/dist/glShapeMesh.d.ts.map +1 -0
- package/dist/glShapeMesh.js +90 -0
- package/dist/glShapeMesh.js.map +1 -0
- package/dist/glSprite.d.ts +3 -0
- package/dist/glSprite.d.ts.map +1 -0
- package/dist/glSprite.js +28 -0
- package/dist/glSprite.js.map +1 -0
- package/dist/glSpriteBatch.d.ts +11 -0
- package/dist/glSpriteBatch.d.ts.map +1 -0
- package/dist/glSpriteBatch.js +241 -0
- package/dist/glSpriteBatch.js.map +1 -0
- package/dist/glSpriteRenderer.d.ts +3 -0
- package/dist/glSpriteRenderer.d.ts.map +1 -0
- package/dist/glSpriteRenderer.js +50 -0
- package/dist/glSpriteRenderer.js.map +1 -0
- package/dist/glTestHelper.d.ts +9 -0
- package/dist/glTestHelper.d.ts.map +1 -0
- package/dist/glTestHelper.js +17 -0
- package/dist/glTestHelper.js.map +1 -0
- package/dist/glTextInput.d.ts +4 -0
- package/dist/glTextInput.d.ts.map +1 -0
- package/dist/glTextInput.js +43 -0
- package/dist/glTextInput.js.map +1 -0
- package/dist/glTextLabel.d.ts +4 -0
- package/dist/glTextLabel.d.ts.map +1 -0
- package/dist/glTextLabel.js +130 -0
- package/dist/glTextLabel.js.map +1 -0
- package/dist/glTilemap.d.ts +3 -0
- package/dist/glTilemap.d.ts.map +1 -0
- package/dist/glTilemap.js +74 -0
- package/dist/glTilemap.js.map +1 -0
- package/dist/glUniformColorTransformMaterial.d.ts +4 -0
- package/dist/glUniformColorTransformMaterial.d.ts.map +1 -0
- package/dist/glUniformColorTransformMaterial.js +56 -0
- package/dist/glUniformColorTransformMaterial.js.map +1 -0
- package/dist/glVelocity.d.ts +22 -0
- package/dist/glVelocity.d.ts.map +1 -0
- package/dist/glVelocity.js +319 -0
- package/dist/glVelocity.js.map +1 -0
- package/dist/glVideo.d.ts +6 -0
- package/dist/glVideo.d.ts.map +1 -0
- package/dist/glVideo.js +60 -0
- package/dist/glVideo.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/moduleMockTestHelper.d.ts +15 -0
- package/dist/moduleMockTestHelper.d.ts.map +1 -0
- package/dist/moduleMockTestHelper.js +25 -0
- package/dist/moduleMockTestHelper.js.map +1 -0
- package/package.json +51 -0
- package/src/glBitmap.test.ts +128 -0
- package/src/glCache.test.ts +230 -0
- package/src/glClip.test.ts +101 -0
- package/src/glClipContours.test.ts +61 -0
- package/src/glClipRectangle.test.ts +47 -0
- package/src/glColorTransformMaterial.test.ts +45 -0
- package/src/glDefaultMaterial.test.ts +19 -0
- package/src/glDisplayObject.test.ts +85 -0
- package/src/glDisplayObjectRegistration.test.ts +130 -0
- package/src/glMaterials.test.ts +91 -0
- package/src/glParticleEmitter.test.ts +98 -0
- package/src/glQuadBatch.test.ts +132 -0
- package/src/glRichText.test.ts +135 -0
- package/src/glScale9Mapper.test.ts +20 -0
- package/src/glScale9Shape.test.ts +90 -0
- package/src/glShape.test.ts +115 -0
- package/src/glShapeMesh.test.ts +64 -0
- package/src/glSprite.test.ts +79 -0
- package/src/glSpriteBatch.test.ts +153 -0
- package/src/glSpriteRenderer.test.ts +75 -0
- package/src/glTextInput.test.ts +51 -0
- package/src/glTextLabel.test.ts +151 -0
- package/src/glTilemap.test.ts +127 -0
- package/src/glUniformColorTransformMaterial.test.ts +24 -0
- package/src/glVelocity.test.ts +155 -0
- package/src/glVideo.test.ts +65 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DisplayObjectRenderer, GlRenderState, RenderProxy2D } from '@flighthq/types';
|
|
2
|
+
export declare function drawGlBitmap(state: GlRenderState, renderProxy: RenderProxy2D): void;
|
|
3
|
+
export declare const defaultGlBitmapRenderer: DisplayObjectRenderer;
|
|
4
|
+
//# sourceMappingURL=glBitmap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBitmap.d.ts","sourceRoot":"","sources":["../src/glBitmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,qBAAqB,EACrB,aAAa,EAGb,aAAa,EACd,MAAM,iBAAiB,CAAC;AA2BzB,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAuFnF;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAKrC,CAAC"}
|
package/dist/glBitmap.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { resolveGlMaterialRenderer } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlRenderStateRuntime } from '@flighthq/render-gl';
|
|
3
|
+
import { BatchFormat } from '@flighthq/types';
|
|
4
|
+
import { ensureGlQuadBatchShader, packGlSpriteBatchMaterialInstance, prepareGlSpriteBatchWrite } from './glSpriteBatch';
|
|
5
|
+
function createGlBitmapData(_state, _source) {
|
|
6
|
+
return { lastSrc: null, lastVersion: -1 };
|
|
7
|
+
}
|
|
8
|
+
// Deletes the cached GPU texture when this bitmap is torn down. Prevents textures from leaking when
|
|
9
|
+
// a bitmap is removed from the scene via disposeDisplayObjectRender.
|
|
10
|
+
function destroyGlBitmapData(state, data) {
|
|
11
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
12
|
+
const { lastSrc } = data;
|
|
13
|
+
if (lastSrc === null)
|
|
14
|
+
return;
|
|
15
|
+
const texture = runtime.textureCache.get(lastSrc);
|
|
16
|
+
if (texture !== undefined) {
|
|
17
|
+
state.gl.deleteTexture(texture);
|
|
18
|
+
runtime.textureCache.delete(lastSrc);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function drawGlBitmap(state, renderProxy) {
|
|
22
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
23
|
+
const source = renderProxy.source;
|
|
24
|
+
const imageSource = source.data.image;
|
|
25
|
+
if (imageSource === null || imageSource.source === null)
|
|
26
|
+
return;
|
|
27
|
+
if (renderProxy.rendererData === null)
|
|
28
|
+
return;
|
|
29
|
+
const bitmapData = renderProxy.rendererData;
|
|
30
|
+
const src = imageSource.source;
|
|
31
|
+
const version = imageSource.version;
|
|
32
|
+
// Invalidate the cached GPU texture when the image content changes in place (Surface edits) or
|
|
33
|
+
// when the element reference is replaced (setBitmapImage). Both cases bump imageSource.version.
|
|
34
|
+
if (bitmapData.lastVersion !== version || bitmapData.lastSrc !== src) {
|
|
35
|
+
if (bitmapData.lastSrc !== null && bitmapData.lastSrc !== src) {
|
|
36
|
+
const oldTexture = runtime.textureCache.get(bitmapData.lastSrc);
|
|
37
|
+
if (oldTexture !== undefined) {
|
|
38
|
+
state.gl.deleteTexture(oldTexture);
|
|
39
|
+
runtime.textureCache.delete(bitmapData.lastSrc);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const staleTexture = runtime.textureCache.get(src);
|
|
43
|
+
if (staleTexture !== undefined) {
|
|
44
|
+
state.gl.deleteTexture(staleTexture);
|
|
45
|
+
runtime.textureCache.delete(src);
|
|
46
|
+
}
|
|
47
|
+
bitmapData.lastSrc = src;
|
|
48
|
+
bitmapData.lastVersion = version;
|
|
49
|
+
}
|
|
50
|
+
const material = renderProxy.material;
|
|
51
|
+
const materialRenderer = resolveGlMaterialRenderer(state, material);
|
|
52
|
+
if (materialRenderer === null)
|
|
53
|
+
return;
|
|
54
|
+
ensureGlQuadBatchShader(state);
|
|
55
|
+
const sr = source.data.sourceRectangle ?? null;
|
|
56
|
+
const iw = 1 / (imageSource.width || 1);
|
|
57
|
+
const ih = 1 / (imageSource.height || 1);
|
|
58
|
+
let w;
|
|
59
|
+
let h;
|
|
60
|
+
let u0;
|
|
61
|
+
let v0;
|
|
62
|
+
let u1;
|
|
63
|
+
let v1;
|
|
64
|
+
if (sr === null) {
|
|
65
|
+
w = imageSource.width;
|
|
66
|
+
h = imageSource.height;
|
|
67
|
+
u0 = 0;
|
|
68
|
+
v0 = 0;
|
|
69
|
+
u1 = 1;
|
|
70
|
+
v1 = 1;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
w = sr.width;
|
|
74
|
+
h = sr.height;
|
|
75
|
+
u0 = sr.x * iw;
|
|
76
|
+
v0 = sr.y * ih;
|
|
77
|
+
u1 = (sr.x + sr.width) * iw;
|
|
78
|
+
v1 = (sr.y + sr.height) * ih;
|
|
79
|
+
}
|
|
80
|
+
const startCount = runtime.spriteBatchCount;
|
|
81
|
+
const base = prepareGlSpriteBatchWrite(state, imageSource.source, renderProxy.blendMode, material, materialRenderer, 1);
|
|
82
|
+
const d = runtime.spriteBatchInstanceData;
|
|
83
|
+
const t = renderProxy.transform2D;
|
|
84
|
+
d[base] = t.a;
|
|
85
|
+
d[base + 1] = t.b;
|
|
86
|
+
d[base + 2] = t.c;
|
|
87
|
+
d[base + 3] = t.d;
|
|
88
|
+
d[base + 4] = t.tx;
|
|
89
|
+
d[base + 5] = t.ty;
|
|
90
|
+
d[base + 6] = w;
|
|
91
|
+
d[base + 7] = h;
|
|
92
|
+
d[base + 8] = u0;
|
|
93
|
+
d[base + 9] = v0;
|
|
94
|
+
d[base + 10] = u1;
|
|
95
|
+
d[base + 11] = v1;
|
|
96
|
+
d[base + 12] = renderProxy.alpha;
|
|
97
|
+
packGlSpriteBatchMaterialInstance(state, renderProxy.materialData, startCount);
|
|
98
|
+
runtime.spriteBatchCount++;
|
|
99
|
+
}
|
|
100
|
+
export const defaultGlBitmapRenderer = {
|
|
101
|
+
format: BatchFormat.Quad,
|
|
102
|
+
createData: createGlBitmapData,
|
|
103
|
+
destroyData: destroyGlBitmapData,
|
|
104
|
+
submit: drawGlBitmap,
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=glBitmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBitmap.js","sourceRoot":"","sources":["../src/glBitmap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DisplayObject, DisplayObjectRenderer, GlRenderState, GlRenderTarget, RenderCache, RenderCacheRefreshOptions } from '@flighthq/types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an offscreen render state for baking render caches consumed by `screenState`.
|
|
4
|
+
*
|
|
5
|
+
* Gl textures and framebuffers cannot cross GL contexts, so — unlike the canvas backend —
|
|
6
|
+
* this offscreen state must share the screen state's GL context and every context-bound
|
|
7
|
+
* resource (shaders, buffers, the uploaded-texture cache). What it keeps separate is the
|
|
8
|
+
* scene-graph bookkeeping: its own render node map, adapter map, and frame counter, so baking
|
|
9
|
+
* neither substitutes a cache into itself nor disturbs the screen state's nodes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createGlCacheState(screenState: GlRenderState): GlRenderState;
|
|
12
|
+
export declare function enableGlRenderCache(state: GlRenderState): void;
|
|
13
|
+
/**
|
|
14
|
+
* Allocates or resizes the framebuffer-backed texture `screenState` composites for `cache`,
|
|
15
|
+
* returning it so a caller can render custom content into it directly. For engine-baked
|
|
16
|
+
* content prefer refreshGlRenderCache.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureGlRenderCacheTarget(state: GlRenderState, cache: RenderCache, width: number, height: number): GlRenderTarget;
|
|
19
|
+
export declare function getGlRenderCacheTarget(state: GlRenderState, cache: RenderCache): GlRenderTarget | null;
|
|
20
|
+
/**
|
|
21
|
+
* Bakes `source`'s subtree into its cache target using the offscreen `cacheState`, then records
|
|
22
|
+
* the transform that places the result back in scene space. Returns whether a bake happened —
|
|
23
|
+
* the offscreen state's own dirtiness decides it (honoring its sceneGraphSyncPolicy), so this is
|
|
24
|
+
* cheap to call every frame. Because the bake runs on the shared GL context, the screen state's
|
|
25
|
+
* cached GL state is reset afterward so it re-establishes cleanly on its next draw.
|
|
26
|
+
*/
|
|
27
|
+
export declare function refreshGlRenderCache(cacheState: GlRenderState, cache: RenderCache, source: DisplayObject, options?: Readonly<RenderCacheRefreshOptions>): boolean;
|
|
28
|
+
export declare function releaseGlRenderCache(state: GlRenderState, cache: RenderCache): void;
|
|
29
|
+
export declare const defaultGlRenderCacheRenderer: DisplayObjectRenderer;
|
|
30
|
+
//# sourceMappingURL=glCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glCache.d.ts","sourceRoot":"","sources":["../src/glCache.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,cAAc,EAEd,WAAW,EACX,yBAAyB,EAE1B,MAAM,iBAAiB,CAAC;AAMzB;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,aAAa,GAAG,aAAa,CA4D5E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,cAAc,CAUhB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,GAAG,cAAc,GAAG,IAAI,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAC5C,OAAO,CAwCT;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAOnF;AA0BD,eAAO,MAAM,4BAA4B,EAAE,qBAG1C,CAAC"}
|
package/dist/glCache.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { createMatrix, createRectangle } from '@flighthq/geometry';
|
|
2
|
+
import { computeNodeBoundsRectangle } from '@flighthq/node';
|
|
3
|
+
import { computeDisplayObjectRenderTargetTransform, computeRenderCacheTransform, computeRenderTargetSize, copyAllRenderersFromRenderState, createRenderState, getRenderProxyCache, noopRendererData, prepareDisplayObjectRender, registerRenderCacheRenderer, } from '@flighthq/render';
|
|
4
|
+
import { createGlRenderStateRuntime, getGlRenderStateRuntime } from '@flighthq/render-gl';
|
|
5
|
+
import { beginGlRenderTarget, createGlRenderTarget, destroyGlRenderTarget, drawGlRenderTargetResult, endGlRenderTarget, resizeGlRenderTarget, } from '@flighthq/render-gl';
|
|
6
|
+
import { EntityRuntimeKey } from '@flighthq/types';
|
|
7
|
+
import { renderGlDisplayObject } from './glDisplayObject';
|
|
8
|
+
import { flushGlSpriteBatch } from './glSpriteBatch';
|
|
9
|
+
/**
|
|
10
|
+
* Creates an offscreen render state for baking render caches consumed by `screenState`.
|
|
11
|
+
*
|
|
12
|
+
* Gl textures and framebuffers cannot cross GL contexts, so — unlike the canvas backend —
|
|
13
|
+
* this offscreen state must share the screen state's GL context and every context-bound
|
|
14
|
+
* resource (shaders, buffers, the uploaded-texture cache). What it keeps separate is the
|
|
15
|
+
* scene-graph bookkeeping: its own render node map, adapter map, and frame counter, so baking
|
|
16
|
+
* neither substitutes a cache into itself nor disturbs the screen state's nodes.
|
|
17
|
+
*/
|
|
18
|
+
export function createGlCacheState(screenState) {
|
|
19
|
+
const screenRuntime = getGlRenderStateRuntime(screenState);
|
|
20
|
+
const cacheState = createRenderState({
|
|
21
|
+
allowSmoothing: screenState.allowSmoothing,
|
|
22
|
+
pixelRatio: screenState.pixelRatio,
|
|
23
|
+
renderTransform2D: createMatrix(),
|
|
24
|
+
roundPixels: screenState.roundPixels,
|
|
25
|
+
sceneGraphSyncPolicy: screenState.sceneGraphSyncPolicy,
|
|
26
|
+
});
|
|
27
|
+
// Attach the cache runtime before copying renderers: copyAllRenderersFromRenderState registers
|
|
28
|
+
// into the runtime's rendererMap, so the backend runtime must already be installed.
|
|
29
|
+
const cacheRuntime = createGlRenderStateRuntime();
|
|
30
|
+
cacheState[EntityRuntimeKey] = cacheRuntime;
|
|
31
|
+
copyAllRenderersFromRenderState(cacheState, screenState);
|
|
32
|
+
cacheState.applyBlendMode = screenState.applyBlendMode;
|
|
33
|
+
cacheState.canvas = screenState.canvas;
|
|
34
|
+
cacheState.gl = screenState.gl;
|
|
35
|
+
cacheRuntime.defaultBitmapShader = screenRuntime.defaultBitmapShader;
|
|
36
|
+
cacheRuntime.colorTransformBitmapShader = screenRuntime.colorTransformBitmapShader;
|
|
37
|
+
cacheRuntime.particleShader = screenRuntime.particleShader;
|
|
38
|
+
cacheRuntime.particleCornerBuffer = screenRuntime.particleCornerBuffer;
|
|
39
|
+
cacheRuntime.particleInstanceBuffer = screenRuntime.particleInstanceBuffer;
|
|
40
|
+
cacheRuntime.particleInstanceData = screenRuntime.particleInstanceData;
|
|
41
|
+
cacheRuntime.quadBatchShader = screenRuntime.quadBatchShader;
|
|
42
|
+
cacheRuntime.quadBatchCornerBuffer = screenRuntime.quadBatchCornerBuffer;
|
|
43
|
+
cacheRuntime.colorTransformInstancedShader = screenRuntime.colorTransformInstancedShader;
|
|
44
|
+
cacheRuntime.uniformColorTransformShader = screenRuntime.uniformColorTransformShader;
|
|
45
|
+
cacheRuntime.materialRendererMap = screenRuntime.materialRendererMap;
|
|
46
|
+
cacheRuntime.materialBitmapShaderMap = screenRuntime.materialBitmapShaderMap;
|
|
47
|
+
cacheRuntime.shaderLoc = screenRuntime.shaderLoc;
|
|
48
|
+
cacheRuntime.textureCache = screenRuntime.textureCache;
|
|
49
|
+
cacheRuntime.quadVertexBuffer = screenRuntime.quadVertexBuffer;
|
|
50
|
+
cacheRuntime.quadIndexBuffer = screenRuntime.quadIndexBuffer;
|
|
51
|
+
cacheRuntime.quadVertexData = screenRuntime.quadVertexData;
|
|
52
|
+
cacheRuntime.matrixArray = screenRuntime.matrixArray;
|
|
53
|
+
cacheRuntime.currentBlendMode = null;
|
|
54
|
+
cacheRuntime.currentFramebuffer = null;
|
|
55
|
+
cacheRuntime.currentMaskDepth = 0;
|
|
56
|
+
cacheRuntime.currentProgram = null;
|
|
57
|
+
cacheRuntime.currentScissorRect = null;
|
|
58
|
+
cacheRuntime.currentTexture = null;
|
|
59
|
+
cacheRuntime.renderTargetViewport = null;
|
|
60
|
+
cacheRuntime.scissorStack = [];
|
|
61
|
+
cacheRuntime.spriteBatchBlendMode = null;
|
|
62
|
+
cacheRuntime.spriteBatchMaterial = null;
|
|
63
|
+
cacheRuntime.spriteBatchMaterialRenderer = null;
|
|
64
|
+
cacheRuntime.spriteBatchMaterialFloats = 0;
|
|
65
|
+
cacheRuntime.spriteBatchMaterialData = new Float32Array(0);
|
|
66
|
+
cacheRuntime.spriteBatchMaterialBuffer = null;
|
|
67
|
+
cacheRuntime.spriteBatchCount = 0;
|
|
68
|
+
cacheRuntime.spriteBatchInstanceBuffer = null;
|
|
69
|
+
cacheRuntime.spriteBatchInstanceData = new Float32Array(0);
|
|
70
|
+
cacheRuntime.spriteBatchTexture = null;
|
|
71
|
+
_cacheStateScreen.set(cacheState, screenState);
|
|
72
|
+
return cacheState;
|
|
73
|
+
}
|
|
74
|
+
export function enableGlRenderCache(state) {
|
|
75
|
+
registerRenderCacheRenderer(state, defaultGlRenderCacheRenderer);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Allocates or resizes the framebuffer-backed texture `screenState` composites for `cache`,
|
|
79
|
+
* returning it so a caller can render custom content into it directly. For engine-baked
|
|
80
|
+
* content prefer refreshGlRenderCache.
|
|
81
|
+
*/
|
|
82
|
+
export function ensureGlRenderCacheTarget(state, cache, width, height) {
|
|
83
|
+
const targets = getTargets(state);
|
|
84
|
+
let target = targets.get(cache);
|
|
85
|
+
if (target === undefined) {
|
|
86
|
+
target = createGlRenderTarget(state, { width, height });
|
|
87
|
+
targets.set(cache, target);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
resizeGlRenderTarget(state, target, width, height);
|
|
91
|
+
}
|
|
92
|
+
return target;
|
|
93
|
+
}
|
|
94
|
+
export function getGlRenderCacheTarget(state, cache) {
|
|
95
|
+
return getTargets(state).get(cache) ?? null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Bakes `source`'s subtree into its cache target using the offscreen `cacheState`, then records
|
|
99
|
+
* the transform that places the result back in scene space. Returns whether a bake happened —
|
|
100
|
+
* the offscreen state's own dirtiness decides it (honoring its sceneGraphSyncPolicy), so this is
|
|
101
|
+
* cheap to call every frame. Because the bake runs on the shared GL context, the screen state's
|
|
102
|
+
* cached GL state is reset afterward so it re-establishes cleanly on its next draw.
|
|
103
|
+
*/
|
|
104
|
+
export function refreshGlRenderCache(cacheState, cache, source, options) {
|
|
105
|
+
const screenState = _cacheStateScreen.get(cacheState) ?? cacheState;
|
|
106
|
+
const padding = options?.padding ?? 0;
|
|
107
|
+
const minWidth = options?.minWidth ?? 1;
|
|
108
|
+
const minHeight = options?.minHeight ?? 1;
|
|
109
|
+
computeNodeBoundsRectangle(_bounds, source, source);
|
|
110
|
+
const { width, height } = computeRenderTargetSize(_bounds, padding, minWidth, minHeight);
|
|
111
|
+
const existing = getGlRenderCacheTarget(screenState, cache);
|
|
112
|
+
const resized = existing === null || existing.width !== width || existing.height !== height;
|
|
113
|
+
const target = ensureGlRenderCacheTarget(screenState, cache, width, height);
|
|
114
|
+
computeDisplayObjectRenderTargetTransform(_renderTransform, source, _bounds, padding, padding);
|
|
115
|
+
computeRenderCacheTransform(cache.transform, _bounds, padding, padding);
|
|
116
|
+
beginGlRenderTarget(cacheState, target, _renderTransform);
|
|
117
|
+
const dirty = prepareDisplayObjectRender(cacheState, source);
|
|
118
|
+
if (dirty || resized) {
|
|
119
|
+
const cacheRuntime = getGlRenderStateRuntime(cacheState);
|
|
120
|
+
// The cache state shares the screen's GL context, so the actual GL program/blend/scissor are
|
|
121
|
+
// whatever the screen render (or a prior blur pass) last left — state this cache state does not
|
|
122
|
+
// track. Reset its cached GL state so the bake re-establishes everything instead of skipping a
|
|
123
|
+
// rebind and setting uniforms on the wrong program.
|
|
124
|
+
cacheRuntime.currentProgram = null;
|
|
125
|
+
cacheRuntime.currentTexture = null;
|
|
126
|
+
cacheRuntime.currentBlendMode = null;
|
|
127
|
+
cacheRuntime.currentScissorRect = null;
|
|
128
|
+
cacheState.gl.clearColor(0, 0, 0, 0);
|
|
129
|
+
cacheState.gl.clear(cacheState.gl.COLOR_BUFFER_BIT);
|
|
130
|
+
renderGlDisplayObject(cacheState, source);
|
|
131
|
+
}
|
|
132
|
+
endGlRenderTarget(cacheState);
|
|
133
|
+
const screenRuntime = getGlRenderStateRuntime(screenState);
|
|
134
|
+
screenRuntime.currentBlendMode = null;
|
|
135
|
+
screenRuntime.currentProgram = null;
|
|
136
|
+
screenRuntime.currentScissorRect = null;
|
|
137
|
+
screenRuntime.currentTexture = null;
|
|
138
|
+
return dirty || resized;
|
|
139
|
+
}
|
|
140
|
+
export function releaseGlRenderCache(state, cache) {
|
|
141
|
+
const targets = getTargets(state);
|
|
142
|
+
const target = targets.get(cache);
|
|
143
|
+
if (target === undefined)
|
|
144
|
+
return;
|
|
145
|
+
// A GlRenderTarget owns a framebuffer and texture; GC will not free them.
|
|
146
|
+
destroyGlRenderTarget(state, target);
|
|
147
|
+
targets.delete(cache);
|
|
148
|
+
}
|
|
149
|
+
function drawGlRenderCache(state, renderProxy) {
|
|
150
|
+
const cache = getRenderProxyCache(state, renderProxy.source);
|
|
151
|
+
if (cache === null)
|
|
152
|
+
return;
|
|
153
|
+
const target = getTargets(state).get(cache);
|
|
154
|
+
if (target === undefined)
|
|
155
|
+
return;
|
|
156
|
+
// Drain pending batched geometry before the immediate composite quad. Like every other
|
|
157
|
+
// immediate-draw renderer (RichText, Video, Scale9), this bypasses the sprite batch; without the
|
|
158
|
+
// flush the cached result draws ahead of geometry submitted earlier in the walk, which only
|
|
159
|
+
// flushes at the end — producing out-of-order replay (a doubled image on Gl).
|
|
160
|
+
flushGlSpriteBatch(state);
|
|
161
|
+
// renderProxy.transform2D already carries the cache placement transform (folded in by the
|
|
162
|
+
// adapter), so the target composites with an identity offset.
|
|
163
|
+
drawGlRenderTargetResult(state, renderProxy, target, _identity);
|
|
164
|
+
}
|
|
165
|
+
function getTargets(state) {
|
|
166
|
+
let targets = _renderCacheTargets.get(state);
|
|
167
|
+
if (targets === undefined) {
|
|
168
|
+
targets = new WeakMap();
|
|
169
|
+
_renderCacheTargets.set(state, targets);
|
|
170
|
+
}
|
|
171
|
+
return targets;
|
|
172
|
+
}
|
|
173
|
+
export const defaultGlRenderCacheRenderer = {
|
|
174
|
+
createData: noopRendererData,
|
|
175
|
+
submit: drawGlRenderCache,
|
|
176
|
+
};
|
|
177
|
+
// The screen state owns each cache's target, keyed by the handle, so one handle can be
|
|
178
|
+
// composited by several states without the handle carrying a backend resource.
|
|
179
|
+
const _renderCacheTargets = new WeakMap();
|
|
180
|
+
// Links an offscreen cache state back to the screen state whose targets it bakes into.
|
|
181
|
+
const _cacheStateScreen = new WeakMap();
|
|
182
|
+
const _bounds = createRectangle();
|
|
183
|
+
const _renderTransform = createMatrix();
|
|
184
|
+
const _identity = createMatrix();
|
|
185
|
+
//# sourceMappingURL=glCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glCache.js","sourceRoot":"","sources":["../src/glCache.ts"],"names":[],"mappings":"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"}
|
package/dist/glClip.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glClip.d.ts","sourceRoot":"","sources":["../src/glClip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAyC,aAAa,EAAiB,MAAM,iBAAiB,CAAC;AAO3G,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE9D"}
|
package/dist/glClip.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getGlRenderStateRuntime } from '@flighthq/render-gl';
|
|
2
|
+
import { popGlClipContours, pushGlClipContours } from './glClipContours';
|
|
3
|
+
import { popGlClipRectangle, pushGlClipRectangle } from './glClipRectangle';
|
|
4
|
+
// Clip support installs the unified clip hooks. Masks are RETIRED — a former mask is now a path
|
|
5
|
+
// ClipRegion (createClipRegionFromPath + setDisplayObjectClip), realized by the contour stencil below.
|
|
6
|
+
export function enableGlClipSupport(state) {
|
|
7
|
+
state.displayObjectClipHooks = webglClipHooks;
|
|
8
|
+
}
|
|
9
|
+
// A clip is realized as a scissor (rect form) or stencil-then-cover (contour form). These are
|
|
10
|
+
// independent hardware gates that AND together when nested. `clipForms` records each pushed clip's
|
|
11
|
+
// form so the depth-driven unwind un-installs the right gate.
|
|
12
|
+
function popOneGlClip(state) {
|
|
13
|
+
const form = getGlRenderStateRuntime(state).clipForms.pop();
|
|
14
|
+
if (form === 'contour')
|
|
15
|
+
popGlClipContours(state);
|
|
16
|
+
else
|
|
17
|
+
popGlClipRectangle(state);
|
|
18
|
+
}
|
|
19
|
+
const webglClipHooks = {
|
|
20
|
+
finalize(state) {
|
|
21
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
22
|
+
while (runtime.clipForms.length > 0)
|
|
23
|
+
popOneGlClip(state);
|
|
24
|
+
},
|
|
25
|
+
popClip(state, data, source) {
|
|
26
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
27
|
+
const target = data.clipDepth - (source.clip != null ? 1 : 0);
|
|
28
|
+
while (runtime.clipForms.length > target)
|
|
29
|
+
popOneGlClip(state);
|
|
30
|
+
},
|
|
31
|
+
pushClip(state, data, source) {
|
|
32
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
33
|
+
const clip = source.clip;
|
|
34
|
+
if (clip === null)
|
|
35
|
+
return;
|
|
36
|
+
if (clip.contours === null) {
|
|
37
|
+
pushGlClipRectangle(state, clip.rect, data.transform2D);
|
|
38
|
+
runtime.clipForms.push('rect');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
pushGlClipContours(state, clip.contours, clip.winding, data.transform2D);
|
|
42
|
+
runtime.clipForms.push('contour');
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=glClip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glClip.js","sourceRoot":"","sources":["../src/glClip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,gGAAgG;AAChG,uGAAuG;AACvG,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,KAAK,CAAC,sBAAsB,GAAG,cAAc,CAAC;AAChD,CAAC;AAED,8FAA8F;AAC9F,mGAAmG;AACnG,8DAA8D;AAC9D,SAAS,YAAY,CAAC,KAAoB;IACxC,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;IAC5D,IAAI,IAAI,KAAK,SAAS;QAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;;QAC5C,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,cAAc,GAA2B;IAC7C,QAAQ,CAAC,KAAoB;QAC3B,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,CAAC,KAAoB,EAAE,IAAmB,EAAE,MAAqB;QACtE,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IACD,QAAQ,CAAC,KAAoB,EAAE,IAAmB,EAAE,MAAqB;QACvE,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACzE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlRenderState, Matrix, PathWinding } from '@flighthq/types';
|
|
2
|
+
export declare function popGlClipContours(state: GlRenderState): void;
|
|
3
|
+
export declare function pushGlClipContours(state: GlRenderState, contours: readonly (readonly number[])[], winding: PathWinding, worldTransform: Readonly<Matrix>): void;
|
|
4
|
+
//# sourceMappingURL=glClipContours.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glClipContours.d.ts","sourceRoot":"","sources":["../src/glClipContours.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAsC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAa5D;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EACxC,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC/B,IAAI,CAiDN"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createGlProgram } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlRenderStateRuntime } from '@flighthq/render-gl';
|
|
3
|
+
import { flushGlSpriteBatch } from './glSpriteBatch';
|
|
4
|
+
// Stencil-then-cover fill of arbitrary flattened contours, used to realize a *path* ClipRegion exactly
|
|
5
|
+
// (crisp at any zoom — the contours are transformed in the vertex shader each frame, never cached as a
|
|
6
|
+
// texture). This is the contour counterpart to webglClipRectangle's scissor and replaces the old mask
|
|
7
|
+
// stencil. It needs no display node — just geometry + a winding rule.
|
|
8
|
+
//
|
|
9
|
+
// MODEL: a single-level contour clip gates content to the polygon's covered pixels. PHASE 1 accumulates
|
|
10
|
+
// the winding into the stencil with color off (non-zero: front/back INCR/DECR_WRAP; even-odd: INVERT);
|
|
11
|
+
// PHASE 2 enables color and sets the stencil test so only covered pixels pass (non-zero: != 0; even-odd:
|
|
12
|
+
// low bit set). state.currentMaskDepth tracks whether the gate is live (it is the "a stencil test is
|
|
13
|
+
// active" signal the rest of the GPU path keys off) and triggers a stencil clear when a sibling clip
|
|
14
|
+
// opens at depth 0. Scissor (rect) clips compose independently via the scissor test. Nested *contour*
|
|
15
|
+
// clips share one stencil buffer and are not re-derived on pop — nest a contour inside a rect/scissor
|
|
16
|
+
// clip when ANDing is needed (documented in popGlClipContours).
|
|
17
|
+
//
|
|
18
|
+
// Verified via the `mask` functional capture (canvas/dom/webgl agree). The clip program must keep
|
|
19
|
+
// state.currentProgram in sync (see pushGlClipContours) so content draws re-bind their own program.
|
|
20
|
+
// Position-only program: transform contour points (clip-local) by the node world transform, then by the
|
|
21
|
+
// backend's pixels->clip projection. Fragment writes nothing — color is masked off; only stencil moves.
|
|
22
|
+
const VERTEX_SOURCE = `
|
|
23
|
+
attribute vec2 a_position;
|
|
24
|
+
uniform mat3 u_worldMatrix; // node world transform2D (a,b,c,d,tx,ty) lifted to mat3
|
|
25
|
+
uniform mat3 u_projection; // device pixels -> clip space (same one the sprite/shape shaders use)
|
|
26
|
+
void main() {
|
|
27
|
+
vec3 clip = u_projection * (u_worldMatrix * vec3(a_position, 1.0));
|
|
28
|
+
gl_Position = vec4(clip.xy, 0.0, 1.0);
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
const FRAGMENT_SOURCE = `
|
|
32
|
+
precision mediump float;
|
|
33
|
+
void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }
|
|
34
|
+
`;
|
|
35
|
+
export function popGlClipContours(state) {
|
|
36
|
+
flushGlSpriteBatch(state);
|
|
37
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
38
|
+
const gl = state.gl;
|
|
39
|
+
const nextDepth = Math.max(0, (runtime.currentMaskDepth ?? 0) - 1);
|
|
40
|
+
runtime.currentMaskDepth = nextDepth;
|
|
41
|
+
// Single-level contour clips are the common case; the outermost pop turns the stencil gate off. Nested
|
|
42
|
+
// contour clips share one stencil buffer and are not re-derived on pop (a documented limitation — nest
|
|
43
|
+
// a contour inside a rect/scissor clip instead, which composes independently).
|
|
44
|
+
if (nextDepth === 0) {
|
|
45
|
+
gl.disable(gl.STENCIL_TEST);
|
|
46
|
+
gl.stencilMask(0xff);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function pushGlClipContours(state, contours, winding, worldTransform) {
|
|
50
|
+
flushGlSpriteBatch(state);
|
|
51
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
52
|
+
const gl = state.gl;
|
|
53
|
+
const depth = runtime.currentMaskDepth ?? 0;
|
|
54
|
+
if (depth === 0) {
|
|
55
|
+
gl.enable(gl.STENCIL_TEST);
|
|
56
|
+
gl.stencilMask(0xff);
|
|
57
|
+
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
58
|
+
}
|
|
59
|
+
ensureClipProgram(state);
|
|
60
|
+
const program = clipProgramFor(state);
|
|
61
|
+
gl.useProgram(program.program);
|
|
62
|
+
// Content draws skip gl.useProgram when state.currentProgram already matches their program. Record the
|
|
63
|
+
// clip program here so the next content draw detects the change and re-binds — otherwise it would set
|
|
64
|
+
// its uniforms against the clip program (INVALID_OPERATION: location not from the associated program).
|
|
65
|
+
runtime.currentProgram = program.program;
|
|
66
|
+
uploadClipUniforms(state, program, worldTransform);
|
|
67
|
+
// PHASE 1 — accumulate the polygon's winding into the stencil with color writes off. Non-zero uses
|
|
68
|
+
// separate front/back INCR/DECR_WRAP (interior ends up != 0); even-odd uses INVERT (interior ends odd).
|
|
69
|
+
gl.colorMask(false, false, false, false);
|
|
70
|
+
gl.stencilMask(0xff);
|
|
71
|
+
gl.disable(gl.CULL_FACE); // non-zero needs both faces rasterized; 2D content leaves culling off anyway
|
|
72
|
+
if (winding === 'evenOdd') {
|
|
73
|
+
gl.stencilFunc(gl.ALWAYS, 0, 0xff);
|
|
74
|
+
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INVERT);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
gl.stencilFunc(gl.ALWAYS, 0, 0xff);
|
|
78
|
+
gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.INCR_WRAP);
|
|
79
|
+
gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.DECR_WRAP);
|
|
80
|
+
}
|
|
81
|
+
drawClipContours(state, program, contours);
|
|
82
|
+
// PHASE 2 — enable color and gate subsequent content to the covered pixels: non-zero passes where the
|
|
83
|
+
// accumulated count != 0; even-odd passes where the low bit is set. stencilMask 0 so content cannot
|
|
84
|
+
// disturb the coverage. The gate persists through the content draws until popGlClipContours.
|
|
85
|
+
gl.colorMask(true, true, true, true);
|
|
86
|
+
gl.stencilMask(0x00);
|
|
87
|
+
if (winding === 'evenOdd') {
|
|
88
|
+
gl.stencilFunc(gl.EQUAL, 0x1, 0x1);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
gl.stencilFunc(gl.NOTEQUAL, 0x0, 0xff);
|
|
92
|
+
}
|
|
93
|
+
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
94
|
+
runtime.currentMaskDepth = depth + 1;
|
|
95
|
+
}
|
|
96
|
+
const clipPrograms = new WeakMap();
|
|
97
|
+
function clipProgramFor(state) {
|
|
98
|
+
return clipPrograms.get(state.gl);
|
|
99
|
+
}
|
|
100
|
+
function ensureClipProgram(state) {
|
|
101
|
+
const gl = state.gl;
|
|
102
|
+
if (clipPrograms.has(gl))
|
|
103
|
+
return;
|
|
104
|
+
const program = compileProgram(gl, VERTEX_SOURCE, FRAGMENT_SOURCE);
|
|
105
|
+
clipPrograms.set(gl, {
|
|
106
|
+
program,
|
|
107
|
+
buffer: gl.createBuffer(),
|
|
108
|
+
positionLocation: gl.getAttribLocation(program, 'a_position'),
|
|
109
|
+
worldMatrixLocation: gl.getUniformLocation(program, 'u_worldMatrix'),
|
|
110
|
+
projectionLocation: gl.getUniformLocation(program, 'u_projection'),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function compileProgram(gl, vertex, fragment) {
|
|
114
|
+
return createGlProgram(gl, vertex, fragment, 'Clip-contours');
|
|
115
|
+
}
|
|
116
|
+
function uploadClipUniforms(state, program, m) {
|
|
117
|
+
const gl = state.gl;
|
|
118
|
+
// mat3 column-major from Matrix(a,b,c,d,tx,ty).
|
|
119
|
+
// prettier-ignore
|
|
120
|
+
gl.uniformMatrix3fv(program.worldMatrixLocation, false, [m.a, m.b, 0, m.c, m.d, 0, m.tx, m.ty, 1]);
|
|
121
|
+
gl.uniformMatrix3fv(program.projectionLocation, false, getProjectionMat3(state));
|
|
122
|
+
}
|
|
123
|
+
function drawClipContours(state, program, contours) {
|
|
124
|
+
const gl = state.gl;
|
|
125
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, program.buffer);
|
|
126
|
+
gl.enableVertexAttribArray(program.positionLocation);
|
|
127
|
+
gl.vertexAttribPointer(program.positionLocation, 2, gl.FLOAT, false, 0, 0);
|
|
128
|
+
for (let c = 0; c < contours.length; c++) {
|
|
129
|
+
const contour = contours[c];
|
|
130
|
+
if (contour.length < 6)
|
|
131
|
+
continue; // need at least a triangle
|
|
132
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(contour), gl.STREAM_DRAW);
|
|
133
|
+
// TRIANGLE_FAN fills the (possibly concave) polygon into the stencil; winding op handles correctness.
|
|
134
|
+
gl.drawArrays(gl.TRIANGLE_FAN, 0, contour.length >> 1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Device pixels -> clip space for the current viewport / render target. This is the same column-major
|
|
138
|
+
// mat3 the sprite/shape batch builds in setGlQuadBatchWorldAndTexture, so a clip's contours and the
|
|
139
|
+
// content it clips land in identical clip space (the clip stays pixel-exact under the node transform).
|
|
140
|
+
function getProjectionMat3(state) {
|
|
141
|
+
const runtime = getGlRenderStateRuntime(state);
|
|
142
|
+
const w = (runtime.renderTargetViewport ?? state.canvas).width || 1;
|
|
143
|
+
const h = (runtime.renderTargetViewport ?? state.canvas).height || 1;
|
|
144
|
+
// pixels (origin top-left, y down) -> clip space (-1..1, y up)
|
|
145
|
+
// prettier-ignore
|
|
146
|
+
return new Float32Array([2 / w, 0, 0, 0, -2 / h, 0, -1, 1, 1]);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=glClipContours.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glClipContours.js","sourceRoot":"","sources":["../src/glClipContours.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,uGAAuG;AACvG,uGAAuG;AACvG,sGAAsG;AACtG,sEAAsE;AACtE,EAAE;AACF,wGAAwG;AACxG,uGAAuG;AACvG,yGAAyG;AACzG,qGAAqG;AACrG,qGAAqG;AACrG,sGAAsG;AACtG,sGAAsG;AACtG,gEAAgE;AAChE,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AAEpG,wGAAwG;AACxG,wGAAwG;AACxG,MAAM,aAAa,GAAG;;;;;;;;CAQrB,CAAC;AAEF,MAAM,eAAe,GAAG;;;CAGvB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACpD,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACrC,uGAAuG;IACvG,uGAAuG;IACvG,+EAA+E;IAC/E,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAC5B,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAoB,EACpB,QAAwC,EACxC,OAAoB,EACpB,cAAgC;IAEhC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAE5C,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAC3B,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACrB,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAClC,CAAC;IAED,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,uGAAuG;IACvG,sGAAsG;IACtG,uGAAuG;IACvG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IACzC,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IAEnD,mGAAmG;IACnG,wGAAwG;IACxG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACrB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,6EAA6E;IAEvG,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACnC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACnC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;QAC/D,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IACD,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE3C,sGAAsG;IACtG,oGAAoG;IACpG,6FAA6F;IAC7F,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACrB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,gBAAgB,GAAG,KAAK,GAAG,CAAC,CAAC;AACvC,CAAC;AAYD,MAAM,YAAY,GAAG,IAAI,OAAO,EAAsC,CAAC;AAEvE,SAAS,cAAc,CAAC,KAAoB;IAC1C,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAE,CAAC;AACrC,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAoB;IAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO;IACjC,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;IACnE,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE;QACnB,OAAO;QACP,MAAM,EAAE,EAAE,CAAC,YAAY,EAAG;QAC1B,gBAAgB,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC;QAC7D,mBAAmB,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,eAAe,CAAC;QACpE,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,cAAc,CAAC;KACnE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,EAA0B,EAAE,MAAc,EAAE,QAAgB;IAClF,OAAO,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAoB,EAAE,OAAoB,EAAE,CAAmB;IACzF,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,gDAAgD;IAChD,kBAAkB;IAClB,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACnG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAoB,EAAE,OAAoB,EAAE,QAAwC;IAC5G,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrD,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS,CAAC,2BAA2B;QAC7D,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;QAC1E,sGAAsG;QACtG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,sGAAsG;AACtG,oGAAoG;AACpG,uGAAuG;AACvG,SAAS,iBAAiB,CAAC,KAAoB;IAC7C,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IACrE,+DAA+D;IAC/D,kBAAkB;IAClB,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlRenderState, MatrixLike, RectangleLike } from '@flighthq/types';
|
|
2
|
+
export declare function popGlClipRectangle(state: GlRenderState): void;
|
|
3
|
+
export declare function pushGlClipRectangle(state: GlRenderState, rect: Readonly<RectangleLike>, transform: Readonly<MatrixLike>): void;
|
|
4
|
+
//# sourceMappingURL=glClipRectangle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glClipRectangle.d.ts","sourceRoot":"","sources":["../src/glClipRectangle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAc7D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC9B,IAAI,CAUN"}
|