1 | import { Color } from '@pixi/color';
|
2 | import { ExtensionType, extensions } from '@pixi/extensions';
|
3 | import { Rectangle } from '@pixi/math';
|
4 |
|
5 | const tempRect = new Rectangle();
|
6 | const tempRect2 = new Rectangle();
|
7 | class RenderTextureSystem {
|
8 | constructor(renderer) {
|
9 | this.renderer = renderer;
|
10 | this.defaultMaskStack = [];
|
11 | this.current = null;
|
12 | this.sourceFrame = new Rectangle();
|
13 | this.destinationFrame = new Rectangle();
|
14 | this.viewportFrame = new Rectangle();
|
15 | }
|
16 | bind(renderTexture = null, sourceFrame, destinationFrame) {
|
17 | const renderer = this.renderer;
|
18 | this.current = renderTexture;
|
19 | let baseTexture;
|
20 | let framebuffer;
|
21 | let resolution;
|
22 | if (renderTexture) {
|
23 | baseTexture = renderTexture.baseTexture;
|
24 | resolution = baseTexture.resolution;
|
25 | if (!sourceFrame) {
|
26 | tempRect.width = renderTexture.frame.width;
|
27 | tempRect.height = renderTexture.frame.height;
|
28 | sourceFrame = tempRect;
|
29 | }
|
30 | if (!destinationFrame) {
|
31 | tempRect2.x = renderTexture.frame.x;
|
32 | tempRect2.y = renderTexture.frame.y;
|
33 | tempRect2.width = sourceFrame.width;
|
34 | tempRect2.height = sourceFrame.height;
|
35 | destinationFrame = tempRect2;
|
36 | }
|
37 | framebuffer = baseTexture.framebuffer;
|
38 | } else {
|
39 | resolution = renderer.resolution;
|
40 | if (!sourceFrame) {
|
41 | tempRect.width = renderer._view.screen.width;
|
42 | tempRect.height = renderer._view.screen.height;
|
43 | sourceFrame = tempRect;
|
44 | }
|
45 | if (!destinationFrame) {
|
46 | destinationFrame = tempRect;
|
47 | destinationFrame.width = sourceFrame.width;
|
48 | destinationFrame.height = sourceFrame.height;
|
49 | }
|
50 | }
|
51 | const viewportFrame = this.viewportFrame;
|
52 | viewportFrame.x = destinationFrame.x * resolution;
|
53 | viewportFrame.y = destinationFrame.y * resolution;
|
54 | viewportFrame.width = destinationFrame.width * resolution;
|
55 | viewportFrame.height = destinationFrame.height * resolution;
|
56 | if (!renderTexture) {
|
57 | viewportFrame.y = renderer.view.height - (viewportFrame.y + viewportFrame.height);
|
58 | }
|
59 | viewportFrame.ceil();
|
60 | this.renderer.framebuffer.bind(framebuffer, viewportFrame);
|
61 | this.renderer.projection.update(destinationFrame, sourceFrame, resolution, !framebuffer);
|
62 | if (renderTexture) {
|
63 | this.renderer.mask.setMaskStack(baseTexture.maskStack);
|
64 | } else {
|
65 | this.renderer.mask.setMaskStack(this.defaultMaskStack);
|
66 | }
|
67 | this.sourceFrame.copyFrom(sourceFrame);
|
68 | this.destinationFrame.copyFrom(destinationFrame);
|
69 | }
|
70 | clear(clearColor, mask) {
|
71 | const fallbackColor = this.current ? this.current.baseTexture.clear : this.renderer.background.backgroundColor;
|
72 | const color = clearColor ? Color.shared.setValue(clearColor) : fallbackColor;
|
73 | const destinationFrame = this.destinationFrame;
|
74 | const baseFrame = this.current ? this.current.baseTexture : this.renderer._view.screen;
|
75 | const clearMask = destinationFrame.width !== baseFrame.width || destinationFrame.height !== baseFrame.height;
|
76 | if (clearMask) {
|
77 | let { x, y, width, height } = this.viewportFrame;
|
78 | x = Math.round(x);
|
79 | y = Math.round(y);
|
80 | width = Math.round(width);
|
81 | height = Math.round(height);
|
82 | this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);
|
83 | this.renderer.gl.scissor(x, y, width, height);
|
84 | }
|
85 | this.renderer.framebuffer.clear(color.red, color.green, color.blue, color.alpha, mask);
|
86 | if (clearMask) {
|
87 | this.renderer.scissor.pop();
|
88 | }
|
89 | }
|
90 | resize() {
|
91 | this.bind(null);
|
92 | }
|
93 | reset() {
|
94 | this.bind(null);
|
95 | }
|
96 | destroy() {
|
97 | this.renderer = null;
|
98 | }
|
99 | }
|
100 | RenderTextureSystem.extension = {
|
101 | type: ExtensionType.RendererSystem,
|
102 | name: "renderTexture"
|
103 | };
|
104 | extensions.add(RenderTextureSystem);
|
105 |
|
106 | export { RenderTextureSystem };
|
107 |
|