phaser/src/renderer/webgl/WebGLRenderer.js

2249 lines
66 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
2018-04-05 08:02:36 +00:00
* @author Felipe Alfonso <@bitnenfer>
2018-02-12 16:01:20 +00:00
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var BaseCamera = require('../../cameras/2d/BaseCamera');
var Class = require('../../utils/Class');
var CONST = require('../../const');
2018-01-20 04:05:56 +00:00
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
var SpliceOne = require('../../utils/array/SpliceOne');
var TransformMatrix = require('../../gameobjects/components/TransformMatrix');
2018-01-24 03:57:33 +00:00
var Utils = require('./Utils');
2018-02-09 19:19:21 +00:00
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
2018-01-17 21:25:43 +00:00
2018-01-22 21:21:47 +00:00
// Default Pipelines
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
2018-01-29 21:46:48 +00:00
var ForwardDiffuseLightPipeline = require('./pipelines/ForwardDiffuseLightPipeline');
2018-02-09 19:19:21 +00:00
var TextureTintPipeline = require('./pipelines/TextureTintPipeline');
2018-01-22 21:21:47 +00:00
2018-03-19 20:41:24 +00:00
/**
* @callback WebGLContextCallback
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - [description]
*/
/**
* @typedef {object} SnapshotState
*
* @property {SnapshotCallback} callback - [description]
* @property {string} type - [description]
* @property {number} encoder - [description]
*/
2018-01-31 13:54:44 +00:00
/**
2018-02-09 19:19:21 +00:00
* @classdesc
2018-04-25 23:30:41 +00:00
* WebGLRenderer is a class that contains the needed functionality to keep the
* WebGLRenderingContext state clean. The main idea of the WebGLRenderer is to keep track of
* any context change that happens for WebGL rendering inside of Phaser. This means
* if raw webgl functions are called outside the WebGLRenderer of the Phaser WebGL
* rendering ecosystem they might pollute the current WebGLRenderingContext state producing
* unexpected behavior. It's recommended that WebGL interaction is done through
2018-04-25 23:30:41 +00:00
* WebGLRenderer and/or WebGLPipeline.
2018-02-09 19:19:21 +00:00
*
* @class WebGLRenderer
* @memberOf Phaser.Renderer.WebGL
* @constructor
* @since 3.0.0
*
* @param {Phaser.Game} game - [description]
2018-01-31 13:54:44 +00:00
*/
2018-01-17 21:25:43 +00:00
var WebGLRenderer = new Class({
2016-12-07 02:28:22 +00:00
initialize:
2018-01-17 21:25:43 +00:00
function WebGLRenderer (game)
2016-12-07 02:28:22 +00:00
{
2018-02-16 18:44:07 +00:00
// eslint-disable-next-line consistent-this
2018-01-17 21:25:43 +00:00
var renderer = this;
2018-02-09 19:19:21 +00:00
var gameConfig = game.config;
var contextCreationConfig = {
alpha: gameConfig.transparent,
depth: false, // enable when 3D is added in the future
antialias: gameConfig.antialias,
premultipliedAlpha: gameConfig.premultipliedAlpha,
stencil: true,
preserveDrawingBuffer: gameConfig.preserveDrawingBuffer,
failIfMajorPerformanceCaveat: gameConfig.failIfMajorPerformanceCaveat,
powerPreference: gameConfig.powerPreference
2018-01-17 21:25:43 +00:00
};
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#config
* @type {RendererConfig}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
this.config = {
clearBeforeRender: gameConfig.clearBeforeRender,
antialias: gameConfig.antialias,
backgroundColor: gameConfig.backgroundColor,
contextCreation: contextCreationConfig,
resolution: gameConfig.resolution,
autoResize: gameConfig.autoResize,
roundPixels: gameConfig.roundPixels,
maxTextures: gameConfig.maxTextures,
maxTextureSize: gameConfig.maxTextureSize,
batchSize: gameConfig.batchSize
};
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#game
* @type {Phaser.Game}
* @since 3.0.0
*/
this.game = game;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#type
* @type {integer}
* @since 3.0.0
*/
this.type = CONST.WEBGL;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#width
* @type {number}
* @since 3.0.0
*/
2018-02-09 18:45:22 +00:00
this.width = game.config.width;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#height
* @type {number}
* @since 3.0.0
*/
2018-02-09 18:45:22 +00:00
this.height = game.config.height;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#canvas
* @type {HTMLCanvasElement}
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.canvas = game.canvas;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#lostContextCallbacks
2018-03-19 20:41:24 +00:00
* @type {WebGLContextCallback[]}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
2018-01-24 00:40:20 +00:00
this.lostContextCallbacks = [];
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#restoredContextCallbacks
2018-03-19 20:41:24 +00:00
* @type {WebGLContextCallback[]}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
2018-01-24 00:40:20 +00:00
this.restoredContextCallbacks = [];
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#blendModes
* @type {array}
* @default []
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.blendModes = [];
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Keeps track of any WebGLTexture created with the current WebGLRenderingContext
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#nativeTextures
* @type {array}
* @default []
* @since 3.0.0
*/
this.nativeTextures = [];
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#contextLost
* @type {boolean}
* @default false
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.contextLost = false;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* This object will store all pipelines created through addPipeline
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#pipelines
2018-02-13 00:12:17 +00:00
* @type {object}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.pipelines = null;
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#snapshotState
* @type {SnapshotState}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
2018-01-20 04:05:56 +00:00
this.snapshotState = {
callback: null,
type: null,
encoder: null
};
2018-02-16 18:07:49 +00:00
// Internal Renderer State (Textures, Framebuffers, Pipelines, Buffers, etc)
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Cached value for the last texture unit that was used
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentActiveTextureUnit
2018-02-16 18:07:49 +00:00
* @type {integer}
2018-02-15 14:31:15 +00:00
* @since 3.1.0
*/
this.currentActiveTextureUnit = 0;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* An array of the last texture handles that were bound to the WebGLRenderingContext
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentTextures
2018-02-13 00:12:17 +00:00
* @type {array}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.currentTextures = new Array(16);
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current framebuffer in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentFramebuffer
2018-02-13 00:12:17 +00:00
* @type {WebGLFramebuffer}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.currentFramebuffer = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current WebGLPipeline in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentPipeline
2018-02-13 00:12:17 +00:00
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.currentPipeline = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current WebGLProgram in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentProgram
2018-02-13 00:12:17 +00:00
* @type {WebGLProgram}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-22 21:21:47 +00:00
this.currentProgram = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current WebGLBuffer (Vertex buffer) in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentVertexBuffer
2018-02-13 00:12:17 +00:00
* @type {WebGLBuffer}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.currentVertexBuffer = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current WebGLBuffer (Index buffer) in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentIndexBuffer
2018-02-13 00:12:17 +00:00
* @type {WebGLBuffer}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.currentIndexBuffer = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Current blend mode in use
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentBlendMode
2018-02-16 18:07:49 +00:00
* @type {integer}
2018-02-09 19:19:21 +00:00
* @since 3.0.0
*/
2018-01-22 21:21:47 +00:00
this.currentBlendMode = Infinity;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Indicates if the the scissor state is enabled in WebGLRenderingContext
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissorEnabled
* @type {boolean}
* @default false
* @since 3.0.0
*/
2018-01-24 18:55:23 +00:00
this.currentScissorEnabled = false;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Stores the current scissor data
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissor
* @type {Uint32Array}
* @since 3.0.0
*/
2018-07-26 16:50:07 +00:00
// this.currentScissor = new Uint32Array([ 0, 0, this.width, this.height ]);
this.currentScissor = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Stack of scissor data
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#scissorStack
* @type {Uint32Array}
* @since 3.0.0
*/
2018-07-26 16:50:07 +00:00
this.scissorStack = [];
2018-01-17 21:25:43 +00:00
// Setup context lost and restore event listeners
2018-02-09 19:19:21 +00:00
2018-02-16 18:17:51 +00:00
this.canvas.addEventListener('webglcontextlost', function (event)
{
2018-01-17 21:25:43 +00:00
renderer.contextLost = true;
event.preventDefault();
2018-01-24 00:40:20 +00:00
for (var index = 0; index < renderer.lostContextCallbacks.length; ++index)
{
var callback = renderer.lostContextCallbacks[index];
callback[0].call(callback[1], renderer);
}
2018-01-17 21:25:43 +00:00
}, false);
2018-02-16 18:44:07 +00:00
this.canvas.addEventListener('webglcontextrestored', function ()
2018-02-16 18:17:51 +00:00
{
2018-01-17 21:25:43 +00:00
renderer.contextLost = false;
renderer.init(renderer.config);
2018-01-24 00:40:20 +00:00
for (var index = 0; index < renderer.restoredContextCallbacks.length; ++index)
{
var callback = renderer.restoredContextCallbacks[index];
callback[0].call(callback[1], renderer);
}
2018-01-17 21:25:43 +00:00
}, false);
2018-04-24 14:32:08 +00:00
// These are initialized post context creation
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#gl
2018-02-13 00:12:17 +00:00
* @type {WebGLRenderingContext}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
this.gl = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Array of strings that indicate which WebGL extensions are supported by the browser
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#supportedExtensions
2018-02-13 00:12:17 +00:00
* @type {object}
2018-02-09 19:19:21 +00:00
* @default null
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.supportedExtensions = null;
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Extensions loaded into the current context
2018-02-09 19:19:21 +00:00
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#extensions
* @type {object}
* @default {}
* @since 3.0.0
*/
2018-01-17 21:25:43 +00:00
this.extensions = {};
/**
2018-04-25 23:30:41 +00:00
* Stores the current WebGL component formats for further use
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#glFormats
* @type {array}
* @default []
* @since 3.2.0
*/
this.glFormats = [];
/**
* Stores the supported WebGL texture compression formats.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#compression
* @type {array}
* @since 3.8.0
*/
this.compression = {
ETC1: false,
PVRTC: false,
S3TC: false
};
2018-07-10 15:32:28 +00:00
/**
* Cached drawing buffer height to reduce gl calls.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#drawingBufferHeight
* @type {number}
* @readOnly
* @since 3.11.0
*/
this.drawingBufferHeight = 0;
/**
* A blank 32x32 transparent texture, as used by the Graphics system where needed.
* This is set in the `boot` method.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#blankTexture
* @type {WebGLTexture}
* @readOnly
* @since 3.12.0
*/
this.blankTexture = null;
this.defaultCamera = new BaseCamera(0, 0, 0, 0);
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#_tempMatrix1
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.12.0
*/
this._tempMatrix1 = new TransformMatrix();
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#_tempMatrix2
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.12.0
*/
this._tempMatrix2 = new TransformMatrix();
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#_tempMatrix3
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.12.0
*/
this._tempMatrix3 = new TransformMatrix();
/**
* A temporary Transform Matrix, re-used internally during batching.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#_tempMatrix4
* @private
* @type {Phaser.GameObjects.Components.TransformMatrix}
* @since 3.12.0
*/
this._tempMatrix4 = new TransformMatrix();
this.init(this.config);
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Creates a new WebGLRenderingContext and initializes all internal
* state.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#init
* @since 3.0.0
*
* @param {object} config - [description]
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
init: function (config)
{
var gl;
2018-01-17 21:25:43 +00:00
var canvas = this.canvas;
var clearColor = config.backgroundColor;
// Did they provide their own context?
if (this.game.config.context)
{
gl = this.game.config.context;
}
else
{
gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation);
}
2018-03-19 20:41:24 +00:00
if (!gl || gl.isContextLost())
2016-12-07 02:28:22 +00:00
{
this.contextLost = true;
2018-07-26 16:50:07 +00:00
throw new Error('WebGL unsupported');
2016-12-07 02:28:22 +00:00
}
2018-01-22 21:21:47 +00:00
this.gl = gl;
// Set it back into the Game, so developers can access it from there too
this.game.context = gl;
for (var i = 0; i <= 16; i++)
{
this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD });
}
this.blendModes[1].func = [ gl.ONE, gl.DST_ALPHA ];
this.blendModes[2].func = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ];
this.blendModes[3].func = [ gl.ONE, gl.ONE_MINUS_SRC_COLOR ];
this.glFormats[0] = gl.BYTE;
this.glFormats[1] = gl.SHORT;
this.glFormats[2] = gl.UNSIGNED_BYTE;
this.glFormats[3] = gl.UNSIGNED_SHORT;
this.glFormats[4] = gl.FLOAT;
2018-01-17 21:25:43 +00:00
// Load supported extensions
var exts = gl.getSupportedExtensions();
if (!config.maxTextures)
{
config.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
}
if (!config.maxTextureSize)
{
config.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
}
2018-05-09 13:32:32 +00:00
var extString = 'WEBGL_compressed_texture_';
var wkExtString = 'WEBKIT_' + extString;
this.compression.ETC1 = gl.getExtension(extString + 'etc1') || gl.getExtension(wkExtString + 'etc1');
this.compression.PVRTC = gl.getExtension(extString + 'pvrtc') || gl.getExtension(wkExtString + 'pvrtc');
this.compression.S3TC = gl.getExtension(extString + 's3tc') || gl.getExtension(wkExtString + 's3tc');
this.supportedExtensions = exts;
2018-01-17 21:25:43 +00:00
// Setup initial WebGL state
2016-12-07 02:28:22 +00:00
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
2018-07-10 15:32:28 +00:00
// gl.disable(gl.SCISSOR_TEST);
2016-12-07 02:28:22 +00:00
gl.enable(gl.BLEND);
2018-01-17 21:25:43 +00:00
gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, 1.0);
2018-01-17 21:25:43 +00:00
// Initialize all textures to null
for (var index = 0; index < this.currentTextures.length; ++index)
{
2018-01-17 21:25:43 +00:00
this.currentTextures[index] = null;
}
2018-01-17 21:25:43 +00:00
// Clear previous pipelines and reload default ones
this.pipelines = {};
this.addPipeline('TextureTintPipeline', new TextureTintPipeline({ game: this.game, renderer: this }));
this.addPipeline('BitmapMaskPipeline', new BitmapMaskPipeline({ game: this.game, renderer: this }));
this.addPipeline('Light2D', new ForwardDiffuseLightPipeline({ game: this.game, renderer: this }));
2018-03-19 20:41:24 +00:00
2018-01-17 21:25:43 +00:00
this.setBlendMode(CONST.BlendModes.NORMAL);
2018-07-26 16:50:07 +00:00
2018-02-09 18:45:22 +00:00
this.resize(this.width, this.height);
2018-03-19 20:41:24 +00:00
this.game.events.once('texturesready', this.boot, this);
2018-07-13 10:13:46 +00:00
2018-01-17 21:25:43 +00:00
return this;
},
2018-07-13 10:13:46 +00:00
/**
* Internal boot handler. Calls 'boot' on each pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#boot
* @private
* @since 3.11.0
*/
boot: function ()
{
for (var pipelineName in this.pipelines)
{
this.pipelines[pipelineName].boot();
}
2018-07-26 14:04:46 +00:00
var blank = this.game.textures.getFrame('__DEFAULT');
this.pipelines.TextureTintPipeline.currentFrame = blank;
2018-07-26 14:04:46 +00:00
this.blankTexture = blank;
2018-07-13 10:13:46 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Resizes the internal canvas and drawing buffer.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resize
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {number} width - The width of the renderer.
* @param {number} height - The height of the renderer.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-02-09 18:45:22 +00:00
resize: function (width, height)
{
2018-01-17 21:25:43 +00:00
var gl = this.gl;
2018-01-22 21:21:47 +00:00
var pipelines = this.pipelines;
2018-02-09 18:45:22 +00:00
var resolution = this.config.resolution;
this.width = Math.floor(width * resolution);
this.height = Math.floor(height * resolution);
2018-03-19 20:41:24 +00:00
2018-01-17 21:25:43 +00:00
this.canvas.width = this.width;
this.canvas.height = this.height;
2018-02-12 19:03:13 +00:00
if (this.config.autoResize)
{
2018-01-17 21:25:43 +00:00
this.canvas.style.width = (this.width / resolution) + 'px';
this.canvas.style.height = (this.height / resolution) + 'px';
}
2018-01-17 21:25:43 +00:00
gl.viewport(0, 0, this.width, this.height);
2018-07-13 10:13:46 +00:00
// Update all registered pipelines
2018-01-20 04:05:56 +00:00
for (var pipelineName in pipelines)
{
2018-01-22 21:21:47 +00:00
pipelines[pipelineName].resize(width, height, resolution);
2018-01-20 04:05:56 +00:00
}
2018-07-10 15:32:28 +00:00
this.drawingBufferHeight = gl.drawingBufferHeight;
this.defaultCamera.setSize(width, height);
2018-01-17 21:25:43 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Adds a callback to be invoked when the WebGL context has been restored by the browser.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#onContextRestored
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLContextCallback} callback - The callback to be invoked on context restoration.
* @param {object} target - The context of the callback.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-24 00:40:20 +00:00
onContextRestored: function (callback, target)
{
2018-02-16 18:17:51 +00:00
this.restoredContextCallbacks.push([ callback, target ]);
2018-01-24 00:40:20 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Adds a callback to be invoked when the WebGL context has been lost by the browser.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#onContextLost
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLContextCallback} callback - The callback to be invoked on context loss.
* @param {object} target - The context of the callback.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-24 00:40:20 +00:00
onContextLost: function (callback, target)
{
2018-02-16 18:17:51 +00:00
this.lostContextCallbacks.push([ callback, target ]);
2018-01-24 00:40:20 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Checks if a WebGL extension is supported
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#hasExtension
* @since 3.0.0
*
2018-04-25 23:30:41 +00:00
* @param {string} extensionName - Name of the WebGL extension
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {boolean} `true` if the extension is supported, otherwise `false`.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
hasExtension: function (extensionName)
{
2018-01-17 21:25:43 +00:00
return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Loads a WebGL extension
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getExtension
* @since 3.0.0
*
2018-02-13 00:12:17 +00:00
* @param {string} extensionName - [description]
2018-02-09 19:19:21 +00:00
*
2018-04-25 23:30:41 +00:00
* @return {object} WebGL extension if the extension is supported
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
getExtension: function (extensionName)
2017-01-19 23:20:36 +00:00
{
2018-02-16 18:17:51 +00:00
if (!this.hasExtension(extensionName)) { return null; }
2018-01-17 21:25:43 +00:00
if (!(extensionName in this.extensions))
2017-01-19 23:20:36 +00:00
{
2018-01-17 21:25:43 +00:00
this.extensions[extensionName] = this.gl.getExtension(extensionName);
2017-01-19 23:20:36 +00:00
}
2018-01-17 21:25:43 +00:00
return this.extensions[extensionName];
2017-01-19 23:20:36 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Flushes the current pipeline if the pipeline is bound
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#flush
* @since 3.0.0
*/
2018-01-20 04:05:56 +00:00
flush: function ()
{
if (this.currentPipeline)
{
this.currentPipeline.flush();
}
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Checks if a pipeline is present in the current WebGLRenderer
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#hasPipeline
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {string} pipelineName - The name of the pipeline.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {boolean} `true` if the given pipeline is loaded, otherwise `false`.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
hasPipeline: function (pipelineName)
2017-01-19 22:43:41 +00:00
{
2018-01-17 21:25:43 +00:00
return (pipelineName in this.pipelines);
2017-04-07 01:49:15 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Returns the pipeline by name if the pipeline exists
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getPipeline
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {string} pipelineName - The name of the pipeline.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance, or `null` if not found.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
getPipeline: function (pipelineName)
2017-04-07 01:49:15 +00:00
{
2018-02-09 19:19:21 +00:00
return (this.hasPipeline(pipelineName)) ? this.pipelines[pipelineName] : null;
2017-01-19 22:43:41 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Removes a pipeline by name.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#removePipeline
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {string} pipelineName - The name of the pipeline to be removed.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
removePipeline: function (pipelineName)
2016-12-07 02:28:22 +00:00
{
2018-01-17 21:25:43 +00:00
delete this.pipelines[pipelineName];
2018-01-17 21:25:43 +00:00
return this;
2016-12-07 02:28:22 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Adds a pipeline instance into the collection of pipelines
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#addPipeline
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {string} pipelineName - A unique string-based key for the pipeline.
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipelineInstance - A pipeline instance which must extend WebGLPipeline.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipline instance that was passed.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
addPipeline: function (pipelineName, pipelineInstance)
2016-12-07 02:28:22 +00:00
{
if (!this.hasPipeline(pipelineName))
{
this.pipelines[pipelineName] = pipelineInstance;
}
else
{
2018-09-28 11:19:21 +00:00
console.warn('Pipeline exists: ' + pipelineName);
}
2018-01-30 22:46:43 +00:00
pipelineInstance.name = pipelineName;
this.pipelines[pipelineName].resize(this.width, this.height, this.config.resolution);
2016-12-07 02:28:22 +00:00
return pipelineInstance;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Pushes a new scissor state. This is used to set nested scissor states.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#pushScissor
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {integer} x - The x position of the scissor.
* @param {integer} y - The y position of the scissor.
* @param {integer} width - The width of the scissor.
* @param {integer} height - The height of the scissor.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {integer[]} An array containing the scissor values.
2018-02-09 19:19:21 +00:00
*/
2018-09-28 11:19:21 +00:00
pushScissor: function (x, y, width, height)
2018-01-24 18:55:23 +00:00
{
var scissorStack = this.scissorStack;
2018-09-28 11:19:21 +00:00
var scissor = [ x, y, width, height ];
2018-07-26 16:50:07 +00:00
scissorStack.push(scissor);
2018-03-19 20:41:24 +00:00
2018-09-28 11:19:21 +00:00
this.setScissor(x, y, width, height);
2018-01-24 18:55:23 +00:00
this.currentScissor = scissor;
2018-07-26 16:50:07 +00:00
return scissor;
2018-01-24 18:55:23 +00:00
},
/**
2018-09-28 11:19:21 +00:00
* Sets the current scissor state.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setScissor
* @since 3.0.0
2018-09-28 11:19:21 +00:00
*
* @param {integer} x - The x position of the scissor.
* @param {integer} y - The y position of the scissor.
* @param {integer} width - The width of the scissor.
* @param {integer} height - The height of the scissor.
*/
2018-09-28 11:19:21 +00:00
setScissor: function (x, y, width, height)
{
var gl = this.gl;
var current = this.currentScissor;
var cx = current[0];
var cy = current[1];
var cw = current[2];
var ch = current[3];
2018-09-28 11:19:21 +00:00
if (cx !== x || cy !== y || cw !== width || ch !== height)
{
this.flush();
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/scissor
2018-08-31 17:19:31 +00:00
2018-09-28 11:19:21 +00:00
if (width > 0 && height > 0)
2018-08-31 17:19:31 +00:00
{
2018-09-28 11:19:21 +00:00
gl.scissor(x, (this.drawingBufferHeight - y - height), width, height);
2018-08-31 17:19:31 +00:00
}
}
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Pops the last scissor state and sets it.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#popScissor
* @since 3.0.0
*/
2018-01-24 18:55:23 +00:00
popScissor: function ()
{
var scissorStack = this.scissorStack;
2018-03-19 20:41:24 +00:00
// Remove the current scissor
scissorStack.pop();
// Reset the previous scissor
var scissor = scissorStack[scissorStack.length - 1];
if (scissor)
{
this.setScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
2018-01-24 18:55:23 +00:00
this.currentScissor = scissor;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Binds a WebGLPipeline and sets it as the current pipeline to be used.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setPipeline
* @since 3.0.0
*
2018-07-11 15:24:20 +00:00
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipelineInstance - The pipeline instance to be activated.
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
2018-02-09 19:19:21 +00:00
*
2018-07-11 15:24:20 +00:00
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline that was activated.
2018-02-09 19:19:21 +00:00
*/
2018-07-11 15:24:20 +00:00
setPipeline: function (pipelineInstance, gameObject)
2018-01-20 04:05:56 +00:00
{
2018-01-25 05:26:14 +00:00
if (this.currentPipeline !== pipelineInstance ||
2018-01-30 03:38:31 +00:00
this.currentPipeline.vertexBuffer !== this.currentVertexBuffer ||
this.currentPipeline.program !== this.currentProgram)
2018-01-20 04:05:56 +00:00
{
2018-01-24 03:08:14 +00:00
this.flush();
2018-01-23 16:38:58 +00:00
this.currentPipeline = pipelineInstance;
2018-01-30 03:38:31 +00:00
this.currentPipeline.bind();
2018-01-20 04:05:56 +00:00
}
2018-07-11 15:24:20 +00:00
this.currentPipeline.onBind(gameObject);
2018-01-25 05:26:14 +00:00
2018-01-23 19:29:47 +00:00
return this.currentPipeline;
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-07-23 00:39:32 +00:00
* Sets the blend mode to the value given.
*
* If the current blend mode is different from the one given, the pipeline is flushed and the new
* blend mode is enabled.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setBlendMode
* @since 3.0.0
*
2018-07-23 00:39:32 +00:00
* @param {integer} blendModeId - The blend mode to be set. Can be a `BlendModes` const or an integer value.
2018-02-09 19:19:21 +00:00
*
2018-07-23 00:39:32 +00:00
* @return {boolean} `true` if the blend mode was changed as a result of this call, forcing a flush, otherwise `false`.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
setBlendMode: function (blendModeId)
{
var gl = this.gl;
2018-01-17 21:25:43 +00:00
var blendMode = this.blendModes[blendModeId];
2017-02-07 16:12:20 +00:00
2018-07-23 00:39:32 +00:00
if (blendModeId !== CONST.BlendModes.SKIP_CHECK && this.currentBlendMode !== blendModeId)
2017-01-19 17:53:20 +00:00
{
2018-01-20 04:05:56 +00:00
this.flush();
2017-12-15 04:07:16 +00:00
2018-01-17 21:25:43 +00:00
gl.enable(gl.BLEND);
gl.blendEquation(blendMode.equation);
2018-01-17 21:25:43 +00:00
if (blendMode.func.length > 2)
2017-11-06 22:12:19 +00:00
{
2018-01-17 21:25:43 +00:00
gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]);
2017-11-06 22:12:19 +00:00
}
2018-01-17 21:25:43 +00:00
else
2017-11-06 22:12:19 +00:00
{
2018-01-17 21:25:43 +00:00
gl.blendFunc(blendMode.func[0], blendMode.func[1]);
2017-11-06 22:12:19 +00:00
}
2018-01-17 21:25:43 +00:00
this.currentBlendMode = blendModeId;
2018-07-23 00:39:32 +00:00
return true;
2017-02-10 00:48:32 +00:00
}
2018-07-23 00:39:32 +00:00
return false;
},
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#addBlendMode
* @since 3.0.0
*
* @param {function} func - [description]
* @param {function} equation - [description]
*
* @return {integer} [description]
*/
addBlendMode: function (func, equation)
{
var index = this.blendModes.push({ func: func, equation: equation });
return index - 1;
},
/**
2018-09-28 11:19:21 +00:00
* Updates the function bound to a given custom blend mode.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#updateBlendMode
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {integer} index - The index of the custom blend mode.
* @param {function} func - The function to use for the blend mode.
* @param {function} equation - The equation to use for the blend mode.
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
*/
updateBlendMode: function (index, func, equation)
{
if (this.blendModes[index])
{
this.blendModes[index].func = func;
if (equation)
{
this.blendModes[index].equation = equation;
}
}
return this;
},
/**
2018-09-28 11:19:21 +00:00
* Removes a custom blend mode from the renderer.
* Any Game Objects still using this blend mode will error, so be sure to clear them first.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#removeBlendMode
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {integer} index - The index of the custom blend mode to be removed.
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
*/
removeBlendMode: function (index)
{
if (index > 16 && this.blendModes[index])
{
this.blendModes.splice(index, 1);
}
2018-01-17 21:25:43 +00:00
return this;
2017-02-07 19:30:50 +00:00
},
2016-12-07 02:28:22 +00:00
2018-07-26 14:04:46 +00:00
/**
* Sets the current active texture for texture unit zero to be a blank texture.
* This only happens if there isn't a texture already in use by texture unit zero.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setBlankTexture
* @private
* @since 3.12.0
*
* @param {boolean} [force=false] - Force a blank texture set, regardless of what's already bound?
2018-07-26 14:04:46 +00:00
*/
setBlankTexture: function (force)
2018-07-26 14:04:46 +00:00
{
if (force === undefined) { force = false; }
if (force || this.currentActiveTextureUnit !== 0 || !this.currentTextures[0])
2018-07-26 14:04:46 +00:00
{
this.setTexture2D(this.blankTexture.glTexture, 0);
}
},
2018-02-09 19:19:21 +00:00
/**
* Binds a texture at a texture unit. If a texture is already
2018-04-25 23:30:41 +00:00
* bound to that unit it will force a flush on the current pipeline.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setTexture2D
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLTexture} texture - The WebGL texture that needs to be bound.
* @param {integer} textureUnit - The texture unit to which the texture will be bound.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
setTexture2D: function (texture, textureUnit)
2017-02-07 19:30:50 +00:00
{
2018-01-17 21:25:43 +00:00
var gl = this.gl;
2017-05-16 19:15:01 +00:00
2018-01-17 21:25:43 +00:00
if (texture !== this.currentTextures[textureUnit])
2017-05-16 19:15:01 +00:00
{
2018-01-23 19:29:47 +00:00
this.flush();
if (this.currentActiveTextureUnit !== textureUnit)
{
gl.activeTexture(gl.TEXTURE0 + textureUnit);
this.currentActiveTextureUnit = textureUnit;
}
2018-01-17 21:25:43 +00:00
gl.bindTexture(gl.TEXTURE_2D, texture);
2017-05-16 19:15:01 +00:00
2018-01-17 21:25:43 +00:00
this.currentTextures[textureUnit] = texture;
}
2016-12-07 02:28:22 +00:00
2018-01-17 21:25:43 +00:00
return this;
2017-05-16 19:15:01 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Binds a framebuffer. If there was another framebuffer already bound it will force a pipeline flush.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFramebuffer
* @since 3.0.0
*
* @param {WebGLFramebuffer} framebuffer - The framebuffer that needs to be bound.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
setFramebuffer: function (framebuffer)
2017-01-23 21:42:47 +00:00
{
var gl = this.gl;
var width = this.width;
var height = this.height;
2018-01-17 21:25:43 +00:00
if (framebuffer !== this.currentFramebuffer)
{
if (framebuffer && framebuffer.renderTexture)
{
width = framebuffer.renderTexture.width;
height = framebuffer.renderTexture.height;
}
else
{
this.flush();
}
2018-01-23 19:29:47 +00:00
2018-01-17 21:25:43 +00:00
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.viewport(0, 0, width, height);
2018-01-25 05:26:14 +00:00
this.currentFramebuffer = framebuffer;
}
2018-01-17 21:25:43 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Binds a program. If there was another program already bound it will force a pipeline flush.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setProgram
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLProgram} program - The program that needs to be bound.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setProgram: function (program)
{
var gl = this.gl;
if (program !== this.currentProgram)
{
2018-01-23 19:29:47 +00:00
this.flush();
2018-01-22 21:21:47 +00:00
gl.useProgram(program);
2018-01-25 05:26:14 +00:00
this.currentProgram = program;
2018-01-22 21:21:47 +00:00
}
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Bounds a vertex buffer. If there is a vertex buffer already bound it'll force a pipeline flush.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setVertexBuffer
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLBuffer} vertexBuffer - The buffer that needs to be bound.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
setVertexBuffer: function (vertexBuffer)
{
2018-01-17 21:25:43 +00:00
var gl = this.gl;
2018-01-17 21:25:43 +00:00
if (vertexBuffer !== this.currentVertexBuffer)
{
2018-01-23 19:29:47 +00:00
this.flush();
2018-01-17 21:25:43 +00:00
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
2018-01-25 05:26:14 +00:00
this.currentVertexBuffer = vertexBuffer;
}
2018-01-17 21:25:43 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Bounds a index buffer. If there is a index buffer already bound it'll force a pipeline flush.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setIndexBuffer
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLBuffer} indexBuffer - The buffer the needs to be bound.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-17 21:25:43 +00:00
setIndexBuffer: function (indexBuffer)
2017-05-20 01:16:45 +00:00
{
var gl = this.gl;
2018-01-17 21:25:43 +00:00
if (indexBuffer !== this.currentIndexBuffer)
{
2018-01-23 19:29:47 +00:00
this.flush();
2018-03-19 20:41:24 +00:00
2018-01-17 21:25:43 +00:00
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
2018-01-25 05:26:14 +00:00
this.currentIndexBuffer = indexBuffer;
}
2017-05-20 01:16:45 +00:00
2018-01-17 21:25:43 +00:00
return this;
2017-05-20 01:16:45 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Creates a texture from an image source. If the source is not valid it creates an empty texture.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createTextureFromSource
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {object} source - The source of the texture.
* @param {integer} width - The width of the texture.
* @param {integer} height - The height of the texture.
* @param {integer} scaleMode - The scale mode to be used by the texture.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {?WebGLTexture} The WebGL Texture that was created, or `null` if it couldn't be created.
2018-02-09 19:19:21 +00:00
*/
2018-01-24 00:40:20 +00:00
createTextureFromSource: function (source, width, height, scaleMode)
2018-02-16 18:17:51 +00:00
{
2018-01-20 04:05:56 +00:00
var gl = this.gl;
var filter = gl.NEAREST;
var wrap = gl.CLAMP_TO_EDGE;
2018-01-24 00:40:20 +00:00
var texture = null;
2018-01-20 04:05:56 +00:00
width = source ? source.width : width;
height = source ? source.height : height;
if (IsSizePowerOfTwo(width, height))
{
wrap = gl.REPEAT;
}
if (scaleMode === CONST.ScaleModes.LINEAR && this.config.antialias)
2018-01-20 04:05:56 +00:00
{
2018-01-24 00:40:20 +00:00
filter = gl.LINEAR;
}
2018-01-20 04:05:56 +00:00
2018-01-24 00:40:20 +00:00
if (!source && typeof width === 'number' && typeof height === 'number')
{
texture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height);
}
else
{
texture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, source);
2018-01-20 04:05:56 +00:00
}
2018-01-24 00:40:20 +00:00
return texture;
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* A wrapper for creating a WebGLTexture. If no pixel data is passed it will create an empty texture.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createTexture2D
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {integer} mipLevel - Mip level of the texture.
* @param {integer} minFilter - Filtering of the texture.
* @param {integer} magFilter - Filtering of the texture.
* @param {integer} wrapT - Wrapping mode of the texture.
* @param {integer} wrapS - Wrapping mode of the texture.
* @param {integer} format - Which format does the texture use.
* @param {object} pixels - pixel data.
* @param {integer} width - Width of the texture in pixels.
* @param {integer} height - Height of the texture in pixels.
* @param {boolean} pma - Does the texture have premultiplied alpha?
2018-04-25 23:30:41 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {WebGLTexture} The WebGLTexture that was created.
2018-02-09 19:19:21 +00:00
*/
2018-01-20 00:37:52 +00:00
createTexture2D: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma)
2018-01-17 21:25:43 +00:00
{
pma = (pma === undefined || pma === null) ? true : pma;
2018-01-20 00:37:52 +00:00
var gl = this.gl;
var texture = gl.createTexture();
this.setTexture2D(texture, 0);
2018-03-19 20:41:24 +00:00
2018-01-20 00:37:52 +00:00
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, pma);
if (pixels === null || pixels === undefined)
{
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null);
}
else
{
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels);
width = pixels.width;
height = pixels.height;
}
this.setTexture2D(null, 0);
texture.isAlphaPremultiplied = pma;
texture.isRenderTexture = false;
texture.width = width;
texture.height = height;
this.nativeTextures.push(texture);
2018-01-20 00:37:52 +00:00
return texture;
2018-01-17 21:25:43 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Wrapper for creating WebGLFramebuffer.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createFramebuffer
* @since 3.0.0
*
2018-04-25 23:30:41 +00:00
* @param {integer} width - Width in pixels of the framebuffer
* @param {integer} height - Height in pixels of the framebuffer
* @param {WebGLTexture} renderTexture - The color texture to where the color pixels are written
2018-04-25 23:30:41 +00:00
* @param {boolean} addDepthStencilBuffer - Indicates if the current framebuffer support depth and stencil buffers
2018-02-09 19:19:21 +00:00
*
2018-04-25 23:30:41 +00:00
* @return {WebGLFramebuffer} Raw WebGLFramebuffer
2018-02-09 19:19:21 +00:00
*/
2018-01-20 00:37:52 +00:00
createFramebuffer: function (width, height, renderTexture, addDepthStencilBuffer)
2018-01-17 21:25:43 +00:00
{
2018-01-20 00:37:52 +00:00
var gl = this.gl;
var framebuffer = gl.createFramebuffer();
var complete = 0;
this.setFramebuffer(framebuffer);
if (addDepthStencilBuffer)
{
var depthStencilBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
}
renderTexture.isRenderTexture = true;
renderTexture.isAlphaPremultiplied = false;
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture, 0);
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (complete !== gl.FRAMEBUFFER_COMPLETE)
{
var errors = {
36054: 'Incomplete Attachment',
36055: 'Missing Attachment',
36057: 'Incomplete Dimensions',
36061: 'Framebuffer Unsupported'
};
2018-01-20 00:37:52 +00:00
throw new Error('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
}
framebuffer.renderTexture = renderTexture;
2018-01-20 00:37:52 +00:00
this.setFramebuffer(null);
return framebuffer;
2018-01-17 21:25:43 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Wrapper for creating a WebGLProgram
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createProgram
* @since 3.0.0
*
2018-04-25 23:30:41 +00:00
* @param {string} vertexShader - Source to the vertex shader
* @param {string} fragmentShader - Source to the fragment shader
2018-02-09 19:19:21 +00:00
*
2018-04-25 23:30:41 +00:00
* @return {WebGLProgram} Raw WebGLProgram
2018-02-09 19:19:21 +00:00
*/
2018-01-20 00:37:52 +00:00
createProgram: function (vertexShader, fragmentShader)
2018-01-17 21:25:43 +00:00
{
2018-01-20 00:37:52 +00:00
var gl = this.gl;
var program = gl.createProgram();
var vs = gl.createShader(gl.VERTEX_SHADER);
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vs, vertexShader);
gl.shaderSource(fs, fragmentShader);
gl.compileShader(vs);
gl.compileShader(fs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
{
throw new Error('Failed to compile Vertex Shader:\n' + gl.getShaderInfoLog(vs));
2018-01-20 00:37:52 +00:00
}
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
{
throw new Error('Failed to compile Fragment Shader:\n' + gl.getShaderInfoLog(fs));
2018-01-20 00:37:52 +00:00
}
2017-08-03 20:02:57 +00:00
2018-01-20 00:37:52 +00:00
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
{
throw new Error('Failed to link program:\n' + gl.getProgramInfoLog(program));
2018-01-20 00:37:52 +00:00
}
return program;
2018-01-17 21:25:43 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Wrapper for creating a vertex buffer.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createVertexBuffer
* @since 3.0.0
*
2018-04-25 23:30:41 +00:00
* @param {ArrayBuffer} initialDataOrSize - It's either ArrayBuffer or an integer indicating the size of the vbo
* @param {integer} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW
2018-02-09 19:19:21 +00:00
*
2018-04-25 23:30:41 +00:00
* @return {WebGLBuffer} Raw vertex buffer
2018-02-09 19:19:21 +00:00
*/
2018-01-20 00:37:52 +00:00
createVertexBuffer: function (initialDataOrSize, bufferUsage)
2018-01-17 21:25:43 +00:00
{
2018-01-20 00:37:52 +00:00
var gl = this.gl;
var vertexBuffer = gl.createBuffer();
2018-01-20 00:37:52 +00:00
this.setVertexBuffer(vertexBuffer);
2018-01-20 00:37:52 +00:00
gl.bufferData(gl.ARRAY_BUFFER, initialDataOrSize, bufferUsage);
2018-01-20 00:37:52 +00:00
this.setVertexBuffer(null);
return vertexBuffer;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Wrapper for creating a vertex buffer.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createIndexBuffer
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {ArrayBuffer} initialDataOrSize - Either ArrayBuffer or an integer indicating the size of the vbo.
* @param {integer} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW.
2018-02-09 19:19:21 +00:00
*
2018-04-25 23:30:41 +00:00
* @return {WebGLBuffer} Raw index buffer
2018-02-09 19:19:21 +00:00
*/
2018-01-25 00:15:51 +00:00
createIndexBuffer: function (initialDataOrSize, bufferUsage)
{
2018-01-20 00:37:52 +00:00
var gl = this.gl;
var indexBuffer = gl.createBuffer();
this.setIndexBuffer(indexBuffer);
2018-01-20 00:37:52 +00:00
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, initialDataOrSize, bufferUsage);
2018-01-20 00:37:52 +00:00
this.setIndexBuffer(null);
return indexBuffer;
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Removes the given texture from the nativeTextures array and then deletes it from the GPU.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteTexture
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLTexture} texture - The WebGL Texture to be deleted.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
deleteTexture: function (texture)
2018-01-25 00:15:51 +00:00
{
var index = this.nativeTextures.indexOf(texture);
if (index !== -1)
{
SpliceOne(this.nativeTextures, index);
}
this.gl.deleteTexture(texture);
2018-01-25 00:15:51 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Deletes a WebGLFramebuffer from the GL instance.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteFramebuffer
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLFramebuffer} framebuffer - The Framebuffer to be deleted.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
deleteFramebuffer: function (framebuffer)
2018-01-25 00:15:51 +00:00
{
this.gl.deleteFramebuffer(framebuffer);
2018-01-25 00:15:51 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Deletes a WebGLProgram from the GL instance.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteProgram
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLProgram} program - The shader program to be deleted.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
deleteProgram: function (program)
2018-01-25 00:15:51 +00:00
{
this.gl.deleteProgram(program);
2018-01-25 00:15:51 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Deletes a WebGLBuffer from the GL instance.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteBuffer
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {WebGLBuffer} vertexBuffer - The WebGLBuffer to be deleted.
2018-02-09 19:19:21 +00:00
*
2018-09-28 11:19:21 +00:00
* @return {this} This WebGLRenderer instance.
2018-02-09 19:19:21 +00:00
*/
deleteBuffer: function (buffer)
2018-01-25 00:15:51 +00:00
{
this.gl.deleteBuffer(buffer);
2018-01-25 00:15:51 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Controls the pre-render operations for the given camera.
* Handles any clipping needed by the camera and renders the background color if a color is visible.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#preRenderCamera
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to pre-render.
2018-02-09 19:19:21 +00:00
*/
2018-01-24 03:57:33 +00:00
preRenderCamera: function (camera)
{
2018-07-18 13:32:06 +00:00
var cx = camera._cx;
var cy = camera._cy;
var cw = camera._cw;
var ch = camera._ch;
var TextureTintPipeline = this.pipelines.TextureTintPipeline;
var color = camera.backgroundColor;
if (camera.renderToTexture)
2018-01-24 03:57:33 +00:00
{
2018-08-31 17:19:31 +00:00
this.flush();
this.pushScissor(cx, cy, cw, -ch);
this.setFramebuffer(camera.framebuffer);
2018-01-24 03:57:33 +00:00
var gl = this.gl;
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
TextureTintPipeline.projOrtho(cx, cw + cx, cy, ch + cy, -1000, 1000);
if (color.alphaGL > 0)
{
TextureTintPipeline.drawFillRect(
cx, cy, cw + cx, ch + cy,
Utils.getTintFromFloats(color.redGL, color.greenGL, color.blueGL, 1),
color.alphaGL
);
}
camera.emit('prerender', camera);
}
else if (color.alphaGL > 0)
{
this.pushScissor(cx, cy, cw, ch);
TextureTintPipeline.drawFillRect(
cx, cy, cw , ch,
Utils.getTintFromFloats(color.redGL, color.greenGL, color.blueGL, 1),
color.alphaGL
2018-01-24 03:57:33 +00:00
);
}
else
{
this.pushScissor(cx, cy, cw, ch);
}
2018-01-24 03:57:33 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* Controls the post-render operations for the given camera.
* Renders the foreground camera effects like flash and fading. It resets the current scissor state.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#postRenderCamera
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to post-render.
2018-02-09 19:19:21 +00:00
*/
2018-01-24 03:57:33 +00:00
postRenderCamera: function (camera)
{
var TextureTintPipeline = this.pipelines.TextureTintPipeline;
2018-01-24 03:57:33 +00:00
camera.flashEffect.postRenderWebGL(TextureTintPipeline, Utils.getTintFromFloats);
camera.fadeEffect.postRenderWebGL(TextureTintPipeline, Utils.getTintFromFloats);
2018-01-24 03:57:33 +00:00
camera.dirty = false;
2018-01-24 18:55:23 +00:00
this.popScissor();
if (camera.renderToTexture)
{
TextureTintPipeline.flush();
this.setFramebuffer(null);
camera.emit('postrender', camera);
TextureTintPipeline.projOrtho(0, TextureTintPipeline.width, TextureTintPipeline.height, 0, -1000.0, 1000.0);
var getTint = Utils.getTintAppendFloatAlpha;
2018-08-08 00:33:55 +00:00
2018-08-31 17:19:31 +00:00
var pipeline = (camera.pipeline) ? camera.pipeline : TextureTintPipeline;
2018-08-31 17:19:31 +00:00
pipeline.batchTexture(
camera,
camera.glTexture,
camera.width, camera.height,
camera.x, camera.y,
camera.width, camera.height,
camera.zoom, camera.zoom,
camera.rotation,
camera.flipX, !camera.flipY,
1, 1,
0, 0,
0, 0, camera.width, camera.height,
2018-08-08 00:33:55 +00:00
getTint(camera._tintTL, camera._alphaTL),
getTint(camera._tintTR, camera._alphaTR),
getTint(camera._tintBL, camera._alphaBL),
getTint(camera._tintBR, camera._alphaBR),
(camera._isTinted && camera.tintFill),
0, 0,
this.defaultCamera,
null
);
// Force clear the current texture so that items next in the batch (like Graphics) don't try and use it
this.setBlankTexture(true);
}
2018-01-24 03:57:33 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Clears the current vertex buffer and updates pipelines.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#preRender
* @since 3.0.0
*/
2018-01-20 04:05:56 +00:00
preRender: function ()
{
2018-02-16 18:17:51 +00:00
if (this.contextLost) { return; }
2018-01-20 04:05:56 +00:00
2018-01-22 22:51:15 +00:00
var gl = this.gl;
var color = this.config.backgroundColor;
2018-01-26 23:17:11 +00:00
var pipelines = this.pipelines;
2018-01-22 22:51:15 +00:00
if (this.config.clearBeforeRender)
{
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
2018-01-26 23:17:11 +00:00
gl.enable(gl.SCISSOR_TEST);
2018-01-26 23:17:11 +00:00
for (var key in pipelines)
{
pipelines[key].onPreRender();
}
// TODO - Find a way to stop needing to create these arrays every frame
// and equally not need a huge array buffer created to hold them
this.currentScissor = [ 0, 0, this.width, this.height ];
this.scissorStack = [ this.currentScissor ];
if (this.game.scene.customViewports)
{
gl.scissor(0, (this.drawingBufferHeight - this.height), this.width, this.height);
}
2018-07-26 16:50:07 +00:00
this.setPipeline(this.pipelines.TextureTintPipeline);
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* The core render step for a Scene.
* Iterates through the given Game Object's array and renders them with the given Camera.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#render
* @since 3.0.0
*
2018-09-28 11:19:21 +00:00
* @param {Phaser.Scene} scene - The Scene to render.
* @param {Phaser.GameObjects.GameObject} children - The Game Object's within the Scene to be rendered.
* @param {number} interpolationPercentage - The interpolation percentage to apply. Currently un-used.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with.
2018-02-09 19:19:21 +00:00
*/
2018-01-20 04:05:56 +00:00
render: function (scene, children, interpolationPercentage, camera)
{
2018-02-16 18:17:51 +00:00
if (this.contextLost) { return; }
2018-01-20 04:05:56 +00:00
2018-01-22 21:21:47 +00:00
var list = children.list;
var childCount = list.length;
2018-01-29 21:46:48 +00:00
var pipelines = this.pipelines;
for (var key in pipelines)
{
pipelines[key].onRender(scene, camera);
}
2018-01-22 21:37:47 +00:00
// Apply scissor for cam region + render background color, if not transparent
2018-01-24 03:57:33 +00:00
this.preRenderCamera(camera);
2018-01-22 21:37:47 +00:00
for (var i = 0; i < childCount; i++)
2018-01-22 21:21:47 +00:00
{
var child = list[i];
2018-01-22 21:21:47 +00:00
if (!child.willRender(camera))
2018-01-22 21:21:47 +00:00
{
continue;
}
2018-01-22 21:37:47 +00:00
if (child.blendMode !== this.currentBlendMode)
{
this.setBlendMode(child.blendMode);
}
var mask = child.mask;
if (mask)
2018-01-22 21:37:47 +00:00
{
mask.preRenderWebGL(this, child, camera);
2018-01-22 21:37:47 +00:00
child.renderWebGL(this, child, interpolationPercentage, camera);
2018-01-22 21:21:47 +00:00
mask.postRenderWebGL(this, child);
}
else
2018-01-22 21:37:47 +00:00
{
child.renderWebGL(this, child, interpolationPercentage, camera);
2018-01-22 21:37:47 +00:00
}
}
2018-01-24 03:57:33 +00:00
this.setBlendMode(CONST.BlendModes.NORMAL);
// Applies camera effects and pops the scissor, if set
2018-01-24 03:57:33 +00:00
this.postRenderCamera(camera);
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
2018-09-28 11:19:21 +00:00
* The post-render step happens after all Cameras in all Scenes have been rendered.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#postRender
* @since 3.0.0
*/
2018-01-20 04:05:56 +00:00
postRender: function ()
{
2018-02-16 18:17:51 +00:00
if (this.contextLost) { return; }
2018-01-20 04:05:56 +00:00
this.flush();
2018-01-22 22:51:15 +00:00
// Unbind custom framebuffer here
2018-01-20 04:05:56 +00:00
if (this.snapshotState.callback)
{
this.snapshotState.callback(WebGLSnapshot(this.canvas, this.snapshotState.type, this.snapshotState.encoder));
this.snapshotState.callback = null;
}
2018-01-26 23:17:11 +00:00
var pipelines = this.pipelines;
for (var key in pipelines)
{
pipelines[key].onPostRender();
}
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#snapshot
* @since 3.0.0
*
2018-03-19 20:41:24 +00:00
* @param {SnapshotCallback} callback - [description]
2018-02-13 00:12:17 +00:00
* @param {string} type - [description]
* @param {number} encoderOptions - [description]
2018-02-09 19:19:21 +00:00
*
* @return {Phaser.Renderer.WebGL.WebGLRenderer} [description]
*/
2018-01-20 04:05:56 +00:00
snapshot: function (callback, type, encoderOptions)
{
this.snapshotState.callback = callback;
this.snapshotState.type = type;
this.snapshotState.encoder = encoderOptions;
2018-01-20 04:05:56 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Creates a WebGL Texture based on the given canvas element.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#canvasToTexture
* @since 3.0.0
*
* @param {HTMLCanvasElement} srcCanvas - The Canvas element that will be used to populate the texture.
* @param {WebGLTexture} [dstTexture] - Is this going to replace an existing texture? If so, pass it here.
2018-02-09 19:19:21 +00:00
*
* @return {WebGLTexture} The newly created WebGL Texture.
2018-02-09 19:19:21 +00:00
*/
2018-03-05 01:45:28 +00:00
canvasToTexture: function (srcCanvas, dstTexture)
2018-01-20 04:05:56 +00:00
{
var gl = this.gl;
var wrapping = gl.CLAMP_TO_EDGE;
2018-01-20 04:05:56 +00:00
if (IsSizePowerOfTwo(srcCanvas.width, srcCanvas.height))
{
wrapping = gl.REPEAT;
2018-01-20 04:05:56 +00:00
}
var newTexture = this.createTexture2D(0, gl.NEAREST, gl.NEAREST, wrapping, wrapping, gl.RGBA, srcCanvas, srcCanvas.width, srcCanvas.height, true);
if (newTexture && dstTexture)
{
this.deleteTexture(dstTexture);
}
return newTexture;
2018-01-20 04:05:56 +00:00
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureFilter
* @since 3.0.0
*
2018-02-16 18:07:49 +00:00
* @param {integer} texture - [description]
* @param {integer} filter - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-20 04:05:56 +00:00
setTextureFilter: function (texture, filter)
{
var gl = this.gl;
var glFilter = [ gl.LINEAR, gl.NEAREST ][filter];
this.setTexture2D(texture, 0);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
this.setTexture2D(null, 0);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat1
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - [description]
*
* @return {this} This WebGL Renderer instance.
*/
setFloat1: function (program, name, x)
{
this.setProgram(program);
this.gl.uniform1f(this.gl.getUniformLocation(program, name), x);
return this;
},
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat2
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - [description]
* @param {number} y - [description]
*
* @return {this} This WebGL Renderer instance.
*/
setFloat2: function (program, name, x, y)
{
this.setProgram(program);
this.gl.uniform2f(this.gl.getUniformLocation(program, name), x, y);
return this;
},
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat3
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - [description]
* @param {number} y - [description]
* @param {number} z - [description]
*
* @return {this} This WebGL Renderer instance.
*/
setFloat3: function (program, name, x, y, z)
{
this.setProgram(program);
this.gl.uniform3f(this.gl.getUniformLocation(program, name), x, y, z);
return this;
},
/**
* Sets uniform of a WebGLProgram
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat4
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
* @param {number} x - X component
* @param {number} y - Y component
* @param {number} z - Z component
* @param {number} w - W component
*
* @return {this} This WebGL Renderer instance.
*/
setFloat4: function (program, name, x, y, z, w)
{
this.setProgram(program);
this.gl.uniform4f(this.gl.getUniformLocation(program, name), x, y, z, w);
return this;
},
/**
* Sets the value of a uniform variable in the given WebGLProgram.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat1v
* @since 3.13.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @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.
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
setFloat1v: function (program, name, arr)
2018-01-22 21:21:47 +00:00
{
this.setProgram(program);
this.gl.uniform1fv(this.gl.getUniformLocation(program, name), arr);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat2v
* @since 3.13.0
2018-02-09 19:19:21 +00:00
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @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.
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
setFloat2v: function (program, name, arr)
2018-01-22 21:21:47 +00:00
{
this.setProgram(program);
this.gl.uniform2fv(this.gl.getUniformLocation(program, name), arr);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat3v
* @since 3.13.0
2018-02-09 19:19:21 +00:00
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @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.
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
setFloat3v: function (program, name, arr)
2018-01-22 21:21:47 +00:00
{
this.setProgram(program);
this.gl.uniform3fv(this.gl.getUniformLocation(program, name), arr);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFloat4v
* @since 3.13.0
2018-02-09 19:19:21 +00:00
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @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.
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
setFloat4v: function (program, name, arr)
2018-01-22 21:21:47 +00:00
{
this.setProgram(program);
this.gl.uniform4fv(this.gl.getUniformLocation(program, name), arr);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setInt1
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-02-16 18:07:49 +00:00
* @param {integer} x - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setInt1: function (program, name, x)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniform1i(this.gl.getUniformLocation(program, name), x);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setInt2
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-02-16 18:07:49 +00:00
* @param {integer} x - [description]
* @param {integer} y - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setInt2: function (program, name, x, y)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniform2i(this.gl.getUniformLocation(program, name), x, y);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setInt3
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-02-16 18:07:49 +00:00
* @param {integer} x - [description]
* @param {integer} y - [description]
* @param {integer} z - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setInt3: function (program, name, x, y, z)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniform3i(this.gl.getUniformLocation(program, name), x, y, z);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* Sets the value of a uniform variable in the given WebGLProgram.
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setInt4
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-04-25 23:30:41 +00:00
* @param {integer} x - X component
* @param {integer} y - Y component
* @param {integer} z - Z component
* @param {integer} w - W component
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setInt4: function (program, name, x, y, z, w)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniform4i(this.gl.getUniformLocation(program, name), x, y, z, w);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setMatrix2
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-02-13 00:12:17 +00:00
* @param {boolean} transpose - [description]
* @param {Float32Array} matrix - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setMatrix2: function (program, name, transpose, matrix)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(program, name), transpose, matrix);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setMatrix3
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-02-13 00:12:17 +00:00
* @param {boolean} transpose - [description]
* @param {Float32Array} matrix - [description]
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setMatrix3: function (program, name, transpose, matrix)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniformMatrix3fv(this.gl.getUniformLocation(program, name), transpose, matrix);
2018-01-22 21:21:47 +00:00
return this;
},
2018-02-09 19:19:21 +00:00
/**
2018-04-25 23:30:41 +00:00
* Sets uniform of a WebGLProgram
2018-02-09 19:19:21 +00:00
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setMatrix4
* @since 3.0.0
*
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
* @param {string} name - The name of the uniform to look-up and modify.
2018-04-25 23:30:41 +00:00
* @param {boolean} transpose - Is the matrix transposed
* @param {Float32Array} matrix - Matrix data
2018-02-09 19:19:21 +00:00
*
* @return {this} This WebGL Renderer instance.
2018-02-09 19:19:21 +00:00
*/
2018-01-22 21:21:47 +00:00
setMatrix4: function (program, name, transpose, matrix)
{
this.setProgram(program);
2018-01-22 21:21:47 +00:00
this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, name), transpose, matrix);
2018-01-20 04:05:56 +00:00
return this;
},
/**
* Returns the maximum number of texture units that can be used in a fragment shader.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getMaxTextures
* @since 3.8.0
*
* @return {integer} The maximum number of textures WebGL supports.
*/
getMaxTextures: function ()
{
return this.config.maxTextures;
},
/**
* Returns the largest texture size (either width or height) that can be created.
* Note that VRAM may not allow a texture of any given size, it just expresses
* hardware / driver support for a given size.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getMaxTextureSize
* @since 3.8.0
*
* @return {integer} The maximum supported texture size.
*/
getMaxTextureSize: function ()
{
return this.config.maxTextureSize;
},
2018-02-09 19:19:21 +00:00
/**
* [description]
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#destroy
* @since 3.0.0
*/
destroy: function ()
{
// Clear-up anything that should be cleared :)
for (var key in this.pipelines)
{
this.pipelines[key].destroy();
2018-04-23 18:11:16 +00:00
delete this.pipelines[key];
}
for (var index = 0; index < this.nativeTextures.length; ++index)
{
this.deleteTexture(this.nativeTextures[index]);
2018-04-23 18:11:16 +00:00
2018-02-16 18:17:51 +00:00
delete this.nativeTextures[index];
}
delete this.gl;
delete this.game;
this.contextLost = true;
this.extensions = {};
this.nativeTextures.length = 0;
2017-01-23 21:42:47 +00:00
}
});
2016-12-07 02:28:22 +00:00
2018-01-17 21:25:43 +00:00
module.exports = WebGLRenderer;