2020-11-06 11:42:39 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
2023-01-02 17:36:27 +00:00
|
|
|
* @copyright 2013-2023 Photon Storm Ltd.
|
2020-11-06 11:42:39 +00:00
|
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
var Class = require('../../utils/Class');
|
2020-12-04 15:07:26 +00:00
|
|
|
var Events = require('../events');
|
2020-11-06 11:42:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @classdesc
|
|
|
|
* A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it.
|
|
|
|
*
|
2020-11-19 11:36:58 +00:00
|
|
|
* Instances of this class are typically created by, and belong to WebGL Pipelines, however
|
|
|
|
* other Game Objects and classes can take advantage of Render Targets as well.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @class RenderTarget
|
|
|
|
* @memberof Phaser.Renderer.WebGL
|
|
|
|
* @constructor
|
|
|
|
* @since 3.50.0
|
|
|
|
*
|
2020-11-19 11:36:58 +00:00
|
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGLRenderer.
|
|
|
|
* @param {number} width - The width of this Render Target.
|
|
|
|
* @param {number} height - The height of this Render Target.
|
|
|
|
* @param {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer.
|
|
|
|
* @param {number} [minFilter=0] - The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`.
|
|
|
|
* @param {boolean} [autoClear=true] - Automatically clear this framebuffer when bound?
|
|
|
|
* @param {boolean} [autoResize=false] - Automatically resize this Render Target if the WebGL Renderer resizes?
|
2020-11-06 11:42:39 +00:00
|
|
|
*/
|
|
|
|
var RenderTarget = new Class({
|
|
|
|
|
|
|
|
initialize:
|
|
|
|
|
2023-03-02 18:46:16 +00:00
|
|
|
function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize, addDepthBuffer)
|
2020-11-06 11:42:39 +00:00
|
|
|
{
|
2020-11-19 11:36:58 +00:00
|
|
|
if (scale === undefined) { scale = 1; }
|
|
|
|
if (minFilter === undefined) { minFilter = 0; }
|
|
|
|
if (autoClear === undefined) { autoClear = true; }
|
|
|
|
if (autoResize === undefined) { autoResize = false; }
|
2023-03-14 19:42:09 +00:00
|
|
|
if (addDepthBuffer === undefined) { addDepthBuffer = true; }
|
2020-11-06 11:42:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A reference to the WebGLRenderer instance.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#renderer
|
|
|
|
* @type {Phaser.Renderer.WebGL.WebGLRenderer}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
2020-11-19 11:36:58 +00:00
|
|
|
this.renderer = renderer;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
|
|
|
/**
|
2020-11-06 12:24:46 +00:00
|
|
|
* The WebGLFramebuffer of this Render Target.
|
|
|
|
*
|
|
|
|
* This is created in the `RenderTarget.resize` method.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#framebuffer
|
|
|
|
* @type {WebGLFramebuffer}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.framebuffer = null;
|
|
|
|
|
|
|
|
/**
|
2020-11-06 12:24:46 +00:00
|
|
|
* The WebGLTexture of this Render Target.
|
|
|
|
*
|
|
|
|
* This is created in the `RenderTarget.resize` method.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#texture
|
|
|
|
* @type {WebGLTexture}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.texture = null;
|
|
|
|
|
2020-11-11 17:45:58 +00:00
|
|
|
/**
|
|
|
|
* The width of the texture.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#width
|
|
|
|
* @type {number}
|
|
|
|
* @readonly
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.width = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The height of the texture.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#height
|
|
|
|
* @type {number}
|
|
|
|
* @readonly
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.height = 0;
|
|
|
|
|
2020-11-06 11:42:39 +00:00
|
|
|
/**
|
2020-11-06 12:24:46 +00:00
|
|
|
* A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
2020-11-06 12:24:46 +00:00
|
|
|
* A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#scale
|
|
|
|
* @type {number}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.scale = scale;
|
|
|
|
|
2020-11-06 12:24:46 +00:00
|
|
|
/**
|
|
|
|
* The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#minFilter
|
|
|
|
* @type {number}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.minFilter = minFilter;
|
|
|
|
|
2020-11-06 11:42:39 +00:00
|
|
|
/**
|
|
|
|
* Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`)
|
2020-11-06 12:24:46 +00:00
|
|
|
* during the `RenderTarget.bind` method.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* If you need more control over how, or if, the target is cleared, you can disable
|
2020-11-06 12:24:46 +00:00
|
|
|
* this via the config on creation, or even toggle it directly at runtime.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#autoClear
|
|
|
|
* @type {boolean}
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
this.autoClear = autoClear;
|
|
|
|
|
2020-11-19 11:36:58 +00:00
|
|
|
/**
|
|
|
|
* Does this Render Target automatically resize when the WebGL Renderer does?
|
|
|
|
*
|
|
|
|
* Modify this property via the `setAutoResize` method.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#autoResize
|
|
|
|
* @type {boolean}
|
|
|
|
* @readonly
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
2023-02-14 01:29:46 +00:00
|
|
|
this.autoResize = true;
|
2020-11-19 11:36:58 +00:00
|
|
|
|
2023-03-02 18:46:16 +00:00
|
|
|
/**
|
|
|
|
* Does this Render Target have a Depth Buffer?
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#hasDepthBuffer
|
|
|
|
* @type {boolean}
|
|
|
|
* @readonly
|
|
|
|
* @since 3.60.0
|
|
|
|
*/
|
|
|
|
this.hasDepthBuffer = addDepthBuffer;
|
|
|
|
|
2020-11-06 11:42:39 +00:00
|
|
|
this.resize(width, height);
|
2020-11-19 11:36:58 +00:00
|
|
|
|
|
|
|
if (autoResize)
|
|
|
|
{
|
|
|
|
this.setAutoResize(true);
|
|
|
|
}
|
2023-02-14 01:29:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Block resizing unless this RT allows it
|
|
|
|
this.autoResize = false;
|
|
|
|
}
|
2020-11-19 11:36:58 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets if this Render Target should automatically resize when the WebGL Renderer
|
|
|
|
* emits a resize event.
|
|
|
|
*
|
|
|
|
* @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize
|
|
|
|
* @since 3.50.0
|
|
|
|
*
|
|
|
|
* @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes?
|
|
|
|
*
|
|
|
|
* @return {this} This RenderTarget instance.
|
|
|
|
*/
|
|
|
|
setAutoResize: function (autoResize)
|
|
|
|
{
|
|
|
|
if (autoResize && !this.autoResize)
|
|
|
|
{
|
|
|
|
this.renderer.on(Events.RESIZE, this.resize, this);
|
|
|
|
|
|
|
|
this.autoResize = true;
|
|
|
|
}
|
|
|
|
else if (!autoResize && this.autoResize)
|
|
|
|
{
|
|
|
|
this.renderer.off(Events.RESIZE, this.resize, this);
|
|
|
|
|
|
|
|
this.autoResize = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
2020-11-06 11:42:39 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes this Render Target.
|
|
|
|
*
|
|
|
|
* Deletes both the frame buffer and texture, if they exist and then re-creates
|
|
|
|
* them using the new sizes.
|
|
|
|
*
|
|
|
|
* This method is called automatically by the pipeline during its resize handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Renderer.WebGL.RenderTarget#resize
|
|
|
|
* @since 3.50.0
|
|
|
|
*
|
2020-11-19 11:36:58 +00:00
|
|
|
* @param {number} width - The new width of this Render Target.
|
|
|
|
* @param {number} height - The new height of this Render Target.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
|
|
|
* @return {this} This RenderTarget instance.
|
|
|
|
*/
|
|
|
|
resize: function (width, height)
|
|
|
|
{
|
2020-12-10 16:53:48 +00:00
|
|
|
var scaledWidth = width * this.scale;
|
|
|
|
var scaledHeight = height * this.scale;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2023-02-14 01:29:46 +00:00
|
|
|
if (this.autoResize && (scaledWidth !== this.width || scaledHeight !== this.height))
|
2020-12-10 16:53:48 +00:00
|
|
|
{
|
|
|
|
var renderer = this.renderer;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
renderer.deleteFramebuffer(this.framebuffer);
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
renderer.deleteTexture(this.texture);
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
width *= this.scale;
|
|
|
|
height *= this.scale;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2021-02-16 12:32:55 +00:00
|
|
|
width = Math.round(width);
|
|
|
|
height = Math.round(height);
|
|
|
|
|
|
|
|
if (width <= 0)
|
|
|
|
{
|
|
|
|
width = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (height <= 0)
|
|
|
|
{
|
|
|
|
height = 1;
|
|
|
|
}
|
|
|
|
|
2021-10-14 17:45:41 +00:00
|
|
|
this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter, true);
|
2023-03-02 18:46:16 +00:00
|
|
|
this.framebuffer = renderer.createFramebuffer(width, height, this.texture, this.hasDepthBuffer);
|
2020-12-10 16:53:48 +00:00
|
|
|
|
|
|
|
this.width = width;
|
|
|
|
this.height = height;
|
|
|
|
}
|
2020-11-11 17:45:58 +00:00
|
|
|
|
2020-11-06 11:42:39 +00:00
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2020-11-06 12:24:46 +00:00
|
|
|
* Pushes this Render Target as the current frame buffer of the renderer.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
2020-11-06 12:24:46 +00:00
|
|
|
* If `autoClear` is set, then clears the texture.
|
2020-11-06 11:42:39 +00:00
|
|
|
*
|
2020-11-19 16:40:19 +00:00
|
|
|
* If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport.
|
|
|
|
*
|
2020-11-06 12:24:46 +00:00
|
|
|
* @method Phaser.Renderer.WebGL.RenderTarget#bind
|
2020-11-06 11:42:39 +00:00
|
|
|
* @since 3.50.0
|
2020-11-19 16:40:19 +00:00
|
|
|
*
|
|
|
|
* @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ?
|
2020-12-10 16:53:48 +00:00
|
|
|
* @param {number} [width] - Optional new width of this Render Target.
|
|
|
|
* @param {number} [height] - Optional new height of this Render Target.
|
2020-11-06 11:42:39 +00:00
|
|
|
*/
|
2020-12-10 16:53:48 +00:00
|
|
|
bind: function (adjustViewport, width, height)
|
2020-11-06 11:42:39 +00:00
|
|
|
{
|
2020-11-19 16:40:19 +00:00
|
|
|
if (adjustViewport === undefined) { adjustViewport = false; }
|
|
|
|
|
2023-03-14 19:42:09 +00:00
|
|
|
var renderer = this.renderer;
|
|
|
|
|
2020-11-19 16:40:19 +00:00
|
|
|
if (adjustViewport)
|
|
|
|
{
|
2023-03-14 19:42:09 +00:00
|
|
|
renderer.flush();
|
2020-11-19 16:40:19 +00:00
|
|
|
}
|
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
if (width && height)
|
|
|
|
{
|
|
|
|
this.resize(width, height);
|
|
|
|
}
|
|
|
|
|
2023-03-14 19:42:09 +00:00
|
|
|
renderer.pushFramebuffer(this.framebuffer, false, false);
|
2020-11-06 11:42:39 +00:00
|
|
|
|
2020-12-14 09:08:28 +00:00
|
|
|
if (adjustViewport)
|
|
|
|
{
|
|
|
|
this.adjustViewport();
|
|
|
|
}
|
|
|
|
|
2020-11-06 11:42:39 +00:00
|
|
|
if (this.autoClear)
|
|
|
|
{
|
2020-11-19 11:36:58 +00:00
|
|
|
var gl = this.renderer.gl;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
|
|
|
gl.clearColor(0, 0, 0, 0);
|
|
|
|
|
2020-12-11 10:24:05 +00:00
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
2020-11-06 11:42:39 +00:00
|
|
|
}
|
2023-03-14 19:42:09 +00:00
|
|
|
|
|
|
|
renderer.zeroStencilMask();
|
2020-11-19 16:40:19 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2020-12-10 16:53:48 +00:00
|
|
|
* Adjusts the GL viewport to match the width and height of this Render Target.
|
|
|
|
*
|
|
|
|
* Also disables `SCISSOR_TEST`.
|
2020-11-19 16:40:19 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
adjustViewport: function ()
|
|
|
|
{
|
2020-12-10 16:53:48 +00:00
|
|
|
var gl = this.renderer.gl;
|
2020-11-19 16:40:19 +00:00
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
gl.viewport(0, 0, this.width, this.height);
|
2020-11-19 18:07:26 +00:00
|
|
|
|
2020-12-10 16:53:48 +00:00
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
2020-11-06 11:42:39 +00:00
|
|
|
},
|
|
|
|
|
2020-11-19 11:36:58 +00:00
|
|
|
/**
|
|
|
|
* Clears this Render Target.
|
|
|
|
*
|
|
|
|
* @method Phaser.Renderer.WebGL.RenderTarget#clear
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
clear: function ()
|
|
|
|
{
|
2020-12-14 09:08:28 +00:00
|
|
|
var renderer = this.renderer;
|
|
|
|
var gl = renderer.gl;
|
2020-11-19 11:36:58 +00:00
|
|
|
|
2020-12-14 09:08:28 +00:00
|
|
|
renderer.pushFramebuffer(this.framebuffer);
|
|
|
|
|
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
2020-11-19 11:36:58 +00:00
|
|
|
|
|
|
|
gl.clearColor(0, 0, 0, 0);
|
|
|
|
|
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
|
|
|
2020-12-14 09:08:28 +00:00
|
|
|
renderer.popFramebuffer();
|
|
|
|
|
|
|
|
renderer.resetScissor();
|
2020-11-19 11:36:58 +00:00
|
|
|
},
|
|
|
|
|
2020-11-06 12:24:46 +00:00
|
|
|
/**
|
2020-11-19 16:40:19 +00:00
|
|
|
* Unbinds this Render Target and optionally flushes the WebGL Renderer first.
|
2020-11-06 12:24:46 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#unbind
|
|
|
|
* @since 3.50.0
|
2020-11-13 14:19:42 +00:00
|
|
|
*
|
2020-11-19 16:40:19 +00:00
|
|
|
* @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding?
|
|
|
|
*
|
2020-11-13 14:19:42 +00:00
|
|
|
* @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack.
|
2020-11-06 12:24:46 +00:00
|
|
|
*/
|
2020-11-19 16:40:19 +00:00
|
|
|
unbind: function (flush)
|
2020-11-06 11:42:39 +00:00
|
|
|
{
|
2020-11-19 16:40:19 +00:00
|
|
|
if (flush === undefined) { flush = false; }
|
|
|
|
|
2020-11-19 18:07:26 +00:00
|
|
|
var renderer = this.renderer;
|
|
|
|
|
2020-11-19 16:40:19 +00:00
|
|
|
if (flush)
|
|
|
|
{
|
2020-11-19 18:07:26 +00:00
|
|
|
renderer.flush();
|
2020-11-19 16:40:19 +00:00
|
|
|
}
|
|
|
|
|
2020-11-19 18:07:26 +00:00
|
|
|
return renderer.popFramebuffer();
|
2020-11-06 11:42:39 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes all external references from this class and deletes the
|
|
|
|
* WebGL framebuffer and texture instances.
|
|
|
|
*
|
|
|
|
* Does not remove this Render Target from the parent pipeline.
|
|
|
|
*
|
|
|
|
* @name Phaser.Renderer.WebGL.RenderTarget#destroy
|
|
|
|
* @since 3.50.0
|
|
|
|
*/
|
|
|
|
destroy: function ()
|
|
|
|
{
|
2020-11-19 11:36:58 +00:00
|
|
|
var renderer = this.renderer;
|
2020-11-06 11:42:39 +00:00
|
|
|
|
|
|
|
renderer.deleteFramebuffer(this.framebuffer);
|
|
|
|
renderer.deleteTexture(this.texture);
|
|
|
|
|
2020-11-19 11:36:58 +00:00
|
|
|
renderer.off(Events.RESIZE, this.resize, this);
|
|
|
|
|
|
|
|
this.renderer = null;
|
2020-11-06 11:42:39 +00:00
|
|
|
this.framebuffer = null;
|
|
|
|
this.texture = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = RenderTarget;
|