UNPKG

3.92 kBJavaScriptView Raw
1import { AbstractMaskSystem } from './AbstractMaskSystem.mjs';
2import { Matrix, Rectangle } from '@pixi/math';
3import { ExtensionType, extensions } from '@pixi/extensions';
4import { settings } from '@pixi/settings';
5
6const tempMatrix = new Matrix();
7const rectPool = [];
8const _ScissorSystem = class extends AbstractMaskSystem {
9 constructor(renderer) {
10 super(renderer);
11 this.glConst = settings.ADAPTER.getWebGLRenderingContext().SCISSOR_TEST;
12 }
13 getStackLength() {
14 const maskData = this.maskStack[this.maskStack.length - 1];
15 if (maskData) {
16 return maskData._scissorCounter;
17 }
18 return 0;
19 }
20 calcScissorRect(maskData) {
21 if (maskData._scissorRectLocal) {
22 return;
23 }
24 const prevData = maskData._scissorRect;
25 const { maskObject } = maskData;
26 const { renderer } = this;
27 const renderTextureSystem = renderer.renderTexture;
28 const rect = maskObject.getBounds(true, rectPool.pop() ?? new Rectangle());
29 this.roundFrameToPixels(rect, renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution, renderTextureSystem.sourceFrame, renderTextureSystem.destinationFrame, renderer.projection.transform);
30 if (prevData) {
31 rect.fit(prevData);
32 }
33 maskData._scissorRectLocal = rect;
34 }
35 static isMatrixRotated(matrix) {
36 if (!matrix) {
37 return false;
38 }
39 const { a, b, c, d } = matrix;
40 return (Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4);
41 }
42 testScissor(maskData) {
43 const { maskObject } = maskData;
44 if (!maskObject.isFastRect || !maskObject.isFastRect()) {
45 return false;
46 }
47 if (_ScissorSystem.isMatrixRotated(maskObject.worldTransform)) {
48 return false;
49 }
50 if (_ScissorSystem.isMatrixRotated(this.renderer.projection.transform)) {
51 return false;
52 }
53 this.calcScissorRect(maskData);
54 const rect = maskData._scissorRectLocal;
55 return rect.width > 0 && rect.height > 0;
56 }
57 roundFrameToPixels(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) {
58 if (_ScissorSystem.isMatrixRotated(transform)) {
59 return;
60 }
61 transform = transform ? tempMatrix.copyFrom(transform) : tempMatrix.identity();
62 transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale(bindingDestinationFrame.width / bindingSourceFrame.width, bindingDestinationFrame.height / bindingSourceFrame.height).translate(bindingDestinationFrame.x, bindingDestinationFrame.y);
63 this.renderer.filter.transformAABB(transform, frame);
64 frame.fit(bindingDestinationFrame);
65 frame.x = Math.round(frame.x * resolution);
66 frame.y = Math.round(frame.y * resolution);
67 frame.width = Math.round(frame.width * resolution);
68 frame.height = Math.round(frame.height * resolution);
69 }
70 push(maskData) {
71 if (!maskData._scissorRectLocal) {
72 this.calcScissorRect(maskData);
73 }
74 const { gl } = this.renderer;
75 if (!maskData._scissorRect) {
76 gl.enable(gl.SCISSOR_TEST);
77 }
78 maskData._scissorCounter++;
79 maskData._scissorRect = maskData._scissorRectLocal;
80 this._useCurrent();
81 }
82 pop(maskData) {
83 const { gl } = this.renderer;
84 if (maskData) {
85 rectPool.push(maskData._scissorRectLocal);
86 }
87 if (this.getStackLength() > 0) {
88 this._useCurrent();
89 } else {
90 gl.disable(gl.SCISSOR_TEST);
91 }
92 }
93 _useCurrent() {
94 const rect = this.maskStack[this.maskStack.length - 1]._scissorRect;
95 let y;
96 if (this.renderer.renderTexture.current) {
97 y = rect.y;
98 } else {
99 y = this.renderer.height - rect.height - rect.y;
100 }
101 this.renderer.gl.scissor(rect.x, y, rect.width, rect.height);
102 }
103};
104let ScissorSystem = _ScissorSystem;
105ScissorSystem.extension = {
106 type: ExtensionType.RendererSystem,
107 name: "scissor"
108};
109extensions.add(ScissorSystem);
110
111export { ScissorSystem };
112//# sourceMappingURL=ScissorSystem.mjs.map