text: /*!
   * pixi-gl-core - v1.1.4
   * Compiled Mon, 20 Nov 2017 18:13:25 UTC
   *
   * pixi-gl-core is licensed under the MIT License.
   * http://www.opensource.org/licenses/mit-license
   */
  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pixiGlCore = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  var EMPTY_ARRAY_BUFFER = new ArrayBuffer(0);
  
  /**
   * Helper class to create a webGL buffer
   *
   * @class
   * @memberof PIXI.glCore
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param type {gl.ARRAY_BUFFER | gl.ELEMENT_ARRAY_BUFFER} @mat
   * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
   * @param drawType {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
   */
  var Buffer = function(gl, type, data, drawType)
  {
  
  	/**
       * The current WebGL rendering context
       *
       * @member {WebGLRenderingContext}
       */
  	this.gl = gl;
  
  	/**
       * The WebGL buffer, created upon instantiation
       *
       * @member {WebGLBuffer}
       */
  	this.buffer = gl.createBuffer();
  
  	/**
       * The type of the buffer
       *
       * @member {gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER}
       */
  	this.type = type || gl.ARRAY_BUFFER;
  
  	/**
       * The draw type of the buffer
       *
       * @member {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
       */
  	this.drawType = drawType || gl.STATIC_DRAW;
  
  	/**
       * The data in the buffer, as a typed array
       *
       * @member {ArrayBuffer| SharedArrayBuffer|ArrayBufferView}
       */
  	this.data = EMPTY_ARRAY_BUFFER;
  
  	if(data)
  	{
  		this.upload(data);
  	}
  
  	this._updateID = 0;
  };
  
  /**
   * Uploads the buffer to the GPU
   * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data to upload
   * @param offset {Number} if only a subset of the data should be uploaded, this is the amount of data to subtract
   * @param dontBind {Boolean} whether to bind the buffer before uploading it
   */
  Buffer.prototype.upload = function(data, offset, dontBind)
  {
  	// todo - needed?
  	if(!dontBind) this.bind();
  
  	var gl = this.gl;
  
  	data = data || this.data;
  	offset = offset || 0;
  
  	if(this.data.byteLength >= data.byteLength)
  	{
  		gl.bufferSubData(this.type, offset, data);
  	}
  	else
  	{
  		gl.bufferData(this.type, data, this.drawType);
  	}
  
  	this.data = data;
  };
  /**
   * Binds the buffer
   *
   */
  Buffer.prototype.bind = function()
  {
  	var gl = this.gl;
  	gl.bindBuffer(this.type, this.buffer);
  };
  
  Buffer.createVertexBuffer = function(gl, data, drawType)
  {
  	return new Buffer(gl, gl.ARRAY_BUFFER, data, drawType);
  };
  
  Buffer.createIndexBuffer = function(gl, data, drawType)
  {
  	return new Buffer(gl, gl.ELEMENT_ARRAY_BUFFER, data, drawType);
  };
  
  Buffer.create = function(gl, type, data, drawType)
  {
  	return new Buffer(gl, type, data, drawType);
  };
  
  /**
   * Destroys the buffer
   *
   */
  Buffer.prototype.destroy = function(){
  	this.gl.deleteBuffer(this.buffer);
  };
  
  module.exports = Buffer;
  
  },{}],2:[function(require,module,exports){
  
  var Texture = require('./GLTexture');
  
  /**
   * Helper class to create a webGL Framebuffer
   *
   * @class
   * @memberof PIXI.glCore
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param width {Number} the width of the drawing area of the frame buffer
   * @param height {Number} the height of the drawing area of the frame buffer
   */
  var Framebuffer = function(gl, width, height)
  {
      /**
       * The current WebGL rendering context
       *
       * @member {WebGLRenderingContext}
       */
      this.gl = gl;
  
      /**
       * The frame buffer
       *
       * @member {WebGLFramebuffer}
       */
      this.framebuffer = gl.createFramebuffer();
  
      /**
       * The stencil buffer
       *
       * @member {WebGLRenderbuffer}
       */
      this.stencil = null;
  
      /**
       * The stencil buffer
       *
       * @member {PIXI.glCore.GLTexture}
       */
      this.texture = null;
  
      /**
       * The width of the drawing area of the buffer
       *
       * @member {Number}
       */
      this.width = width || 100;
      /**
       * The height of the drawing area of the buffer
       *
       * @member {Number}
       */
      this.height = height || 100;
  };
  
  /**
   * Adds a texture to the frame buffer
   * @param texture {PIXI.glCore.GLTexture}
   */
  Framebuffer.prototype.enableTexture = function(texture)
  {
      var gl = this.gl;
  
      this.texture = texture || new Texture(gl);
  
      this.texture.bind();
  
      //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  
      this.bind();
  
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
  };
  
  /**
   * Initialises the stencil buffer
   */
  Framebuffer.prototype.enableStencil = function()
  {
      if(this.stencil)return;
  
      var gl = this.gl;
  
      this.stencil = gl.createRenderbuffer();
  
      gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
  
      // TODO.. this is depth AND stencil?
      gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencil);
      gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,  this.width  , this.height );
  
  
  };
  
  /**
   * Erases the drawing area and fills it with a colour
   * @param  r {Number} the red value of the clearing colour
   * @param  g {Number} the green value of the clearing colour
   * @param  b {Number} the blue value of the clearing colour
   * @param  a {Number} the alpha value of the clearing colour
   */
  Framebuffer.prototype.clear = function( r, g, b, a )
  {
      this.bind();
  
      var gl = this.gl;
  
      gl.clearColor(r, g, b, a);
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  };
  
  /**
   * Binds the frame buffer to the WebGL context
   */
  Framebuffer.prototype.bind = function()
  {
      var gl = this.gl;
      gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer );
  };
  
  /**
   * Unbinds the frame buffer to the WebGL context
   */
  Framebuffer.prototype.unbind = function()
  {
      var gl = this.gl;
      gl.bindFramebuffer(gl.FRAMEBUFFER, null );
  };
  /**
   * Resizes the drawing area of the buffer to the given width and height
   * @param  width  {Number} the new width
   * @param  height {Number} the new height
   */
  Framebuffer.prototype.resize = function(width, height)
  {
      var gl = this.gl;
  
      this.width = width;
      this.height = height;
  
      if ( this.texture )
      {
          this.texture.uploadData(null, width, height);
      }
  
      if ( this.stencil )
      {
          // update the stencil buffer width and height
          gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
          gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
      }
  };
  
  /**
   * Destroys this buffer
   */
  Framebuffer.prototype.destroy = function()
  {
      var gl = this.gl;
  
      //TODO
      if(this.texture)
      {
          this.texture.destroy();
      }
  
      gl.deleteFramebuffer(this.framebuffer);
  
      this.gl = null;
  
      this.stencil = null;
      this.texture = null;
  };
  
  /**
   * Creates a frame buffer with a texture containing the given data
   * @static
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param width {Number} the width of the drawing area of the frame buffer
   * @param height {Number} the height of the drawing area of the frame buffer
   * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
   */
  Framebuffer.createRGBA = function(gl, width, height, data)
  {
      var texture = Texture.fromData(gl, null, width, height);
      texture.enableNearestScaling();
      texture.enableWrapClamp();
  
      //now create the framebuffer object and attach the texture to it.
      var fbo = new Framebuffer(gl, width, height);
      fbo.enableTexture(texture);
      //fbo.enableStencil(); // get this back on soon!
  
      //fbo.enableStencil(); // get this back on soon!
  
      fbo.unbind();
  
      return fbo;
  };
  
  /**
   * Creates a frame buffer with a texture containing the given data
   * @static
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param width {Number} the width of the drawing area of the frame buffer
   * @param height {Number} the height of the drawing area of the frame buffer
   * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
   */
  Framebuffer.createFloat32 = function(gl, width, height, data)
  {
      // create a new texture..
      var texture = new Texture.fromData(gl, data, width, height);
      texture.enableNearestScaling();
      texture.enableWrapClamp();
  
      //now create the framebuffer object and attach the texture to it.
      var fbo = new Framebuffer(gl, width, height);
      fbo.enableTexture(texture);
  
      fbo.unbind();
  
      return fbo;
  };
  
  module.exports = Framebuffer;
  
  },{"./GLTexture":4}],3:[function(require,module,exports){
  
  var compileProgram = require('./shader/compileProgram'),
  	extractAttributes = require('./shader/extractAttributes'),
  	extractUniforms = require('./shader/extractUniforms'),
  	setPrecision = require('./shader/setPrecision'),
  	generateUniformAccessObject = require('./shader/generateUniformAccessObject');
  
  /**
   * Helper class to create a webGL Shader
   *
   * @class
   * @memberof PIXI.glCore
   * @param gl {WebGLRenderingContext}
   * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
   * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
   * @param precision {string} The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
   * @param attributeLocations {object} A key value pair showing which location eact attribute should sit eg {position:0, uvs:1}
   */
  var Shader = function(gl, vertexSrc, fragmentSrc, precision, attributeLocations)
  {
  	/**
  	 * The current WebGL rendering context
  	 *
  	 * @member {WebGLRenderingContext}
  	 */
  	this.gl = gl;
  
  	if(precision)
  	{
  		vertexSrc = setPrecision(vertexSrc, precision);
  		fragmentSrc = setPrecision(fragmentSrc, precision);
  	}
  
  	/**
  	 * The shader program
  	 *
  	 * @member {WebGLProgram}
  	 */
  	// First compile the program..
  	this.program = compileProgram(gl, vertexSrc, fragmentSrc, attributeLocations);
  
  	/**
  	 * The attributes of the shader as an object containing the following properties
  	 * {
  	 * 	type,
  	 * 	size,
  	 * 	location,
  	 * 	pointer
  	 * }
  	 * @member {Object}
  	 */
  	// next extract the attributes
  	this.attributes = extractAttributes(gl, this.program);
  
      this.uniformData = extractUniforms(gl, this.program);
  
  	/**
  	 * The uniforms of the shader as an object containing the following properties
  	 * {
  	 * 	gl,
  	 * 	data
  	 * }
  	 * @member {Object}
  	 */
  	this.uniforms = generateUniformAccessObject( gl, this.uniformData );
  
  };
  /**
   * Uses this shader
   * 
   * @return {PIXI.glCore.GLShader} Returns itself.
   */
  Shader.prototype.bind = function()
  {
  	this.gl.useProgram(this.program);
  	return this;
  };
  
  /**
   * Destroys this shader
   * TODO
   */
  Shader.prototype.destroy = function()
  {
  	this.attributes = null;
  	this.uniformData = null;
  	this.uniforms = null;
  
  	var gl = this.gl;
  	gl.deleteProgram(this.program);
  };
  
  
  module.exports = Shader;
  
  },{"./shader/compileProgram":8,"./shader/extractAttributes":10,"./shader/extractUniforms":11,"./shader/generateUniformAccessObject":12,"./shader/setPrecision":16}],4:[function(require,module,exports){
  
  /**
   * Helper class to create a WebGL Texture
   *
   * @class
   * @memberof PIXI.glCore
   * @param gl {WebGLRenderingContext} The current WebGL context
   * @param width {number} the width of the texture
   * @param height {number} the height of the texture
   * @param format {number} the pixel format of the texture. defaults to gl.RGBA
   * @param type {number} the gl type of the texture. defaults to gl.UNSIGNED_BYTE
   */
  var Texture = function(gl, width, height, format, type)
  {
  	/**
  	 * The current WebGL rendering context
  	 *
  	 * @member {WebGLRenderingContext}
  	 */
  	this.gl = gl;
  
  
  	/**
  	 * The WebGL texture
  	 *
  	 * @member {WebGLTexture}
  	 */
  	this.texture = gl.createTexture();
  
  	/**
  	 * If mipmapping was used for this texture, enable and disable with enableMipmap()
  	 *
  	 * @member {Boolean}
  	 */
  	// some settings..
  	this.mipmap = false;
  
  
  	/**
  	 * Set to true to enable pre-multiplied alpha
  	 *
  	 * @member {Boolean}
  	 */
  	this.premultiplyAlpha = false;
  
  	/**
  	 * The width of texture
  	 *
  	 * @member {Number}
  	 */
  	this.width = width || -1;
  	/**
  	 * The height of texture
  	 *
  	 * @member {Number}
  	 */
  	this.height = height || -1;
  
  	/**
  	 * The pixel format of the texture. defaults to gl.RGBA
  	 *
  	 * @member {Number}
  	 */
  	this.format = format || gl.RGBA;
  
  	/**
  	 * The gl type of the texture. defaults to gl.UNSIGNED_BYTE
  	 *
  	 * @member {Number}
  	 */
  	this.type = type || gl.UNSIGNED_BYTE;
  
  
  };
  
  /**
   * Uploads this texture to the GPU
   * @param source {HTMLImageElement|ImageData|HTMLVideoElement} the source image of the texture
   */
  Texture.prototype.upload = function(source)
  {
  	this.bind();
  
  	var gl = this.gl;
  
  
  	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
  
  	var newWidth = source.videoWidth || source.width;
  	var newHeight = source.videoHeight || source.height;
  
  	if(newHeight !== this.height || newWidth !== this.width)
  	{
  		gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source);
  	}
  	else
  	{
      	gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.format, this.type, source);
  	}
  
  	// if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect.
  	this.width = newWidth;
  	this.height = newHeight;
  
  };
  
  var FLOATING_POINT_AVAILABLE = false;
  
  /**
   * Use a data source and uploads this texture to the GPU
   * @param data {TypedArray} the data to upload to the texture
   * @param width {number} the new width of the texture
   * @param height {number} the new height of the texture
   */
  Texture.prototype.uploadData = function(data, width, height)
  {
  	this.bind();
  
  	var gl = this.gl;
  
  
  	if(data instanceof Float32Array)
  	{
  		if(!FLOATING_POINT_AVAILABLE)
  		{
  			var ext = gl.getExtension("OES_texture_float");
  
  			if(ext)
  			{
  				FLOATING_POINT_AVAILABLE = true;
  			}
  			else
  			{
  				throw new Error('floating point textures not available');
  			}
  		}
  
  		this.type = gl.FLOAT;
  	}
  	else
  	{
  		// TODO support for other types
  		this.type = this.type || gl.UNSIGNED_BYTE;
  	}
  
  	// what type of data?
  	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
  
  
  	if(width !== this.width || height !== this.height)
  	{
  		gl.texImage2D(gl.TEXTURE_2D, 0, this.format,  width, height, 0, this.format, this.type, data || null);
  	}
  	else
  	{
  		gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, this.format, this.type, data || null);
  	}
  
  	this.width = width;
  	this.height = height;
  
  
  //	texSubImage2D
  };
  
  /**
   * Binds the texture
   * @param  location
   */
  Texture.prototype.bind = function(location)
  {
  	var gl = this.gl;
  
  	if(location !== undefined)
  	{
  		gl.activeTexture(gl.TEXTURE0 + location);
  	}
  
  	gl.bindTexture(gl.TEXTURE_2D, this.texture);
  };
  
  /**
   * Unbinds the texture
   */
  Texture.prototype.unbind = function()
  {
  	var gl = this.gl;
  	gl.bindTexture(gl.TEXTURE_2D, null);
  };
  
  /**
   * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
   */
  Texture.prototype.minFilter = function( linear )
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	if(this.mipmap)
  	{
  		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
  	}
  	else
  	{
  		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR : gl.NEAREST);
  	}
  };
  
  /**
   * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
   */
  Texture.prototype.magFilter = function( linear )
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linear ? gl.LINEAR : gl.NEAREST);
  };
  
  /**
   * Enables mipmapping
   */
  Texture.prototype.enableMipmap = function()
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	this.mipmap = true;
  
  	gl.generateMipmap(gl.TEXTURE_2D);
  };
  
  /**
   * Enables linear filtering
   */
  Texture.prototype.enableLinearScaling = function()
  {
  	this.minFilter(true);
  	this.magFilter(true);
  };
  
  /**
   * Enables nearest neighbour interpolation
   */
  Texture.prototype.enableNearestScaling = function()
  {
  	this.minFilter(false);
  	this.magFilter(false);
  };
  
  /**
   * Enables clamping on the texture so WebGL will not repeat it
   */
  Texture.prototype.enableWrapClamp = function()
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	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);
  };
  
  /**
   * Enable tiling on the texture
   */
  Texture.prototype.enableWrapRepeat = function()
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  };
  
  Texture.prototype.enableWrapMirrorRepeat = function()
  {
  	var gl = this.gl;
  
  	this.bind();
  
  	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
  };
  
  
  /**
   * Destroys this texture
   */
  Texture.prototype.destroy = function()
  {
  	var gl = this.gl;
  	//TODO
  	gl.deleteTexture(this.texture);
  };
  
  /**
   * @static
   * @param gl {WebGLRenderingContext} The current WebGL context
   * @param source {HTMLImageElement|ImageData} the source image of the texture
   * @param premultiplyAlpha {Boolean} If we want to use pre-multiplied alpha
   */
  Texture.fromSource = function(gl, source, premultiplyAlpha)
  {
  	var texture = new Texture(gl);
  	texture.premultiplyAlpha = premultiplyAlpha || false;
  	texture.upload(source);
  
  	return texture;
  };
  
  /**
   * @static
   * @param gl {WebGLRenderingContext} The current WebGL context
   * @param data {TypedArray} the data to upload to the texture
   * @param width {number} the new width of the texture
   * @param height {number} the new height of the texture
   */
  Texture.fromData = function(gl, data, width, height)
  {
  	//console.log(data, width, height);
  	var texture = new Texture(gl);
  	texture.uploadData(data, width, height);
  
  	return texture;
  };
  
  
  module.exports = Texture;
  
  },{}],5:[function(require,module,exports){
  
  // state object//
  var setVertexAttribArrays = require( './setVertexAttribArrays' );
  
  /**
   * Helper class to work with WebGL VertexArrayObjects (vaos)
   * Only works if WebGL extensions are enabled (they usually are)
   *
   * @class
   * @memberof PIXI.glCore
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   */
  function VertexArrayObject(gl, state)
  {
      this.nativeVaoExtension = null;
  
      if(!VertexArrayObject.FORCE_NATIVE)
      {
          this.nativeVaoExtension = gl.getExtension('OES_vertex_array_object') ||
                                    gl.getExtension('MOZ_OES_vertex_array_object') ||
                                    gl.getExtension('WEBKIT_OES_vertex_array_object');
      }
  
      this.nativeState = state;
  
      if(this.nativeVaoExtension)
      {
          this.nativeVao = this.nativeVaoExtension.createVertexArrayOES();
  
          var maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
  
          // VAO - overwrite the state..
          this.nativeState = {
              tempAttribState: new Array(maxAttribs),
              attribState: new Array(maxAttribs)
          };
      }
  
      /**
       * The current WebGL rendering context
       *
       * @member {WebGLRenderingContext}
       */
      this.gl = gl;
  
      /**
       * An array of attributes
       *
       * @member {Array}
       */
      this.attributes = [];
  
      /**
       * @member {PIXI.glCore.GLBuffer}
       */
      this.indexBuffer = null;
  
      /**
       * A boolean flag
       *
       * @member {Boolean}
       */
      this.dirty = false;
  }
  
  VertexArrayObject.prototype.constructor = VertexArrayObject;
  module.exports = VertexArrayObject;
  
  /**
  * Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
  * If you find on older devices that things have gone a bit weird then set this to true.
  */
  /**
   * Lets the VAO know if you should use the WebGL extension or the native methods.
   * Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
   * If you find on older devices that things have gone a bit weird then set this to true.
   * @static
   * @property {Boolean} FORCE_NATIVE
   */
  VertexArrayObject.FORCE_NATIVE = false;
  
  /**
   * Binds the buffer
   */
  VertexArrayObject.prototype.bind = function()
  {
      if(this.nativeVao)
      {
          this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
  
          if(this.dirty)
          {
              this.dirty = false;
              this.activate();
              return this;
          }
          if (this.indexBuffer)
          {
              this.indexBuffer.bind();
          }
      }
      else
      {
          this.activate();
      }
  
      return this;
  };
  
  /**
   * Unbinds the buffer
   */
  VertexArrayObject.prototype.unbind = function()
  {
      if(this.nativeVao)
      {
          this.nativeVaoExtension.bindVertexArrayOES(null);
      }
  
      return this;
  };
  
  /**
   * Uses this vao
   */
  VertexArrayObject.prototype.activate = function()
  {
  
      var gl = this.gl;
      var lastBuffer = null;
  
      for (var i = 0; i < this.attributes.length; i++)
      {
          var attrib = this.attributes[i];
  
          if(lastBuffer !== attrib.buffer)
          {
              attrib.buffer.bind();
              lastBuffer = attrib.buffer;
          }
  
          gl.vertexAttribPointer(attrib.attribute.location,
                                 attrib.attribute.size,
                                 attrib.type || gl.FLOAT,
                                 attrib.normalized || false,
                                 attrib.stride || 0,
                                 attrib.start || 0);
      }
  
      setVertexAttribArrays(gl, this.attributes, this.nativeState);
  
      if(this.indexBuffer)
      {
          this.indexBuffer.bind();
      }
  
      return this;
  };
  
  /**
   *
   * @param buffer     {PIXI.gl.GLBuffer}
   * @param attribute  {*}
   * @param type       {String}
   * @param normalized {Boolean}
   * @param stride     {Number}
   * @param start      {Number}
   */
  VertexArrayObject.prototype.addAttribute = function(buffer, attribute, type, normalized, stride, start)
  {
      this.attributes.push({
          buffer:     buffer,
          attribute:  attribute,
  
          location:   attribute.location,
          type:       type || this.gl.FLOAT,
          normalized: normalized || false,
          stride:     stride || 0,
          start:      start || 0
      });
  
      this.dirty = true;
  
      return this;
  };
  
  /**
   *
   * @param buffer   {PIXI.gl.GLBuffer}
   */
  VertexArrayObject.prototype.addIndex = function(buffer/*, options*/)
  {
      this.indexBuffer = buffer;
  
      this.dirty = true;
  
      return this;
  };
  
  /**
   * Unbinds this vao and disables it
   */
  VertexArrayObject.prototype.clear = function()
  {
      // var gl = this.gl;
  
      // TODO - should this function unbind after clear?
      // for now, no but lets see what happens in the real world!
      if(this.nativeVao)
      {
          this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
      }
  
      this.attributes.length = 0;
      this.indexBuffer = null;
  
      return this;
  };
  
  /**
   * @param type  {Number}
   * @param size  {Number}
   * @param start {Number}
   */
  VertexArrayObject.prototype.draw = function(type, size, start)
  {
      var gl = this.gl;
  
      if(this.indexBuffer)
      {
          gl.drawElements(type, size || this.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2 );
      }
      else
      {
          // TODO need a better way to calculate size..
          gl.drawArrays(type, start, size || this.getSize());
      }
  
      return this;
  };
  
  /**
   * Destroy this vao
   */
  VertexArrayObject.prototype.destroy = function()
  {
      // lose references
      this.gl = null;
      this.indexBuffer = null;
      this.attributes = null;
      this.nativeState = null;
  
      if(this.nativeVao)
      {
          this.nativeVaoExtension.deleteVertexArrayOES(this.nativeVao);
      }
  
      this.nativeVaoExtension = null;
      this.nativeVao = null;
  };
  
  VertexArrayObject.prototype.getSize = function()
  {
      var attrib = this.attributes[0];
      return attrib.buffer.data.length / (( attrib.stride/4 ) || attrib.attribute.size);
  };
  
  },{"./setVertexAttribArrays":7}],6:[function(require,module,exports){
  
  /**
   * Helper class to create a webGL Context
   *
   * @class
   * @memberof PIXI.glCore
   * @param canvas {HTMLCanvasElement} the canvas element that we will get the context from
   * @param options {Object} An options object that gets passed in to the canvas element containing the context attributes,
   *                         see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext for the options available
   * @return {WebGLRenderingContext} the WebGL context
   */
  var createContext = function(canvas, options)
  {
      var gl = canvas.getContext('webgl', options) || 
           canvas.getContext('experimental-webgl', options);
  
      if (!gl)
      {
          // fail, not able to get a context
          throw new Error('This browser does not support webGL. Try using the canvas renderer');
      }
  
      return gl;
  };
  
  module.exports = createContext;
  
  },{}],7:[function(require,module,exports){
  // var GL_MAP = {};
  
  /**
   * @param gl {WebGLRenderingContext} The current WebGL context
   * @param attribs {*}
   * @param state {*}
   */
  var setVertexAttribArrays = function (gl, attribs, state)
  {
      var i;
      if(state)
      {
          var tempAttribState = state.tempAttribState,
              attribState = state.attribState;
  
          for (i = 0; i < tempAttribState.length; i++)
          {
              tempAttribState[i] = false;
          }
  
          // set the new attribs
          for (i = 0; i < attribs.length; i++)
          {
              tempAttribState[attribs[i].attribute.location] = true;
          }
  
          for (i = 0; i < attribState.length; i++)
          {
              if (attribState[i] !== tempAttribState[i])
              {
                  attribState[i] = tempAttribState[i];
  
                  if (state.attribState[i])
                  {
                      gl.enableVertexAttribArray(i);
                  }
                  else
                  {
                      gl.disableVertexAttribArray(i);
                  }
              }
          }
  
      }
      else
      {
          for (i = 0; i < attribs.length; i++)
          {
              var attrib = attribs[i];
              gl.enableVertexAttribArray(attrib.attribute.location);
          }
      }
  };
  
  module.exports = setVertexAttribArrays;
  
  },{}],8:[function(require,module,exports){
  
  /**
   * @class
   * @memberof PIXI.glCore.shader
   * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
   * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
   * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
   * @param attributeLocations {Object} An attribute location map that lets you manually set the attribute locations
   * @return {WebGLProgram} the shader program
   */
  var compileProgram = function(gl, vertexSrc, fragmentSrc, attributeLocations)
  {
      var glVertShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);
      var glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);
  
      var program = gl.createProgram();
  
      gl.attachShader(program, glVertShader);
      gl.attachShader(program, glFragShader);
  
      // optionally, set the attributes manually for the program rather than letting WebGL decide..
      if(attributeLocations)
      {
          for(var i in attributeLocations)
          {
              gl.bindAttribLocation(program, attributeLocations[i], i);
          }
      }
  
  
      gl.linkProgram(program);
  
      // if linking fails, then log and cleanup
      if (!gl.getProgramParameter(program, gl.LINK_STATUS))
      {
          console.error('Pixi.js Error: Could not initialize shader.');
          console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));
          console.error('gl.getError()', gl.getError());
  
          // if there is a program info log, log it
          if (gl.getProgramInfoLog(program) !== '')
          {
              console.warn('Pixi.js Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));
          }
  
          gl.deleteProgram(program);
          program = null;
      }
  
      // clean up some shaders
      gl.deleteShader(glVertShader);
      gl.deleteShader(glFragShader);
  
      return program;
  };
  
  /**
   * @private
   * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
   * @param type {Number} the type, can be either VERTEX_SHADER or FRAGMENT_SHADER
   * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
   * @return {WebGLShader} the shader
   */
  var compileShader = function (gl, type, src)
  {
      var shader = gl.createShader(type);
  
      gl.shaderSource(shader, src);
      gl.compileShader(shader);
  
      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
      {
          console.log(gl.getShaderInfoLog(shader));
          return null;
      }
  
      return shader;
  };
  
  module.exports = compileProgram;
  
  },{}],9:[function(require,module,exports){
  /**
   * @class
   * @memberof PIXI.glCore.shader
   * @param type {String} Type of value
   * @param size {Number}
   */
  var defaultValue = function(type, size) 
  {
      switch (type)
      {
          case 'float':
              return 0;
  
          case 'vec2': 
              return new Float32Array(2 * size);
  
          case 'vec3':
              return new Float32Array(3 * size);
  
          case 'vec4':     
              return new Float32Array(4 * size);
              
          case 'int':
          case 'sampler2D':
              return 0;
  
          case 'ivec2':   
              return new Int32Array(2 * size);
  
          case 'ivec3':
              return new Int32Array(3 * size);
  
          case 'ivec4': 
              return new Int32Array(4 * size);
  
          case 'bool':     
              return false;
  
          case 'bvec2':
  
              return booleanArray( 2 * size);
  
          case 'bvec3':
              return booleanArray(3 * size);
  
          case 'bvec4':
              return booleanArray(4 * size);
  
          case 'mat2':
              return new Float32Array([1, 0,
                                       0, 1]);
  
          case 'mat3': 
              return new Float32Array([1, 0, 0,
                                       0, 1, 0,
                                       0, 0, 1]);
  
          case 'mat4':
              return new Float32Array([1, 0, 0, 0,
                                       0, 1, 0, 0,
                                       0, 0, 1, 0,
                                       0, 0, 0, 1]);
      }
  };
  
  var booleanArray = function(size)
  {
      var array = new Array(size);
  
      for (var i = 0; i < array.length; i++) 
      {
          array[i] = false;
      }
  
      return array;
  };
  
  module.exports = defaultValue;
  
  },{}],10:[function(require,module,exports){
  
  var mapType = require('./mapType');
  var mapSize = require('./mapSize');
  
  /**
   * Extracts the attributes
   * @class
   * @memberof PIXI.glCore.shader
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param program {WebGLProgram} The shader program to get the attributes from
   * @return attributes {Object}
   */
  var extractAttributes = function(gl, program)
  {
      var attributes = {};
  
      var totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
  
      for (var i = 0; i < totalAttributes; i++)
      {
          var attribData = gl.getActiveAttrib(program, i);
          var type = mapType(gl, attribData.type);
  
          attributes[attribData.name] = {
              type:type,
              size:mapSize(type),
              location:gl.getAttribLocation(program, attribData.name),
              //TODO - make an attribute object
              pointer: pointer
          };
      }
  
      return attributes;
  };
  
  var pointer = function(type, normalized, stride, start){
      // console.log(this.location)
      gl.vertexAttribPointer(this.location,this.size, type || gl.FLOAT, normalized || false, stride || 0, start || 0);
  };
  
  module.exports = extractAttributes;
  
  },{"./mapSize":14,"./mapType":15}],11:[function(require,module,exports){
  var mapType = require('./mapType');
  var defaultValue = require('./defaultValue');
  
  /**
   * Extracts the uniforms
   * @class
   * @memberof PIXI.glCore.shader
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param program {WebGLProgram} The shader program to get the uniforms from
   * @return uniforms {Object}
   */
  var extractUniforms = function(gl, program)
  {
  	var uniforms = {};
  
      var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
  
      for (var i = 0; i < totalUniforms; i++)
      {
      	var uniformData = gl.getActiveUniform(program, i);
      	var name = uniformData.name.replace(/\[.*?\]/, "");
          var type = mapType(gl, uniformData.type );
  
      	uniforms[name] = {
      		type:type,
      		size:uniformData.size,
      		location:gl.getUniformLocation(program, name),
      		value:defaultValue(type, uniformData.size)
      	};
      }
  
  	return uniforms;
  };
  
  module.exports = extractUniforms;
  
  },{"./defaultValue":9,"./mapType":15}],12:[function(require,module,exports){
  /**
   * Extracts the attributes
   * @class
   * @memberof PIXI.glCore.shader
   * @param gl {WebGLRenderingContext} The current WebGL rendering context
   * @param uniforms {Array} @mat ?
   * @return attributes {Object}
   */
  var generateUniformAccessObject = function(gl, uniformData)
  {
      // this is the object we will be sending back.
      // an object hierachy will be created for structs
      var uniforms = {data:{}};
  
      uniforms.gl = gl;
  
      var uniformKeys= Object.keys(uniformData);
  
      for (var i = 0; i < uniformKeys.length; i++)
      {
          var fullName = uniformKeys[i];
  
          var nameTokens = fullName.split('.');
          var name = nameTokens[nameTokens.length - 1];
  
  
          var uniformGroup = getUniformGroup(nameTokens, uniforms);
  
          var uniform =  uniformData[fullName];
          uniformGroup.data[name] = uniform;
  
          uniformGroup.gl = gl;
  
          Object.defineProperty(uniformGroup, name, {
              get: generateGetter(name),
              set: generateSetter(name, uniform)
          });
      }
  
      return uniforms;
  };
  
  var generateGetter = function(name)
  {
      return function() {
          return this.data[name].value;
      };
  };
  
  var GLSL_SINGLE_SETTERS = {
      float: function setSingleFloat(gl, location, value) { gl.uniform1f(location, value); },
      vec2: function setSingleVec2(gl, location, value) { gl.uniform2f(location, value[0], value[1]); },
      vec3: function setSingleVec3(gl, location, value) { gl.uniform3f(location, value[0], value[1], value[2]); },
      vec4: function setSingleVec4(gl, location, value) { gl.uniform4f(location, value[0], value[1], value[2], value[3]); },
  
      int: function setSingleInt(gl, location, value) { gl.uniform1i(location, value); },
      ivec2: function setSingleIvec2(gl, location, value) { gl.uniform2i(location, value[0], value[1]); },
      ivec3: function setSingleIvec3(gl, location, value) { gl.uniform3i(location, value[0], value[1], value[2]); },
      ivec4: function setSingleIvec4(gl, location, value) { gl.uniform4i(location, value[0], value[1], value[2], value[3]); },
  
      bool: function setSingleBool(gl, location, value) { gl.uniform1i(location, value); },
      bvec2: function setSingleBvec2(gl, location, value) { gl.uniform2i(location, value[0], value[1]); },
      bvec3: function setSingleBvec3(gl, location, value) { gl.uniform3i(location, value[0], value[1], value[2]); },
      bvec4: function setSingleBvec4(gl, location, value) { gl.uniform4i(location, value[0], value[1], value[2], value[3]); },
  
      mat2: function setSingleMat2(gl, location, value) { gl.uniformMatrix2fv(location, false, value); },
      mat3: function setSingleMat3(gl, location, value) { gl.uniformMatrix3fv(location, false, value); },
      mat4: function setSingleMat4(gl, location, value) { gl.uniformMatrix4fv(location, false, value); },
  
      sampler2D: function setSingleSampler2D(gl, location, value) { gl.uniform1i(location, value); },
  };
  
  var GLSL_ARRAY_SETTERS = {
      float: function setFloatArray(gl, location, value) { gl.uniform1fv(location, value); },
      vec2: function setVec2Array(gl, location, value) { gl.uniform2fv(location, value); },
      vec3: function setVec3Array(gl, location, value) { gl.uniform3fv(location, value); },
      vec4: function setVec4Array(gl, location, value) { gl.uniform4fv(location, value); },
      int: function setIntArray(gl, location, value) { gl.uniform1iv(location, value); },
      ivec2: function setIvec2Array(gl, location, value) { gl.uniform2iv(location, value); },
      ivec3: function setIvec3Array(gl, location, value) { gl.uniform3iv(location, value); },
      ivec4: function setIvec4Array(gl, location, value) { gl.uniform4iv(location, value); },
      bool: function setBoolArray(gl, location, value) { gl.uniform1iv(location, value); },
      bvec2: function setBvec2Array(gl, location, value) { gl.uniform2iv(location, value); },
      bvec3: function setBvec3Array(gl, location, value) { gl.uniform3iv(location, value); },
      bvec4: function setBvec4Array(gl, location, value) { gl.uniform4iv(location, value); },
      sampler2D: function setSampler2DArray(gl, location, value) { gl.uniform1iv(location, value); },
  };
  
  function generateSetter(name, uniform)
  {
      return function(value) {
          this.data[name].value = value;
          var location = this.data[name].location;
          if (uniform.size === 1)
          {
              GLSL_SINGLE_SETTERS[uniform.type](this.gl, location, value);
          }
          else
          {
              // glslSetArray(gl, location, type, value) {
              GLSL_ARRAY_SETTERS[uniform.type](this.gl, location, value);
          }
      };
  }
  
  function getUniformGroup(nameTokens, uniform)
  {
      var cur = uniform;
  
      for (var i = 0; i < nameTokens.length - 1; i++)
      {
          var o = cur[nameTokens[i]] || {data:{}};
          cur[nameTokens[i]] = o;
          cur = o;
      }
  
      return cur;
  }
  
  
  module.exports = generateUniformAccessObject;
  
  },{}],13:[function(require,module,exports){
  module.exports = {
      compileProgram: require('./compileProgram'),
      defaultValue: require('./defaultValue'),
      extractAttributes: require('./extractAttributes'),
      extractUniforms: require('./extractUniforms'),
      generateUniformAccessObject: require('./generateUniformAccessObject'),
      setPrecision: require('./setPrecision'),
      mapSize: require('./mapSize'),
      mapType: require('./mapType')
  };
  },{"./compileProgram":8,"./defaultValue":9,"./extractAttributes":10,"./extractUniforms":11,"./generateUniformAccessObject":12,"./mapSize":14,"./mapType":15,"./setPrecision":16}],14:[function(require,module,exports){
  /**
   * @class
   * @memberof PIXI.glCore.shader
   * @param type {String}
   * @return {Number}
   */
  var mapSize = function(type) 
  { 
      return GLSL_TO_SIZE[type];
  };
  
  
  var GLSL_TO_SIZE = {
      'float':    1,
      'vec2':     2,
      'vec3':     3,
      'vec4':     4,
  
      'int':      1,
      'ivec2':    2,
      'ivec3':    3,
      'ivec4':    4,
  
      'bool':     1,
      'bvec2':    2,
      'bvec3':    3,
      'bvec4':    4,
  
      'mat2':     4,
      'mat3':     9,
      'mat4':     16,
  
      'sampler2D':  1
  };
  
  module.exports = mapSize;
  
  },{}],15:[function(require,module,exports){
  
  
  var mapType = function(gl, type) 
  {
      if(!GL_TABLE) 
      {
          var typeNames = Object.keys(GL_TO_GLSL_TYPES);
  
          GL_TABLE = {};
  
          for(var i = 0; i < typeNames.length; ++i) 
          {
              var tn = typeNames[i];
              GL_TABLE[ gl[tn] ] = GL_TO_GLSL_TYPES[tn];
          }
      }
  
    return GL_TABLE[type];
  };
  
  var GL_TABLE = null;
  
  var GL_TO_GLSL_TYPES = {
    'FLOAT':       'float',
    'FLOAT_VEC2':  'vec2',
    'FLOAT_VEC3':  'vec3',
    'FLOAT_VEC4':  'vec4',
  
    'INT':         'int',
    'INT_VEC2':    'ivec2',
    'INT_VEC3':    'ivec3',
    'INT_VEC4':    'ivec4',
    
    'BOOL':        'bool',
    'BOOL_VEC2':   'bvec2',
    'BOOL_VEC3':   'bvec3',
    'BOOL_VEC4':   'bvec4',
    
    'FLOAT_MAT2':  'mat2',
    'FLOAT_MAT3':  'mat3',
    'FLOAT_MAT4':  'mat4',
    
    'SAMPLER_2D':  'sampler2D'  
  };
  
  module.exports = mapType;
  
  },{}],16:[function(require,module,exports){
  /**
   * Sets the float precision on the shader. If the precision is already present this function will do nothing
   * @param {string} src       the shader source
   * @param {string} precision The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
   *
   * @return {string} modified shader source
   */
  var setPrecision = function(src, precision)
  {
      if(src.substring(0, 9) !== 'precision')
      {
          return 'precision ' + precision + ' float;\n' + src;
      }
  
      return src;
  };
  
  module.exports = setPrecision;
  
  },{}],17:[function(require,module,exports){
  var gl = {
      createContext:          require('./createContext'),
      setVertexAttribArrays:  require('./setVertexAttribArrays'),
      GLBuffer:               require('./GLBuffer'),
      GLFramebuffer:          require('./GLFramebuffer'),
      GLShader:               require('./GLShader'),
      GLTexture:              require('./GLTexture'),
      VertexArrayObject:      require('./VertexArrayObject'),
      shader:                 require('./shader')
  };
  
  // Export for Node-compatible environments
  if (typeof module !== 'undefined' && module.exports)
  {
      // Export the module
      module.exports = gl;
  }
  
  // Add to the browser window pixi.gl
  if (typeof window !== 'undefined')
  {
      // add the window object
      window.PIXI = window.PIXI || {};
      window.PIXI.glCore = gl;
  }
  
  },{"./GLBuffer":1,"./GLFramebuffer":2,"./GLShader":3,"./GLTexture":4,"./VertexArrayObject":5,"./createContext":6,"./setVertexAttribArrays":7,"./shader":13}]},{},[17])(17)
  });
  
  
  //# sourceMappingURL=pixi-gl-core.js.map
  