phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
836 lines (783 loc) • 38.1 kB
JavaScript
/**
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2025 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../utils/Class');
var DynamicTexture = require('../../textures/DynamicTexture');
var Image = require('../image/Image');
/**
* @classdesc
* A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the
* Dynamic Texture to display itself with.
*
* A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of
* Game Objects directly to it.
*
* You can take many complex objects and draw them to this one texture, which can then be used as the
* base texture for other Game Objects, such as Sprites. Should you then update this texture, all
* Game Objects using it will instantly be updated as well, reflecting the changes immediately.
*
* It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke
* expensive GPU uploads on each change.
*
* In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture
* like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to
* the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result,
* the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers
* proxy methods to the features available from a Dynamic Texture.
*
* **When should you use a Render Texture vs. a Dynamic Texture?**
*
* You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects,
* or you want to use it across multiple Scenes, because textures are globally stored.
*
* You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is
* instead going to be used for something like a mask or shader.
*
* You should use a Render Texture if you need to display the texture in-game on a single Game Object,
* as it provides the convenience of wrapping an Image and Dynamic Texture together for you.
*
* Under WebGL1, a FrameBuffer, which is what this Dynamic Texture uses internally, cannot be anti-aliased.
* This means that when drawing objects such as Shapes or Graphics instances to this texture, they may appear
* to be drawn with no aliasing around the edges. This is a technical limitation of WebGL1. To get around it,
* create your shape as a texture in an art package, then draw that to this texture.
*
* @class RenderTexture
* @extends Phaser.GameObjects.Image
* @memberof Phaser.GameObjects
* @constructor
* @since 3.2.0
*
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
* @param {number} [x=0] - The horizontal position of this Game Object in the world.
* @param {number} [y=0] - The vertical position of this Game Object in the world.
* @param {number} [width=32] - The width of the Render Texture.
* @param {number} [height=32] - The height of the Render Texture.
* @param {boolean} [forceEven=true] - Force the given width and height to be rounded to even values. This significantly improves the rendering quality. Set to false if you know you need an odd sized texture.
*/
var RenderTexture = new Class({
Extends: Image,
initialize:
function RenderTexture (scene, x, y, width, height, forceEven)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (width === undefined) { width = 32; }
if (height === undefined) { height = 32; }
if (forceEven === undefined) { forceEven = true; }
var dynamicTexture = new DynamicTexture(scene.sys.textures, '', width, height, forceEven);
Image.call(this, scene, x, y, dynamicTexture);
this.type = 'RenderTexture';
/**
* An internal Camera that can be used to move around this Render Texture.
*
* Control it just like you would any Scene Camera. The difference is that it only impacts
* the placement of Game Objects that you then draw to this texture.
*
* You can scroll, zoom and rotate this Camera.
*
* This property is a reference to `RenderTexture.texture.camera`.
*
* @name Phaser.GameObjects.RenderTexture#camera
* @type {Phaser.Cameras.Scene2D.BaseCamera}
* @since 3.12.0
*/
this.camera = this.texture.camera;
/**
* Internal saved texture flag.
*
* @name Phaser.GameObjects.RenderTexture#_saved
* @type {boolean}
* @private
* @since 3.12.0
*/
this._saved = false;
},
/**
* Sets the internal size of this Render Texture, as used for frame or physics body creation.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values. You could also call the `resize` method, as that
* will resize the underlying texture.
*
* If you have enabled this Game Object for input, changing the size will also change the
* size of the hit area, unless you have defined a custom hit area.
*
* @method Phaser.GameObjects.RenderTexture#setSize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function (width, height)
{
this.width = width;
this.height = height;
this.updateDisplayOrigin();
var input = this.input;
if (input && !input.customHitArea)
{
input.hitArea.width = width;
input.hitArea.height = height;
}
return this;
},
/**
* Resizes the Render Texture to the new dimensions given.
*
* In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture.
* In Canvas it will resize the underlying canvas element.
*
* Both approaches will erase everything currently drawn to the Render Texture.
*
* Calling this will then invoke the `setSize` method, setting the internal size of this Game Object
* to the values given to this method.
*
* If the dimensions given are the same as those already being used, calling this method will do nothing.
*
* @method Phaser.GameObjects.RenderTexture#resize
* @since 3.10.0
*
* @param {number} width - The new width of the Render Texture.
* @param {number} [height=width] - The new height of the Render Texture. If not specified, will be set the same as the `width`.
* @param {boolean} [forceEven=true] - Force the given width and height to be rounded to even values. This significantly improves the rendering quality. Set to false if you know you need an odd sized texture.
*
* @return {this} This Render Texture.
*/
resize: function (width, height, forceEven)
{
this.texture.setSize(width, height, forceEven);
this.setSize(this.texture.width, this.texture.height);
return this;
},
/**
* Stores a copy of this Render Texture in the Texture Manager using the given key.
*
* After doing this, any texture based Game Object, such as a Sprite, can use the contents of this
* Render Texture by using the texture key:
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 128, 128);
*
* // Draw something to the Render Texture
*
* rt.saveTexture('doodle');
*
* this.add.image(400, 300, 'doodle');
* ```
*
* Updating the contents of this Render Texture will automatically update _any_ Game Object
* that is using it as a texture. Calling `saveTexture` again will not save another copy
* of the same texture, it will just rename the key of the existing copy.
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame from a Render Texture.
*
* If you destroy this Render Texture, any Game Object using it via the Texture Manager will
* stop rendering. Ensure you remove the texture from the Texture Manager and any Game Objects
* using it first, before destroying this Render Texture.
*
* @method Phaser.GameObjects.RenderTexture#saveTexture
* @since 3.12.0
*
* @param {string} key - The unique key to store the texture as within the global Texture Manager.
*
* @return {Phaser.Textures.DynamicTexture} The Texture that was saved.
*/
saveTexture: function (key)
{
var texture = this.texture;
texture.key = key;
if (texture.manager.addDynamicTexture(texture))
{
this._saved = true;
}
return texture;
},
/**
* Fills this Render Texture with the given color.
*
* By default it will fill the entire texture, however you can set it to fill a specific
* rectangular area by using the x, y, width and height arguments.
*
* The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc.
*
* @method Phaser.GameObjects.RenderTexture#fill
* @since 3.2.0
*
* @param {number} rgb - The color to fill this Render Texture with, such as 0xff0000 for red.
* @param {number} [alpha=1] - The alpha value used by the fill.
* @param {number} [x=0] - The left coordinate of the fill rectangle.
* @param {number} [y=0] - The top coordinate of the fill rectangle.
* @param {number} [width=this.width] - The width of the fill rectangle.
* @param {number} [height=this.height] - The height of the fill rectangle.
*
* @return {this} This Render Texture instance.
*/
fill: function (rgb, alpha, x, y, width, height)
{
this.texture.fill(rgb, alpha, x, y, width, height);
return this;
},
/**
* Fully clears this Render Texture, erasing everything from it and resetting it back to
* a blank, transparent, texture.
*
* @method Phaser.GameObjects.RenderTexture#clear
* @since 3.2.0
*
* @return {this} This Render Texture instance.
*/
clear: function ()
{
this.texture.clear();
return this;
},
/**
* Takes the given texture key and frame and then stamps it at the given
* x and y coordinates. You can use the optional 'config' argument to provide
* lots more options about how the stamp is applied, including the alpha,
* tint, angle, scale and origin.
*
* By default, the frame will stamp on the x/y coordinates based on its center.
*
* If you wish to stamp from the top-left, set the config `originX` and
* `originY` properties both to zero.
*
* @method Phaser.GameObjects.RenderTexture#stamp
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {Phaser.Types.Textures.StampConfig} [config] - The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp.
*
* @return {this} This Render Texture instance.
*/
stamp: function (key, frame, x, y, config)
{
this.texture.stamp(key, frame, x, y, config);
return this;
},
/**
* Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE.
* This has the effect of erasing any filled pixels present in the objects from this texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note: You cannot erase a Render Texture from itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* @method Phaser.GameObjects.RenderTexture#erase
* @since 3.16.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
*
* @return {this} This Render Texture instance.
*/
erase: function (entries, x, y)
{
this.texture.erase(entries, x, y);
return this;
},
/**
* Draws the given object, or an array of objects, to this Render Texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note 1: You cannot draw a Render Texture to itself.
*
* Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be
* used when drawn to this texture.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* @method Phaser.GameObjects.RenderTexture#draw
* @since 3.2.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
draw: function (entries, x, y, alpha, tint)
{
this.texture.draw(entries, x, y, alpha, tint);
return this;
},
/**
* Draws the Texture Frame to the Render Texture at the given position.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 800, 600);
* rt.drawFrame(key, frame);
* ```
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* Calling this method will cause a batch flush, so if you've got a stack of things to draw
* in a tight loop, try using the `draw` method instead.
*
* If you need to draw a Sprite to this Render Texture, use the `draw` method instead.
*
* @method Phaser.GameObjects.RenderTexture#drawFrame
* @since 3.12.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. WebGL only.
*
* @return {this} This Render Texture instance.
*/
drawFrame: function (key, frame, x, y, alpha, tint)
{
this.texture.drawFrame(key, frame, x, y, alpha, tint);
return this;
},
/**
* Takes the given Texture Frame and draws it to this Render Texture as a fill pattern,
* i.e. in a grid-layout based on the frame dimensions.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, width, height, alpha and tint value to apply to
* the frames before they are drawn. The position controls the top-left where the repeating
* fill will start from. The width and height control the size of the filled area.
*
* The position can be negative if required, but the dimensions cannot.
*
* Calling this method will cause a batch flush by default. Use the `skipBatch` argument
* to disable this if this call is part of a larger batch draw.
*
* @method Phaser.GameObjects.RenderTexture#repeat
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to start drawing the frames from (can be negative to offset).
* @param {number} [y=0] - The y position to start drawing the frames from (can be negative to offset).
* @param {number} [width=this.width] - The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture.
* @param {number} [height=this.height] - The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture.
* @param {number} [alpha=1] - The alpha to use. Defaults to 1, no alpha.
* @param {number} [tint=0xffffff] - WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint.
* @param {boolean} [skipBatch=false] - Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw.
*
* @return {this} This Render Texture instance.
*/
repeat: function (key, frame, x, y, width, height, alpha, tint, skipBatch)
{
this.texture.repeat(key, frame, x, y, width, height, alpha, tint, skipBatch);
return this;
},
/**
* Use this method if you need to batch draw a large number of Game Objects to
* this Render Texture in a single pass, or on a frequent basis. This is especially
* useful under WebGL, however, if your game is using Canvas only, it will not make
* any speed difference in that situation.
*
* This method starts the beginning of a batched draw, unless one is already open.
*
* Batched drawing is faster than calling `draw` in loop, but you must be careful
* to manage the flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.GameObjects.RenderTexture#beginDraw
* @since 3.50.0
*
* @return {this} This Render Texture instance.
*/
beginDraw: function ()
{
this.texture.beginDraw();
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of objects to this Render Texture.
*
* This method batches the drawing of the given objects to this texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of objects it's much safer and easier to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* This method can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene's Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture or Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up a texture from the Texture Manager.
*
* Note: You cannot draw a Render Texture to itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* @method Phaser.GameObjects.RenderTexture#batchDraw
* @since 3.50.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
batchDraw: function (entries, x, y, alpha, tint)
{
this.texture.batchDraw(entries, x, y, alpha, tint);
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of texture frames to this Render Texture.
*
* This method batches the drawing of the given frames to this Render Texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `drawFrame`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of frames it's much safer and easier to use the `drawFrame` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* @method Phaser.GameObjects.RenderTexture#batchDrawFrame
* @since 3.50.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
batchDrawFrame: function (key, frame, x, y, alpha, tint)
{
this.texture.batchDrawFrame(key, frame, x, y, alpha, tint);
return this;
},
/**
* Use this method to finish batch drawing to this Render Texture.
*
* Doing so will stop the WebGL Renderer from capturing draws and then blit the
* framebuffer to the Render Target owned by this texture.
*
* Calling this method without first calling `beginDraw` will have no effect.
*
* Batch drawing is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.GameObjects.RenderTexture#endDraw
* @since 3.50.0
*
* @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn.
*
* @return {this} This Render Texture instance.
*/
endDraw: function (erase)
{
this.texture.endDraw(erase);
return this;
},
/**
* Takes a snapshot of the given area of this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Render Texture see the `snapshot` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Render Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.GameObjects.RenderTexture#snapshotArea
* @since 3.19.0
*
* @param {number} x - The x coordinate to grab from.
* @param {number} y - The y coordinate to grab from.
* @param {number} width - The width of the area to grab.
* @param {number} height - The height of the area to grab.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Render Texture instance.
*/
snapshotArea: function (x, y, width, height, callback, type, encoderOptions)
{
this.texture.snapshotArea(x, y, width, height, callback, type, encoderOptions);
return this;
},
/**
* Takes a snapshot of the whole of this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture a portion of this Render Texture see the `snapshotArea` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Render Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.GameObjects.RenderTexture#snapshot
* @since 3.19.0
*
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Render Texture instance.
*/
snapshot: function (callback, type, encoderOptions)
{
return this.snapshotArea(0, 0, this.width, this.height, callback, type, encoderOptions);
},
/**
* Takes a snapshot of the given pixel from this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Render Texture see the `snapshot` method.
* To capture a portion of this Render Texture see the `snapshotArea` method.
*
* Unlike the two other snapshot methods, this one will send your callback a `Color` object
* containing the color data for the requested pixel. It doesn't need to create an internal
* Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods.
*
* @method Phaser.GameObjects.RenderTexture#snapshotPixel
* @since 3.19.0
*
* @param {number} x - The x coordinate of the pixel to get.
* @param {number} y - The y coordinate of the pixel to get.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted.
*
* @return {this} This Render Texture instance.
*/
snapshotPixel: function (x, y, callback)
{
return this.snapshotArea(x, y, 1, 1, callback, 'pixel');
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.RenderTexture#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function ()
{
this.camera = null;
if (!this._saved)
{
this.texture.destroy();
}
}
});
module.exports = RenderTexture;