phaser/src/gameobjects/shader/Shader.js

625 lines
18 KiB
JavaScript
Raw Normal View History

2019-04-25 02:15:51 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2019 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var Class = require('../../utils/Class');
var Components = require('../components');
var GameObject = require('../GameObject');
2019-04-25 10:30:23 +00:00
var ModelViewProjection = require('../../renderer/webgl/pipelines/components/ModelViewProjection');
2019-04-25 02:15:51 +00:00
var ShaderRender = require('./ShaderRender');
2019-04-25 10:30:23 +00:00
var TransformMatrix = require('../components/TransformMatrix');
2019-04-25 02:15:51 +00:00
/**
* @classdesc
* A Shader Game Object.
*
* @class Shader
* @extends Phaser.GameObjects.GameObject
* @memberof Phaser.GameObjects
* @constructor
* @webglOnly
* @since 3.17.0
*
* @extends Phaser.GameObjects.Components.Depth
* @extends Phaser.GameObjects.Components.GetBounds
* @extends Phaser.GameObjects.Components.Mask
* @extends Phaser.GameObjects.Components.Origin
* @extends Phaser.GameObjects.Components.Pipeline
* @extends Phaser.GameObjects.Components.Size
* @extends Phaser.GameObjects.Components.Transform
* @extends Phaser.GameObjects.Components.Visible
* @extends Phaser.GameObjects.Components.ScrollFactor
*
* @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 - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
*/
var Shader = new Class({
Extends: GameObject,
Mixins: [
2019-04-25 10:30:23 +00:00
ModelViewProjection,
2019-04-25 02:15:51 +00:00
Components.BlendMode,
Components.Depth,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Size,
Components.Transform,
Components.Visible,
Components.ScrollFactor,
ShaderRender
],
initialize:
function Shader (scene, x, y, width, height, vert, frag)
{
GameObject.call(this, scene, 'Shader');
2019-04-25 10:30:23 +00:00
this.vertexCount = 0;
this.vertexCapacity = 6;
2019-04-25 02:15:51 +00:00
2019-04-25 10:30:23 +00:00
this.renderer = scene.sys.renderer;
2019-04-25 02:15:51 +00:00
2019-04-25 10:30:23 +00:00
/**
* The size in bytes of the vertex.
* The attribute sizes all added together (2 + 2 + 1 + 4)
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexSize
* @type {integer}
* @since 3.0.0
*/
this.vertexSize = Float32Array.BYTES_PER_ELEMENT * 2;
/**
* The WebGL context this WebGL Pipeline uses.
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#gl
* @type {WebGLRenderingContext}
* @since 3.17.0
*/
this.gl = this.renderer.gl;
/**
* Raw byte buffer of vertices.
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexData
* @type {ArrayBuffer}
* @since 3.0.0
*/
this.vertexData = new ArrayBuffer(this.vertexCapacity * this.vertexSize);
/**
* The handle to a WebGL vertex buffer object.
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexBuffer
* @type {WebGLBuffer}
* @since 3.0.0
*/
this.vertexBuffer = this.renderer.createVertexBuffer(this.vertexData.byteLength, this.gl.STREAM_DRAW);
/**
* The handle to a WebGL program
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#program
* @type {WebGLProgram}
* @since 3.0.0
*/
this.program = this.renderer.createProgram(vert, frag);
/**
* Array of objects that describe the vertex attributes
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#attributes
* @type {object}
* @since 3.0.0
*/
this.attributes = [
{
name: 'inPosition',
size: 2,
type: this.gl.FLOAT,
normalized: false,
offset: 0
}
];
/**
* The primitive topology which the pipeline will use to submit draw calls
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#topology
* @type {integer}
* @since 3.0.0
*/
this.topology = this.gl.TRIANGLES;
/**
* Uint8 view to the vertex raw buffer. Used for uploading vertex buffer resources
* to the GPU.
*
* @name Phaser.Renderer.WebGL.WebGLPipeline#bytes
* @type {Uint8Array}
* @since 3.0.0
*/
this.bytes = new Uint8Array(this.vertexData);
/**
* Float32 view of the array buffer containing the pipeline's vertices.
*
* @name Phaser.Renderer.WebGL.Pipelines.QuadShaderPipeline#vertexViewF32
* @type {Float32Array}
* @since 3.17.0
*/
this.vertexViewF32 = new Float32Array(this.vertexData);
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.Pipelines.QuadShaderPipeline#_tempMatrix1
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.17.0
*/
this._tempMatrix1 = new TransformMatrix();
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.Pipelines.QuadShaderPipeline#_tempMatrix2
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.17.0
*/
this._tempMatrix2 = new TransformMatrix();
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.Pipelines.QuadShaderPipeline#_tempMatrix3
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.17.0
*/
this._tempMatrix3 = new TransformMatrix();
2019-04-25 02:15:51 +00:00
this.setPosition(x, y);
this.setSize(width, height);
this.setOrigin(0.5, 0.5);
2019-04-25 10:30:23 +00:00
this.mvpInit();
2019-04-25 10:30:23 +00:00
this.projOrtho(0, this.renderer.width, this.renderer.height, 0, -1000.0, 1000.0);
},
/**
* Adds a description of vertex attribute to the pipeline
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#addAttribute
* @since 3.2.0
*
* @param {string} name - Name of the vertex attribute
* @param {integer} size - Vertex component size
* @param {integer} type - Type of the attribute
* @param {boolean} normalized - Is the value normalized to a range
* @param {integer} offset - Byte offset to the beginning of the first element in the vertex
*
* @return {this} This WebGLPipeline instance.
*/
addAttribute: function (name, size, type, normalized, offset)
{
this.attributes.push({
name: name,
size: size,
type: this.renderer.glFormats[type],
normalized: normalized,
offset: offset
});
return this;
},
/**
* Binds the pipeline resources, including programs, vertex buffers and binds attributes
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#bind
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
bind: function ()
{
var gl = this.gl;
var vertexBuffer = this.vertexBuffer;
var attributes = this.attributes;
var program = this.program;
var renderer = this.renderer;
var vertexSize = this.vertexSize;
renderer.setProgram(program);
renderer.setVertexBuffer(vertexBuffer);
for (var index = 0; index < attributes.length; index++)
{
var element = attributes[index];
var location = gl.getAttribLocation(program, element.name);
if (location >= 0)
{
gl.enableVertexAttribArray(location);
gl.vertexAttribPointer(location, element.size, element.type, element.normalized, vertexSize, element.offset);
}
else if (location !== -1)
{
gl.disableVertexAttribArray(location);
}
}
this.setFloat1('time', this.renderer.game.loop.time / 1000);
this.setFloat2('resolution', this.width, this.height);
},
/**
* 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
*
* @return {this} This WebGLPipeline instance.
*/
flush: function ()
{
var gl = this.gl;
var vertexCount = 6;
var topology = this.topology;
var vertexSize = this.vertexSize;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize));
gl.drawArrays(topology, 0, vertexCount);
},
/**
* Renders a single quad using the current shader and then flushes the batch.
*
* @method Phaser.Renderer.WebGL.Pipelines.QuadShaderPipeline#draw
* @since 3.17.0
*/
draw: function ()
2019-04-25 10:30:23 +00:00
{
var xw = this.width;
var yh = this.height;
2019-04-25 10:30:23 +00:00
var vertexViewF32 = this.vertexViewF32;
vertexViewF32[0] = 0;
vertexViewF32[1] = 0;
vertexViewF32[2] = 0;
vertexViewF32[3] = yh;
vertexViewF32[4] = xw;
vertexViewF32[5] = yh;
vertexViewF32[6] = 0;
vertexViewF32[7] = 0;
vertexViewF32[8] = xw;
vertexViewF32[9] = yh;
vertexViewF32[10] = xw;
vertexViewF32[11] = 0;
2019-04-25 10:30:23 +00:00
this.flush();
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat1
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - The new value of the `float` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat1: function (name, x)
{
this.renderer.setFloat1(this.program, name, x);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat2
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - The new X component of the `vec2` uniform.
* @param {number} y - The new Y component of the `vec2` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat2: function (name, x, y)
{
this.renderer.setFloat2(this.program, name, x, y);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat3
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - The new X component of the `vec3` uniform.
* @param {number} y - The new Y component of the `vec3` uniform.
* @param {number} z - The new Z component of the `vec3` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat3: function (name, x, y, z)
{
this.renderer.setFloat3(this.program, name, x, y, z);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat4
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - X component of the uniform
* @param {number} y - Y component of the uniform
* @param {number} z - Z component of the uniform
* @param {number} w - W component of the uniform
*
* @return {this} This WebGLPipeline instance.
*/
setFloat4: function (name, x, y, z, w)
{
this.renderer.setFloat4(this.program, name, x, y, z, w);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat1v
* @since 3.13.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat1v: function (name, arr)
{
this.renderer.setFloat1v(this.program, name, arr);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat2v
* @since 3.13.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat2v: function (name, arr)
{
this.renderer.setFloat2v(this.program, name, arr);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat3v
* @since 3.13.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat3v: function (name, arr)
{
this.renderer.setFloat3v(this.program, name, arr);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setFloat4v
* @since 3.13.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLPipeline instance.
*/
setFloat4v: function (name, arr)
{
this.renderer.setFloat4v(this.program, name, arr);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setInt1
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {integer} x - The new value of the `int` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setInt1: function (name, x)
{
this.renderer.setInt1(this.program, name, x);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setInt2
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {integer} x - The new X component of the `ivec2` uniform.
* @param {integer} y - The new Y component of the `ivec2` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setInt2: function (name, x, y)
{
this.renderer.setInt2(this.program, name, x, y);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setInt3
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {integer} x - The new X component of the `ivec3` uniform.
* @param {integer} y - The new Y component of the `ivec3` uniform.
* @param {integer} z - The new Z component of the `ivec3` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setInt3: function (name, x, y, z)
{
this.renderer.setInt3(this.program, name, x, y, z);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setInt4
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {integer} x - X component of the uniform
* @param {integer} y - Y component of the uniform
* @param {integer} z - Z component of the uniform
* @param {integer} w - W component of the uniform
*
* @return {this} This WebGLPipeline instance.
*/
setInt4: function (name, x, y, z, w)
{
this.renderer.setInt4(this.program, name, x, y, z, w);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix2
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {Float32Array} matrix - The new values for the `mat2` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix2: function (name, transpose, matrix)
{
this.renderer.setMatrix2(this.program, name, transpose, matrix);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix3
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {Float32Array} matrix - The new values for the `mat3` uniform.
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix3: function (name, transpose, matrix)
{
this.renderer.setMatrix3(this.program, name, transpose, matrix);
return this;
},
/**
* Set a uniform value of the current pipeline program.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix4
* @since 3.2.0
*
* @param {string} name - The name of the uniform to look-up and modify.
* @param {boolean} transpose - Should the matrix be transpose
* @param {Float32Array} matrix - Matrix data
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix4: function (name, transpose, matrix)
{
this.renderer.setMatrix4(this.program, name, transpose, matrix);
return this;
},
/**
* Removes all object references in this WebGL Pipeline and removes its program from the WebGL context.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#destroy
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function ()
{
var gl = this.gl;
gl.deleteProgram(this.program);
gl.deleteBuffer(this.vertexBuffer);
delete this.program;
delete this.vertexBuffer;
delete this.gl;
return this;
2019-04-25 02:15:51 +00:00
}
});
module.exports = Shader;