1 | import { ExtensionType, extensions } from '@pixi/extensions';
|
2 | import { settings } from '@pixi/settings';
|
3 | import { AbstractMaskSystem } from './AbstractMaskSystem.mjs';
|
4 |
|
5 | class StencilSystem extends AbstractMaskSystem {
|
6 | constructor(renderer) {
|
7 | super(renderer);
|
8 | this.glConst = settings.ADAPTER.getWebGLRenderingContext().STENCIL_TEST;
|
9 | }
|
10 | getStackLength() {
|
11 | const maskData = this.maskStack[this.maskStack.length - 1];
|
12 | if (maskData) {
|
13 | return maskData._stencilCounter;
|
14 | }
|
15 | return 0;
|
16 | }
|
17 | push(maskData) {
|
18 | const maskObject = maskData.maskObject;
|
19 | const { gl } = this.renderer;
|
20 | const prevMaskCount = maskData._stencilCounter;
|
21 | if (prevMaskCount === 0) {
|
22 | this.renderer.framebuffer.forceStencil();
|
23 | gl.clearStencil(0);
|
24 | gl.clear(gl.STENCIL_BUFFER_BIT);
|
25 | gl.enable(gl.STENCIL_TEST);
|
26 | }
|
27 | maskData._stencilCounter++;
|
28 | const colorMask = maskData._colorMask;
|
29 | if (colorMask !== 0) {
|
30 | maskData._colorMask = 0;
|
31 | gl.colorMask(false, false, false, false);
|
32 | }
|
33 | gl.stencilFunc(gl.EQUAL, prevMaskCount, 4294967295);
|
34 | gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
|
35 | maskObject.renderable = true;
|
36 | maskObject.render(this.renderer);
|
37 | this.renderer.batch.flush();
|
38 | maskObject.renderable = false;
|
39 | if (colorMask !== 0) {
|
40 | maskData._colorMask = colorMask;
|
41 | gl.colorMask((colorMask & 1) !== 0, (colorMask & 2) !== 0, (colorMask & 4) !== 0, (colorMask & 8) !== 0);
|
42 | }
|
43 | this._useCurrent();
|
44 | }
|
45 | pop(maskObject) {
|
46 | const gl = this.renderer.gl;
|
47 | if (this.getStackLength() === 0) {
|
48 | gl.disable(gl.STENCIL_TEST);
|
49 | } else {
|
50 | const maskData = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null;
|
51 | const colorMask = maskData ? maskData._colorMask : 15;
|
52 | if (colorMask !== 0) {
|
53 | maskData._colorMask = 0;
|
54 | gl.colorMask(false, false, false, false);
|
55 | }
|
56 | gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
|
57 | maskObject.renderable = true;
|
58 | maskObject.render(this.renderer);
|
59 | this.renderer.batch.flush();
|
60 | maskObject.renderable = false;
|
61 | if (colorMask !== 0) {
|
62 | maskData._colorMask = colorMask;
|
63 | gl.colorMask((colorMask & 1) !== 0, (colorMask & 2) !== 0, (colorMask & 4) !== 0, (colorMask & 8) !== 0);
|
64 | }
|
65 | this._useCurrent();
|
66 | }
|
67 | }
|
68 | _useCurrent() {
|
69 | const gl = this.renderer.gl;
|
70 | gl.stencilFunc(gl.EQUAL, this.getStackLength(), 4294967295);
|
71 | gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
72 | }
|
73 | }
|
74 | StencilSystem.extension = {
|
75 | type: ExtensionType.RendererSystem,
|
76 | name: "stencil"
|
77 | };
|
78 | extensions.add(StencilSystem);
|
79 |
|
80 | export { StencilSystem };
|
81 |
|