1 | import { MASK_TYPES } from "@pixi/constants";
|
2 | import { ExtensionType, extensions } from "@pixi/extensions";
|
3 | import { SpriteMaskFilter } from "../filters/spriteMask/SpriteMaskFilter.mjs";
|
4 | import { MaskData } from "./MaskData.mjs";
|
5 | class MaskSystem {
|
6 | |
7 |
|
8 |
|
9 | constructor(renderer) {
|
10 | this.renderer = renderer, this.enableScissor = !0, this.alphaMaskPool = [], this.maskDataPool = [], this.maskStack = [], this.alphaMaskIndex = 0;
|
11 | }
|
12 | |
13 |
|
14 |
|
15 |
|
16 | setMaskStack(maskStack) {
|
17 | this.maskStack = maskStack, this.renderer.scissor.setMaskStack(maskStack), this.renderer.stencil.setMaskStack(maskStack);
|
18 | }
|
19 | |
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | push(target, maskDataOrTarget) {
|
27 | let maskData = maskDataOrTarget;
|
28 | if (!maskData.isMaskData) {
|
29 | const d = this.maskDataPool.pop() || new MaskData();
|
30 | d.pooled = !0, d.maskObject = maskDataOrTarget, maskData = d;
|
31 | }
|
32 | const maskAbove = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null;
|
33 | if (maskData.copyCountersOrReset(maskAbove), maskData._colorMask = maskAbove ? maskAbove._colorMask : 15, maskData.autoDetect && this.detect(maskData), maskData._target = target, maskData.type !== MASK_TYPES.SPRITE && this.maskStack.push(maskData), maskData.enabled)
|
34 | switch (maskData.type) {
|
35 | case MASK_TYPES.SCISSOR:
|
36 | this.renderer.scissor.push(maskData);
|
37 | break;
|
38 | case MASK_TYPES.STENCIL:
|
39 | this.renderer.stencil.push(maskData);
|
40 | break;
|
41 | case MASK_TYPES.SPRITE:
|
42 | maskData.copyCountersOrReset(null), this.pushSpriteMask(maskData);
|
43 | break;
|
44 | case MASK_TYPES.COLOR:
|
45 | this.pushColorMask(maskData);
|
46 | break;
|
47 | default:
|
48 | break;
|
49 | }
|
50 | maskData.type === MASK_TYPES.SPRITE && this.maskStack.push(maskData);
|
51 | }
|
52 | |
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 | pop(target) {
|
59 | const maskData = this.maskStack.pop();
|
60 | if (!(!maskData || maskData._target !== target)) {
|
61 | if (maskData.enabled)
|
62 | switch (maskData.type) {
|
63 | case MASK_TYPES.SCISSOR:
|
64 | this.renderer.scissor.pop(maskData);
|
65 | break;
|
66 | case MASK_TYPES.STENCIL:
|
67 | this.renderer.stencil.pop(maskData.maskObject);
|
68 | break;
|
69 | case MASK_TYPES.SPRITE:
|
70 | this.popSpriteMask(maskData);
|
71 | break;
|
72 | case MASK_TYPES.COLOR:
|
73 | this.popColorMask(maskData);
|
74 | break;
|
75 | default:
|
76 | break;
|
77 | }
|
78 | if (maskData.reset(), maskData.pooled && this.maskDataPool.push(maskData), this.maskStack.length !== 0) {
|
79 | const maskCurrent = this.maskStack[this.maskStack.length - 1];
|
80 | maskCurrent.type === MASK_TYPES.SPRITE && maskCurrent._filters && (maskCurrent._filters[0].maskSprite = maskCurrent.maskObject);
|
81 | }
|
82 | }
|
83 | }
|
84 | |
85 |
|
86 |
|
87 |
|
88 | detect(maskData) {
|
89 | const maskObject = maskData.maskObject;
|
90 | maskObject ? maskObject.isSprite ? maskData.type = MASK_TYPES.SPRITE : this.enableScissor && this.renderer.scissor.testScissor(maskData) ? maskData.type = MASK_TYPES.SCISSOR : maskData.type = MASK_TYPES.STENCIL : maskData.type = MASK_TYPES.COLOR;
|
91 | }
|
92 | |
93 |
|
94 |
|
95 |
|
96 | pushSpriteMask(maskData) {
|
97 | const { maskObject } = maskData, target = maskData._target;
|
98 | let alphaMaskFilter = maskData._filters;
|
99 | alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex], alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new SpriteMaskFilter()])), alphaMaskFilter[0].resolution = maskData.resolution, alphaMaskFilter[0].multisample = maskData.multisample, alphaMaskFilter[0].maskSprite = maskObject;
|
100 | const stashFilterArea = target.filterArea;
|
101 | target.filterArea = maskObject.getBounds(!0), this.renderer.filter.push(target, alphaMaskFilter), target.filterArea = stashFilterArea, maskData._filters || this.alphaMaskIndex++;
|
102 | }
|
103 | |
104 |
|
105 |
|
106 |
|
107 | popSpriteMask(maskData) {
|
108 | this.renderer.filter.pop(), maskData._filters ? maskData._filters[0].maskSprite = null : (this.alphaMaskIndex--, this.alphaMaskPool[this.alphaMaskIndex][0].maskSprite = null);
|
109 | }
|
110 | |
111 |
|
112 |
|
113 |
|
114 | pushColorMask(maskData) {
|
115 | const currColorMask = maskData._colorMask, nextColorMask = maskData._colorMask = currColorMask & maskData.colorMask;
|
116 | nextColorMask !== currColorMask && this.renderer.gl.colorMask(
|
117 | (nextColorMask & 1) !== 0,
|
118 | (nextColorMask & 2) !== 0,
|
119 | (nextColorMask & 4) !== 0,
|
120 | (nextColorMask & 8) !== 0
|
121 | );
|
122 | }
|
123 | |
124 |
|
125 |
|
126 |
|
127 | popColorMask(maskData) {
|
128 | const currColorMask = maskData._colorMask, nextColorMask = this.maskStack.length > 0 ? this.maskStack[this.maskStack.length - 1]._colorMask : 15;
|
129 | nextColorMask !== currColorMask && this.renderer.gl.colorMask(
|
130 | (nextColorMask & 1) !== 0,
|
131 | (nextColorMask & 2) !== 0,
|
132 | (nextColorMask & 4) !== 0,
|
133 | (nextColorMask & 8) !== 0
|
134 | );
|
135 | }
|
136 | destroy() {
|
137 | this.renderer = null;
|
138 | }
|
139 | }
|
140 | MaskSystem.extension = {
|
141 | type: ExtensionType.RendererSystem,
|
142 | name: "mask"
|
143 | };
|
144 | extensions.add(MaskSystem);
|
145 | export {
|
146 | MaskSystem
|
147 | };
|
148 |
|