Added manager, target auto clear, clearTarget and lots of new hooks for handlers, plus post bind and post flush support.

This commit is contained in:
Richard Davey 2020-11-04 18:02:11 +00:00
parent f94e7b4f75
commit 4287181b2b

View file

@ -81,6 +81,18 @@ var WebGLPipeline = new Class({
*/
this.renderer = renderer;
/**
* A reference to the WebGL Pipeline Manager.
*
* This is initially undefined and only set when this pipeline is added
* to the manager.
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#manager
* @type {?Phaser.Renderer.WebGL.PipelineManager}
* @since 3.50.0
*/
this.manager;
/**
* The WebGL context this WebGL Pipeline uses.
*
@ -275,6 +287,19 @@ var WebGLPipeline = new Class({
*/
this.targetScale = GetFastValue(config, 'targetScale', 1);
/**
* When using a targetTexture this controls if the target is
* automatically cleared (via `gl.COLOR_BUFFER_BIT`) during the `postBind` method.
*
* If you need more control how, or if, the target is cleared, you can disable
* this via the config, or even directly at runtime.
*
* @name Phaser.GameObjects.Shader#targetAutoClear
* @type {boolean}
* @since 3.50.0
*/
this.targetAutoClear = GetFastValue(config, 'targetAutoClear', true);
/**
* An array of all the WebGLShader instances that belong to this pipeline.
*
@ -350,8 +375,6 @@ var WebGLPipeline = new Class({
{
this.targetTexture = renderer.createTextureFromSource(null, width, height, 0);
this.targetFramebuffer = renderer.createFramebuffer(width, height, this.targetTexture, false);
// this.targetTexture.flipY = flipY;
}
this.setShadersFromConfig(config);
@ -412,6 +435,24 @@ var WebGLPipeline = new Class({
this.onBoot();
},
clearTarget: function ()
{
var gl = this.gl;
var renderer = this.renderer;
var target = this.targetTexture;
if (target)
{
renderer.setFramebuffer(this.targetFramebuffer);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.setFramebuffer(null, false);
}
},
/**
* This method is called once when this pipeline has finished being set-up
* at the end of the boot process. By the time this method is called, all
@ -664,8 +705,6 @@ var WebGLPipeline = new Class({
this.targetTexture = renderer.createTextureFromSource(null, width, height, 0);
this.targetFramebuffer = renderer.createFramebuffer(width, height, this.targetTexture, false);
// this.targetTexture.flipY = flipY;
}
var shaders = this.shaders;
@ -698,11 +737,6 @@ var WebGLPipeline = new Class({
*/
bind: function ()
{
if (this.targetTexture)
{
this.renderer.setFramebuffer(this.targetFramebuffer);
}
var wasBound = this.renderer.setVertexBuffer(this.vertexBuffer);
this.currentShader.bind(wasBound);
@ -710,6 +744,40 @@ var WebGLPipeline = new Class({
return this;
},
/**
* TODO
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#postBind
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
postBind: function (gameObject)
{
var renderer = this.renderer;
var target = this.targetTexture;
if (target)
{
renderer.setFramebuffer(this.targetFramebuffer);
if (this.targetAutoClear)
{
var gl = this.gl;
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
}
this.onPostBind(gameObject);
return this;
},
/**
* This method is called every time the Pipeline Manager deactivates this pipeline, swapping from
* it to another one. This happens after a call to `flush` and before the new pipeline is bound.
@ -725,134 +793,25 @@ var WebGLPipeline = new Class({
}
},
/**
* This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline.
*
* Unlike the `bind` method, which is only called once per frame, this is called for every object
* that requests use of this pipeline, allowing you to perform per-object set-up, such as loading
* shader uniform data.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
onBind: function ()
{
return this;
},
/**
* This method is called once per frame, right before anything has been rendered, but after the canvas
* has been cleared. If this pipeline has a targetTexture, it will be cleared.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
onPreRender: function ()
{
var gl = this.gl;
var renderer = this.renderer;
var target = this.targetTexture;
if (target)
{
renderer.setFramebuffer(this.targetFramebuffer);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.setFramebuffer(null, false);
}
return this;
},
/**
* This method is called once per frame, for every Camera in a Scene that wants to render.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onRender
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with.
*
* @return {this} This WebGLPipeline instance.
*/
onRender: function ()
{
return this;
},
/**
* This method is called once per frame, after all rendering has happened and snapshots have been taken.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
onPostRender: function ()
{
return this;
},
/**
* This method is called every time this pipeline is asked to flush its batch.
*
* It is called immediately before the gl.bufferData and gl.drawArray calls are made, so you can
* perform any final pre-render modifications. To apply changes post-render, see `onPostFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onFlush
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
onFlush: function ()
{
return this;
},
/**
* This method is called immediately after this pipeline has finished flushing its batch.
*
* It is called after the `gl.drawArray` call.
*
* You can perform additional post-render effects, but be careful not to call `flush`
* on this pipeline from within this method, or you'll cause an infinite loop.
*
* To apply changes pre-render, see `onFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostFlush
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
onPostFlush: function ()
{
return this;
},
/**
* Uploads the vertex data and emits a draw call for the current batch of vertices.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#flush
* @since 3.0.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*
* @return {this} This WebGLPipeline instance.
*/
flush: function ()
flush: function (isPostFlush)
{
if (isPostFlush === undefined) { isPostFlush = false; }
var vertexCount = this.vertexCount;
if (vertexCount > 0)
{
this.onFlush();
this.onBeforeFlush(isPostFlush);
var gl = this.gl;
var vertexSize = this.currentShader.vertexSize;
@ -870,12 +829,173 @@ var WebGLPipeline = new Class({
this.vertexCount = 0;
this.onPostFlush();
this.onAfterFlush(isPostFlush);
}
return this;
},
/**
* TODO
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#postFlush
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
postFlush: function (gameObject)
{
this.renderer.setFramebuffer(null);
this.renderer.resetTextures();
var wasBound = this.renderer.setVertexBuffer(this.vertexBuffer);
this.currentShader.bind(wasBound);
var texture = this.targetTexture;
var width = texture.width;
var height = texture.height;
this.drawFillRect(0, 0, width, height, 0x0, 0.5, texture, true);
this.flush(true);
this.onPostFlush(gameObject);
return this;
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline.
*
* Unlike the `bind` method, which is only called once per frame, this is called for every object
* that requests use of this pipeline, allowing you to perform per-object set-up, such as loading
* shader uniform data.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onBind: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline
* as the post-render pipeline.
*
* Unlike the `bind` method, which is only called once per frame, this is called for every object
* that requests use of this pipeline, allowing you to perform per-object set-up, such as loading
* shader uniform data.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostBind
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onPostBind: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* TODO
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostFlush
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onPostFlush: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called once per frame, right before anything has been rendered, but after the canvas
* has been cleared. If this pipeline has a targetTexture, it will be cleared.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender
* @since 3.50.0
*/
onPreRender: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called once per frame, for every Camera in a Scene that wants to render.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onRender
* @since 3.50.0
*
* @param {Phaser.Scene} scene - The Scene being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with.
*/
onRender: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called once per frame, after all rendering has happened and snapshots have been taken.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender
* @since 3.50.0
*/
onPostRender: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time this pipeline is asked to flush its batch.
*
* It is called immediately before the gl.bufferData and gl.drawArray calls are made, so you can
* perform any final pre-render modifications. To apply changes post-render, see `onPostFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBeforeFlush
* @since 3.50.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*/
onBeforeFlush: function ()
{
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called immediately after this pipeline has finished flushing its batch.
*
* It is called after the `gl.drawArrays` call.
*
* You can perform additional post-render effects, but be careful not to call `flush`
* on this pipeline from within this method, or you'll cause an infinite loop.
*
* To apply changes pre-render, see `onBeforeFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onAfterFlush
* @since 3.50.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*/
onAfterFlush: function ()
{
},
/**
* Adds a single vertex to the current vertex buffer and increments the
* `vertexCount` property by 1.
@ -1059,10 +1179,12 @@ var WebGLPipeline = new Class({
* @param {number} color - Color of the rectangle to draw.
* @param {number} alpha - Alpha value of the rectangle to draw.
* @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs.
* @param {boolean} [flipUV=true] - Flip the vertical UV coordinates of the texture before rendering?
*/
drawFillRect: function (x, y, width, height, color, alpha, texture)
drawFillRect: function (x, y, width, height, color, alpha, texture, flipUV)
{
if (texture === undefined) { texture = this.renderer.whiteTexture.glTexture; }
if (flipUV === undefined) { flipUV = true; }
x = Math.floor(x);
y = Math.floor(y);
@ -1074,7 +1196,18 @@ var WebGLPipeline = new Class({
var tint = Utils.getTintAppendFloatAlphaAndSwap(color, alpha);
this.batchQuad(x, y, x, yh, xw, yh, xw, y, 0, 0, 1, 1, tint, tint, tint, tint, 0, texture, unit);
var u0 = 0;
var v0 = 0;
var u1 = 1;
var v1 = 1;
if (flipUV)
{
v0 = 1;
v1 = 0;
}
this.batchQuad(x, y, x, yh, xw, yh, xw, y, u0, v0, u1, v1, tint, tint, tint, tint, 0, texture, unit);
},
/**