import System from '../System'; import { Rectangle } from '@pixi/math'; const tempRect = new Rectangle(); /** * System plugin to the renderer to manage render textures. * * @class * @extends PIXI.System * @memberof PIXI.systems */ export default class RenderTextureSystem extends System { /** * @param {PIXI.Renderer} renderer - The renderer this System works for. */ constructor(renderer) { super(renderer); /** * The clear background color as rgba * @member {number[]} */ this.clearColor = renderer._backgroundColorRgba; // TODO move this property somewhere else! /** * List of masks for the StencilSystem * @member {PIXI.Graphics[]} * @readonly */ this.defaultMaskStack = []; // empty render texture? /** * Render texture * @member {PIXI.RenderTexture} * @readonly */ this.current = null; /** * Source frame * @member {PIXI.Rectangle} * @readonly */ this.sourceFrame = new Rectangle(); /** * Destination frame * @member {PIXI.Rectangle} * @readonly */ this.destinationFrame = new Rectangle(); } /** * Bind the current render texture * @param {PIXI.RenderTexture} renderTexture * @param {PIXI.Rectangle} sourceFrame * @param {PIXI.Rectangle} destinationFrame */ bind(renderTexture, sourceFrame, destinationFrame) { // TODO - do we want this?? if (this.current === renderTexture) return; this.current = renderTexture; const renderer = this.renderer; let resolution; if (renderTexture) { const baseTexture = renderTexture.baseTexture; resolution = baseTexture.resolution; if (!destinationFrame) { tempRect.width = baseTexture.realWidth; tempRect.height = baseTexture.realHeight; destinationFrame = tempRect; } if (!sourceFrame) { sourceFrame = destinationFrame; } this.renderer.framebuffer.bind(baseTexture.framebuffer, destinationFrame); this.renderer.projection.update(destinationFrame, sourceFrame, resolution, false); this.renderer.stencil.setMaskStack(baseTexture.stencilMaskStack); } else { resolution = this.renderer.resolution; // TODO these validation checks happen deeper down.. // thing they can be avoided.. if (!destinationFrame) { tempRect.width = renderer.width; tempRect.height = renderer.height; destinationFrame = tempRect; } if (!sourceFrame) { sourceFrame = destinationFrame; } renderer.framebuffer.bind(null, destinationFrame); // TODO store this.. this.renderer.projection.update(destinationFrame, sourceFrame, resolution, true); this.renderer.stencil.setMaskStack(this.defaultMaskStack); } this.sourceFrame.copyFrom(sourceFrame); this.destinationFrame.x = destinationFrame.x / resolution; this.destinationFrame.y = destinationFrame.y / resolution; this.destinationFrame.width = destinationFrame.width / resolution; this.destinationFrame.height = destinationFrame.height / resolution; } /** * Erases the render texture and fills the drawing area with a colour * * @param {number[]} [clearColor] - The color as rgba, default to use the renderer backgroundColor * @return {PIXI.Renderer} Returns itself. */ clear(clearColor) { if (this.current) { clearColor = clearColor || this.current.baseTexture.clearColor; } else { clearColor = clearColor || this.clearColor; } this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); } resize()// screenWidth, screenHeight) { // resize the root only! this.bind(null); } }