UNPKG

4.54 kBJavaScriptView Raw
1import { ExtensionType, extensions } from "@pixi/extensions";
2import { Matrix, Rectangle } from "@pixi/math";
3import { settings } from "@pixi/settings";
4import { AbstractMaskSystem } from "./AbstractMaskSystem.mjs";
5const tempMatrix = new Matrix(), rectPool = [], _ScissorSystem = class _ScissorSystem2 extends AbstractMaskSystem {
6 /**
7 * @param {PIXI.Renderer} renderer - The renderer this System works for.
8 */
9 constructor(renderer) {
10 super(renderer), this.glConst = settings.ADAPTER.getWebGLRenderingContext().SCISSOR_TEST;
11 }
12 getStackLength() {
13 const maskData = this.maskStack[this.maskStack.length - 1];
14 return maskData ? maskData._scissorCounter : 0;
15 }
16 /**
17 * evaluates _boundsTransformed, _scissorRect for MaskData
18 * @param maskData
19 */
20 calcScissorRect(maskData) {
21 if (maskData._scissorRectLocal)
22 return;
23 const prevData = maskData._scissorRect, { maskObject } = maskData, { renderer } = this, renderTextureSystem = renderer.renderTexture, rect = maskObject.getBounds(!0, rectPool.pop() ?? new Rectangle());
24 this.roundFrameToPixels(
25 rect,
26 renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution,
27 renderTextureSystem.sourceFrame,
28 renderTextureSystem.destinationFrame,
29 renderer.projection.transform
30 ), prevData && rect.fit(prevData), maskData._scissorRectLocal = rect;
31 }
32 static isMatrixRotated(matrix) {
33 if (!matrix)
34 return !1;
35 const { a, b, c, d } = matrix;
36 return (Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4);
37 }
38 /**
39 * Test, whether the object can be scissor mask with current renderer projection.
40 * Calls "calcScissorRect()" if its true.
41 * @param maskData - mask data
42 * @returns whether Whether the object can be scissor mask
43 */
44 testScissor(maskData) {
45 const { maskObject } = maskData;
46 if (!maskObject.isFastRect || !maskObject.isFastRect() || _ScissorSystem2.isMatrixRotated(maskObject.worldTransform) || _ScissorSystem2.isMatrixRotated(this.renderer.projection.transform))
47 return !1;
48 this.calcScissorRect(maskData);
49 const rect = maskData._scissorRectLocal;
50 return rect.width > 0 && rect.height > 0;
51 }
52 roundFrameToPixels(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) {
53 _ScissorSystem2.isMatrixRotated(transform) || (transform = transform ? tempMatrix.copyFrom(transform) : tempMatrix.identity(), transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale(
54 bindingDestinationFrame.width / bindingSourceFrame.width,
55 bindingDestinationFrame.height / bindingSourceFrame.height
56 ).translate(bindingDestinationFrame.x, bindingDestinationFrame.y), this.renderer.filter.transformAABB(transform, frame), frame.fit(bindingDestinationFrame), frame.x = Math.round(frame.x * resolution), frame.y = Math.round(frame.y * resolution), frame.width = Math.round(frame.width * resolution), frame.height = Math.round(frame.height * resolution));
57 }
58 /**
59 * Applies the Mask and adds it to the current stencil stack.
60 * @author alvin
61 * @param maskData - The mask data.
62 */
63 push(maskData) {
64 maskData._scissorRectLocal || this.calcScissorRect(maskData);
65 const { gl } = this.renderer;
66 maskData._scissorRect || gl.enable(gl.SCISSOR_TEST), maskData._scissorCounter++, maskData._scissorRect = maskData._scissorRectLocal, this._useCurrent();
67 }
68 /**
69 * This should be called after a mask is popped off the mask stack. It will rebind the scissor box to be latest with the
70 * last mask in the stack.
71 *
72 * This can also be called when you directly modify the scissor box and want to restore PixiJS state.
73 * @param maskData - The mask data.
74 */
75 pop(maskData) {
76 const { gl } = this.renderer;
77 maskData && rectPool.push(maskData._scissorRectLocal), this.getStackLength() > 0 ? this._useCurrent() : gl.disable(gl.SCISSOR_TEST);
78 }
79 /**
80 * Setup renderer to use the current scissor data.
81 * @private
82 */
83 _useCurrent() {
84 const rect = this.maskStack[this.maskStack.length - 1]._scissorRect;
85 let y;
86 this.renderer.renderTexture.current ? y = rect.y : y = this.renderer.height - rect.height - rect.y, this.renderer.gl.scissor(rect.x, y, rect.width, rect.height);
87 }
88};
89_ScissorSystem.extension = {
90 type: ExtensionType.RendererSystem,
91 name: "scissor"
92};
93let ScissorSystem = _ScissorSystem;
94extensions.add(ScissorSystem);
95export {
96 ScissorSystem
97};
98//# sourceMappingURL=ScissorSystem.mjs.map