From f69cec7975e80709dff1fa9eb69798418fa8754a Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 12 Apr 2019 17:47:28 +0100 Subject: [PATCH] Improving support for child masking --- src/renderer/webgl/WebGLRenderer.js | 82 ++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/src/renderer/webgl/WebGLRenderer.js b/src/renderer/webgl/WebGLRenderer.js index ed3895562..85a1ff3f1 100644 --- a/src/renderer/webgl/WebGLRenderer.js +++ b/src/renderer/webgl/WebGLRenderer.js @@ -470,6 +470,15 @@ var WebGLRenderer = new Class({ */ this._tempMatrix4 = new TransformMatrix(); + /** + * A reference to the mask the current camera is using, if any. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentMask + * @type {(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} + * @since 3.17.0 + */ + this.currentMask = null; + this.init(this.config); }, @@ -1688,12 +1697,22 @@ var WebGLRenderer = new Class({ var color = camera.backgroundColor; + // Clear the current mask, if set + this.currentMask = null; + if (camera.renderToTexture) { this.flush(); this.pushScissor(cx, cy, cw, -ch); + this.currentStencil = 0; + + if (camera.mask) + { + this.setCameraMask(camera); + } + this.setFramebuffer(camera.framebuffer); var gl = this.gl; @@ -1719,11 +1738,9 @@ var WebGLRenderer = new Class({ { this.pushScissor(cx, cy, cw, ch); - var mask = camera.mask; - - if (mask) + if (camera.mask) { - mask.preRenderWebGL(this, null, camera._maskCamera); + this.setCameraMask(camera); } if (color.alphaGL > 0) @@ -1755,13 +1772,6 @@ var WebGLRenderer = new Class({ camera.dirty = false; - var mask = camera.mask; - - if (mask) - { - mask.postRenderWebGL(this); - } - this.popScissor(); if (camera.renderToTexture) @@ -1803,6 +1813,11 @@ var WebGLRenderer = new Class({ // Force clear the current texture so that items next in the batch (like Graphics) don't try and use it this.setBlankTexture(true); } + + if (camera.mask) + { + this.clearCameraMask(camera); + } }, /** @@ -1899,15 +1914,9 @@ var WebGLRenderer = new Class({ this.setBlendMode(child.blendMode); } - var mask = child.mask; - - if (mask) + if (child.mask) { - mask.preRenderWebGL(this, child, camera); - - child.renderWebGL(this, child, interpolationPercentage, camera); - - mask.postRenderWebGL(this, child); + this.setChildMask(this, child, interpolationPercentage, camera); } else { @@ -1952,6 +1961,41 @@ var WebGLRenderer = new Class({ } }, + setCameraMask: function (camera) + { + var mask = camera.mask; + + // Cameras cannot have child cameras, so each one can clear the mask stack + this.currentMask = mask; + + mask.preRenderWebGL(this, null, camera._maskCamera); + }, + + clearCameraMask: function (camera) + { + camera.mask.postRenderWebGL(this); + }, + + setChildMask: function (renderer, child, interpolationPercentage, camera) + { + var mask = child.mask; + + if (mask !== this.currentMask) + { + mask.preRenderWebGL(renderer, child, camera); + + child.renderWebGL(renderer, child, interpolationPercentage, camera); + + mask.postRenderWebGL(renderer); + + // Restore camera mask + if (this.currentMask) + { + this.setCameraMask(camera); + } + } + }, + /** * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. *