phaser/src/renderer/webgl/PipelineManager.js

923 lines
30 KiB
JavaScript
Raw Normal View History

2020-09-09 10:38:45 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../utils/Class');
var CONST = require('./pipelines/const');
var CustomMap = require('../../structs/Map');
2020-09-09 10:38:45 +00:00
// Default Phaser 3 Pipelines
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
2020-10-28 17:39:54 +00:00
var GraphicsPipeline = require('./pipelines/GraphicsPipeline');
2020-09-09 10:38:45 +00:00
var LightPipeline = require('./pipelines/LightPipeline');
var MultiPipeline = require('./pipelines/MultiPipeline');
var PostFXPipeline = require('./pipelines/PostFXPipeline');
2020-09-09 10:38:45 +00:00
var RopePipeline = require('./pipelines/RopePipeline');
var SinglePipeline = require('./pipelines/SinglePipeline');
var UtilityPipeline = require('./pipelines/UtilityPipeline');
2020-09-09 10:38:45 +00:00
/**
* @classdesc
2020-09-22 10:33:40 +00:00
* The Pipeline Manager is responsible for the creation, activation, running and destruction
* of WebGL Pipelines in Phaser 3.
2020-09-09 10:38:45 +00:00
*
2020-09-22 10:33:40 +00:00
* The `WebGLRenderer` owns a single instance of the Pipeline Manager, which you can access
* via the `WebGLRenderer.pipelines` property.
*
* By default, there are 5 pipelines installed into the Pipeline Manager when Phaser boots:
2020-09-22 10:33:40 +00:00
*
* 1. The Multi Pipeline. Responsible for all multi-texture rendering, i.e. Sprites, Shapes.
* 2. The Single Pipeline. Responsible for rendering Game Objects that explicitly require one bound texture.
* 3. The Rope Pipeline. Responsible for rendering the Rope Game Object.
* 4. The Light Pipeline. Responsible for rendering the Light Game Object.
* 5. The Bitmap Mask Pipeline. Responsible for Bitmap Mask rendering.
2020-09-22 10:33:40 +00:00
*
* You can add your own custom pipeline via the `PipelineManager.add` method. Pipelines are
* identified by unique string-based keys.
2020-09-09 10:38:45 +00:00
*
* @class PipelineManager
* @memberof Phaser.Renderer.WebGL
* @constructor
* @since 3.50.0
*
2020-09-09 12:04:45 +00:00
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGL Renderer that owns this Pipeline Manager.
2020-09-09 10:38:45 +00:00
*/
var PipelineManager = new Class({
initialize:
2020-09-09 12:04:45 +00:00
function PipelineManager (renderer)
2020-09-09 10:38:45 +00:00
{
/**
* A reference to the Game instance.
*
* @name Phaser.Renderer.WebGL.PipelineManager#game
* @type {Phaser.Game}
* @since 3.50.0
*/
2020-09-09 12:04:45 +00:00
this.game = renderer.game;
2020-09-09 10:38:45 +00:00
/**
* A reference to the WebGL Renderer instance.
*
* @name Phaser.Renderer.WebGL.PipelineManager#renderer
* @type {Phaser.Renderer.WebGL.WebGLRenderer}
* @since 3.50.0
*/
2020-09-09 12:04:45 +00:00
this.renderer = renderer;
2020-09-09 10:38:45 +00:00
/**
* This map stores all pipeline instances in this manager.
*
* This is populated with the default pipelines in the `boot` method.
*
* @name Phaser.Renderer.WebGL.PipelineManager#pipelines
2020-09-09 10:38:45 +00:00
* @type {Phaser.Structs.Map.<string, Phaser.Renderer.WebGL.WebGLPipeline>}
* @since 3.50.0
*/
this.pipelines = new CustomMap();
/**
* Current pipeline in use by the WebGLRenderer.
*
2020-09-09 12:04:45 +00:00
* @name Phaser.Renderer.WebGL.PipelineManager#current
2020-09-09 10:38:45 +00:00
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @since 3.50.0
*/
2020-09-09 12:04:45 +00:00
this.current = null;
2020-09-09 10:38:45 +00:00
/**
* The previous WebGLPipeline that was in use.
*
* This is set when `clearPipeline` is called and restored in `rebindPipeline` if none is given.
*
2020-09-09 12:04:45 +00:00
* @name Phaser.Renderer.WebGL.PipelineManager#previous
2020-09-09 10:38:45 +00:00
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @since 3.50.0
*/
2020-09-09 12:04:45 +00:00
this.previous = null;
2020-11-04 18:01:01 +00:00
/**
* Current post pipeline in use by the WebGLRenderer.
*
* @name Phaser.Renderer.WebGL.PipelineManager#currentPost
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @since 3.50.0
*/
this.currentPost = null;
/**
* The previous post pipeline that was in use.
*
* @name Phaser.Renderer.WebGL.PipelineManager#previousPost
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @since 3.50.0
*/
this.previousPost = null;
2020-09-09 12:04:45 +00:00
/**
* A constant-style reference to the Multi Pipeline Instance.
*
* This is the default Phaser 3 pipeline and is used by the WebGL Renderer to manage
* camera effects and more. This property is set during the `boot` method.
*
* @name Phaser.Renderer.WebGL.PipelineManager#MULTI_PIPELINE
* @type {Phaser.Renderer.WebGL.Pipelines.MultiPipeline}
* @default null
* @since 3.50.0
*/
this.MULTI_PIPELINE = null;
/**
* A constant-style reference to the Bitmap Mask Pipeline Instance.
*
* This is the default Phaser 3 mask pipeline and is used Game Objects using
* a Bitmap Mask. This property is set during the `boot` method.
*
* @name Phaser.Renderer.WebGL.PipelineManager#BITMAPMASK_PIPELINE
* @type {Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline}
* @default null
* @since 3.50.0
*/
this.BITMAPMASK_PIPELINE = null;
2020-10-30 17:55:56 +00:00
/**
2020-11-10 11:59:12 +00:00
* A constant-style reference to the Post FX Pipeline Instance.
2020-10-30 17:55:56 +00:00
*
* This is the default Phaser 3 camera pipeline and is used by cameras to handle
2020-11-10 11:59:12 +00:00
* their pre and post render, as well as used by other Game Objects for
* post-render effects. This property is set during the `boot` method.
2020-10-30 17:55:56 +00:00
*
2020-11-10 11:59:12 +00:00
* @name Phaser.Renderer.WebGL.PipelineManager#POSTFX_PIPELINE
* @type {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline}
2020-10-30 17:55:56 +00:00
* @default null
* @since 3.50.0
*/
2020-11-10 11:59:12 +00:00
this.POSTFX_PIPELINE = null;
/**
* A constant-style reference to the Utility Pipeline Instance.
*
* @name Phaser.Renderer.WebGL.PipelineManager#UTILITY_PIPELINE
* @type {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline}
* @default null
* @since 3.50.0
*/
this.UTILITY_PIPELINE = null;
2020-11-13 15:54:49 +00:00
/**
* A reference to the Full Frame 1 Render Target that belongs to the
* Utility Pipeline. This property is set during the `boot` method.
*
* This Render Target is the full size of the renderer.
*
* You can use this directly in Post FX Pipelines for multi-target effects.
* However, be aware that these targets are shared between all post fx pipelines.
*
* @name Phaser.Renderer.WebGL.PipelineManager#fullFrame1
* @type {Phaser.Renderer.WebGL.RenderTarget}
* @default null
* @since 3.50.0
*/
this.fullFrame1;
/**
* A reference to the Full Frame 2 Render Target that belongs to the
* Utility Pipeline. This property is set during the `boot` method.
*
* This Render Target is the full size of the renderer.
*
* You can use this directly in Post FX Pipelines for multi-target effects.
* However, be aware that these targets are shared between all post fx pipelines.
*
* @name Phaser.Renderer.WebGL.PipelineManager#fullFrame2
* @type {Phaser.Renderer.WebGL.RenderTarget}
* @default null
* @since 3.50.0
*/
this.fullFrame2;
/**
* A reference to the Half Frame 1 Render Target that belongs to the
* Utility Pipeline. This property is set during the `boot` method.
*
* This Render Target is half the size of the renderer.
*
* You can use this directly in Post FX Pipelines for multi-target effects.
* However, be aware that these targets are shared between all post fx pipelines.
*
* @name Phaser.Renderer.WebGL.PipelineManager#halfFrame1
* @type {Phaser.Renderer.WebGL.RenderTarget}
* @default null
* @since 3.50.0
*/
this.halfFrame1;
/**
* A reference to the Half Frame 2 Render Target that belongs to the
* Utility Pipeline. This property is set during the `boot` method.
*
* This Render Target is half the size of the renderer.
*
* You can use this directly in Post FX Pipelines for multi-target effects.
* However, be aware that these targets are shared between all post fx pipelines.
*
* @name Phaser.Renderer.WebGL.PipelineManager#halfFrame2
* @type {Phaser.Renderer.WebGL.RenderTarget}
* @default null
* @since 3.50.0
*/
this.halfFrame2;
2020-09-09 10:38:45 +00:00
},
/**
* Internal boot handler, called by the WebGLRenderer durings its boot process.
*
* Adds all of the default pipelines, based on the game config, and then calls
* the `boot` method on each one of them.
*
* Finally, the default pipeline is set.
*
* @method Phaser.Renderer.WebGL.PipelineManager#boot
* @since 3.50.0
*/
boot: function ()
{
var game = this.game;
2020-11-13 15:54:49 +00:00
// Must always be set first, before any other pipeline
this.UTILITY_PIPELINE = this.add(CONST.UTILITY_PIPELINE, new UtilityPipeline({ game: game }));
2020-09-09 12:04:45 +00:00
this.MULTI_PIPELINE = this.add(CONST.MULTI_PIPELINE, new MultiPipeline({ game: game }));
this.BITMAPMASK_PIPELINE = this.add(CONST.BITMAPMASK_PIPELINE, new BitmapMaskPipeline({ game: game }));
2020-11-10 11:59:12 +00:00
this.POSTFX_PIPELINE = this.add(CONST.POSTFX_PIPELINE, new PostFXPipeline({ game: game }));
2020-09-09 10:38:45 +00:00
this.add(CONST.SINGLE_PIPELINE, new SinglePipeline({ game: game }));
this.add(CONST.ROPE_PIPELINE, new RopePipeline({ game: game }));
this.add(CONST.LIGHT_PIPELINE, new LightPipeline({ game: game }));
2020-10-28 17:39:54 +00:00
this.add(CONST.GRAPHICS_PIPELINE, new GraphicsPipeline({ game: game }));
2020-11-13 15:54:49 +00:00
var utility = this.UTILITY_PIPELINE;
this.fullFrame1 = utility.fullFrame1;
this.fullFrame2 = utility.fullFrame2;
this.halfFrame1 = utility.halfFrame1;
this.halfFrame2 = utility.halfFrame2;
2020-09-09 10:38:45 +00:00
},
/**
* Adds a pipeline instance to this Pipeline Manager.
*
* The name of the instance must be unique within this manager.
*
* Make sure to pass an instance to this method, not a base class.
*
* For example, you should pass it like this:
*
* ```javascript
* this.add('yourName', new CustomPipeline());`
* ```
*
* and **not** like this:
2020-09-09 10:38:45 +00:00
*
* ```javascript
* this.add('yourName', CustomPipeline);`
2020-09-09 10:38:45 +00:00
* ```
*
* @method Phaser.Renderer.WebGL.PipelineManager#addPipeline
* @since 3.50.0
*
* @param {string} name - A unique string-based key for the pipeline within the manager.
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - A pipeline _instance_ which must extend `WebGLPipeline`.
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was passed.
*/
add: function (name, pipeline)
{
var pipelines = this.pipelines;
var renderer = this.renderer;
if (!pipelines.has(name))
{
pipeline.name = name;
2020-11-04 18:01:01 +00:00
pipeline.manager = this;
2020-09-09 10:38:45 +00:00
pipelines.set(name, pipeline);
}
else
{
console.warn('Pipeline exists: ' + name);
}
2020-11-04 18:01:01 +00:00
if (!pipeline.hasBooted)
{
2020-11-04 18:01:01 +00:00
pipeline.boot();
}
2020-09-09 10:38:45 +00:00
2020-11-04 18:01:01 +00:00
if (renderer.width !== 0 && renderer.height !== 0)
2020-09-09 10:38:45 +00:00
{
2020-11-04 18:01:01 +00:00
pipeline.resize(renderer.width, renderer.height);
2020-09-09 10:38:45 +00:00
}
return pipeline;
},
/**
* Resizes handler.
*
* This is called automatically by the `WebGLRenderer` when the game resizes.
*
* @method Phaser.Renderer.WebGL.PipelineManager#resize
* @since 3.50.0
*
* @param {number} [width] - The new width of the renderer.
* @param {number} [height] - The new height of the renderer.
*/
resize: function (width, height)
2020-09-09 10:38:45 +00:00
{
var pipelines = this.pipelines;
pipelines.each(function (pipelineName, pipelineInstance)
{
pipelineInstance.resize(width, height);
2020-09-09 10:38:45 +00:00
});
},
2020-09-09 12:04:45 +00:00
/**
* Calls the `onPreRender` method on each pipeline in this manager.
*
* This is called automatically by the `WebGLRenderer.preRender` method.
*
* @method Phaser.Renderer.WebGL.PipelineManager#preRender
* @since 3.50.0
*/
preRender: function ()
{
var pipelines = this.pipelines;
pipelines.each(function (pipelineName, pipelineInstance)
{
pipelineInstance.onPreRender();
});
},
/**
* Calls the `onRender` method on each pipeline in this manager.
*
* This is called automatically by the `WebGLRenderer.render` method.
*
* @method Phaser.Renderer.WebGL.PipelineManager#render
* @since 3.50.0
*
* @param {Phaser.Scene} scene - The Scene to render.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with.
*/
render: function (scene, camera)
{
var pipelines = this.pipelines;
pipelines.each(function (pipelineName, pipelineInstance)
{
pipelineInstance.onRender(scene, camera);
});
},
/**
* Calls the `onPostRender` method on each pipeline in this manager.
*
* This is called automatically by the `WebGLRenderer.postRender` method.
*
* @method Phaser.Renderer.WebGL.PipelineManager#postRender
* @since 3.50.0
*/
postRender: function ()
{
2020-10-27 18:06:28 +00:00
this.flush();
2020-09-09 12:04:45 +00:00
var pipelines = this.pipelines;
pipelines.each(function (pipelineName, pipelineInstance)
{
pipelineInstance.onPostRender();
});
},
2020-09-09 10:38:45 +00:00
/**
* Flushes the current pipeline, if one is bound.
*
* @method Phaser.Renderer.WebGL.PipelineManager#flush
* @since 3.50.0
*/
flush: function ()
{
2020-09-09 12:21:38 +00:00
if (this.current)
2020-09-09 10:38:45 +00:00
{
2020-09-09 12:21:38 +00:00
this.current.flush();
2020-09-09 10:38:45 +00:00
}
},
/**
2020-10-27 14:05:48 +00:00
* Checks if a pipeline is present in this Pipeline Manager.
2020-09-09 10:38:45 +00:00
*
* @method Phaser.Renderer.WebGL.PipelineManager#has
* @since 3.50.0
*
2020-10-27 14:05:48 +00:00
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up.
2020-09-09 10:38:45 +00:00
*
* @return {boolean} `true` if the given pipeline is loaded, otherwise `false`.
*/
2020-10-27 14:05:48 +00:00
has: function (pipeline)
2020-09-09 10:38:45 +00:00
{
2020-10-27 14:05:48 +00:00
var pipelines = this.pipelines;
if (typeof pipeline === 'string')
{
return pipelines.has(pipeline);
}
else if (pipelines.contains(pipeline))
{
return true;
}
return false;
2020-09-09 10:38:45 +00:00
},
/**
2020-10-27 14:05:48 +00:00
* Returns the pipeline instance based on the given name, or instance.
2020-09-09 10:38:45 +00:00
*
2020-10-27 14:05:48 +00:00
* If no instance, or matching name, exists in this manager, it returns `undefined`.
2020-09-09 10:38:45 +00:00
*
* @method Phaser.Renderer.WebGL.PipelineManager#get
* @since 3.50.0
*
2020-10-27 14:05:48 +00:00
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up.
2020-09-09 10:38:45 +00:00
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance, or `undefined` if not found.
*/
2020-10-27 14:05:48 +00:00
get: function (pipeline)
2020-09-09 10:38:45 +00:00
{
2020-10-27 14:05:48 +00:00
var pipelines = this.pipelines;
if (typeof pipeline === 'string')
{
return pipelines.get(pipeline);
}
else if (pipelines.contains(pipeline))
{
return pipeline;
}
2020-09-09 10:38:45 +00:00
},
/**
* Removes a pipeline based on the given name.
*
* If no pipeline matches the name, this method does nothing.
*
* Note that the pipeline will not be flushed or destroyed, it's simply removed from
* this manager.
*
* @method Phaser.Renderer.WebGL.PipelineManager#remove
* @since 3.50.0
*
* @param {string} name - The name of the pipeline to be removed.
*/
remove: function (name)
{
this.pipelines.delete(name);
},
/**
* Sets the current pipeline to be used by the `WebGLRenderer`.
*
* This method accepts a pipeline instance as its parameter, not the name.
*
* If the pipeline isn't already the current one it will call `WebGLPipeline.bind` and then `onBind`.
2020-09-09 10:38:45 +00:00
*
* @method Phaser.Renderer.WebGL.PipelineManager#set
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be set as current.
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
2020-09-09 10:38:45 +00:00
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline that was set.
*/
set: function (pipeline, gameObject, currentShader)
2020-09-09 10:38:45 +00:00
{
if (!this.isCurrent(pipeline, currentShader))
2020-09-09 10:38:45 +00:00
{
2020-10-30 17:55:56 +00:00
this.flush();
2020-11-03 18:04:57 +00:00
if (this.current)
{
this.current.unbind();
}
2020-09-09 12:04:45 +00:00
this.current = pipeline;
2020-09-09 10:38:45 +00:00
pipeline.bind(currentShader);
2020-09-09 10:38:45 +00:00
}
2020-11-04 18:01:01 +00:00
pipeline.onBind(gameObject);
2020-09-09 10:38:45 +00:00
return pipeline;
},
2020-11-13 15:54:49 +00:00
/**
* This method is called by the `WebGLPipeline.batchQuad` method, right before a quad
* belonging to a Game Object is about to be added to the batch. It causes a batch
* flush, then calls the `preBatch` method on the post-fx pipeline belonging to the
* Game Object.
*
* @method Phaser.Renderer.WebGL.PipelineManager#preBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object about to be batched.
*/
2020-11-04 18:01:01 +00:00
preBatch: function (gameObject)
{
2020-11-04 18:01:01 +00:00
this.flush();
gameObject.postPipeline.preBatch(gameObject);
2020-11-04 18:01:01 +00:00
},
2020-11-13 15:54:49 +00:00
/**
* This method is called by the `WebGLPipeline.batchQuad` method, right after a quad
* belonging to a Game Object has been added to the batch. It causes a batch
* flush, then calls the `postBatch` method on the post-fx pipeline belonging to the
* Game Object.
*
* @method Phaser.Renderer.WebGL.PipelineManager#postBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to the batch.
*/
2020-11-04 18:01:01 +00:00
postBatch: function (gameObject)
{
this.flush();
gameObject.postPipeline.postBatch(gameObject);
},
2020-11-13 15:54:49 +00:00
/**
* Called at the start of the `WebGLRenderer.preRenderCamera` method.
*
* If the Camera has a postPipeline set, it will flush the batch and then call the
* `preBatch` method on the post-fx pipeline belonging to the Camera.
*
* @method Phaser.Renderer.WebGL.PipelineManager#preBatchCamera
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera being pre-rendered.
*/
preBatchCamera: function (camera)
{
if (camera.postPipeline)
2020-11-04 18:01:01 +00:00
{
this.flush();
camera.postPipeline.preBatch(camera);
2020-11-04 18:01:01 +00:00
}
},
2020-11-13 15:54:49 +00:00
/**
* Called at the end of the `WebGLRenderer.postRenderCamera` method.
*
* If the Camera has a postPipeline set, it will flush the batch and then call the
* `postBatch` method on the post-fx pipeline belonging to the Camera.
*
* @method Phaser.Renderer.WebGL.PipelineManager#postBatchCamera
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that was just rendered.
*/
postBatchCamera: function (camera)
{
if (camera.postPipeline)
{
this.flush();
camera.postPipeline.postBatch(camera);
}
},
/**
2020-11-04 18:01:01 +00:00
* Checks to see if the given pipeline is already the active pipeline, both within this
* Pipeline Manager, and also has the same vertex buffer and shader set within the Renderer.
*
2020-11-04 18:01:01 +00:00
* @method Phaser.Renderer.WebGL.PipelineManager#isCurrent
* @since 3.50.0
*
2020-11-04 18:01:01 +00:00
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be checked.
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
2020-11-04 18:01:01 +00:00
*
* @return {boolean} `true` if the given pipeline is already the current pipeline, otherwise `false`.
*/
isCurrent: function (pipeline, currentShader)
{
2020-11-04 18:01:01 +00:00
var renderer = this.renderer;
var current = this.current;
if (current && !currentShader)
{
currentShader = current.currentShader;
}
2020-11-04 18:01:01 +00:00
return !(
current !== pipeline ||
current.vertexBuffer !== renderer.currentVertexBuffer ||
currentShader.program !== renderer.currentProgram
2020-11-04 18:01:01 +00:00
);
},
2020-11-13 15:54:49 +00:00
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* You can optionally set the brightness factor of the copy.
*
* The difference between this method and `drawFrame` is that this method
* uses a faster copy shader, where only the brightness can be modified.
* If you need color level manipulation, see `drawFrame` instead.
*
* The copy itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#copyFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
copyFrame: function (source, target, brightness, clearAlpha)
{
var pipeline = this.setUtility(this.UTILITY_PIPELINE.copyShader);
pipeline.copyFrame(source, target, brightness, clearAlpha);
return this;
},
2020-11-13 15:54:49 +00:00
/**
* Copy the `source` Render Target to the `target` Render Target, using the
* given Color Matrix.
*
* The difference between this method and `copyFrame` is that this method
* uses a color matrix shader, where you have full control over the luminance
* values used during the copy. If you don't need this, you can use the faster
* `copyFrame` method instead.
*
* The copy itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#drawFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw.
*
* @return {this} This Pipeline Manager instance.
*/
drawFrame: function (source, target, clearAlpha, colorMatrix)
2020-11-12 18:09:21 +00:00
{
var pipeline = this.setUtility(this.UTILITY_PIPELINE.colorMatrixShader);
pipeline.drawFrame(source, target, clearAlpha, colorMatrix);
2020-11-12 18:09:21 +00:00
return this;
},
2020-11-13 15:54:49 +00:00
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using a linear blend effect, which is controlled by the `strength` parameter.
*
* The draw itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#blendFrames
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
blendFrames: function (source1, source2, target, strength, clearAlpha)
2020-11-12 18:09:21 +00:00
{
var pipeline = this.setUtility(this.UTILITY_PIPELINE.linearShader);
pipeline.blendFrames(source1, source2, target, strength, clearAlpha);
return this;
},
2020-11-13 15:54:49 +00:00
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using an additive blend effect, which is controlled by the `strength` parameter.
*
* The draw itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#blendFramesAdditive
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
blendFramesAdditive: function (source1, source2, target, strength, clearAlpha)
{
var pipeline = this.setUtility(this.UTILITY_PIPELINE.addShader);
2020-11-12 18:09:21 +00:00
pipeline.blendFrames(source1, source2, target, strength, clearAlpha);
2020-11-12 18:09:21 +00:00
return this;
},
2020-11-13 15:54:49 +00:00
/**
* Returns `true` if the current pipeline is forced to use texture unit zero.
*
* @method Phaser.Renderer.WebGL.PipelineManager#forceZero
* @since 3.50.0
*
* @return {boolean} `true` if the current pipeline is forced to use texture unit zero.
*/
2020-11-05 10:50:40 +00:00
forceZero: function ()
{
return (this.current && this.current.forceZero);
},
2020-09-09 12:09:25 +00:00
/**
* Sets the Multi Pipeline to be the currently bound pipeline.
*
* This is the default Phaser 3 rendering pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setMulti
* @since 3.50.0
*
* @return {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} The Multi Pipeline instance.
*/
2020-09-09 12:04:45 +00:00
setMulti: function ()
{
return this.set(this.MULTI_PIPELINE);
},
2020-10-30 17:55:56 +00:00
/**
* Sets the Camera Pipeline to be the currently bound pipeline.
*
* This is the default Phaser 3 pipeline for cameras.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setCameraPipeline
* @since 3.50.0
*
* @return {Phaser.Renderer.WebGL.Pipelines.CameraPipeline} The Camera Pipeline instance.
*/
setCameraPipeline: function ()
{
return this.set(this.CAMERA_PIPELINE);
},
/**
* Sets the Utility Pipeline to be the currently bound pipeline.
*
* This is the default Phaser 3 rendering pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setUtility
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} The Utility Pipeline instance.
*/
setUtility: function (currentShader)
{
return this.set(this.UTILITY_PIPELINE, null, currentShader);
},
2020-09-09 10:38:45 +00:00
/**
* Use this to reset the gl context to the state that Phaser requires to continue rendering.
*
* Calling this will:
*
* * Disable `DEPTH_TEST`, `CULL_FACE` and `STENCIL_TEST`.
* * Clear the depth buffer and stencil buffers.
* * Reset the viewport size.
* * Reset the blend mode.
* * Bind a blank texture as the active texture on texture unit zero.
* * Rebinds the given pipeline instance.
*
* You should call this if you have previously called `clear`, and then wish to return
* rendering control to Phaser again.
*
* @method Phaser.Renderer.WebGL.PipelineManager#rebind
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} [pipeline] - The pipeline instance to be rebound. If not given, the previous pipeline will be bound.
*/
rebind: function (pipeline)
{
2020-09-09 12:04:45 +00:00
if (pipeline === undefined && this.previous)
2020-09-09 10:38:45 +00:00
{
2020-09-09 12:04:45 +00:00
pipeline = this.previous;
2020-09-09 10:38:45 +00:00
}
if (!pipeline)
{
return;
}
var renderer = this.renderer;
2020-09-09 12:33:25 +00:00
var gl = renderer.gl;
2020-09-09 10:38:45 +00:00
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
if (renderer.hasActiveStencilMask())
{
gl.clear(gl.DEPTH_BUFFER_BIT);
}
else
{
// If there wasn't a stencil mask set before this call, we can disable it safely
gl.disable(gl.STENCIL_TEST);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
gl.viewport(0, 0, renderer.width, renderer.height);
renderer.currentProgram = null;
renderer.currentVertexBuffer = null;
renderer.currentIndexBuffer = null;
renderer.setBlendMode(0, true);
2020-09-09 12:04:45 +00:00
this.current = pipeline;
2020-09-09 10:38:45 +00:00
2020-11-10 15:50:30 +00:00
pipeline.rebind();
2020-09-09 10:38:45 +00:00
},
/**
* Flushes the current pipeline being used and then clears it, along with the
* the current shader program and vertex buffer from the `WebGLRenderer`.
*
* Then resets the blend mode to NORMAL.
*
* Call this before jumping to your own gl context handler, and then call `rebind` when
* you wish to return control to Phaser again.
*
* @method Phaser.Renderer.WebGL.PipelineManager#clear
* @since 3.50.0
*/
2020-09-09 12:04:45 +00:00
clear: function ()
2020-09-09 10:38:45 +00:00
{
var renderer = this.renderer;
this.flush();
2020-09-09 12:04:45 +00:00
this.previous = this.current;
this.current = null;
2020-09-09 10:38:45 +00:00
renderer.currentProgram = null;
renderer.currentVertexBuffer = null;
renderer.currentIndexBuffer = null;
renderer.setBlendMode(0, true);
},
/**
* Destroy the Pipeline Manager, cleaning up all related resources and references.
*
* @method Phaser.Renderer.WebGL.PipelineManager#destroy
* @since 3.50.0
*/
destroy: function ()
{
this.flush();
this.pipelines.clear();
this.renderer = null;
this.game = null;
this.pipelines = null;
2020-09-09 12:04:45 +00:00
this.current = null;
this.previous = null;
2020-09-09 10:38:45 +00:00
}
});
module.exports = PipelineManager;