There are 2 polyfills in this folder:

ArrayBuffer and DataView support for IE9, required by P2 Physics.

You do not need this polyfill unless:

1) You are using P2 Physics in Phaser AND
2) You need to support IE9 specifically

Base64 Encoding and Decoding (adds window.atob and window.btoa support)

You only need this polyfill if you wish to load Base64 encoded Tile Map data in IE9, as exported by Tiled 0.13.0+

Ensure any polyfills are required before the Phaser library.


this.projection.y = -(this.height / 2) / this.game.resolution;

* If Multi Texture support has been enabled, then calling this method will enable batching on the given

* textures. The texture collection is an array of keys, that map to Phaser.Cache image entries.

* The number of textures that can be batched is dependent on hardware. If you provide more textures

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Collision Group
*
* @class Phaser.Physics.P2.CollisionGroup
* @constructor
* @param {number} bitmask - The CollisionGroup bitmask.
*/
Phaser.Physics.P2.CollisionGroup = function (bitmask) {

    /**
    * @property {number} mask - The CollisionGroup bitmask.
    */
    this.mask = bitmask;

};


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Phaser Source: src/pixi/renderers/canvas/utils/CanvasBuffer.js</title>

	<link type="text/css" rel="stylesheet" href="styles/default.css">

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			Phaser API

					Namespaces

							Phaser

							PIXI

					Classes

							Event

							EventTarget

							Animation

							AnimationManager

							AnimationParser

							ArraySet

							ArrayUtils

							AudioSprite

							BitmapData

							BitmapText

							Bullet

							Button

							Cache

							Camera

							Canvas

							Circle

							Color

							Angle

							Animation

							AutoCull

							Bounds

							BringToTop

							Core

							Crop

							Delta

							Destroy

							FixedToCamera

							Health

							InCamera

							InputEnabled

							InWorld

							LifeSpan

							LoadTexture

							Overlap

							PhysicsBody

							Reset

							ScaleMinMax

							Smoothed

							Create

							Creature

							Device

							DeviceButton

							DOM

							Easing

							Back

							Bounce

							Circular

							Cubic

							Elastic

							Exponential

							Linear

							Quadratic

							Quartic

							Quintic

							Sinusoidal

							Ellipse

							Events

							Filter

							FlexGrid

							FlexLayer

							Frame

							FrameData

							Game

							GameObjectCreator

							GameObjectFactory

							Gamepad

							Graphics

							Group

							Hermite

							Image

							ImageCollection

							Input

							InputHandler

							Key

							Keyboard

							KeyCode

							Line

							LinkedList

							Loader

							LoaderParser

							Math

							Matrix

							Mouse

							MSPointer

							Net

							Particle

							Particles

							Arcade

							Emitter

							Path

							PathFollower

							PathPoint

							Physics

							Arcade

							Body

							TilemapCollision

							Ninja

							AABB

							Body

							Circle

							Tile

							P2

							Body

							BodyDebug

							CollisionGroup

							ContactMaterial

							DistanceConstraint

							FixtureList

							GearConstraint

							InversePointProxy

							LockConstraint

							Material

							PointProxy

							PrismaticConstraint

							RevoluteConstraint

							RotationalSpring

							Spring

							Plugin

							PathManager

							PluginManager

							Point

							Pointer

							PointerMode

							Polygon

							QuadTree

							RandomDataGenerator

							Rectangle

							RenderTexture

							RequestAnimationFrame

							RetroFont

							Rope

							RoundedRectangle

							ScaleManager

							Signal

							SignalBinding

							SinglePad

							Sound

							SoundManager

							Sprite

							SpriteBatch

							Stage

							State

							StateManager

							Text

							Tile

							Tilemap

							TilemapLayer

							TilemapParser

							Tileset

							TileSprite

							Time

							Timer

							TimerEvent

							Touch

							Tween

							TweenData

							TweenManager

							Utils

							Debug

							Video

							Weapon

							World

							AbstractFilter

							BaseTexture

							CanvasBuffer

							CanvasGraphics

							CanvasMaskManager

							CanvasPool

							CanvasRenderer

							CanvasTinter

							ComplexPrimitiveShader

							DisplayObjectContainer

							EarCut

							Event

							EventTarget

							FilterTexture

							Graphics

							GraphicsData

							PIXI

							DisplayObject

							PixiFastShader

							PixiShader

							PrimitiveShader

							RenderTexture

							Rope

							Sprite

							SpriteBatch

							Strip

							StripShader

							Texture

							TilingSprite

							WebGLBlendModeManager

							WebGLFastSpriteBatch

							WebGLFilterManager

							WebGLRenderer

					Global

							ANGLE_DOWN

							ANGLE_LEFT

							ANGLE_NORTH_EAST

							ANGLE_NORTH_WEST

							ANGLE_RIGHT

							ANGLE_SOUTH_EAST

							ANGLE_SOUTH_WEST

							ANGLE_UP

							AUTO

							BITMAPDATA

							BITMAPTEXT

							blendModes

							BOTTOM_CENTER

							BOTTOM_LEFT

							BOTTOM_RIGHT

							BUTTON

							CANVAS

							CANVAS_FILTER

							CENTER

							CIRCLE

							CREATURE

							displayList

							DOWN

							ELLIPSE

							emit

							EMITTER

							GAMES

							GRAPHICS

							GROUP

							HEADLESS

							HORIZONTAL

							IMAGE

							LANDSCAPE

							LEFT

							LEFT_BOTTOM

							LEFT_CENTER

							LEFT_TOP

							LINE

							listeners

							MATRIX

							mixin

							NONE

							off

							on

							once

							PENDING_ATLAS

							Phaser.Path#numPoints
return {number} The total number of PathPoints in this Path.

							POINT

							POINTER

							POLYGON

							PORTRAIT

							RECTANGLE

							removeAllListeners

							RENDERTEXTURE

							RETROFONT

							RIGHT

							RIGHT_BOTTOM

							RIGHT_CENTER

							RIGHT_TOP

							ROPE

							ROUNDEDRECTANGLE

							scaleModes

							SPRITE

							SPRITEBATCH

							stopImmediatePropagation

							stopPropagation

							TEXT

							TILEMAP

							TILEMAPLAYER

							TILESPRITE

							TOP_CENTER

							TOP_LEFT

							TOP_RIGHT

							UP

							VERSION

							VERTICAL

							VIDEO

							WEBGL

							WEBGL_FILTER

					Core

Game

Group

World

Loader

Cache

Time

Camera

State Manager

Tween Manager

Sound Manager

Input Manager

Scale Manager

					Game Objects

Factory (game.add)

Creator (game.make)

Sprite

Image

Sound

Video

Particle Emitter

Particle

Text

Tween

BitmapText

Tilemap

BitmapData

RetroFont

Button

Animation

Graphics

RenderTexture

TileSprite

					Geometry

Circle

Ellipse

Line

Matrix

Point

Polygon

Rectangle

Rounded Rectangle

					Physics

Arcade Physics

Body

Weapon

P2 Physics

Body

Spring

CollisionGroup

ContactMaterial

Ninja Physics

Body

					Input

Input Handler

Pointer

Device Button

Mouse

Keyboard

Key

Key Codes

Gamepad

					Community

Phaser Web Site

Phaser Github

Phaser Examples

Phaser Plugins

Forum

Stack Overflow

Tutorials

Newsletter

Twitter

Slack

Donate

Texture Packer

Source: src/pixi/renderers/canvas/utils/CanvasBuffer.js

/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * Creates a Canvas element of the given size.
 *
 * @class CanvasBuffer
 * @constructor
 * @param width {Number} the width for the newly created canvas
 * @param height {Number} the height for the newly created canvas
 */
PIXI.CanvasBuffer = function(width, height)
{
    /**
     * The width of the Canvas in pixels.
     *
     * @property width
     * @type Number
     */
    this.width = width;

    /**
     * The height of the Canvas in pixels.
     *
     * @property height
     * @type Number
     */
    this.height = height;

    /**
     * The Canvas object that belongs to this CanvasBuffer.
     *
     * @property canvas
     * @type HTMLCanvasElement
     */
    this.canvas = PIXI.CanvasPool.create(this, this.width, this.height);

    /**
     * A CanvasRenderingContext2D object representing a two-dimensional rendering context.
     *
     * @property context
     * @type CanvasRenderingContext2D
     */
    this.context = this.canvas.getContext("2d");

    this.canvas.width = width;
    this.canvas.height = height;
};

PIXI.CanvasBuffer.prototype.constructor = PIXI.CanvasBuffer;

/**
 * Clears the canvas that was created by the CanvasBuffer class.
 *
 * @method clear
 * @private
 */
PIXI.CanvasBuffer.prototype.clear = function()
{
    this.context.setTransform(1, 0, 0, 1, 0, 0);
    this.context.clearRect(0,0, this.width, this.height);
};

/**
 * Resizes the canvas to the specified width and height.
 *
 * @method resize
 * @param width {Number} the new width of the canvas
 * @param height {Number} the new height of the canvas
 */
PIXI.CanvasBuffer.prototype.resize = function(width, height)
{
    this.width = this.canvas.width = width;
    this.height = this.canvas.height = height;
};

/**
 * Frees the canvas up for use again.
 *
 * @method destroy
 */
PIXI.CanvasBuffer.prototype.destroy = function()
{
    PIXI.CanvasPool.remove(this);
};

		Phaser Copyright © 2012-2016 Photon Storm Ltd.

		Documentation generated by JSDoc 3.4.0
		on Fri Aug 26 2016 01:16:09 GMT+0100 (BST) using the DocStrap template.


keep keep keep keep keep replace keep keep keep

/**
* @author       Richard Davey <rich@photonstorm.com>
* @author       Mat Groves (@Doormat23)
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* New version of PIXI.DefaultShader which was PIXI.PixiShader
*
* @class Phaser.Renderer.Canvas
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
*/
Phaser.Renderer.WebGL.Shaders.Sprite = function (renderer)
{
    this.renderer = renderer;

    //  WebGLContext
    this.gl = renderer.gl;

    /**
     * @property _UID
     * @type Number
     * @private
     */
    this._UID = Phaser._UID++;

    /**
     * The WebGL program.
     * @property program
     * @type Any
     */
    this.program = null;

    /**
    * The Default Vertex shader source.
    *
    * @property defaultVertexSrc
    * @type String
    */
    this.vertexSrc = [
        'attribute vec2 aVertexPosition;',
        'attribute vec2 aTextureCoord;',
        'attribute vec4 aColor;',
        'attribute float aTextureIndex;',

        'uniform vec2 projectionVector;',
        'uniform vec2 offsetVector;',

        'varying vec2 vTextureCoord;',
        'varying vec4 vColor;',
        'varying float vTextureIndex;',

        'const vec2 center = vec2(-1.0, 1.0);',

        'void main(void) {',
        '   if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
        '   gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
        '   vTextureCoord = aTextureCoord;',
        '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
        '   vTextureIndex = aTextureIndex;',
        '}'
    ];

    /**
     * The fragment shader.
     * @property fragmentSrc
     * @type Array
     */
    this.fragmentSrc = null;

    /**
     * Uniform attributes cache.
     * @property attributes
     * @type Array
     * @private
     */
    this.attributes = [];

    /**
     * A local texture counter for multi-texture shaders.
     * @property textureCount
     * @type Number
     */
    this.textureCount = 0;

    //  @type {WebGLUniformLocation }
    this.uSampler;

    //  @type {WebGLUniformLocation }
    this.projectionVector;

    //  @type {WebGLUniformLocation }
    this.offsetVector;

    //  @type {GLint}
    this.colorAttribute;

    //  @type {GLint}
    this.aTextureIndex;

    //  @type {GLint}
    this.aVertexPosition;

    //  @type {GLint}
    this.aTextureCoord;

    //  @type {WebGLUniformLocation }
    this.translationMatrix;

    //  @type {WebGLUniformLocation }
    this.alpha;

    this.init();
};

Phaser.Renderer.WebGL.Shaders.Sprite.prototype.constructor = Phaser.Renderer.WebGL.Shaders.Sprite;

Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {

    init: function (usingFilter)
    {
        if (this.renderer.enableMultiTextureToggle && !usingFilter)
        {
            this.initMultitexShader();
        }
        else
        {
            this.initDefaultShader();
        }
    },

    initDefaultShader: function ()
    {
        if (this.fragmentSrc === null)
        {
            this.fragmentSrc = [
                'precision lowp float;',
                'varying vec2 vTextureCoord;',
                'varying vec4 vColor;',
                'varying float vTextureIndex;',
                'uniform sampler2D uSampler;',
                'void main(void) {',
                '   gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
                '}'
            ];
        }

        var gl = this.gl;

        var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);

        gl.useProgram(program);

        // get and store the uniforms for the shader
        this.uSampler = gl.getUniformLocation(program, 'uSampler');
        this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
        this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
        this.dimensions = gl.getUniformLocation(program, 'dimensions');

        // get and store the attributes
        this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
        this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
        this.colorAttribute = gl.getAttribLocation(program, 'aColor');
        this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');

        this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];

        // add those custom shaders!
        for (var key in this.uniforms)
        {
            // get the uniform locations..
            this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
        }

        this.initUniforms();

        this.program = program;
    },

    initMultitexShader: function ()
    {
        var gl = this.gl;
        var max = this.renderer.getMaxTextureUnits();

        var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n';

        for (var index = 1; index < max; ++index)
        {
            dynamicIfs += '\telse if (vTextureIndex == ' +
                        index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
                        index + '], vTextureCoord) * vColor;\n'
        }

        this.fragmentSrc = [
            'precision lowp float;',
            'varying vec2 vTextureCoord;',
            'varying vec4 vColor;',
            'varying float vTextureIndex;',
            'uniform sampler2D uSamplerArray[' + max + '];',
            'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
            'const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);',
            'void main(void) {',
            dynamicIfs,
            'else gl_FragColor = PINK;',
            '}'
        ];

        var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);

        gl.useProgram(program);

        // get and store the uniforms for the shader
        this.uSamplerArray = gl.getUniformLocation(program, 'uSamplerArray[0]');
        this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
        this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
        this.dimensions = gl.getUniformLocation(program, 'dimensions');

        // get and store the attributes
        this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
        this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
        this.colorAttribute = gl.getAttribLocation(program, 'aColor');
        this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');

        var indices = [];

        //  Bind an empty texture to avoid WebGL console warning spam
        var tempTexture = gl.createTexture();

        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, tempTexture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);

        for (var i = 0; i < max; ++i)
        {
            gl.activeTexture(gl.TEXTURE0 + i);
            gl.bindTexture(gl.TEXTURE_2D, tempTexture);
            indices.push(i);
        }

        gl.activeTexture(gl.TEXTURE0);
        gl.uniform1iv(this.uSamplerArray, indices);

        this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];

        //  Add those custom shaders!
        for (var key in this.uniforms)
        {
            this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
        }

        this.initUniforms();

        this.program = program;
    },

    initUniforms: function ()
    {
        this.textureCount = 1;
        var gl = this.gl;
        var uniform;

        for (var key in this.uniforms)
        {
            uniform = this.uniforms[key];

            switch (uniform.type)
            {
                case 'sampler2D':

                    uniform._init = false;

                    if (uniform.value !== null)
                    {
                        this.initSampler2D(uniform);
                    }

                    break;

                case 'mat2':

                    uniform.glMatrix = true;
                    uniform.glValueLength = 1;
                    uniform.glFunc = gl.uniformMatrix2fv;
                    break;

                case 'mat3':

                    uniform.glMatrix = true;
                    uniform.glValueLength = 1;
                    uniform.glFunc = gl.uniformMatrix3fv;
                    break;

                case 'mat4':

                    uniform.glMatrix = true;
                    uniform.glValueLength = 1;
                    uniform.glFunc = gl.uniformMatrix4fv;
                    break;

                default:

                    //  GL function reference
                    uniform.glFunc = gl['uniform' + uniform.type];

                    if (uniform.type === '2f' || uniform.type === '2i')
                    {
                        uniform.glValueLength = 2;
                    }
                    else if (uniform.type === '3f' || uniform.type === '3i')
                    {
                        uniform.glValueLength = 3;
                    }
                    else if (uniform.type === '4f' || uniform.type === '4i')
                    {
                        uniform.glValueLength = 4;
                    }
                    else
                    {
                        uniform.glValueLength = 1;
                    }
            }
        }

    },

    /**
    * Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded)
    *
    * @method initSampler2D
    */
    initSampler2D: function (uniform)
    {
        if (!uniform.value || !uniform.value.baseTexture || !uniform.value.baseTexture.hasLoaded)
        {
            return;
        }

        var gl = this.gl;

        // No need to do string manipulation for this.
        gl.activeTexture(gl.TEXTURE0 + this.textureCount);
        gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures);

        //  Extended texture data
        if (uniform.textureData)
        {
            var data = uniform.textureData;

            // GLTexture = mag linear, min linear_mipmap_linear, wrap repeat + gl.generateMipmap(gl.TEXTURE_2D);
            // GLTextureLinear = mag/min linear, wrap clamp
            // GLTextureNearestRepeat = mag/min NEAREST, wrap repeat
            // GLTextureNearest = mag/min nearest, wrap clamp
            // AudioTexture = whatever + luminance + width 512, height 2, border 0
            // KeyTexture = whatever + luminance + width 256, height 2, border 0

            //  magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST
            //  wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT

            var magFilter = (data.magFilter) ? data.magFilter : gl.LINEAR;
            var minFilter = (data.minFilter) ? data.minFilter : gl.LINEAR;
            var wrapS = (data.wrapS) ? data.wrapS : gl.CLAMP_TO_EDGE;
            var wrapT = (data.wrapT) ? data.wrapT : gl.CLAMP_TO_EDGE;
            var format = (data.luminance) ? gl.LUMINANCE : gl.RGBA;

            if (data.repeat)
            {
                wrapS = gl.REPEAT;
                wrapT = gl.REPEAT;
            }

            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY);

            if (data.width)
            {
                var width = (data.width) ? data.width : 512;
                var height = (data.height) ? data.height : 2;
                var border = (data.border) ? data.border : 0;

                // void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
                gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null);
            }
            else
            {
                //  void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels);
                gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.value.baseTexture.source);
            }

            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
        }

        gl.uniform1i(uniform.uniformLocation, this.textureCount);

        uniform._init = true;

        this.textureCount++;
    },

    /**
    * Updates the shader uniform values.
    *
    * @method syncUniforms
    */
    syncUniforms: function ()
    {
        this.textureCount = 1;

        var uniform;

        var gl = this.gl;

        //  This would probably be faster in an array and it would guarantee key order
        for (var key in this.uniforms)
        {
            uniform = this.uniforms[key];

            if (uniform.glValueLength === 1)
            {
                if (uniform.glMatrix === true)
                {
                    uniform.glFunc.call(gl, uniform.uniformLocation, uniform.transpose, uniform.value);
                }
                else
                {
                    uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value);
                }
            }
            else if (uniform.glValueLength === 2)
            {
                uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y);
            }
            else if (uniform.glValueLength === 3)
            {
                uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z);
            }
            else if (uniform.glValueLength === 4)
            {
                uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w);
            }
            else if (uniform.type === 'sampler2D')
            {
                if (uniform._init)
                {
                    gl.activeTexture(gl['TEXTURE' + this.textureCount]);

                    if (uniform.value.baseTexture._dirty)
                    {
                        this.renderer.updateTexture(uniform.value.baseTexture);
                    }
                    else
                    {
                        gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures);
                    }

                    gl.uniform1i(uniform.uniformLocation, this.textureCount);

                    this.textureCount++;
                }
                else
                {
                    this.initSampler2D(uniform);
                }
            }
        }

    },

    destroy: function ()
    {
        this.gl.deleteProgram(this.program);
        this.uniforms = null;
        this.gl = null;
        this.renderer = null;
        this.attributes = null;
    }

};


Phaser Copyright © 2012-2016 Photon Storm Ltd.


/* global styles */
.sunlight-container {
	clear: both !important;
	position: relative !important;
	margin: 10px 0 !important;
}
.sunlight-code-container {
	clear: both !important;
	position: relative !important;
	border: none;
	border-color: #626262 !important;
	background-color: #262626 !important;
}
.sunlight-highlighted, .sunlight-container, .sunlight-container textarea {
	font-family: Consolas, Inconsolata, Monaco, "Courier New" !important;
	font-size: 12px !important;
	line-height: 15px !important;
}
.sunlight-highlighted, .sunlight-container textarea {
	color: #FFFFFF !important;
	margin: 0 !important;
}
.sunlight-container textarea {
	padding-left: 0 !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
	padding-right: 0 !important;
}
.sunlight-code-container > .sunlight-highlighted {
	white-space: pre;
	overflow-x: auto;
	overflow-y: hidden; /* ie requires this wtf? */
}
.sunlight-highlighted {
	z-index: 1;
	position: relative;
}
.sunlight-highlighted * {
	background: transparent;
}
.sunlight-line-number-margin {
	float: left !important;
	margin-right: 5px !important;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	padding: 0 !important;
	padding-right: 4px !important;
	padding-left: 4px !important;
	border-right: 1px solid #9A9A9A !important;
	background-color: #3E3E3E !important;
	color: #9A9A9A !important;
	text-align: right !important;
	position: relative;
	z-index: 3;
}
.sunlight-highlighted a, .sunlight-line-number-margin a {
	border: none !important;
	text-decoration: none !important;
	font-style: normal !important;
	padding: 0 !important;
}
.sunlight-line-number-margin a {
	color: inherit !important;
}
.sunlight-line-highlight-overlay {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	z-index: 0;
}
.sunlight-line-highlight-overlay div {
	height: 15px;
	width: 100%;
}
.sunlight-line-highlight-overlay .sunlight-line-highlight-active {
	background-color: #4B4B4B;
}

/* menu */
.sunlight-menu {
	background-color: #FFFFCC;
	color: #000000;
}
.sunlight-menu ul {
	margin: 0 !important;
	padding: 0 !important;
	list-style-type: none !important;
}
.sunlight-menu li {
	float: right !important;
	margin-left: 5px !important;
}
.sunlight-menu a, .sunlight-menu img {
	color: #000099 !important;
	text-decoration: none !important;
	border: none !important;
}

.sunlight-string,
.sunlight-char,
.sunlight-heredoc,
.sunlight-heredocDeclaration,
.sunlight-nowdoc,
.sunlight-longString,
.sunlight-rawString,
.sunlight-binaryString,
.sunlight-verbatimString,
.sunlight-rawLongString,
.sunlight-binaryLongString,
.sunlight-diff .sunlight-added {
	color: #55EB54 !important;
}
.sunlight-operator,
.sunlight-punctuation,
.sunlight-delimiter {
	color: #B1EDEC !important;
}
.sunlight-ident,
.sunlight-diff .sunlight-unchanged {
	color: #E0E0E0 !important;
	font-weight: bold !important;
}
.sunlight-comment,
.sunlight-xmlDocCommentContent,
.sunlight-nginx .sunlight-ssiCommand,
.sunlight-sln .sunlight-formatDeclaration,
.sunlight-diff .sunlight-mergeHeader,
.sunlight-diff .sunlight-noNewLine {
	color: #787D31 !important;
}
.sunlight-number,
.sunlight-cdata,
.sunlight-guid,
.sunlight-diff .sunlight-modified {
	color: #F7BA7E !important;
	font-weight: bold !important;
}
.sunlight-named-ident,
.sunlight-xml .sunlight-attribute,
.sunlight-constant,
.sunlight-javascript .sunlight-globalVariable,
.sunlight-globalObject,
.sunlight-css .sunlight-id,
.sunlight-python .sunlight-attribute,
.sunlight-nginx .sunlight-context,
.sunlight-httpd .sunlight-context,
.sunlight-lisp .sunlight-declarationSpecifier,
.sunlight-erlang .sunlight-userDefinedFunction,
.sunlight-diff .sunlight-removed {
	color: #FBBDEE !important;
	font-weight: bold !important;
}
.sunlight-keyword,
.sunlight-languageConstruct,
.sunlight-specialOperator,
.sunlight-xml .sunlight-tagName,
.sunlight-xml .sunlight-operator,
.sunlight-bash .sunlight-command,
.sunlight-erlang .sunlight-moduleAttribute {
	color: #A3CCF7 !important;
	font-weight: bold !important;
}
.sunlight-shortOpenTag,
.sunlight-openTag,
.sunlight-closeTag,
.sunlight-xmlOpenTag,
.sunlight-xmlCloseTag,
.sunlight-aspOpenTag,
.sunlight-aspCloseTag,
.sunlight-label,
.sunlight-css .sunlight-importantFlag {
	background-color: #7373C1 !important;
}
.sunlight-content {
	color: #FFFFFF !important;
	font-weight: bold !important;
}
.sunlight-function,
.sunlight-globalFunction,
.sunlight-objective-c .sunlight-messageDestination,
.sunlight-ruby .sunlight-specialFunction,
.sunlight-6502asm .sunlight-illegalOpcode,
.sunlight-powershell .sunlight-switch,
.sunlight-lisp .sunlight-macro,
.sunlight-lisp .sunlight-specialForm,
.sunlight-lisp .sunlight-type,
.sunlight-sln .sunlight-sectionName,
.sunlight-diff .sunlight-header {
	color: #C8BBF1 !important;
	font-weight: bold !important;
}
.sunlight-variable,
.sunlight-environmentVariable,
.sunlight-specialVariable,
.sunlight-objective-c .sunlight-messageArgumentName,
.sunlight-lisp .sunlight-globalVariable,
.sunlight-ruby .sunlight-globalVariable,
.sunlight-ruby .sunlight-instanceVariable {
	color: #F5E5B0 !important;
	font-weight: bold !important;
}
.sunlight-regexLiteral,
.sunlight-lisp .sunlight-operator,
.sunlight-6502asm .sunlight-pseudoOp,
.sunlight-erlang .sunlight-macro,
.sunlight-diff .sunlight-rangeInfo {
	color: #E0F16A !important;
}
.sunlight-specialVariable {
	font-style: italic !important;
	font-weight: bold !important;
}
.sunlight-csharp .sunlight-pragma,
.sunlight-preprocessorDirective,
.sunlight-vb .sunlight-compilerDirective {
	color: #666363 !important;
	font-style: italic !important;
}
.sunlight-xmlDocCommentMeta,
.sunlight-java .sunlight-annotation,
.sunlight-scala .sunlight-annotation,
.sunlight-docComment {
	color: #666363 !important;
}
.sunlight-quotedIdent,
.sunlight-ruby .sunlight-subshellCommand,
.sunlight-lisp .sunlight-keywordArgument,
.sunlight-haskell .sunlight-infixOperator,
.sunlight-erlang .sunlight-quotedAtom {
	color: #F8CA16 !important;
}

/* html/xml */
.sunlight-xml .sunlight-tagName,
.sunlight-xml .sunlight-operator,
.sunlight-xml .sunlight-attribute {
	font-weight: normal !important;
}
.sunlight-doctype {
	color: #DEB9B2 !important;
	font-style: italic !important;
}
.sunlight-xml .sunlight-entity {
	background-color: #E6E585 !important;
	color: #000000 !important;
}

/* javascript */
.sunlight-javascript .sunlight-reservedWord {
	font-style: italic !important;
}

/* css */
.sunlight-css .sunlight-element {
	color: #E9EE97 !important;
}
.sunlight-css .sunlight-microsoftFilterPrefix {
	color: #C9FF9F !important;
}
.sunlight-css .sunlight-rule {
	color: #0099FF !important;
}
.sunlight-css .sunlight-class {
	color: #E78282 !important;
}
.sunlight-css .sunlight-pseudoClass, .sunlight-css .sunlight-pseudoElement {
	color: #73D693 !important;
}

/* bash */
.sunlight-bash .sunlight-hashBang {
	color: #FFFF00 !important;
}

.sunlight-bash .sunlight-verbatimCommand {
	color: #BBA4EE !important;
}
.sunlight-bash .sunlight-variable,
.sunlight-bash .sunlight-specialVariable {
	color: #ED8585 !important;
}

/* python */
.sunlight-python .sunlight-specialMethod {
	font-weight: bold !important;
	color: #B0A3C2;
}

/* ruby */
.sunlight-ruby .sunlight-symbol {
	font-weight: bold !important;
	color: #90EEA2 !important;
}

/* brainfuck */
.sunlight-brainfuck {
	font-weight: bold !important;
	color: #000000 !important;
}
.sunlight-brainfuck .sunlight-increment {
	background-color: #FF9900 !important;
}
.sunlight-brainfuck .sunlight-decrement {
	background-color: #FF99FF !important;
}
.sunlight-brainfuck .sunlight-incrementPointer {
	background-color: #FFFF99 !important;
}
.sunlight-brainfuck .sunlight-decrementPointer {
	background-color: #66CCFF !important;
}
.sunlight-brainfuck .sunlight-read {
	background-color: #FFFFFF !important;
}
.sunlight-brainfuck .sunlight-write {
	background-color: #99FF99 !important;
}
.sunlight-brainfuck .sunlight-openLoop, .sunlight-brainfuck .sunlight-closeLoop {
	background-color: #FFFFFF !important;
}

/* 6502 asm */
.sunlight-6502asm .sunlight-label {
	background: none !important;
	color: #FFFFFF !important;
	text-decoration: underline !important;
}

/* lisp */
.sunlight-lisp .sunlight-macro {
	font-style: italic !important;
}

/* erlang */
.sunlight-erlang .sunlight-atom {
	color: #FFFFFF !important;
	font-weight: bold !important;
}


define([
    'phaser'
], function (Phaser) {
    'use strict';

    function Game() {
        console.log('Making the Game');
    }

    Game.prototype = {
        constructor: Game,

        start: function() {
            this.game = new Phaser.Game(800, 600, Phaser.AUTO, '', {
                preload: this.preload,
                create: this.create
            });
        },

        preload: function() {
            this.game.load.image('logo', 'assets/phaser.png');
        },

        create: function() {
            var logo = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, 'logo');
            logo.anchor.setTo(0.5, 0.5);
        }
    };

    return Game;
});


/**
* @author       Richard Davey <rich@photonstorm.com>
* @author       Mat Groves (@Doormat23)
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* New version of PIXI.PixiFastShader
*
* @class Phaser.Renderer.Canvas
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
*/
Phaser.Renderer.WebGL.Shaders.SpriteBatch = function (renderer)
{
    this.renderer = renderer;

    //  WebGLContext
    this.gl = renderer.gl;

    /**
     * @property _UID
     * @type Number
     * @private
     */
    this._UID = Phaser._UID++;

    /**
     * The WebGL program.
     * @property program
     * @type Any
     */
    this.program = null;

    /**
    * The vertex shader.
    * @property vertexSrc
    * @type Array
    */
    this.fragmentSrc = [];

    this.vertexSrc = [];

    this.attributes = [];

    //  @type {WebGLUniformLocation }
    this.uSampler;

    //  @type {WebGLUniformLocation }
    this.projectionVector;

    //  @type {WebGLUniformLocation }
    this.offsetVector;

    //  @type {WebGLUniformLocation }
    this.dimensions;

    //  @type {WebGLUniformLocation }
    this.uMatrix;

    //  @type {GLint}
    this.aVertexPosition;

    //  @type {GLint}
    this.aPositionCoord;

    //  @type {GLint}
    this.aScale;

    //  @type {GLint}
    this.aRotation;

    //  @type {GLint}
    this.aTextureCoord;

    //  @type {GLint}
    this.colorAttribute;

    //  @type {GLint}
    this.aTextureIndex;

    this.init();
};

Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype.constructor = Phaser.Renderer.WebGL.Shaders.SpriteBatch;

Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype = {

    init: function ()
    {
        if (this.renderer.enableMultiTextureToggle)
        {
            var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n'

            for (var index = 1; index < this.renderer.getMaxTextureUnits(); ++index)
            {
                dynamicIfs += '\telse if (vTextureIndex == ' +
                            index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
                            index + '], vTextureCoord) * vColor;\n'
            }

            this.fragmentSrc = [
                'precision lowp float;',
                'varying vec2 vTextureCoord;',
                'varying float vColor;',
                'varying float vTextureIndex;',
                'uniform sampler2D uSamplerArray[' + this.renderer.getMaxTextureUnits() + '];',
                'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
                'const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);',
                'void main(void) {',
                dynamicIfs,
                'else gl_FragColor = PINK;',
                '}'
            ];
        }
        else
        {
            this.fragmentSrc = [
                'precision lowp float;',
                'varying vec2 vTextureCoord;',
                'varying float vColor;',
                'varying float vTextureIndex;',
                'uniform sampler2D uSampler;',
                'void main(void) {',
                '   gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
                '}'
            ];
        }

        this.vertexSrc  = [
            'attribute vec2 aVertexPosition;',
            'attribute vec2 aPositionCoord;',
            'attribute vec2 aScale;',
            'attribute float aRotation;',
            'attribute vec2 aTextureCoord;',
            'attribute float aColor;',
            'attribute float aTextureIndex;',

            'uniform vec2 projectionVector;',
            'uniform vec2 offsetVector;',
            'uniform mat3 uMatrix;',

            'varying vec2 vTextureCoord;',
            'varying float vColor;',
            'varying float vTextureIndex;',

            'const vec2 center = vec2(-1.0, 1.0);',

            'void main(void) {',
            '   vec2 v;',
            '   vec2 sv = aVertexPosition * aScale;',
            '   v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
            '   v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
            '   v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
            '   gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
            '   vTextureCoord = aTextureCoord;',
            '   vTextureIndex = aTextureIndex;',
            '   vColor = aColor;',
            '}'
        ];

        var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);

        var gl = this.gl;

        gl.useProgram(program);

        // get and store the uniforms for the shader
        this.uSampler = (this.renderer.enableMultiTextureToggle) ? gl.getUniformLocation(program, 'uSamplerArray[0]') : gl.getUniformLocation(program, 'uSampler');

        if (this.renderer.enableMultiTextureToggle)
        {
            var indices = [];

            // HACK: we bind an empty texture to avoid WebGL warning spam.
            var tempTexture = gl.createTexture();
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, tempTexture);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);

            for (var i = 0; i < this.renderer.getMaxTextureUnits(); ++i)
            {
                gl.activeTexture(gl.TEXTURE0 + i);
                gl.bindTexture(gl.TEXTURE_2D, tempTexture);
                indices.push(i);
            }

            gl.activeTexture(gl.TEXTURE0);
            gl.uniform1iv(this.uSampler, indices);
        }

        this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
        this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
        this.dimensions = gl.getUniformLocation(program, 'dimensions');
        this.uMatrix = gl.getUniformLocation(program, 'uMatrix');

        // get and store the attributes
        this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
        this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');

        this.aScale = gl.getAttribLocation(program, 'aScale');
        this.aRotation = gl.getAttribLocation(program, 'aRotation');

        this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
        this.colorAttribute = gl.getAttribLocation(program, 'aColor');

        this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');

        this.attributes = [
            this.aVertexPosition,
            this.aPositionCoord,
            this.aScale,
            this.aRotation,
            this.aTextureCoord,
            this.colorAttribute,
            this.aTextureIndex
        ];

        this.program = program;
    },

    destroy: function ()
    {
        this.gl.deleteProgram(this.program);
        this.gl = null;
        this.renderer = null;
        this.attributes = null;
    }

};


<!doctype html>

        <meta charset="UTF-8" />
        <title>Phaser Tutorial 01 - Getting Started</title>

Comenzando con Phaser

Parte 6 - Hola Mundo!

Con tu editor configurado, el servidor web instalado y Phaser descargado, es hora de crear algo y verificar que todo funciona.

Necesitas descubrir dónde está tu 'web root' en tu ordenador. Es la carpeta donde el servidor web busca los ficheros. Si estás usando WAMP en Windows puedes localizarlo haciendo clic en el icono de WAMP de la bandeja de sistema y seleccionar 'www directory' en el menú desplegable. Otros servidores tendrán otros métodos para determinar su localización, pero a partir de ahora nos referiremos a él como 'webroot'.

Descarga este archivo zip. Dentro contiene una carpeta llamada 'hellophaser' en la que encontrarás un fichero JavaScript, un index.html y un PNG. Copia la carpeta 'hellophaser' en tu webroot.

Testear, testear ...

Abre tu navegador web y ve a tu servidor local. Esto puede ser tan sencillo como teclear en la barra de dirección 'localhost' o '127.0.0.1', o quizás también necesites especificar un número de puerto, depende totalmente de cómo esté configurado el servidor. Si el servidor está correctamente instalado y funcionando verás en tu navegador la página de instalación por defecto. Esto varía de servidor en servidor, pero mientras el navegador no se quede colgado cargando la página o no te de un error de permisos, estás listo para avanzar.

Ahora añade /hellophaser al final de la dirección y el ejemplo de Hola Mundo (Hello World) debería cargar. Si es así aparecerá un rectángulo negro con el logotipo de Phaser en el centro. Si por cualquier razón no lo hace necesitarás abrir la consola de depuración y ver qué errores muestra. En la mayoría de navegadores puedes abrirla presionando F12. Esto funciona en Chrome, Firefox e Internet Explorer. Comprueba qué error es. Con suerte será algo simple, como ficheros que faltan, en cuyo caso comprueba los nombres de tus carpetas y recarga la página. Si es algo más complejo no dudes en preguntar acerca de ello en el foro y te ayudaremos.

Parte 7: Los ejemplos de Phaser

Parte 1: Introducción

Parte 2: Instalando un nuevo servidor web

Parte 3: Ejecutar en la nube

Parte 4: Escogiendo un editor

Parte 5: Descargando Phaser

Parte 6: Hola Mundo!

Parte 7: Los ejemplos de Phaser

Parte 8: Siguientes pasos


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Phaser Source: src/core/Filter.js</title>

	<link type="text/css" rel="stylesheet" href="styles/default.css">

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			Phaser API

					Namespaces

							Phaser

							PIXI

					Classes

							Event

							EventTarget

							Animation

							AnimationManager

							AnimationParser

							ArraySet

							ArrayUtils

							AudioSprite

							BitmapData

							BitmapText

							Bullet

							Button

							Cache

							Camera

							Canvas

							Circle

							Color

							Angle

							Animation

							AutoCull

							Bounds

							BringToTop

							Core

							Crop

							Delta

							Destroy

							FixedToCamera

							Health

							InCamera

							InputEnabled

							InWorld

							LifeSpan

							LoadTexture

							Overlap

							PhysicsBody

							Reset

							ScaleMinMax

							Smoothed

							Create

							Creature

							Device

							DeviceButton

							DOM

							Easing

							Back

							Bounce

							Circular

							Cubic

							Elastic

							Exponential

							Linear

							Quadratic

							Quartic

							Quintic

							Sinusoidal

							Ellipse

							Events

							Filter

							FlexGrid

							FlexLayer

							Frame

							FrameData

							Game

							GameObjectCreator

							GameObjectFactory

							Gamepad

							Graphics

							Group

							Hermite

							Image

							ImageCollection

							Input

							InputHandler

							Key

							Keyboard

							KeyCode

							Line

							LinkedList

							Loader

							LoaderParser

							Math

							Matrix

							Mouse

							MSPointer

							Net

							Particle

							Particles

							Arcade

							Emitter

							Path

							PathFollower

							PathPoint

							Physics

							Arcade

							Body

							TilemapCollision

							Ninja

							AABB

							Body

							Circle

							Tile

							P2

							Body

							BodyDebug

							CollisionGroup

							ContactMaterial

							DistanceConstraint

							FixtureList

							GearConstraint

							InversePointProxy

							LockConstraint

							Material

							PointProxy

							PrismaticConstraint

							RevoluteConstraint

							RotationalSpring

							Spring

							Plugin

							PathManager

							PluginManager

							Point

							Pointer

							PointerMode

							Polygon

							QuadTree

							RandomDataGenerator

							Rectangle

							RenderTexture

							RequestAnimationFrame

							RetroFont

							Rope

							RoundedRectangle

							ScaleManager

							Signal

							SignalBinding

							SinglePad

							Sound

							SoundManager

							Sprite

							SpriteBatch

							Stage

							State

							StateManager

							Text

							Tile

							Tilemap

							TilemapLayer

							TilemapParser

							Tileset

							TileSprite

							Time

							Timer

							TimerEvent

							Touch

							Tween

							TweenData

							TweenManager

							Utils

							Debug

							Video

							Weapon

							World

							AbstractFilter

							BaseTexture

							CanvasBuffer

							CanvasGraphics

							CanvasMaskManager

							CanvasPool

							CanvasRenderer

							CanvasTinter

							ComplexPrimitiveShader

							DisplayObjectContainer

							EarCut

							Event

							EventTarget

							FilterTexture

							Graphics

							GraphicsData

							PIXI

							DisplayObject

							PixiFastShader

							PixiShader

							PrimitiveShader

							RenderTexture

							Rope

							Sprite

							SpriteBatch

							Strip

							StripShader

							Texture

							TilingSprite

							WebGLBlendModeManager

							WebGLFastSpriteBatch

							WebGLFilterManager

							WebGLRenderer

					Global

							ANGLE_DOWN

							ANGLE_LEFT

							ANGLE_NORTH_EAST

							ANGLE_NORTH_WEST

							ANGLE_RIGHT

							ANGLE_SOUTH_EAST

							ANGLE_SOUTH_WEST

							ANGLE_UP

							AUTO

							BITMAPDATA

							BITMAPTEXT

							blendModes

							BOTTOM_CENTER

							BOTTOM_LEFT

							BOTTOM_RIGHT

							BUTTON

							CANVAS

							CANVAS_FILTER

							CENTER

							CIRCLE

							CREATURE

							displayList

							DOWN

							ELLIPSE

							emit

							EMITTER

							GAMES

							GRAPHICS

							GROUP

							HEADLESS

							HORIZONTAL

							IMAGE

							LANDSCAPE

							LEFT

							LEFT_BOTTOM

							LEFT_CENTER

							LEFT_TOP

							LINE

							listeners

							MATRIX

							mixin

							NONE

							off

							on

							once

							PENDING_ATLAS

							Phaser.Path#numPoints
return {number} The total number of PathPoints in this Path.

							POINT

							POINTER

							POLYGON

							PORTRAIT

							RECTANGLE

							removeAllListeners

							RENDERTEXTURE

							RETROFONT

							RIGHT

							RIGHT_BOTTOM

							RIGHT_CENTER

							RIGHT_TOP

							ROPE

							ROUNDEDRECTANGLE

							scaleModes

							SPRITE

							SPRITEBATCH

							stopImmediatePropagation

							stopPropagation

							TEXT

							TILEMAP

							TILEMAPLAYER

							TILESPRITE

							TOP_CENTER

							TOP_LEFT

							TOP_RIGHT

							UP

							VERSION

							VERTICAL

							VIDEO

							WEBGL

							WEBGL_FILTER

					Core

Game

Group

World

Loader

Cache

Time

Camera

State Manager

Tween Manager

Sound Manager

Input Manager

Scale Manager

					Game Objects

Factory (game.add)

Creator (game.make)

Sprite

Image

Sound

Video

Particle Emitter

Particle

Text

Tween

BitmapText

Tilemap

BitmapData

RetroFont

Button

Animation

Graphics

RenderTexture

TileSprite

					Geometry

Circle

Ellipse

Line

Matrix

Point

Polygon

Rectangle

Rounded Rectangle

					Physics

Arcade Physics

Body

Weapon

P2 Physics

Body

Spring

CollisionGroup

ContactMaterial

Ninja Physics

Body

					Input

Input Handler

Pointer

Device Button

Mouse

Keyboard

Key

Key Codes

Gamepad

					Community

Phaser Web Site

Phaser Github

Phaser Examples

Phaser Plugins

Forum

Stack Overflow

Tutorials

Newsletter

Twitter

Slack

Donate

Texture Packer

Source: src/core/Filter.js

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* This is a base Filter class to use for any Phaser filter development.
*
* The vast majority of filters (including all of those that ship with Phaser) use fragment shaders, and
* therefore only work in WebGL and are not supported by Canvas at all.
*
* @class Phaser.Filter
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
* @param {object} uniforms - Uniform mappings object
* @param {Array|string} fragmentSrc - The fragment shader code. Either an array, one element per line of code, or a string.
*/
Phaser.Filter = function (game, uniforms, fragmentSrc) {

    /**
    * @property {Phaser.Game} game - A reference to the currently running game.
    */
    this.game = game;

    /**
    * @property {number} type - The const type of this object, either Phaser.WEBGL_FILTER or Phaser.CANVAS_FILTER.
    * @default
    */
    this.type = Phaser.WEBGL_FILTER;

    /**
    * An array of passes - some filters contain a few steps this array simply stores the steps in a linear fashion.
    * For example the blur filter has two passes blurX and blurY.
    * @property {array} passes - An array of filter objects.
    * @private
    */
    this.passes = [this];

    /**
    * @property {array} shaders - Array an array of shaders.
    * @private
    */
    this.shaders = [];

    /**
    * @property {boolean} dirty - Internal PIXI var.
    * @default
    */
    this.dirty = true;

    /**
    * @property {number} padding - Internal PIXI var.
    * @default
    */
    this.padding = 0;

    /**
    * @property {Phaser.Point} prevPoint - The previous position of the pointer (we don't update the uniform if the same)
    */
    this.prevPoint = new Phaser.Point();

    /*
    * The supported types are: 1f, 1fv, 1i, 2f, 2fv, 2i, 2iv, 3f, 3fv, 3i, 3iv, 4f, 4fv, 4i, 4iv, mat2, mat3, mat4 and sampler2D.
    */

    var d = new Date();

    /**
    * @property {object} uniforms - Default uniform mappings. Compatible with ShaderToy and GLSLSandbox.
    */
    this.uniforms = {

        resolution: { type: '2f', value: { x: 256, y: 256 }},
        time: { type: '1f', value: 0 },
        mouse: { type: '2f', value: { x: 0.0, y: 0.0 } },
        date: { type: '4fv', value: [ d.getFullYear(),  d.getMonth(),  d.getDate(), d.getHours() *60 * 60 + d.getMinutes() * 60 + d.getSeconds() ] },
        sampleRate: { type: '1f', value: 44100.0 },
        iChannel0: { type: 'sampler2D', value: null, textureData: { repeat: true } },
        iChannel1: { type: 'sampler2D', value: null, textureData: { repeat: true } },
        iChannel2: { type: 'sampler2D', value: null, textureData: { repeat: true } },
        iChannel3: { type: 'sampler2D', value: null, textureData: { repeat: true } }

    };

    //  Copy over/replace any passed in the constructor
    if (uniforms)
    {
        for (var key in uniforms)
        {
            this.uniforms[key] = uniforms[key];
        }
    }

    /**
    * @property {array|string} fragmentSrc - The fragment shader code.
    */
    this.fragmentSrc = fragmentSrc || '';

};

Phaser.Filter.prototype = {

    /**
    * Should be over-ridden.
    * @method Phaser.Filter#init
    */
    init: function () {
        //  This should be over-ridden. Will receive a variable number of arguments.
    },

    /**
    * Set the resolution uniforms on the filter.
    * @method Phaser.Filter#setResolution
    * @param {number} width - The width of the display.
    * @param {number} height - The height of the display.
    */
    setResolution: function (width, height) {

        this.uniforms.resolution.value.x = width;
        this.uniforms.resolution.value.y = height;

    },

    /**
    * Updates the filter.
    * @method Phaser.Filter#update
    * @param {Phaser.Pointer} [pointer] - A Pointer object to use for the filter. The coordinates are mapped to the mouse uniform.
    */
    update: function (pointer) {

        if (typeof pointer !== 'undefined')
        {
            var x = pointer.x / this.game.width;
            var y = 1 - pointer.y / this.game.height;

            if (x !== this.prevPoint.x || y !== this.prevPoint.y)
            {
                this.uniforms.mouse.value.x = x.toFixed(2);
                this.uniforms.mouse.value.y = y.toFixed(2);
                this.prevPoint.set(x, y);
            }
        }

        this.uniforms.time.value = this.game.time.totalElapsedSeconds();

    },

    /**
    * Creates a new Phaser.Image object using a blank texture and assigns
    * this Filter to it. The image is then added to the world.
    *
    * If you don't provide width and height values then Filter.width and Filter.height are used.
    *
    * If you do provide width and height values then this filter will be resized to match those
    * values.
    *
    * @method Phaser.Filter#addToWorld
    * @param {number} [x=0] - The x coordinate to place the Image at.
    * @param {number} [y=0] - The y coordinate to place the Image at.
    * @param {number} [width] - The width of the Image. If not specified (or null) it will use Filter.width. If specified Filter.width will be set to this value.
    * @param {number} [height] - The height of the Image. If not specified (or null) it will use Filter.height. If specified Filter.height will be set to this value.
    * @param {number} [anchorX=0] - Set the x anchor point of the Image. A value between 0 and 1, where 0 is the top-left and 1 is bottom-right.
    * @param {number} [anchorY=0] - Set the y anchor point of the Image. A value between 0 and 1, where 0 is the top-left and 1 is bottom-right.
    * @return {Phaser.Image} The newly added Image object.
    */
    addToWorld: function (x, y, width, height, anchorX, anchorY) {

        if (anchorX === undefined) { anchorX = 0; }
        if (anchorY === undefined) { anchorY = 0; }

        if (width !== undefined && width !== null)
        {
            this.width = width;
        }
        else
        {
            width = this.width;
        }

        if (height !== undefined && height !== null)
        {
            this.height = height;
        }
        else
        {
            height = this.height;
        }

        var image = this.game.add.image(x, y, '__default');

        image.width = width;
        image.height = height;

        image.anchor.set(anchorX, anchorY);

        image.filters = [ this ];

        return image;

    },

    /**
    * Clear down this Filter and null out references
    * @method Phaser.Filter#destroy
    */
    destroy: function () {

        this.game = null;

    }

};

Phaser.Filter.prototype.constructor = Phaser.Filter;

/**
* @name Phaser.Filter#width
* @property {number} width - The width (resolution uniform)
*/
Object.defineProperty(Phaser.Filter.prototype, 'width', {

    get: function() {
        return this.uniforms.resolution.value.x;
    },

    set: function(value) {
        this.uniforms.resolution.value.x = value;
    }

});

/**
* @name Phaser.Filter#height
* @property {number} height - The height (resolution uniform)
*/
Object.defineProperty(Phaser.Filter.prototype, 'height', {

    get: function() {
        return this.uniforms.resolution.value.y;
    },

    set: function(value) {
        this.uniforms.resolution.value.y = value;
    }

});

		Phaser Copyright © 2012-2016 Photon Storm Ltd.

		Documentation generated by JSDoc 3.4.0
		on Fri Aug 26 2016 01:16:09 GMT+0100 (BST) using the DocStrap template.


/**
* @author       Richard Davey <rich@photonstorm.com>
* @author       Mat Groves (@Doormat23)
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A Canvas based renderer.
*
* @class Phaser.Renderer.Canvas
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
*/
Phaser.Renderer.WebGL = function (game)
{
    /**
    * @property {Phaser.Game} game - A reference to the currently running Game.
    */
    this.game = game;

    this.type = Phaser.WEBGL;

    /**
     * This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
     * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
     * If the Stage is transparent Pixi will use clearRect to clear the canvas every frame.
     * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.
     *
     * @property clearBeforeRender
     * @type Boolean
     * @default
     */
    this.clearBeforeRender = game.clearBeforeRender;

    /**
     * Whether the render view is transparent
     *
     * @property transparent
     * @type Boolean
     */
    this.transparent = game.transparent;

    /**
     * Whether the render view should be resized automatically
     *
     * @property autoResize
     * @type Boolean
     */
    this.autoResize = false;

    /**
     * The width of the canvas view
     *
     * @property width
     * @type Number
     * @default 800
     */
    this.width = game.width * game.resolution;

    /**
     * The height of the canvas view
     *
     * @property height
     * @type Number
     * @default 600
     */
    this.height = game.height * game.resolution;

    this.resolution = game.resolution;

    /**
     * The canvas element that everything is drawn to.
     *
     * @property view
     * @type HTMLCanvasElement
     */
    this.view = game.canvas;

    /**
     * The number of points beyond which the renderer swaps to using the Stencil Buffer to render the Graphics.
     *
     * @type {number}
     */
    this.stencilBufferLimit = 6;

    //  WebGL specific from here

    this.enableMultiTextureToggle = false;

    this.extensions = {};

    /**
     * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering.
     *
     * @property preserveDrawingBuffer
     * @type Boolean
     */
    this.preserveDrawingBuffer = game.preserveDrawingBuffer;

    /**
     * @property _contextOptions
     * @type Object
     * @private
     */
    this.contextOptions = {
        alpha: this.transparent,
        antialias: game.antialias,
        premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied',
        stencil: true,
        preserveDrawingBuffer: this.preserveDrawingBuffer
    };

    /**
     * @property projection
     * @type Point
     */
    this.projection = new Phaser.Point();

    /**
     * @property offset
     * @type Point
     */
    this.offset = new Phaser.Point();

    /**
     * Deals with managing the shader programs and their attribs
     * @property shaderManager
     * @type WebGLShaderManager
     */
    this.shaderManager = new Phaser.Renderer.WebGL.ShaderManager(this);

    /**
     * Manages the rendering of sprites
     * @property spriteBatch
     * @type WebGLSpriteBatch
     */
    this.spriteBatch = new Phaser.Renderer.WebGL.SpriteBatch(this);

    /**
     * Manages the filters
     * @property filterManager
     * @type WebGLFilterManager
     */
    this.filterManager = new Phaser.Renderer.WebGL.FilterManager(this);

    /**
     * Manages the stencil buffer
     * @property stencilManager
     * @type WebGLStencilManager
     */
    this.stencilManager = new Phaser.Renderer.WebGL.StencilManager(this);

    this.gl = null;

    this.textureArray = [];

    this.blendModes = [];

    this.drawCount = 0;
    this.flipY = 1;

    this._fbErrors = {
        36054: 'Incomplete attachment',
        36055: 'Missing attachment',
        36057: 'Incomplete dimensions',
        36061: 'Framebuffer unsupported'
    };

    this.init();

};

Phaser.Renderer.WebGL.GameObjects = {};
Phaser.Renderer.WebGL.Shaders = {};

Phaser.Renderer.WebGL.prototype.constructor = Phaser.Renderer.WebGL;

Phaser.Renderer.WebGL.prototype = {

    init: function ()
    {
        this.gl = this.view.getContext('webgl', this.contextOptions) || this.view.getContext('experimental-webgl', this.contextOptions);

        if (!this.gl)
        {
            throw new Error('This browser does not support WebGL. Try using the Canvas renderer.');
        }

        //  Mixin the renderer functions
        for (var renderer in Phaser.Renderer.WebGL.GameObjects)
        {
            var types = Phaser.Renderer.WebGL.GameObjects[renderer].TYPES;

            if (!types)
            {
                continue;
            }

            for (var i = 0; i < types.length; i++)
            {
                types[i].render = Phaser.Renderer.WebGL.GameObjects[renderer].render;
            }
        }

        var gl = this.gl;

        this.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);

        gl.disable(gl.DEPTH_TEST);
        gl.disable(gl.CULL_FACE);
        gl.enable(gl.BLEND);

        this.shaderManager.init();
        this.spriteBatch.init();
        this.filterManager.init();
        this.stencilManager.init();

        this.resize(this.width, this.height);

        // Load WebGL extension
        this.extensions.compression = {};

        var etc1 = gl.getExtension('WEBGL_compressed_texture_etc1') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc1');
        var pvrtc = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
        var s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');

        if (etc1)
        {
            this.extensions.compression.ETC1 = etc1;
        }

        if (pvrtc)
        {
            this.extensions.compression.PVRTC = pvrtc;
        }

        if (s3tc)
        {
            this.extensions.compression.S3TC = s3tc;
        }

        //  Map Blend Modes

        var add = [ gl.SRC_ALPHA, gl.DST_ALPHA ];
        var normal = [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ];
        var multiply = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ];
        var screen = [ gl.SRC_ALPHA, gl.ONE ];

        this.blendModes = [
            normal, add, multiply, screen, normal,
            normal, normal, normal, normal,
            normal, normal, normal, normal,
            normal, normal, normal, normal
        ];

    },

    resize: function (width, height)
    {
        this.width = width * this.game.resolution;
        this.height = height * this.game.resolution;

        this.view.width = this.width;
        this.view.height = this.height;

        if (this.autoResize)
        {
            this.view.style.width = (this.width / this.game.resolution) + 'px';
            this.view.style.height = (this.height / this.game.resolution) + 'px';
        }

        this.gl.viewport(0, 0, this.width, this.height);

        this.projection.x = (this.width / 2) / this.game.resolution;
        this.projection.y = -(this.height / 2) / this.game.resolution;
    },

    /**
    * If Multi Texture support has been enabled, then calling this method will enable batching on the given
    * textures. The texture collection is an array of keys, that map to Phaser.Cache image entries.
    *
    * The number of textures that can be batched is dependent on hardware. If you provide more textures
    * than can be batched by the GPU, then only those at the start of the array will be used. Generally
    * you shouldn't provide more than 16 textures to this method. You can check the hardware limit via the
    * `maxTextures` property.
    *
    * You can also check the property `currentBatchedTextures` at any time, to see which textures are currently
    * being batched.
    *
    * To stop all textures from being batched, call this method again with an empty array.
    *
    * To change the textures being batched, call this method with a new array of image keys. The old ones
    * will all be purged out and no-longer batched, and the new ones enabled.
    *
    * Note: Throws a warning if you haven't enabled Multiple Texture batching support in the Phaser Game config.
    *
    * @method setTexturePriority
    * @param textureNameCollection {Array} An Array of Texture Cache keys to use for multi-texture batching.
    * @return {Array} An array containing the texture keys that were enabled for batching.
    */
    setTexturePriority: function (textureNameCollection)
    {
        if (!this.enableMultiTextureToggle)
        {
            console.warn('setTexturePriority error: Multi Texture support hasn\'t been enabled in the Phaser Game Config.');
            return;
        }

        var maxTextures = this.maxTextures;
        var imageCache = this.game.cache._cache.image;
        var imageName = null;

        //  Clear out all previously batched textures and reset their flags.
        //  If the array has been modified, then the developer will have to
        //  deal with that in their own way.
        for (var i = 0; i < this.currentBatchedTextures.length; i++)
        {
            imageName = textureNameCollection[index];

            if (!(imageName in imageCache))
            {
                continue;
            }

            imageCache[imageName].base.textureIndex = 0;
        }

        this.currentBatchedTextures.length = 0;

        // We start from 1 because framebuffer texture uses unit 0.
        for (var index = 0; index < textureNameCollection.length; ++index)
        {
            imageName = textureNameCollection[index];

            if (!(imageName in imageCache))
            {
                continue;
            }

            if (index + 1 < maxTextures)
            {
                imageCache[imageName].base.textureIndex = index + 1;
            }
            else
            {
                imageCache[imageName].base.textureIndex = maxTextures - 1;
            }

            this.currentBatchedTextures.push(imageName);
        }

        return this.currentBatchedTextures;

    },

    getMaxTextureUnits: function ()
    {
        return this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS);
    },

    /**
     * Renders the stage to its webGL view
     *
     * @method render
     * @param stage {Stage} the Stage element to be rendered
     */
    render: function (stage)
    {
        // no point rendering if our context has been blown up!
        if (this.contextLost)
        {
            return;
        }

        //  Add Pre-render hook

        var gl = this.gl;

        gl.viewport(0, 0, this.width, this.height);

        // make sure we are bound to the main frame buffer
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);

        if (this.game.clearBeforeRender)
        {
            gl.clearColor(stage._bgColor.r, stage._bgColor.g, stage._bgColor.b, stage._bgColor.a);

            gl.clear(gl.COLOR_BUFFER_BIT);
        }

        this.offset.x = this.game.camera._shake.x;
        this.offset.y = this.game.camera._shake.y;

        this.setBlendMode(this.blendModes.NORMAL);

        //  Reset draw count
        this.drawCount = 0;

        //  RenderTextures set this to -1
        this.flipY = 1;

        this.spriteBatch.begin();

        this.filterManager.begin();

        stage.render(this, stage);

        this.spriteBatch.end();

        //  Add Post-render hook
    },

    updateTexture: function (texture)
    {
        if (!texture.hasLoaded)
        {
            return false;
        }

        if (texture.source.compressionAlgorithm)
        {
            return this.updateCompressedTexture(texture);
        }

        var gl = this.gl;

        if (!texture._glTextures)
        {
            texture._glTextures = gl.createTexture();
        }

        gl.activeTexture(gl.TEXTURE0 + texture.textureIndex);

        gl.bindTexture(gl.TEXTURE_2D, texture._glTextures);

        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);

        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);

        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);

        if (texture.mipmap && Phaser.Math.isPowerOfTwo(texture.width, texture.height))
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
            gl.generateMipmap(gl.TEXTURE_2D);
        }
        else
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
        }

        if (!texture._powerOf2)
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        }
        else
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
        }

        texture._dirty = false;

        return true;
    },

    updateCompressedTexture: function (texture)
    {
        if (!texture.hasLoaded)
        {
            return false;
        }

        var gl = this.gl;
        var textureMetaData = texture.source;

        if (!texture._glTextures)
        {
            texture._glTextures = gl.createTexture();
        }

        gl.activeTexture(gl.TEXTURE0 + texture.textureIndex);

        gl.bindTexture(gl.TEXTURE_2D, texture._glTextures);

        gl.compressedTexImage2D(
            gl.TEXTURE_2D,
            0,
            textureMetaData.glExtensionFormat,
            textureMetaData.width,
            textureMetaData.height,
            0,
            textureMetaData.textureData
        );

        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);

        if (texture.mipmap && Phaser.Math.isPowerOfTwo(texture.width, texture.height))
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
            gl.generateMipmap(gl.TEXTURE_2D);
        }
        else
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
        }

        if (!texture._powerOf2)
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        }
        else
        {
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
        }

        texture._dirty = false;

        return true;
    },

    //  Blend Mode Manager

    setBlendMode: function (blendMode)
    {
        if (this.currentBlendMode === blendMode)
        {
            return false;
        }

        this.currentBlendMode = blendMode;

        var blendModeWebGL = this.blendModes[this.currentBlendMode];

        if (blendModeWebGL)
        {
            this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
        }

        return true;
    },

    //  WebGL Mask Manager

    pushMask: function (maskData)
    {
        var gl = this.gl;

        if (maskData.dirty)
        {
            // PIXI.WebGLGraphics.updateGraphics(maskData, gl);
        }

        if (maskData._webGL === undefined || maskData._webGL.data === undefined || maskData._webGL.data.length === 0)
        {
            return;
        }

        this.stencilManager.pushStencil(maskData, maskData._webGL.data[0]);
    },

    popMask: function (maskData)
    {
        if (maskData._webGL === undefined || maskData._webGL.data === undefined || maskData._webGL.data.length === 0)
        {
            return;
        }

        this.stencilManager.popStencil(maskData, maskData._webGL.data[0]);
    },

    //  Shader Utils

    //  PIXI.CompileVertexShader
    compileVertexShader: function (src)
    {
        return this.compileShader(src, this.gl.VERTEX_SHADER);
    },

    //  PIXI.CompileFragmentShader
    compileFragmentShader: function (src)
    {
        return this.compileShader(src, this.gl.FRAGMENT_SHADER);
    },

    //  PIXI._CompileShader
    compileShader: function (src, type)
    {
        if (Array.isArray(src))
        {
            src = src.join('\n');
        }

        var shader = this.gl.createShader(type);
        this.gl.shaderSource(shader, src);
        this.gl.compileShader(shader);

        if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS))
        {
            console.log(this.gl.getShaderInfoLog(shader));
            return null;
        }

        return shader;
    },

    //  PIXI.compileProgram
    compileProgram: function (vertexSrc, fragmentSrc)
    {
        var gl = this.gl;

        var fragmentShader = this.compileFragmentShader(fragmentSrc);
        var vertexShader = this.compileVertexShader(vertexSrc);

        var shaderProgram = gl.createProgram();

        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);

        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
        {
            console.log(gl.getProgramInfoLog(shaderProgram));
            console.log('Could not initialize shaders');
        }

        return shaderProgram;
    },

    createEmptyTexture: function (width, height, scaleMode)
    {
        var gl = this.gl;
        var texture = gl.createTexture();
        var glScaleMode = (scaleMode === Phaser.scaleModes.LINEAR) ? gl.LINEAR : gl.NEAREST;

        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glScaleMode);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glScaleMode);

        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

        return texture;
    },

    createFramebuffer: function (width, height, scaleMode, textureUnit)
    {
        var gl = this.gl;
        var framebuffer = gl.createFramebuffer();
        var depthStencilBuffer = gl.createRenderbuffer();
        var colorBuffer = null;
        var fbStatus = 0;

        gl.activeTexture(gl.TEXTURE0 + textureUnit);

        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
        gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);

        //  `this.renderBuffer` = undefined? FilterTexture has a renderBuffer, but `this` doesn't.
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);

        colorBuffer = this.createEmptyTexture(width, height, scaleMode);

        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorBuffer, 0);

        fbStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);

        if (fbStatus !== gl.FRAMEBUFFER_COMPLETE)
        {
            console.error('Incomplete GL framebuffer. ', this._fbErrors[fbStatus]);
        }

        framebuffer.width = width;
        framebuffer.height = height;
        framebuffer.targetTexture = colorBuffer;
        framebuffer.renderBuffer = depthStencilBuffer;

        return framebuffer;
    },

    destroy: function ()
    {
        PIXI.glContexts[this.glContextId] = null;

        this.projection = null;
        this.offset = null;

        this.shaderManager.destroy();
        this.spriteBatch.destroy();
        this.maskManager.destroy();
        this.filterManager.destroy();

        this.shaderManager = null;
        this.spriteBatch = null;
        this.maskManager = null;
        this.filterManager = null;

        this.gl = null;
        this.renderSession = null;

        Phaser.CanvasPool.remove(this);

        PIXI.instances[this.glContextId] = null;

        PIXI.WebGLRenderer.glContextId--;
    }

};


/**
* @author       Mat Groves http://matgroves.com/
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The Rounded Rectangle object is an area defined by its position and has nice rounded corners,
* as indicated by its top-left corner point (x, y) and by its width and its height.
*
* @class Phaser.RoundedRectangle
* @constructor
* @param {number} [x=0] - The x coordinate of the top-left corner of the Rectangle.
* @param {number} [y=0] - The y coordinate of the top-left corner of the Rectangle.
* @param {number} [width=0] - The width of the Rectangle. Should always be either zero or a positive value.
* @param {number} [height=0] - The height of the Rectangle. Should always be either zero or a positive value.
* @param {number} [radius=20] - Controls the radius of the rounded corners.
*/
Phaser.RoundedRectangle = function(x, y, width, height, radius)
{
    if (x === undefined) { x = 0; }
    if (y === undefined) { y = 0; }
    if (width === undefined) { width = 0; }
    if (height === undefined) { height = 0; }
    if (radius === undefined) { radius = 20; }

    /**
    * @property {number} x - The x coordinate of the top-left corner of the Rectangle.
    */
    this.x = x;

    /**
    * @property {number} y - The y coordinate of the top-left corner of the Rectangle.
    */
    this.y = y;

    /**
    * @property {number} width - The width of the Rectangle. This value should never be set to a negative.
    */
    this.width = width;

    /**
    * @property {number} height - The height of the Rectangle. This value should never be set to a negative.
    */
    this.height = height;

    /**
    * @property {number} radius - The radius of the rounded corners.
    */
    this.radius = radius || 20;

    /**
    * @property {number} type - The const type of this object.
    * @readonly
    */
    this.type = Phaser.ROUNDEDRECTANGLE;
};

Phaser.RoundedRectangle.prototype = {

    /**
    * Returns a new RoundedRectangle object with the same values for the x, y, width, height and
    * radius properties as this RoundedRectangle object.
    *
    * @method Phaser.RoundedRectangle#clone
    * @return {Phaser.RoundedRectangle}
    */
    clone: function () {

        return new Phaser.RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);

    },

    /**
    * Determines whether the specified coordinates are contained within the region defined by this Rounded Rectangle object.
    *
    * @method Phaser.RoundedRectangle#contains
    * @param {number} x - The x coordinate of the point to test.
    * @param {number} y - The y coordinate of the point to test.
    * @return {boolean} A value of true if the RoundedRectangle Rectangle object contains the specified point; otherwise false.
    */
    contains: function (x, y) {

        if (this.width <= 0 || this.height <= 0)
        {
            return false;
        }

        var x1 = this.x;

        if (x >= x1 && x <= x1 + this.width)
        {
            var y1 = this.y;

            if (y >= y1 && y <= y1 + this.height)
            {
                return true;
            }
        }

        return false;

    }

};

Phaser.RoundedRectangle.prototype.constructor = Phaser.RoundedRectangle;

//  Because PIXI uses its own type, we'll replace it with ours to avoid duplicating code or confusion.
PIXI.RoundedRectangle = Phaser.RoundedRectangle;