diff --git a/bin/pixi.js b/bin/pixi.js index ff131c0..f6c54ef 100644 --- a/bin/pixi.js +++ b/bin/pixi.js @@ -1,1511 +1,4 @@ (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.PIXI = 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= 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, drawType); -} - -/** - * Destroys the buffer - * - */ -Buffer.prototype.destroy = function(){ - this.gl.deleteBuffer(this.buffer); -} - -module.exports = Buffer; - -},{}],3:[function(require,module,exports){ - -var Texture = require('./GLTexture'); - -/** - * Helper class to create a webGL Framebuffer - * - * @class - * @memberof pixi.gl - * @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 {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 {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 - * @mat maybe you can come up with a better explaination - */ -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); -} - -/** - * Binds the frame buffer to the WebGL context - */ -Framebuffer.prototype.bind = function() -{ - var gl = this.gl; - - if(this.texture) - { - this.texture.unbind(); - } - - 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 - * @mat can you confirm ? :) - * @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.unbind(); - - return fbo; -} - -/** - * Creates a frame buffer with a texture containing the given data - * @mat not sure what the difference is with the method above ? - * @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":5}],4:[function(require,module,exports){ - -var compileProgram = require('./shader/compileProgram'), - extractAttributes = require('./shader/extractAttributes'), - extractUniforms = require('./shader/extractUniforms'), - generateUniformAccessObject = require('./shader/generateUniformAccessObject'); - -/** - * Helper class to create a webGL Shader - * - * @class - * @memberof pixi.gl - * @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. - */ -var Shader = function(gl, vertexSrc, fragmentSrc) -{ - /** - * The current WebGL rendering context - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; - - /** - * The shader program - * - * @member {WebGLProgram} - */ - // First compile the program.. - this.program = compileProgram(gl, vertexSrc, fragmentSrc); - - /** - * 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); - - var 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, uniformData ); -} -/** - * Uses this shader - */ -Shader.prototype.bind = function() -{ - this.gl.useProgram(this.program); -} - -/** - * Destroys this shader - * TODO - */ -Shader.prototype.destroy = function() -{ - var gl = this.gl; -} - -module.exports = Shader; - -},{"./shader/compileProgram":9,"./shader/extractAttributes":11,"./shader/extractUniforms":12,"./shader/generateUniformAccessObject":13}],5:[function(require,module,exports){ - -/** - * Helper class to create a WebGL Texture - * - * @class - * @memberof pixi.gl - * @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 || 0; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || 0; - - /** - * 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; - - // if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect. - this.width = source.videoWidth || source.width; - this.height = source.videoHeight || source.height; - - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source); -} - -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; - - this.width = width || this.width; - this.height = height || this.height; - - 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 = gl.UNSIGNED_BYTE; - } - - - - // what type of data? - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, this.type, data || null); - -} - -/** - * Binds the texture - * @param location {@mat} - */ -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); -} - -/** - * @mat - * @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); - } -} - -/** - * @mat - * @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); -} - -/** - * @mat - */ -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; - -},{}],6:[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.gl - * @param gl {WebGLRenderingContext} The current WebGL rendering context - */ -function VertexArrayObject(gl, state) -{ - - 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 ? @mat - * - * @member {Array} - */ - this.attributes = []; - - /** - * @mat - * - * @member {Array} - */ - this.indexBuffer = null; - - /** - * A boolean flag - * - * @member {Boolean} - */ - this.dirty = false; -} - -VertexArrayObject.prototype.constructor = VertexArrayObject; -module.exports = VertexArrayObject; - - -/** - * Binds the buffer - */ -VertexArrayObject.prototype.bind = function() -{ - if(this.nativeVao) - { - this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao); - - if(this.dirty) - { - this.dirty = false; - this.activate(); - } - } - 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; - } - - //attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start); - 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); - - this.indexBuffer.bind(); - - return this; -} - -/** - * - * @param buffer {WebGLBuffer} - * @param attribute {[type]} - * @param type {[type]} - * @param normalized {[type]} - * @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 {WebGLBuffer} - * @param options {Object} - */ -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; -} - -/** - * @mat - * @param type {Number} - * @param size {Number} - * @param start {Number} - */ -VertexArrayObject.prototype.draw = function(type, size, start) -{ - var gl = this.gl; - gl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0); - - return this; -} - -},{"./setVertexAttribArrays":8}],7:[function(require,module,exports){ - -/** - * Helper class to create a webGL Context - * - * @class - * @memberof pixi.gl - * @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; - -},{}],8:[function(require,module,exports){ -var GL_MAP = {}; - -/** - * @mat - * @param gl {WebGLRenderingContext} The current WebGL context - * @param attribs {[type]} - */ -var setVertexAttribArrays = function (gl, attribs, state) -{ - - if(state) - { - - var i, - tempAttribState = state.tempAttribState, - attribState = state.attribState; - - for (i = 0; i < tempAttribState.length; i++) - { - tempAttribState[i] = false; - } - - // set the new attribs - for (i in attribs) - { - 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 (var i = 0; i < attribs.length; i++) - { - var attrib = attribs[i]; - gl.enableVertexAttribArray(attrib.attribute.location); - } - } -}; - -module.exports = setVertexAttribArrays; - -},{}],9:[function(require,module,exports){ - -/** - * - * @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. - * @return {WebGLProgram} the shader program - */ -compileProgram = function(gl, vertexSrc, fragmentSrc) -{ - 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); - 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; -} - -/** - * - * @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; - -},{}],10:[function(require,module,exports){ - - -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; - -},{}],11:[function(require,module,exports){ - -var mapType = require('./mapType'); -var mapSize = require('./mapSize'); - -/** - * Extracts the attributes - * @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:function(type, normalized, stride, start){ - - // console.log(this.location) - gl.vertexAttribPointer(this.location,this.size, type || gl.FLOAT, normalized || false, stride || 0, start || 0); - - } - } - }; - - return attributes; -} - -module.exports = extractAttributes; - -},{"./mapSize":14,"./mapType":15}],12:[function(require,module,exports){ -var mapType = require('./mapType'); -var defaultValue = require('./defaultValue'); - -/** - * Extracts the uniforms - * @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":10,"./mapType":15}],13:[function(require,module,exports){ -/** - * Extracts the attributes - * @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) -{ - var template = getterTemplate.replace('%%', name); - return new Function(template); -} - -var generateSetter = function(name, uniform) -{ - var template = setterTemplate.replace(/%%/g, name); - var setTemplate - - if(uniform.size === 1) - { - setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type]; - } - else - { - setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type]; - } - - if(setTemplate) - { - template += "\nthis.gl." + setTemplate + ";"; - } - - return new Function('value', template); -} - -var getUniformGroup = function(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 -} - -var getterTemplate = [ - 'return this.data.%%.value;', -].join('\n'); - -var setterTemplate = [ - 'this.data.%%.value = value;', - 'var location = this.data.%%.location;' -].join('\n'); - - -var GLSL_TO_SINGLE_SETTERS = { - - 'float': 'uniform1f(location, value)', - - 'vec2': 'uniform2f(location, value[0], value[1])', - 'vec3': 'uniform3f(location, value[0], value[1], value[2])', - 'vec4': 'uniform4f(location, value[0], value[1], value[2], value[3])', - - 'int': 'uniform1i(location, value)', - 'ivec2': 'uniform2i(location, value[0], value[1])', - 'ivec3': 'uniform3i(location, value[0], value[1], value[2])', - 'ivec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', - - 'bool': 'uniform1i(location, value)', - 'bvec2': 'uniform2i(location, value[0], value[1])', - 'bvec3': 'uniform3i(location, value[0], value[1], value[2])', - 'bvec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', - - 'mat2': 'uniformMatrix2fv(location, false, value)', - 'mat3': 'uniformMatrix3fv(location, false, value)', - 'mat4': 'uniformMatrix4fv(location, false, value)', - - 'sampler2D':'uniform1i(location, value)' -} - -var GLSL_TO_ARRAY_SETTERS = { - - 'float': 'uniform1fv(location, value)', - - 'vec2': 'uniform2fv(location, value)', - 'vec3': 'uniform3fv(location, value)', - 'vec4': 'uniform4fv(location, value)', - - 'int': 'uniform1iv(location, value)', - 'ivec2': 'uniform2iv(location, value)', - 'ivec3': 'uniform3iv(location, value)', - 'ivec4': 'uniform4iv(location, value)', - - 'bool': 'uniform1iv(location, value)', - 'bvec2': 'uniform2iv(location, value)', - 'bvec3': 'uniform3iv(location, value)', - 'bvec4': 'uniform4iv(location, value)', - - 'sampler2D':'uniform1iv(location, value)' -} - -module.exports = generateUniformAccessObject; - -},{}],14:[function(require,module,exports){ - - -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 mapSize = 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 = mapSize; - -},{}],16:[function(require,module,exports){ (function (process,global){ /*! * async @@ -2774,7 +1267,7 @@ }()); }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"_process":19}],17:[function(require,module,exports){ +},{"_process":4}],2:[function(require,module,exports){ /** * Bit twiddling hacks for JavaScript. * @@ -2980,7 +1473,7 @@ } -},{}],18:[function(require,module,exports){ +},{}],3:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // @@ -3208,7 +1701,7 @@ ; }).call(this,require('_process')) -},{"_process":19}],19:[function(require,module,exports){ +},{"_process":4}],4:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -3301,7 +1794,7 @@ }; process.umask = function() { return 0; }; -},{}],20:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ (function (global){ /*! https://mths.be/punycode v1.4.0 by @mathias */ ;(function(root) { @@ -3838,7 +2331,7 @@ }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],21:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -3924,7 +2417,7 @@ return Object.prototype.toString.call(xs) === '[object Array]'; }; -},{}],22:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -4011,13 +2504,13 @@ return res; }; -},{}],23:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); -},{"./decode":21,"./encode":22}],24:[function(require,module,exports){ +},{"./decode":6,"./encode":7}],9:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -4726,7 +3219,7 @@ return arg == null; } -},{"punycode":20,"querystring":23}],25:[function(require,module,exports){ +},{"punycode":5,"querystring":8}],10:[function(require,module,exports){ 'use strict'; module.exports = earcut; @@ -4771,22 +3264,19 @@ // create a circular doubly linked list from polygon points in the specified winding order function linkedList(data, start, end, dim, clockwise) { - var sum = 0, - i, j, last; + var i, last; - // calculate original winding order of a polygon ring - for (i = start, j = end - dim; i < end; i += dim) { - sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); - j = i; - } - - // link points into circular doubly-linked list in the specified winding order - if (clockwise === (sum > 0)) { + if (clockwise === (signedArea(data, start, end, dim) > 0)) { for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); } else { for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); } + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } + return last; } @@ -4934,8 +3424,7 @@ var a = p.prev, b = p.next.next; - // a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2]) - if (intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { triangles.push(a.i / dim); triangles.push(p.i / dim); @@ -5031,6 +3520,10 @@ var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); if (x <= hx && x > qx) { qx = x; + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } m = p.x < p.next.x ? p : p.next; } } @@ -5039,21 +3532,23 @@ if (!m) return null; - if (hole.x === m.x) return m.prev; // hole touches outer segment; pick lower endpoint + if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint // look for points inside the triangle of hole point, segment intersection and endpoint; // if there are no points found, we have a valid connection; // otherwise choose the point of the minimum angle with the ray as connection point var stop = m, + mx = m.x, + my = m.y, tanMin = Infinity, tan; p = m.next; while (p !== stop) { - if (hx >= p.x && p.x >= m.x && - pointInTriangle(hy < m.y ? hx : qx, hy, m.x, m.y, hy < m.y ? qx : hx, hy, p.x, p.y)) { + if (hx >= p.x && p.x >= mx && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { tan = Math.abs(hy - p.y) / (hx - p.x); // tangential @@ -5187,7 +3682,7 @@ // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { - return equals(a, b) || a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); } @@ -5203,6 +3698,8 @@ // check if two segments intersect function intersects(p1, q1, p2, q2) { + if ((equals(p1, q1) && equals(p2, q2)) || + (equals(p1, q2) && equals(p2, q1))) return true; return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; } @@ -5312,9 +3809,67 @@ this.steiner = false; } -},{}],26:[function(require,module,exports){ +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } + + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } + + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; + +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} + +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; +}; + +},{}],11:[function(require,module,exports){ 'use strict'; +var has = Object.prototype.hasOwnProperty; + // // We store our EE objects in a plain object whose properties are event names. // If `Object.create(null)` is not supported we prefix the event names with a @@ -5330,7 +3885,7 @@ * * @param {Function} fn Event handler to be called. * @param {Mixed} context Context for function execution. - * @param {Boolean} once Only emit once + * @param {Boolean} [once=false] Only emit once * @api private */ function EE(fn, context, once) { @@ -5349,7 +3904,7 @@ function EventEmitter() { /* Nothing to set */ } /** - * Holds the assigned EventEmitters by name. + * Hold the assigned EventEmitters by name. * * @type {Object} * @private @@ -5357,6 +3912,31 @@ EventEmitter.prototype._events = undefined; /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @api public + */ +EventEmitter.prototype.eventNames = function eventNames() { + var events = this._events + , names = [] + , name; + + if (!events) return names; + + for (name in events) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; +}; + +/** * Return a list of assigned event listeners. * * @param {String} event The events that should be listed. @@ -5441,8 +4021,8 @@ * Register a new EventListener for the given event. * * @param {String} event Name of the event. - * @param {Functon} fn Callback function. - * @param {Mixed} context The context of the function. + * @param {Function} fn Callback function. + * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.on = function on(event, fn, context) { @@ -5466,7 +4046,7 @@ * * @param {String} event Name of the event. * @param {Function} fn Callback function. - * @param {Mixed} context The context of the function. + * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.once = function once(event, fn, context) { @@ -5576,9 +4156,9 @@ module.exports = EventEmitter; } -},{}],27:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ /** - * isMobile.js v0.3.9 + * isMobile.js v0.4.0 * * A simple library to detect Apple phones and tablets, * Android phones and tablets, other mobile devices (like blackberry, mini-opera and windows phone), @@ -5643,6 +4223,14 @@ ua = tmp[0]; } + // Twitter mobile app's integrated browser on iPad adds a "Twitter for + // iPhone" string. Same probable happens on other tablet platforms. + // This will confuse detection so strip it out if it exists. + tmp = ua.split('Twitter'); + if (typeof tmp[1] !== 'undefined') { + ua = tmp[0]; + } + this.apple = { phone: match(apple_phone, ua), ipod: match(apple_ipod, ua), @@ -5707,7 +4295,7 @@ })(this); -},{}],28:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /* eslint-disable no-unused-vars */ 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty; @@ -5748,6 +4336,1534 @@ return to; }; +},{}],14:[function(require,module,exports){ + + +module.exports = { + + createContext: require('./lib/createContext'), + setVertexAttribArrays: require('./lib/setVertexAttribArrays'), + + GLBuffer: require('./lib/GLBuffer'), + GLFramebuffer: require('./lib/GLFramebuffer'), + GLShader: require('./lib/GLShader'), + GLTexture: require('./lib/GLTexture'), + + VertexArrayObject: require('./lib/VertexArrayObject') + +}; +},{"./lib/GLBuffer":15,"./lib/GLFramebuffer":16,"./lib/GLShader":17,"./lib/GLTexture":18,"./lib/VertexArrayObject":19,"./lib/createContext":20,"./lib/setVertexAttribArrays":21}],15:[function(require,module,exports){ +var EMPTY_ARRAY_BUFFER = new ArrayBuffer(0); + +/** + * Helper class to create a webGL buffer + * + * @class + * @memberof pixi.gl + * @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); + } +}; + +/** + * 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, drawType); +}; + +/** + * Destroys the buffer + * + */ +Buffer.prototype.destroy = function(){ + this.gl.deleteBuffer(this.buffer); +}; + +module.exports = Buffer; + +},{}],16:[function(require,module,exports){ + +var Texture = require('./GLTexture'); + +/** + * Helper class to create a webGL Framebuffer + * + * @class + * @memberof pixi.gl + * @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 {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 {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 + * @mat maybe you can come up with a better explaination + */ +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); +}; + +/** + * Binds the frame buffer to the WebGL context + */ +Framebuffer.prototype.bind = function() +{ + var gl = this.gl; + + if(this.texture) + { + this.texture.unbind(); + } + + 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 + * @mat can you confirm ? :) + * @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.unbind(); + + return fbo; +}; + +/** + * Creates a frame buffer with a texture containing the given data + * @mat not sure what the difference is with the method above ? + * @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":18}],17:[function(require,module,exports){ + +var compileProgram = require('./shader/compileProgram'), + extractAttributes = require('./shader/extractAttributes'), + extractUniforms = require('./shader/extractUniforms'), + generateUniformAccessObject = require('./shader/generateUniformAccessObject'); + +/** + * Helper class to create a webGL Shader + * + * @class + * @memberof pixi.gl + * @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. + */ +var Shader = function(gl, vertexSrc, fragmentSrc) +{ + /** + * The current WebGL rendering context + * + * @member {WebGLRenderingContext} + */ + this.gl = gl; + + /** + * The shader program + * + * @member {WebGLProgram} + */ + // First compile the program.. + this.program = compileProgram(gl, vertexSrc, fragmentSrc); + + + /** + * 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); + + var 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, uniformData ); +}; +/** + * Uses this shader + */ +Shader.prototype.bind = function() +{ + this.gl.useProgram(this.program); +}; + +/** + * Destroys this shader + * TODO + */ +Shader.prototype.destroy = function() +{ + var gl = this.gl; +}; + +module.exports = Shader; + +},{"./shader/compileProgram":22,"./shader/extractAttributes":24,"./shader/extractUniforms":25,"./shader/generateUniformAccessObject":26}],18:[function(require,module,exports){ + +/** + * Helper class to create a WebGL Texture + * + * @class + * @memberof pixi.gl + * @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 || 0; + /** + * The height of texture + * + * @member {Number} + */ + this.height = height || 0; + + /** + * 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; + + // if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect. + this.width = source.videoWidth || source.width; + this.height = source.videoHeight || source.height; + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source); +}; + +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; + + this.width = width || this.width; + this.height = height || this.height; + + 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 = gl.UNSIGNED_BYTE; + } + + + + // what type of data? + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, this.type, data || null); + +}; + +/** + * Binds the texture + * @param location {@mat} + */ +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); +}; + +/** + * @mat + * @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); + } +}; + +/** + * @mat + * @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); +}; + +/** + * @mat + */ +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; + +},{}],19:[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.gl + * @param gl {WebGLRenderingContext} The current WebGL rendering context + */ +function VertexArrayObject(gl, state) +{ + + 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 ? @mat + * + * @member {Array} + */ + this.attributes = []; + + /** + * @mat + * + * @member {Array} + */ + this.indexBuffer = null; + + /** + * A boolean flag + * + * @member {Boolean} + */ + this.dirty = false; +} + +VertexArrayObject.prototype.constructor = VertexArrayObject; +module.exports = VertexArrayObject; + + +/** + * Binds the buffer + */ +VertexArrayObject.prototype.bind = function() +{ + if(this.nativeVao) + { + this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao); + + if(this.dirty) + { + this.dirty = false; + this.activate(); + } + } + 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; + } + + //attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start); + 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); + + this.indexBuffer.bind(); + + return this; +}; + +/** + * + * @param buffer {WebGLBuffer} + * @param attribute {[type]} + * @param type {[type]} + * @param normalized {[type]} + * @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 {WebGLBuffer} + * @param options {Object} + */ +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; +}; + +/** + * @mat + * @param type {Number} + * @param size {Number} + * @param start {Number} + */ +VertexArrayObject.prototype.draw = function(type, size, start) +{ + var gl = this.gl; + gl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0); + + 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; +}; + +},{"./setVertexAttribArrays":21}],20:[function(require,module,exports){ + +/** + * Helper class to create a webGL Context + * + * @class + * @memberof pixi.gl + * @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; + +},{}],21:[function(require,module,exports){ +var GL_MAP = {}; + +/** + * @mat + * @param gl {WebGLRenderingContext} The current WebGL context + * @param attribs {[type]} + */ +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 in attribs) + { + 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; + +},{}],22:[function(require,module,exports){ + +/** + * + * @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. + * @return {WebGLProgram} the shader program + */ +var compileProgram = function(gl, vertexSrc, fragmentSrc) +{ + 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); + 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; +}; + +/** + * + * @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; + +},{}],23:[function(require,module,exports){ + + +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; + +},{}],24:[function(require,module,exports){ + +var mapType = require('./mapType'); +var mapSize = require('./mapSize'); + +/** + * Extracts the attributes + * @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":27,"./mapType":28}],25:[function(require,module,exports){ +var mapType = require('./mapType'); +var defaultValue = require('./defaultValue'); + +/** + * Extracts the uniforms + * @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":23,"./mapType":28}],26:[function(require,module,exports){ +/** + * Extracts the attributes + * @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) +{ + var template = getterTemplate.replace('%%', name); + return new Function(template); // jshint ignore:line +}; + +var generateSetter = function(name, uniform) +{ + var template = setterTemplate.replace(/%%/g, name); + var setTemplate; + + if(uniform.size === 1) + { + setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type]; + } + else + { + setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type]; + } + + if(setTemplate) + { + template += "\nthis.gl." + setTemplate + ";"; + } + + return new Function('value', template); // jshint ignore:line +}; + +var getUniformGroup = function(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; +}; + +var getterTemplate = [ + 'return this.data.%%.value;', +].join('\n'); + +var setterTemplate = [ + 'this.data.%%.value = value;', + 'var location = this.data.%%.location;' +].join('\n'); + + +var GLSL_TO_SINGLE_SETTERS = { + + 'float': 'uniform1f(location, value)', + + 'vec2': 'uniform2f(location, value[0], value[1])', + 'vec3': 'uniform3f(location, value[0], value[1], value[2])', + 'vec4': 'uniform4f(location, value[0], value[1], value[2], value[3])', + + 'int': 'uniform1i(location, value)', + 'ivec2': 'uniform2i(location, value[0], value[1])', + 'ivec3': 'uniform3i(location, value[0], value[1], value[2])', + 'ivec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', + + 'bool': 'uniform1i(location, value)', + 'bvec2': 'uniform2i(location, value[0], value[1])', + 'bvec3': 'uniform3i(location, value[0], value[1], value[2])', + 'bvec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', + + 'mat2': 'uniformMatrix2fv(location, false, value)', + 'mat3': 'uniformMatrix3fv(location, false, value)', + 'mat4': 'uniformMatrix4fv(location, false, value)', + + 'sampler2D':'uniform1i(location, value)' +}; + +var GLSL_TO_ARRAY_SETTERS = { + + 'float': 'uniform1fv(location, value)', + + 'vec2': 'uniform2fv(location, value)', + 'vec3': 'uniform3fv(location, value)', + 'vec4': 'uniform4fv(location, value)', + + 'int': 'uniform1iv(location, value)', + 'ivec2': 'uniform2iv(location, value)', + 'ivec3': 'uniform3iv(location, value)', + 'ivec4': 'uniform4iv(location, value)', + + 'bool': 'uniform1iv(location, value)', + 'bvec2': 'uniform2iv(location, value)', + 'bvec3': 'uniform3iv(location, value)', + 'bvec4': 'uniform4iv(location, value)', + + 'sampler2D':'uniform1iv(location, value)' +}; + +module.exports = generateUniformAccessObject; + +},{}],27:[function(require,module,exports){ + + +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; + +},{}],28:[function(require,module,exports){ + + +var mapSize = 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 = mapSize; + },{}],29:[function(require,module,exports){ (function (process){ /*! @@ -6875,7 +6991,7 @@ }()); }).call(this,require('_process')) -},{"_process":19}],30:[function(require,module,exports){ +},{"_process":4}],30:[function(require,module,exports){ var async = require('async'), urlParser = require('url'), Resource = require('./Resource'), @@ -7333,7 +7449,7 @@ Loader.XHR_READY_STATE = Resource.XHR_READY_STATE; Loader.XHR_RESPONSE_TYPE = Resource.XHR_RESPONSE_TYPE; -},{"./Resource":31,"async":29,"eventemitter3":26,"url":24}],31:[function(require,module,exports){ +},{"./Resource":31,"async":29,"eventemitter3":11,"url":9}],31:[function(require,module,exports){ var EventEmitter = require('eventemitter3'), _url = require('url'), // tests is CORS is supported in XHR, if not we need to use XDR @@ -8135,7 +8251,7 @@ map[extname] = val; } -},{"eventemitter3":26,"url":24}],32:[function(require,module,exports){ +},{"eventemitter3":11,"url":9}],32:[function(require,module,exports){ module.exports = { // private property @@ -8827,7 +8943,7 @@ Shader.prototype.constructor = Shader; module.exports = Shader; -},{"./const":40,"pixi-gl-core":1}],40:[function(require,module,exports){ +},{"./const":40,"pixi-gl-core":14}],40:[function(require,module,exports){ /** * Constant values used in pixi @@ -10281,7 +10397,7 @@ this.filterArea = null; }; -},{"../math":62,"./Transform":44,"eventemitter3":26}],43:[function(require,module,exports){ +},{"../math":62,"./Transform":44,"eventemitter3":11}],43:[function(require,module,exports){ /** * An observable point is a point that triggers a callback when the point's position is changed. * @@ -12493,7 +12609,7 @@ this.glIndices = null; }; -},{"pixi-gl-core":1}],52:[function(require,module,exports){ +},{"pixi-gl-core":14}],52:[function(require,module,exports){ var Shader = require('../../../Shader'); /** @@ -12931,7 +13047,7 @@ module.exports = buildPoly; -},{"../../../utils":110,"./buildLine":54,"earcut":25}],56:[function(require,module,exports){ +},{"../../../utils":110,"./buildLine":54,"earcut":10}],56:[function(require,module,exports){ var buildLine = require('./buildLine'), utils = require('../../../utils'); @@ -13133,7 +13249,7 @@ module.exports = buildRoundedRectangle; -},{"../../../utils":110,"./buildLine":54,"earcut":25}],58:[function(require,module,exports){ +},{"../../../utils":110,"./buildLine":54,"earcut":10}],58:[function(require,module,exports){ /** * @file Main export of the PIXI core library * @author Mat Groves @@ -13230,7 +13346,7 @@ } }); -},{"./Shader":39,"./const":40,"./display/Container":41,"./display/DisplayObject":42,"./display/Transform":44,"./display/TransformStatic":45,"./graphics/Graphics":46,"./graphics/GraphicsData":47,"./graphics/canvas/CanvasGraphicsRenderer":48,"./graphics/webgl/GraphicsRenderer":50,"./math":62,"./renderers/canvas/CanvasRenderer":69,"./renderers/canvas/utils/CanvasRenderTarget":71,"./renderers/webgl/WebGLRenderer":76,"./renderers/webgl/filters/Filter":78,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":81,"./renderers/webgl/managers/WebGLManager":85,"./renderers/webgl/utils/ObjectRenderer":86,"./renderers/webgl/utils/Quad":87,"./renderers/webgl/utils/RenderTarget":88,"./sprites/Sprite":92,"./sprites/canvas/CanvasSpriteRenderer":93,"./sprites/canvas/CanvasTinter":94,"./sprites/webgl/SpriteRenderer":96,"./text/Text":98,"./text/TextStyle":99,"./textures/BaseRenderTexture":100,"./textures/BaseTexture":101,"./textures/RenderTexture":102,"./textures/Texture":103,"./textures/TextureUvs":104,"./textures/VideoBaseTexture":105,"./ticker":107,"./utils":110,"pixi-gl-core":1}],59:[function(require,module,exports){ +},{"./Shader":39,"./const":40,"./display/Container":41,"./display/DisplayObject":42,"./display/Transform":44,"./display/TransformStatic":45,"./graphics/Graphics":46,"./graphics/GraphicsData":47,"./graphics/canvas/CanvasGraphicsRenderer":48,"./graphics/webgl/GraphicsRenderer":50,"./math":62,"./renderers/canvas/CanvasRenderer":69,"./renderers/canvas/utils/CanvasRenderTarget":71,"./renderers/webgl/WebGLRenderer":76,"./renderers/webgl/filters/Filter":78,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":81,"./renderers/webgl/managers/WebGLManager":85,"./renderers/webgl/utils/ObjectRenderer":86,"./renderers/webgl/utils/Quad":87,"./renderers/webgl/utils/RenderTarget":88,"./sprites/Sprite":92,"./sprites/canvas/CanvasSpriteRenderer":93,"./sprites/canvas/CanvasTinter":94,"./sprites/webgl/SpriteRenderer":96,"./text/Text":98,"./text/TextStyle":99,"./textures/BaseRenderTexture":100,"./textures/BaseTexture":101,"./textures/RenderTexture":102,"./textures/Texture":103,"./textures/TextureUvs":104,"./textures/VideoBaseTexture":105,"./ticker":107,"./utils":110,"pixi-gl-core":14}],59:[function(require,module,exports){ // Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16 var ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1]; @@ -14780,7 +14896,7 @@ this._lastObjectRendered = null; }; -},{"../const":40,"../display/Container":41,"../math":62,"../textures/RenderTexture":102,"../utils":110,"eventemitter3":26}],69:[function(require,module,exports){ +},{"../const":40,"../display/Container":41,"../math":62,"../textures/RenderTexture":102,"../utils":110,"eventemitter3":11}],69:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), CanvasMaskManager = require('./utils/CanvasMaskManager'), CanvasRenderTarget = require('./utils/CanvasRenderTarget'), @@ -15725,7 +15841,7 @@ module.exports = TextureManager; -},{"../../const":40,"../../utils":110,"./utils/RenderTarget":88,"pixi-gl-core":1}],76:[function(require,module,exports){ +},{"../../const":40,"../../utils":110,"./utils/RenderTarget":88,"pixi-gl-core":14}],76:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), @@ -16280,7 +16396,7 @@ // this = null; }; -},{"../../const":40,"../../utils":110,"../SystemRenderer":68,"./TextureGarbageCollector":74,"./TextureManager":75,"./WebGLState":77,"./managers/FilterManager":82,"./managers/MaskManager":83,"./managers/StencilManager":84,"./utils/ObjectRenderer":86,"./utils/RenderTarget":88,"./utils/mapWebGLDrawModesToPixi":91,"pixi-gl-core":1}],77:[function(require,module,exports){ +},{"../../const":40,"../../utils":110,"../SystemRenderer":68,"./TextureGarbageCollector":74,"./TextureManager":75,"./WebGLState":77,"./managers/FilterManager":82,"./managers/MaskManager":83,"./managers/StencilManager":84,"./utils/ObjectRenderer":86,"./utils/RenderTarget":88,"./utils/mapWebGLDrawModesToPixi":91,"pixi-gl-core":14}],77:[function(require,module,exports){ var mapWebGLBlendModesToPixi = require('./utils/mapWebGLBlendModesToPixi'); /** @@ -16746,7 +16862,7 @@ module.exports = extractUniformsFromSrc; -},{"pixi-gl-core/lib/shader/defaultValue":10,"pixi-gl-core/lib/shader/mapSize":14}],80:[function(require,module,exports){ +},{"pixi-gl-core/lib/shader/defaultValue":23,"pixi-gl-core/lib/shader/mapSize":27}],80:[function(require,module,exports){ var math = require('../../../math'); /* @@ -17207,8 +17323,12 @@ FilterManager.prototype.destroy = function() { + this.shaderCache = []; + FilterManager.emptyPool(); }; + + //TODO move to a seperate class could be on renderer? //also - could cause issue with multiple contexts? FilterManager.getPotRenderTarget = function(gl, minWidth, minHeight, resolution) @@ -17235,6 +17355,23 @@ return renderTarget; }; +FilterManager.emptyPool = function() +{ + for (var i in FilterManager.pool) + { + var textures = FilterManager.pool[i]; + if(textures) + { + for (var j = 0; j < textures.length; j++) + { + textures[j].destroy(true); + } + } + } + + FilterManager.pool = {}; +}; + FilterManager.freePotRenderTarget = function(renderTarget) { var minWidth = renderTarget.size.width * renderTarget.resolution; @@ -17244,7 +17381,7 @@ FilterManager.pool[key].push(renderTarget); }; -},{"../../../Shader":39,"../../../math":62,"../filters/filterTransforms":80,"../utils/Quad":87,"../utils/RenderTarget":88,"./WebGLManager":85,"bit-twiddle":17}],83:[function(require,module,exports){ +},{"../../../Shader":39,"../../../math":62,"../filters/filterTransforms":80,"../utils/Quad":87,"../utils/RenderTarget":88,"./WebGLManager":85,"bit-twiddle":2}],83:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter'); @@ -17805,7 +17942,7 @@ module.exports = Quad; -},{"../../../utils/createIndicesForQuads":108,"pixi-gl-core":1}],88:[function(require,module,exports){ +},{"../../../utils/createIndicesForQuads":108,"pixi-gl-core":14}],88:[function(require,module,exports){ var math = require('../../../math'), CONST = require('../../../const'), GLFramebuffer = require('pixi-gl-core').GLFramebuffer; @@ -18131,7 +18268,7 @@ this.texture = null; }; -},{"../../../const":40,"../../../math":62,"pixi-gl-core":1}],89:[function(require,module,exports){ +},{"../../../const":40,"../../../math":62,"pixi-gl-core":14}],89:[function(require,module,exports){ var glCore = require('pixi-gl-core'); var fragTemplate = [ @@ -18212,7 +18349,7 @@ module.exports = checkMaxIfStatmentsInShader; -},{"pixi-gl-core":1}],90:[function(require,module,exports){ +},{"pixi-gl-core":14}],90:[function(require,module,exports){ var CONST = require('../../../const'); /** @@ -19299,14 +19436,18 @@ this.shaders = new Array(this.MAX_TEXTURES); this.shaders[0] = generateMultiTextureShader(gl, 1); + this.shaders[1] = generateMultiTextureShader(gl, 2); // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); - var shader = this.shaders[0]; + var shader = this.shaders[1]; for (var i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + + console.log(shader); + // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) @@ -19485,7 +19626,7 @@ if(this.vaoMax <= this.vertexCount) { this.vaoMax++; - shader = this.shaders[0]; + shader = this.shaders[1]; this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() @@ -19581,7 +19722,7 @@ }; -},{"../../const":40,"../../renderers/webgl/WebGLRenderer":76,"../../renderers/webgl/utils/ObjectRenderer":86,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":89,"../../utils/createIndicesForQuads":108,"./BatchBuffer":95,"./generateMultiTextureShader":97,"bit-twiddle":17,"pixi-gl-core":1}],97:[function(require,module,exports){ +},{"../../const":40,"../../renderers/webgl/WebGLRenderer":76,"../../renderers/webgl/utils/ObjectRenderer":86,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":89,"../../utils/createIndicesForQuads":108,"./BatchBuffer":95,"./generateMultiTextureShader":97,"bit-twiddle":2,"pixi-gl-core":14}],97:[function(require,module,exports){ var Shader = require('../../Shader'); @@ -20690,7 +20831,7 @@ } } -},{"../const":40,"../utils":110,"eventemitter3":26}],100:[function(require,module,exports){ +},{"../const":40,"../utils":110,"eventemitter3":11}],100:[function(require,module,exports){ var BaseTexture = require('./BaseTexture'), CONST = require('../const'); @@ -21275,7 +21416,7 @@ return baseTexture; }; -},{"../const":40,"../utils":110,"../utils/determineCrossOrigin":109,"bit-twiddle":17,"eventemitter3":26}],102:[function(require,module,exports){ +},{"../const":40,"../utils":110,"../utils/determineCrossOrigin":109,"bit-twiddle":2,"eventemitter3":11}],102:[function(require,module,exports){ var BaseRenderTexture = require('./BaseRenderTexture'), Texture = require('./Texture'); @@ -21898,7 +22039,7 @@ Texture.EMPTY.emit = function() {}; -},{"../math":62,"../utils":110,"./BaseTexture":101,"./TextureUvs":104,"./VideoBaseTexture":105,"eventemitter3":26}],104:[function(require,module,exports){ +},{"../math":62,"../utils":110,"./BaseTexture":101,"./TextureUvs":104,"./VideoBaseTexture":105,"eventemitter3":11}],104:[function(require,module,exports){ /** * A standard object to store the Uvs of a texture @@ -22573,7 +22714,7 @@ module.exports = Ticker; -},{"../const":40,"eventemitter3":26}],107:[function(require,module,exports){ +},{"../const":40,"eventemitter3":11}],107:[function(require,module,exports){ var Ticker = require('./Ticker'); /** @@ -22705,7 +22846,7 @@ module.exports = determineCrossOrigin; -},{"url":24}],110:[function(require,module,exports){ +},{"url":9}],110:[function(require,module,exports){ var CONST = require('../const'); /** @@ -22915,7 +23056,7 @@ BaseTextureCache: {} }; -},{"../const":40,"./pluginTarget":112,"eventemitter3":26}],111:[function(require,module,exports){ +},{"../const":40,"./pluginTarget":112,"eventemitter3":11}],111:[function(require,module,exports){ var Device = require('ismobilejs'); @@ -22936,7 +23077,7 @@ }; module.exports = maxRecommendedTextures; -},{"ismobilejs":27}],112:[function(require,module,exports){ +},{"ismobilejs":12}],112:[function(require,module,exports){ /** * Mixins functionality to make an object have "plugins". * @@ -27938,7 +28079,7 @@ }; }; -},{"../core":58,"../extras":123,"path":18,"resource-loader":33}],143:[function(require,module,exports){ +},{"../core":58,"../extras":123,"path":3,"resource-loader":33}],143:[function(require,module,exports){ /** * @file Main export of the PIXI loaders library * @author Mat Groves @@ -28138,7 +28279,7 @@ }; }; -},{"../core":58,"async":16,"path":18,"resource-loader":33}],146:[function(require,module,exports){ +},{"../core":58,"async":1,"path":3,"resource-loader":33}],146:[function(require,module,exports){ var core = require('../core'); module.exports = function () @@ -28697,7 +28838,7 @@ TRIANGLES: 1 }; -},{"../core":58,"./webgl/MeshShader":151,"pixi-gl-core":1}],148:[function(require,module,exports){ +},{"../core":58,"./webgl/MeshShader":151,"pixi-gl-core":14}],148:[function(require,module,exports){ var Mesh = require('./Mesh'); /** @@ -29671,7 +29812,7 @@ this.staticBuffer.destroy(); }; -},{"../../core/utils/createIndicesForQuads":108,"pixi-gl-core":1}],155:[function(require,module,exports){ +},{"../../core/utils/createIndicesForQuads":108,"pixi-gl-core":14}],155:[function(require,module,exports){ var core = require('../../core'), ParticleShader = require('./ParticleShader'), ParticleBuffer = require('./ParticleBuffer'); @@ -30195,7 +30336,7 @@ Object.assign = require('object-assign'); } -},{"object-assign":28}],159:[function(require,module,exports){ +},{"object-assign":13}],159:[function(require,module,exports){ require('./Object.assign'); require('./requestAnimationFrame'); require('./Math.sign'); diff --git a/bin/pixi.js b/bin/pixi.js index ff131c0..f6c54ef 100644 --- a/bin/pixi.js +++ b/bin/pixi.js @@ -1,1511 +1,4 @@ (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.PIXI = 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= 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, drawType); -} - -/** - * Destroys the buffer - * - */ -Buffer.prototype.destroy = function(){ - this.gl.deleteBuffer(this.buffer); -} - -module.exports = Buffer; - -},{}],3:[function(require,module,exports){ - -var Texture = require('./GLTexture'); - -/** - * Helper class to create a webGL Framebuffer - * - * @class - * @memberof pixi.gl - * @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 {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 {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 - * @mat maybe you can come up with a better explaination - */ -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); -} - -/** - * Binds the frame buffer to the WebGL context - */ -Framebuffer.prototype.bind = function() -{ - var gl = this.gl; - - if(this.texture) - { - this.texture.unbind(); - } - - 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 - * @mat can you confirm ? :) - * @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.unbind(); - - return fbo; -} - -/** - * Creates a frame buffer with a texture containing the given data - * @mat not sure what the difference is with the method above ? - * @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":5}],4:[function(require,module,exports){ - -var compileProgram = require('./shader/compileProgram'), - extractAttributes = require('./shader/extractAttributes'), - extractUniforms = require('./shader/extractUniforms'), - generateUniformAccessObject = require('./shader/generateUniformAccessObject'); - -/** - * Helper class to create a webGL Shader - * - * @class - * @memberof pixi.gl - * @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. - */ -var Shader = function(gl, vertexSrc, fragmentSrc) -{ - /** - * The current WebGL rendering context - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; - - /** - * The shader program - * - * @member {WebGLProgram} - */ - // First compile the program.. - this.program = compileProgram(gl, vertexSrc, fragmentSrc); - - /** - * 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); - - var 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, uniformData ); -} -/** - * Uses this shader - */ -Shader.prototype.bind = function() -{ - this.gl.useProgram(this.program); -} - -/** - * Destroys this shader - * TODO - */ -Shader.prototype.destroy = function() -{ - var gl = this.gl; -} - -module.exports = Shader; - -},{"./shader/compileProgram":9,"./shader/extractAttributes":11,"./shader/extractUniforms":12,"./shader/generateUniformAccessObject":13}],5:[function(require,module,exports){ - -/** - * Helper class to create a WebGL Texture - * - * @class - * @memberof pixi.gl - * @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 || 0; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || 0; - - /** - * 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; - - // if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect. - this.width = source.videoWidth || source.width; - this.height = source.videoHeight || source.height; - - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source); -} - -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; - - this.width = width || this.width; - this.height = height || this.height; - - 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 = gl.UNSIGNED_BYTE; - } - - - - // what type of data? - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, this.type, data || null); - -} - -/** - * Binds the texture - * @param location {@mat} - */ -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); -} - -/** - * @mat - * @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); - } -} - -/** - * @mat - * @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); -} - -/** - * @mat - */ -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; - -},{}],6:[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.gl - * @param gl {WebGLRenderingContext} The current WebGL rendering context - */ -function VertexArrayObject(gl, state) -{ - - 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 ? @mat - * - * @member {Array} - */ - this.attributes = []; - - /** - * @mat - * - * @member {Array} - */ - this.indexBuffer = null; - - /** - * A boolean flag - * - * @member {Boolean} - */ - this.dirty = false; -} - -VertexArrayObject.prototype.constructor = VertexArrayObject; -module.exports = VertexArrayObject; - - -/** - * Binds the buffer - */ -VertexArrayObject.prototype.bind = function() -{ - if(this.nativeVao) - { - this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao); - - if(this.dirty) - { - this.dirty = false; - this.activate(); - } - } - 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; - } - - //attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start); - 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); - - this.indexBuffer.bind(); - - return this; -} - -/** - * - * @param buffer {WebGLBuffer} - * @param attribute {[type]} - * @param type {[type]} - * @param normalized {[type]} - * @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 {WebGLBuffer} - * @param options {Object} - */ -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; -} - -/** - * @mat - * @param type {Number} - * @param size {Number} - * @param start {Number} - */ -VertexArrayObject.prototype.draw = function(type, size, start) -{ - var gl = this.gl; - gl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0); - - return this; -} - -},{"./setVertexAttribArrays":8}],7:[function(require,module,exports){ - -/** - * Helper class to create a webGL Context - * - * @class - * @memberof pixi.gl - * @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; - -},{}],8:[function(require,module,exports){ -var GL_MAP = {}; - -/** - * @mat - * @param gl {WebGLRenderingContext} The current WebGL context - * @param attribs {[type]} - */ -var setVertexAttribArrays = function (gl, attribs, state) -{ - - if(state) - { - - var i, - tempAttribState = state.tempAttribState, - attribState = state.attribState; - - for (i = 0; i < tempAttribState.length; i++) - { - tempAttribState[i] = false; - } - - // set the new attribs - for (i in attribs) - { - 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 (var i = 0; i < attribs.length; i++) - { - var attrib = attribs[i]; - gl.enableVertexAttribArray(attrib.attribute.location); - } - } -}; - -module.exports = setVertexAttribArrays; - -},{}],9:[function(require,module,exports){ - -/** - * - * @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. - * @return {WebGLProgram} the shader program - */ -compileProgram = function(gl, vertexSrc, fragmentSrc) -{ - 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); - 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; -} - -/** - * - * @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; - -},{}],10:[function(require,module,exports){ - - -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; - -},{}],11:[function(require,module,exports){ - -var mapType = require('./mapType'); -var mapSize = require('./mapSize'); - -/** - * Extracts the attributes - * @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:function(type, normalized, stride, start){ - - // console.log(this.location) - gl.vertexAttribPointer(this.location,this.size, type || gl.FLOAT, normalized || false, stride || 0, start || 0); - - } - } - }; - - return attributes; -} - -module.exports = extractAttributes; - -},{"./mapSize":14,"./mapType":15}],12:[function(require,module,exports){ -var mapType = require('./mapType'); -var defaultValue = require('./defaultValue'); - -/** - * Extracts the uniforms - * @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":10,"./mapType":15}],13:[function(require,module,exports){ -/** - * Extracts the attributes - * @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) -{ - var template = getterTemplate.replace('%%', name); - return new Function(template); -} - -var generateSetter = function(name, uniform) -{ - var template = setterTemplate.replace(/%%/g, name); - var setTemplate - - if(uniform.size === 1) - { - setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type]; - } - else - { - setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type]; - } - - if(setTemplate) - { - template += "\nthis.gl." + setTemplate + ";"; - } - - return new Function('value', template); -} - -var getUniformGroup = function(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 -} - -var getterTemplate = [ - 'return this.data.%%.value;', -].join('\n'); - -var setterTemplate = [ - 'this.data.%%.value = value;', - 'var location = this.data.%%.location;' -].join('\n'); - - -var GLSL_TO_SINGLE_SETTERS = { - - 'float': 'uniform1f(location, value)', - - 'vec2': 'uniform2f(location, value[0], value[1])', - 'vec3': 'uniform3f(location, value[0], value[1], value[2])', - 'vec4': 'uniform4f(location, value[0], value[1], value[2], value[3])', - - 'int': 'uniform1i(location, value)', - 'ivec2': 'uniform2i(location, value[0], value[1])', - 'ivec3': 'uniform3i(location, value[0], value[1], value[2])', - 'ivec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', - - 'bool': 'uniform1i(location, value)', - 'bvec2': 'uniform2i(location, value[0], value[1])', - 'bvec3': 'uniform3i(location, value[0], value[1], value[2])', - 'bvec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', - - 'mat2': 'uniformMatrix2fv(location, false, value)', - 'mat3': 'uniformMatrix3fv(location, false, value)', - 'mat4': 'uniformMatrix4fv(location, false, value)', - - 'sampler2D':'uniform1i(location, value)' -} - -var GLSL_TO_ARRAY_SETTERS = { - - 'float': 'uniform1fv(location, value)', - - 'vec2': 'uniform2fv(location, value)', - 'vec3': 'uniform3fv(location, value)', - 'vec4': 'uniform4fv(location, value)', - - 'int': 'uniform1iv(location, value)', - 'ivec2': 'uniform2iv(location, value)', - 'ivec3': 'uniform3iv(location, value)', - 'ivec4': 'uniform4iv(location, value)', - - 'bool': 'uniform1iv(location, value)', - 'bvec2': 'uniform2iv(location, value)', - 'bvec3': 'uniform3iv(location, value)', - 'bvec4': 'uniform4iv(location, value)', - - 'sampler2D':'uniform1iv(location, value)' -} - -module.exports = generateUniformAccessObject; - -},{}],14:[function(require,module,exports){ - - -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 mapSize = 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 = mapSize; - -},{}],16:[function(require,module,exports){ (function (process,global){ /*! * async @@ -2774,7 +1267,7 @@ }()); }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"_process":19}],17:[function(require,module,exports){ +},{"_process":4}],2:[function(require,module,exports){ /** * Bit twiddling hacks for JavaScript. * @@ -2980,7 +1473,7 @@ } -},{}],18:[function(require,module,exports){ +},{}],3:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // @@ -3208,7 +1701,7 @@ ; }).call(this,require('_process')) -},{"_process":19}],19:[function(require,module,exports){ +},{"_process":4}],4:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -3301,7 +1794,7 @@ }; process.umask = function() { return 0; }; -},{}],20:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ (function (global){ /*! https://mths.be/punycode v1.4.0 by @mathias */ ;(function(root) { @@ -3838,7 +2331,7 @@ }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],21:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -3924,7 +2417,7 @@ return Object.prototype.toString.call(xs) === '[object Array]'; }; -},{}],22:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -4011,13 +2504,13 @@ return res; }; -},{}],23:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); -},{"./decode":21,"./encode":22}],24:[function(require,module,exports){ +},{"./decode":6,"./encode":7}],9:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -4726,7 +3219,7 @@ return arg == null; } -},{"punycode":20,"querystring":23}],25:[function(require,module,exports){ +},{"punycode":5,"querystring":8}],10:[function(require,module,exports){ 'use strict'; module.exports = earcut; @@ -4771,22 +3264,19 @@ // create a circular doubly linked list from polygon points in the specified winding order function linkedList(data, start, end, dim, clockwise) { - var sum = 0, - i, j, last; + var i, last; - // calculate original winding order of a polygon ring - for (i = start, j = end - dim; i < end; i += dim) { - sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); - j = i; - } - - // link points into circular doubly-linked list in the specified winding order - if (clockwise === (sum > 0)) { + if (clockwise === (signedArea(data, start, end, dim) > 0)) { for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); } else { for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); } + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } + return last; } @@ -4934,8 +3424,7 @@ var a = p.prev, b = p.next.next; - // a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2]) - if (intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { triangles.push(a.i / dim); triangles.push(p.i / dim); @@ -5031,6 +3520,10 @@ var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); if (x <= hx && x > qx) { qx = x; + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } m = p.x < p.next.x ? p : p.next; } } @@ -5039,21 +3532,23 @@ if (!m) return null; - if (hole.x === m.x) return m.prev; // hole touches outer segment; pick lower endpoint + if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint // look for points inside the triangle of hole point, segment intersection and endpoint; // if there are no points found, we have a valid connection; // otherwise choose the point of the minimum angle with the ray as connection point var stop = m, + mx = m.x, + my = m.y, tanMin = Infinity, tan; p = m.next; while (p !== stop) { - if (hx >= p.x && p.x >= m.x && - pointInTriangle(hy < m.y ? hx : qx, hy, m.x, m.y, hy < m.y ? qx : hx, hy, p.x, p.y)) { + if (hx >= p.x && p.x >= mx && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { tan = Math.abs(hy - p.y) / (hx - p.x); // tangential @@ -5187,7 +3682,7 @@ // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { - return equals(a, b) || a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); } @@ -5203,6 +3698,8 @@ // check if two segments intersect function intersects(p1, q1, p2, q2) { + if ((equals(p1, q1) && equals(p2, q2)) || + (equals(p1, q2) && equals(p2, q1))) return true; return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; } @@ -5312,9 +3809,67 @@ this.steiner = false; } -},{}],26:[function(require,module,exports){ +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } + + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } + + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; + +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} + +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; +}; + +},{}],11:[function(require,module,exports){ 'use strict'; +var has = Object.prototype.hasOwnProperty; + // // We store our EE objects in a plain object whose properties are event names. // If `Object.create(null)` is not supported we prefix the event names with a @@ -5330,7 +3885,7 @@ * * @param {Function} fn Event handler to be called. * @param {Mixed} context Context for function execution. - * @param {Boolean} once Only emit once + * @param {Boolean} [once=false] Only emit once * @api private */ function EE(fn, context, once) { @@ -5349,7 +3904,7 @@ function EventEmitter() { /* Nothing to set */ } /** - * Holds the assigned EventEmitters by name. + * Hold the assigned EventEmitters by name. * * @type {Object} * @private @@ -5357,6 +3912,31 @@ EventEmitter.prototype._events = undefined; /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @api public + */ +EventEmitter.prototype.eventNames = function eventNames() { + var events = this._events + , names = [] + , name; + + if (!events) return names; + + for (name in events) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; +}; + +/** * Return a list of assigned event listeners. * * @param {String} event The events that should be listed. @@ -5441,8 +4021,8 @@ * Register a new EventListener for the given event. * * @param {String} event Name of the event. - * @param {Functon} fn Callback function. - * @param {Mixed} context The context of the function. + * @param {Function} fn Callback function. + * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.on = function on(event, fn, context) { @@ -5466,7 +4046,7 @@ * * @param {String} event Name of the event. * @param {Function} fn Callback function. - * @param {Mixed} context The context of the function. + * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.once = function once(event, fn, context) { @@ -5576,9 +4156,9 @@ module.exports = EventEmitter; } -},{}],27:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ /** - * isMobile.js v0.3.9 + * isMobile.js v0.4.0 * * A simple library to detect Apple phones and tablets, * Android phones and tablets, other mobile devices (like blackberry, mini-opera and windows phone), @@ -5643,6 +4223,14 @@ ua = tmp[0]; } + // Twitter mobile app's integrated browser on iPad adds a "Twitter for + // iPhone" string. Same probable happens on other tablet platforms. + // This will confuse detection so strip it out if it exists. + tmp = ua.split('Twitter'); + if (typeof tmp[1] !== 'undefined') { + ua = tmp[0]; + } + this.apple = { phone: match(apple_phone, ua), ipod: match(apple_ipod, ua), @@ -5707,7 +4295,7 @@ })(this); -},{}],28:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /* eslint-disable no-unused-vars */ 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty; @@ -5748,6 +4336,1534 @@ return to; }; +},{}],14:[function(require,module,exports){ + + +module.exports = { + + createContext: require('./lib/createContext'), + setVertexAttribArrays: require('./lib/setVertexAttribArrays'), + + GLBuffer: require('./lib/GLBuffer'), + GLFramebuffer: require('./lib/GLFramebuffer'), + GLShader: require('./lib/GLShader'), + GLTexture: require('./lib/GLTexture'), + + VertexArrayObject: require('./lib/VertexArrayObject') + +}; +},{"./lib/GLBuffer":15,"./lib/GLFramebuffer":16,"./lib/GLShader":17,"./lib/GLTexture":18,"./lib/VertexArrayObject":19,"./lib/createContext":20,"./lib/setVertexAttribArrays":21}],15:[function(require,module,exports){ +var EMPTY_ARRAY_BUFFER = new ArrayBuffer(0); + +/** + * Helper class to create a webGL buffer + * + * @class + * @memberof pixi.gl + * @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); + } +}; + +/** + * 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, drawType); +}; + +/** + * Destroys the buffer + * + */ +Buffer.prototype.destroy = function(){ + this.gl.deleteBuffer(this.buffer); +}; + +module.exports = Buffer; + +},{}],16:[function(require,module,exports){ + +var Texture = require('./GLTexture'); + +/** + * Helper class to create a webGL Framebuffer + * + * @class + * @memberof pixi.gl + * @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 {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 {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 + * @mat maybe you can come up with a better explaination + */ +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); +}; + +/** + * Binds the frame buffer to the WebGL context + */ +Framebuffer.prototype.bind = function() +{ + var gl = this.gl; + + if(this.texture) + { + this.texture.unbind(); + } + + 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 + * @mat can you confirm ? :) + * @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.unbind(); + + return fbo; +}; + +/** + * Creates a frame buffer with a texture containing the given data + * @mat not sure what the difference is with the method above ? + * @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":18}],17:[function(require,module,exports){ + +var compileProgram = require('./shader/compileProgram'), + extractAttributes = require('./shader/extractAttributes'), + extractUniforms = require('./shader/extractUniforms'), + generateUniformAccessObject = require('./shader/generateUniformAccessObject'); + +/** + * Helper class to create a webGL Shader + * + * @class + * @memberof pixi.gl + * @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. + */ +var Shader = function(gl, vertexSrc, fragmentSrc) +{ + /** + * The current WebGL rendering context + * + * @member {WebGLRenderingContext} + */ + this.gl = gl; + + /** + * The shader program + * + * @member {WebGLProgram} + */ + // First compile the program.. + this.program = compileProgram(gl, vertexSrc, fragmentSrc); + + + /** + * 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); + + var 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, uniformData ); +}; +/** + * Uses this shader + */ +Shader.prototype.bind = function() +{ + this.gl.useProgram(this.program); +}; + +/** + * Destroys this shader + * TODO + */ +Shader.prototype.destroy = function() +{ + var gl = this.gl; +}; + +module.exports = Shader; + +},{"./shader/compileProgram":22,"./shader/extractAttributes":24,"./shader/extractUniforms":25,"./shader/generateUniformAccessObject":26}],18:[function(require,module,exports){ + +/** + * Helper class to create a WebGL Texture + * + * @class + * @memberof pixi.gl + * @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 || 0; + /** + * The height of texture + * + * @member {Number} + */ + this.height = height || 0; + + /** + * 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; + + // if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect. + this.width = source.videoWidth || source.width; + this.height = source.videoHeight || source.height; + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source); +}; + +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; + + this.width = width || this.width; + this.height = height || this.height; + + 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 = gl.UNSIGNED_BYTE; + } + + + + // what type of data? + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha); + gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, this.type, data || null); + +}; + +/** + * Binds the texture + * @param location {@mat} + */ +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); +}; + +/** + * @mat + * @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); + } +}; + +/** + * @mat + * @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); +}; + +/** + * @mat + */ +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; + +},{}],19:[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.gl + * @param gl {WebGLRenderingContext} The current WebGL rendering context + */ +function VertexArrayObject(gl, state) +{ + + 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 ? @mat + * + * @member {Array} + */ + this.attributes = []; + + /** + * @mat + * + * @member {Array} + */ + this.indexBuffer = null; + + /** + * A boolean flag + * + * @member {Boolean} + */ + this.dirty = false; +} + +VertexArrayObject.prototype.constructor = VertexArrayObject; +module.exports = VertexArrayObject; + + +/** + * Binds the buffer + */ +VertexArrayObject.prototype.bind = function() +{ + if(this.nativeVao) + { + this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao); + + if(this.dirty) + { + this.dirty = false; + this.activate(); + } + } + 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; + } + + //attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start); + 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); + + this.indexBuffer.bind(); + + return this; +}; + +/** + * + * @param buffer {WebGLBuffer} + * @param attribute {[type]} + * @param type {[type]} + * @param normalized {[type]} + * @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 {WebGLBuffer} + * @param options {Object} + */ +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; +}; + +/** + * @mat + * @param type {Number} + * @param size {Number} + * @param start {Number} + */ +VertexArrayObject.prototype.draw = function(type, size, start) +{ + var gl = this.gl; + gl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0); + + 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; +}; + +},{"./setVertexAttribArrays":21}],20:[function(require,module,exports){ + +/** + * Helper class to create a webGL Context + * + * @class + * @memberof pixi.gl + * @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; + +},{}],21:[function(require,module,exports){ +var GL_MAP = {}; + +/** + * @mat + * @param gl {WebGLRenderingContext} The current WebGL context + * @param attribs {[type]} + */ +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 in attribs) + { + 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; + +},{}],22:[function(require,module,exports){ + +/** + * + * @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. + * @return {WebGLProgram} the shader program + */ +var compileProgram = function(gl, vertexSrc, fragmentSrc) +{ + 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); + 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; +}; + +/** + * + * @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; + +},{}],23:[function(require,module,exports){ + + +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; + +},{}],24:[function(require,module,exports){ + +var mapType = require('./mapType'); +var mapSize = require('./mapSize'); + +/** + * Extracts the attributes + * @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":27,"./mapType":28}],25:[function(require,module,exports){ +var mapType = require('./mapType'); +var defaultValue = require('./defaultValue'); + +/** + * Extracts the uniforms + * @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":23,"./mapType":28}],26:[function(require,module,exports){ +/** + * Extracts the attributes + * @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) +{ + var template = getterTemplate.replace('%%', name); + return new Function(template); // jshint ignore:line +}; + +var generateSetter = function(name, uniform) +{ + var template = setterTemplate.replace(/%%/g, name); + var setTemplate; + + if(uniform.size === 1) + { + setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type]; + } + else + { + setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type]; + } + + if(setTemplate) + { + template += "\nthis.gl." + setTemplate + ";"; + } + + return new Function('value', template); // jshint ignore:line +}; + +var getUniformGroup = function(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; +}; + +var getterTemplate = [ + 'return this.data.%%.value;', +].join('\n'); + +var setterTemplate = [ + 'this.data.%%.value = value;', + 'var location = this.data.%%.location;' +].join('\n'); + + +var GLSL_TO_SINGLE_SETTERS = { + + 'float': 'uniform1f(location, value)', + + 'vec2': 'uniform2f(location, value[0], value[1])', + 'vec3': 'uniform3f(location, value[0], value[1], value[2])', + 'vec4': 'uniform4f(location, value[0], value[1], value[2], value[3])', + + 'int': 'uniform1i(location, value)', + 'ivec2': 'uniform2i(location, value[0], value[1])', + 'ivec3': 'uniform3i(location, value[0], value[1], value[2])', + 'ivec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', + + 'bool': 'uniform1i(location, value)', + 'bvec2': 'uniform2i(location, value[0], value[1])', + 'bvec3': 'uniform3i(location, value[0], value[1], value[2])', + 'bvec4': 'uniform4i(location, value[0], value[1], value[2], value[3])', + + 'mat2': 'uniformMatrix2fv(location, false, value)', + 'mat3': 'uniformMatrix3fv(location, false, value)', + 'mat4': 'uniformMatrix4fv(location, false, value)', + + 'sampler2D':'uniform1i(location, value)' +}; + +var GLSL_TO_ARRAY_SETTERS = { + + 'float': 'uniform1fv(location, value)', + + 'vec2': 'uniform2fv(location, value)', + 'vec3': 'uniform3fv(location, value)', + 'vec4': 'uniform4fv(location, value)', + + 'int': 'uniform1iv(location, value)', + 'ivec2': 'uniform2iv(location, value)', + 'ivec3': 'uniform3iv(location, value)', + 'ivec4': 'uniform4iv(location, value)', + + 'bool': 'uniform1iv(location, value)', + 'bvec2': 'uniform2iv(location, value)', + 'bvec3': 'uniform3iv(location, value)', + 'bvec4': 'uniform4iv(location, value)', + + 'sampler2D':'uniform1iv(location, value)' +}; + +module.exports = generateUniformAccessObject; + +},{}],27:[function(require,module,exports){ + + +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; + +},{}],28:[function(require,module,exports){ + + +var mapSize = 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 = mapSize; + },{}],29:[function(require,module,exports){ (function (process){ /*! @@ -6875,7 +6991,7 @@ }()); }).call(this,require('_process')) -},{"_process":19}],30:[function(require,module,exports){ +},{"_process":4}],30:[function(require,module,exports){ var async = require('async'), urlParser = require('url'), Resource = require('./Resource'), @@ -7333,7 +7449,7 @@ Loader.XHR_READY_STATE = Resource.XHR_READY_STATE; Loader.XHR_RESPONSE_TYPE = Resource.XHR_RESPONSE_TYPE; -},{"./Resource":31,"async":29,"eventemitter3":26,"url":24}],31:[function(require,module,exports){ +},{"./Resource":31,"async":29,"eventemitter3":11,"url":9}],31:[function(require,module,exports){ var EventEmitter = require('eventemitter3'), _url = require('url'), // tests is CORS is supported in XHR, if not we need to use XDR @@ -8135,7 +8251,7 @@ map[extname] = val; } -},{"eventemitter3":26,"url":24}],32:[function(require,module,exports){ +},{"eventemitter3":11,"url":9}],32:[function(require,module,exports){ module.exports = { // private property @@ -8827,7 +8943,7 @@ Shader.prototype.constructor = Shader; module.exports = Shader; -},{"./const":40,"pixi-gl-core":1}],40:[function(require,module,exports){ +},{"./const":40,"pixi-gl-core":14}],40:[function(require,module,exports){ /** * Constant values used in pixi @@ -10281,7 +10397,7 @@ this.filterArea = null; }; -},{"../math":62,"./Transform":44,"eventemitter3":26}],43:[function(require,module,exports){ +},{"../math":62,"./Transform":44,"eventemitter3":11}],43:[function(require,module,exports){ /** * An observable point is a point that triggers a callback when the point's position is changed. * @@ -12493,7 +12609,7 @@ this.glIndices = null; }; -},{"pixi-gl-core":1}],52:[function(require,module,exports){ +},{"pixi-gl-core":14}],52:[function(require,module,exports){ var Shader = require('../../../Shader'); /** @@ -12931,7 +13047,7 @@ module.exports = buildPoly; -},{"../../../utils":110,"./buildLine":54,"earcut":25}],56:[function(require,module,exports){ +},{"../../../utils":110,"./buildLine":54,"earcut":10}],56:[function(require,module,exports){ var buildLine = require('./buildLine'), utils = require('../../../utils'); @@ -13133,7 +13249,7 @@ module.exports = buildRoundedRectangle; -},{"../../../utils":110,"./buildLine":54,"earcut":25}],58:[function(require,module,exports){ +},{"../../../utils":110,"./buildLine":54,"earcut":10}],58:[function(require,module,exports){ /** * @file Main export of the PIXI core library * @author Mat Groves @@ -13230,7 +13346,7 @@ } }); -},{"./Shader":39,"./const":40,"./display/Container":41,"./display/DisplayObject":42,"./display/Transform":44,"./display/TransformStatic":45,"./graphics/Graphics":46,"./graphics/GraphicsData":47,"./graphics/canvas/CanvasGraphicsRenderer":48,"./graphics/webgl/GraphicsRenderer":50,"./math":62,"./renderers/canvas/CanvasRenderer":69,"./renderers/canvas/utils/CanvasRenderTarget":71,"./renderers/webgl/WebGLRenderer":76,"./renderers/webgl/filters/Filter":78,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":81,"./renderers/webgl/managers/WebGLManager":85,"./renderers/webgl/utils/ObjectRenderer":86,"./renderers/webgl/utils/Quad":87,"./renderers/webgl/utils/RenderTarget":88,"./sprites/Sprite":92,"./sprites/canvas/CanvasSpriteRenderer":93,"./sprites/canvas/CanvasTinter":94,"./sprites/webgl/SpriteRenderer":96,"./text/Text":98,"./text/TextStyle":99,"./textures/BaseRenderTexture":100,"./textures/BaseTexture":101,"./textures/RenderTexture":102,"./textures/Texture":103,"./textures/TextureUvs":104,"./textures/VideoBaseTexture":105,"./ticker":107,"./utils":110,"pixi-gl-core":1}],59:[function(require,module,exports){ +},{"./Shader":39,"./const":40,"./display/Container":41,"./display/DisplayObject":42,"./display/Transform":44,"./display/TransformStatic":45,"./graphics/Graphics":46,"./graphics/GraphicsData":47,"./graphics/canvas/CanvasGraphicsRenderer":48,"./graphics/webgl/GraphicsRenderer":50,"./math":62,"./renderers/canvas/CanvasRenderer":69,"./renderers/canvas/utils/CanvasRenderTarget":71,"./renderers/webgl/WebGLRenderer":76,"./renderers/webgl/filters/Filter":78,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":81,"./renderers/webgl/managers/WebGLManager":85,"./renderers/webgl/utils/ObjectRenderer":86,"./renderers/webgl/utils/Quad":87,"./renderers/webgl/utils/RenderTarget":88,"./sprites/Sprite":92,"./sprites/canvas/CanvasSpriteRenderer":93,"./sprites/canvas/CanvasTinter":94,"./sprites/webgl/SpriteRenderer":96,"./text/Text":98,"./text/TextStyle":99,"./textures/BaseRenderTexture":100,"./textures/BaseTexture":101,"./textures/RenderTexture":102,"./textures/Texture":103,"./textures/TextureUvs":104,"./textures/VideoBaseTexture":105,"./ticker":107,"./utils":110,"pixi-gl-core":14}],59:[function(require,module,exports){ // Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16 var ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1]; @@ -14780,7 +14896,7 @@ this._lastObjectRendered = null; }; -},{"../const":40,"../display/Container":41,"../math":62,"../textures/RenderTexture":102,"../utils":110,"eventemitter3":26}],69:[function(require,module,exports){ +},{"../const":40,"../display/Container":41,"../math":62,"../textures/RenderTexture":102,"../utils":110,"eventemitter3":11}],69:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), CanvasMaskManager = require('./utils/CanvasMaskManager'), CanvasRenderTarget = require('./utils/CanvasRenderTarget'), @@ -15725,7 +15841,7 @@ module.exports = TextureManager; -},{"../../const":40,"../../utils":110,"./utils/RenderTarget":88,"pixi-gl-core":1}],76:[function(require,module,exports){ +},{"../../const":40,"../../utils":110,"./utils/RenderTarget":88,"pixi-gl-core":14}],76:[function(require,module,exports){ var SystemRenderer = require('../SystemRenderer'), MaskManager = require('./managers/MaskManager'), StencilManager = require('./managers/StencilManager'), @@ -16280,7 +16396,7 @@ // this = null; }; -},{"../../const":40,"../../utils":110,"../SystemRenderer":68,"./TextureGarbageCollector":74,"./TextureManager":75,"./WebGLState":77,"./managers/FilterManager":82,"./managers/MaskManager":83,"./managers/StencilManager":84,"./utils/ObjectRenderer":86,"./utils/RenderTarget":88,"./utils/mapWebGLDrawModesToPixi":91,"pixi-gl-core":1}],77:[function(require,module,exports){ +},{"../../const":40,"../../utils":110,"../SystemRenderer":68,"./TextureGarbageCollector":74,"./TextureManager":75,"./WebGLState":77,"./managers/FilterManager":82,"./managers/MaskManager":83,"./managers/StencilManager":84,"./utils/ObjectRenderer":86,"./utils/RenderTarget":88,"./utils/mapWebGLDrawModesToPixi":91,"pixi-gl-core":14}],77:[function(require,module,exports){ var mapWebGLBlendModesToPixi = require('./utils/mapWebGLBlendModesToPixi'); /** @@ -16746,7 +16862,7 @@ module.exports = extractUniformsFromSrc; -},{"pixi-gl-core/lib/shader/defaultValue":10,"pixi-gl-core/lib/shader/mapSize":14}],80:[function(require,module,exports){ +},{"pixi-gl-core/lib/shader/defaultValue":23,"pixi-gl-core/lib/shader/mapSize":27}],80:[function(require,module,exports){ var math = require('../../../math'); /* @@ -17207,8 +17323,12 @@ FilterManager.prototype.destroy = function() { + this.shaderCache = []; + FilterManager.emptyPool(); }; + + //TODO move to a seperate class could be on renderer? //also - could cause issue with multiple contexts? FilterManager.getPotRenderTarget = function(gl, minWidth, minHeight, resolution) @@ -17235,6 +17355,23 @@ return renderTarget; }; +FilterManager.emptyPool = function() +{ + for (var i in FilterManager.pool) + { + var textures = FilterManager.pool[i]; + if(textures) + { + for (var j = 0; j < textures.length; j++) + { + textures[j].destroy(true); + } + } + } + + FilterManager.pool = {}; +}; + FilterManager.freePotRenderTarget = function(renderTarget) { var minWidth = renderTarget.size.width * renderTarget.resolution; @@ -17244,7 +17381,7 @@ FilterManager.pool[key].push(renderTarget); }; -},{"../../../Shader":39,"../../../math":62,"../filters/filterTransforms":80,"../utils/Quad":87,"../utils/RenderTarget":88,"./WebGLManager":85,"bit-twiddle":17}],83:[function(require,module,exports){ +},{"../../../Shader":39,"../../../math":62,"../filters/filterTransforms":80,"../utils/Quad":87,"../utils/RenderTarget":88,"./WebGLManager":85,"bit-twiddle":2}],83:[function(require,module,exports){ var WebGLManager = require('./WebGLManager'), AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter'); @@ -17805,7 +17942,7 @@ module.exports = Quad; -},{"../../../utils/createIndicesForQuads":108,"pixi-gl-core":1}],88:[function(require,module,exports){ +},{"../../../utils/createIndicesForQuads":108,"pixi-gl-core":14}],88:[function(require,module,exports){ var math = require('../../../math'), CONST = require('../../../const'), GLFramebuffer = require('pixi-gl-core').GLFramebuffer; @@ -18131,7 +18268,7 @@ this.texture = null; }; -},{"../../../const":40,"../../../math":62,"pixi-gl-core":1}],89:[function(require,module,exports){ +},{"../../../const":40,"../../../math":62,"pixi-gl-core":14}],89:[function(require,module,exports){ var glCore = require('pixi-gl-core'); var fragTemplate = [ @@ -18212,7 +18349,7 @@ module.exports = checkMaxIfStatmentsInShader; -},{"pixi-gl-core":1}],90:[function(require,module,exports){ +},{"pixi-gl-core":14}],90:[function(require,module,exports){ var CONST = require('../../../const'); /** @@ -19299,14 +19436,18 @@ this.shaders = new Array(this.MAX_TEXTURES); this.shaders[0] = generateMultiTextureShader(gl, 1); + this.shaders[1] = generateMultiTextureShader(gl, 2); // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); - var shader = this.shaders[0]; + var shader = this.shaders[1]; for (var i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + + console.log(shader); + // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) @@ -19485,7 +19626,7 @@ if(this.vaoMax <= this.vertexCount) { this.vaoMax++; - shader = this.shaders[0]; + shader = this.shaders[1]; this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() @@ -19581,7 +19722,7 @@ }; -},{"../../const":40,"../../renderers/webgl/WebGLRenderer":76,"../../renderers/webgl/utils/ObjectRenderer":86,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":89,"../../utils/createIndicesForQuads":108,"./BatchBuffer":95,"./generateMultiTextureShader":97,"bit-twiddle":17,"pixi-gl-core":1}],97:[function(require,module,exports){ +},{"../../const":40,"../../renderers/webgl/WebGLRenderer":76,"../../renderers/webgl/utils/ObjectRenderer":86,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":89,"../../utils/createIndicesForQuads":108,"./BatchBuffer":95,"./generateMultiTextureShader":97,"bit-twiddle":2,"pixi-gl-core":14}],97:[function(require,module,exports){ var Shader = require('../../Shader'); @@ -20690,7 +20831,7 @@ } } -},{"../const":40,"../utils":110,"eventemitter3":26}],100:[function(require,module,exports){ +},{"../const":40,"../utils":110,"eventemitter3":11}],100:[function(require,module,exports){ var BaseTexture = require('./BaseTexture'), CONST = require('../const'); @@ -21275,7 +21416,7 @@ return baseTexture; }; -},{"../const":40,"../utils":110,"../utils/determineCrossOrigin":109,"bit-twiddle":17,"eventemitter3":26}],102:[function(require,module,exports){ +},{"../const":40,"../utils":110,"../utils/determineCrossOrigin":109,"bit-twiddle":2,"eventemitter3":11}],102:[function(require,module,exports){ var BaseRenderTexture = require('./BaseRenderTexture'), Texture = require('./Texture'); @@ -21898,7 +22039,7 @@ Texture.EMPTY.emit = function() {}; -},{"../math":62,"../utils":110,"./BaseTexture":101,"./TextureUvs":104,"./VideoBaseTexture":105,"eventemitter3":26}],104:[function(require,module,exports){ +},{"../math":62,"../utils":110,"./BaseTexture":101,"./TextureUvs":104,"./VideoBaseTexture":105,"eventemitter3":11}],104:[function(require,module,exports){ /** * A standard object to store the Uvs of a texture @@ -22573,7 +22714,7 @@ module.exports = Ticker; -},{"../const":40,"eventemitter3":26}],107:[function(require,module,exports){ +},{"../const":40,"eventemitter3":11}],107:[function(require,module,exports){ var Ticker = require('./Ticker'); /** @@ -22705,7 +22846,7 @@ module.exports = determineCrossOrigin; -},{"url":24}],110:[function(require,module,exports){ +},{"url":9}],110:[function(require,module,exports){ var CONST = require('../const'); /** @@ -22915,7 +23056,7 @@ BaseTextureCache: {} }; -},{"../const":40,"./pluginTarget":112,"eventemitter3":26}],111:[function(require,module,exports){ +},{"../const":40,"./pluginTarget":112,"eventemitter3":11}],111:[function(require,module,exports){ var Device = require('ismobilejs'); @@ -22936,7 +23077,7 @@ }; module.exports = maxRecommendedTextures; -},{"ismobilejs":27}],112:[function(require,module,exports){ +},{"ismobilejs":12}],112:[function(require,module,exports){ /** * Mixins functionality to make an object have "plugins". * @@ -27938,7 +28079,7 @@ }; }; -},{"../core":58,"../extras":123,"path":18,"resource-loader":33}],143:[function(require,module,exports){ +},{"../core":58,"../extras":123,"path":3,"resource-loader":33}],143:[function(require,module,exports){ /** * @file Main export of the PIXI loaders library * @author Mat Groves @@ -28138,7 +28279,7 @@ }; }; -},{"../core":58,"async":16,"path":18,"resource-loader":33}],146:[function(require,module,exports){ +},{"../core":58,"async":1,"path":3,"resource-loader":33}],146:[function(require,module,exports){ var core = require('../core'); module.exports = function () @@ -28697,7 +28838,7 @@ TRIANGLES: 1 }; -},{"../core":58,"./webgl/MeshShader":151,"pixi-gl-core":1}],148:[function(require,module,exports){ +},{"../core":58,"./webgl/MeshShader":151,"pixi-gl-core":14}],148:[function(require,module,exports){ var Mesh = require('./Mesh'); /** @@ -29671,7 +29812,7 @@ this.staticBuffer.destroy(); }; -},{"../../core/utils/createIndicesForQuads":108,"pixi-gl-core":1}],155:[function(require,module,exports){ +},{"../../core/utils/createIndicesForQuads":108,"pixi-gl-core":14}],155:[function(require,module,exports){ var core = require('../../core'), ParticleShader = require('./ParticleShader'), ParticleBuffer = require('./ParticleBuffer'); @@ -30195,7 +30336,7 @@ Object.assign = require('object-assign'); } -},{"object-assign":28}],159:[function(require,module,exports){ +},{"object-assign":13}],159:[function(require,module,exports){ require('./Object.assign'); require('./requestAnimationFrame'); require('./Math.sign'); diff --git a/bin/pixi.js.map b/bin/pixi.js.map index 7c3bf99..c7260fe 100644 --- a/bin/pixi.js.map +++ b/bin/pixi.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["pixi.js"],"sourcesContent":["(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.PIXI = 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= data.byteLength)\n\t{\n\t\tgl.bufferSubData(this.type, offset, data);\n\t}\n\telse\n\t{\n\t\tgl.bufferData(this.type, data, this.drawType);\n\t}\n\n\tthis.data = data;\n}\n/**\n * Binds the buffer\n *\n */\nBuffer.prototype.bind = function()\n{\n\tvar gl = this.gl;\n\tgl.bindBuffer(this.type, this.buffer);\n}\n\nBuffer.createVertexBuffer = function(gl, data, drawType)\n{\n\treturn new Buffer(gl, gl.ARRAY_BUFFER, data, drawType);\n}\n\nBuffer.createIndexBuffer = function(gl, data, drawType)\n{\n\treturn new Buffer(gl, gl.ELEMENT_ARRAY_BUFFER, data, drawType);\n}\n\nBuffer.create = function(gl, type, data, drawType)\n{\n\treturn new Buffer(gl, type, drawType);\n}\n\n/**\n * Destroys the buffer\n *\n */\nBuffer.prototype.destroy = function(){\n\tthis.gl.deleteBuffer(this.buffer);\n}\n\nmodule.exports = Buffer;\n\n},{}],3:[function(require,module,exports){\n\nvar Texture = require('./GLTexture');\n\n/**\n * Helper class to create a webGL Framebuffer\n *\n * @class\n * @memberof pixi.gl\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param width {Number} the width of the drawing area of the frame buffer\n * @param height {Number} the height of the drawing area of the frame buffer\n */\nvar Framebuffer = function(gl, width, height)\n{\n\t/**\n * The current WebGL rendering context\n *\n * @member {WebGLRenderingContext}\n */\n\tthis.gl = gl;\n\n\t/**\n * The frame buffer\n *\n * @member {WebGLFramebuffer}\n */\n\tthis.framebuffer = gl.createFramebuffer();\n\n\t/**\n * The stencil buffer\n *\n * @member {WebGLRenderbuffer}\n */\n\tthis.stencil = null;\n\n\t/**\n * The stencil buffer\n *\n * @member {GLTexture}\n */\n\tthis.texture = null;\n\n\t/**\n * The width of the drawing area of the buffer\n *\n * @member {Number}\n */\n\tthis.width = width || 100;\n\t/**\n * The height of the drawing area of the buffer\n *\n * @member {Number}\n */\n\tthis.height = height || 100;\n}\n\n/**\n * Adds a texture to the frame buffer\n * @param texture {GLTexture}\n */\nFramebuffer.prototype.enableTexture = function(texture)\n{\n\tvar gl = this.gl;\n\n\tthis.texture = texture || new Texture(gl);\n\n\tthis.texture.bind();\n\n\t//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n\n\tthis.bind();\n\n\tgl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);\n}\n\n/**\n * Initialises the stencil buffer\n * @mat maybe you can come up with a better explaination\n */\nFramebuffer.prototype.enableStencil = function()\n{\n\tif(this.stencil)return;\n\n\tvar gl = this.gl;\n\n\tthis.stencil = gl.createRenderbuffer();\n\n gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);\n\n // TODO.. this is depth AND stencil?\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencil);\n gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width , this.height );\n}\n\n/**\n * Erases the drawing area and fills it with a colour\n * @param r {Number} the red value of the clearing colour\n * @param g {Number} the green value of the clearing colour\n * @param b {Number} the blue value of the clearing colour\n * @param a {Number} the alpha value of the clearing colour\n */\nFramebuffer.prototype.clear = function( r, g, b, a )\n{\n\tthis.bind();\n\n\tvar gl = this.gl;\n\n gl.clearColor(r, g, b, a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n}\n\n/**\n * Binds the frame buffer to the WebGL context\n */\nFramebuffer.prototype.bind = function()\n{\n\tvar gl = this.gl;\n\n\tif(this.texture)\n\t{\n\t\tthis.texture.unbind();\n\t}\n\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer );\n}\n\n/**\n * Unbinds the frame buffer to the WebGL context\n */\nFramebuffer.prototype.unbind = function()\n{\n\tvar gl = this.gl;\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, null );\t\n}\n/**\n * Resizes the drawing area of the buffer to the given width and height\n * @param width {Number} the new width\n * @param height {Number} the new height\n */\nFramebuffer.prototype.resize = function(width, height)\n{\n\tvar gl = this.gl;\n\n\tthis.width = width;\n\tthis.height = height;\n\n\tif ( this.texture )\n {\n \tthis.texture.uploadData(null, width, height);\n\t}\n\n\tif ( this.stencil )\n {\n // update the stencil buffer width and height\n gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);\n gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);\n }\n}\n\n/**\n * Destroys this buffer\n */\nFramebuffer.prototype.destroy = function()\n{\n\tvar gl = this.gl;\n\n\t//TODO\n\tif(this.texture)\n\t{\n\t\tthis.texture.destroy();\n\t}\n\n\tgl.deleteFramebuffer(this.framebuffer);\n\n\tthis.gl = null;\n\n\tthis.stencil = null;\n\tthis.texture = null;\n}\n\n/**\n * Creates a frame buffer with a texture containing the given data\n * @mat can you confirm ? :)\n * @static\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param width {Number} the width of the drawing area of the frame buffer\n * @param height {Number} the height of the drawing area of the frame buffer\n * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data\n */\nFramebuffer.createRGBA = function(gl, width, height, data)\n{\n\tvar texture = Texture.fromData(gl, null, width, height);\n\ttexture.enableNearestScaling();\n texture.enableWrapClamp();\n\n //now create the framebuffer object and attach the texture to it.\n var fbo = new Framebuffer(gl, width, height);\n fbo.enableTexture(texture);\n\n fbo.unbind();\n\n return fbo;\n}\n\n/**\n * Creates a frame buffer with a texture containing the given data\n * @mat not sure what the difference is with the method above ?\n * @static\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param width {Number} the width of the drawing area of the frame buffer\n * @param height {Number} the height of the drawing area of the frame buffer\n * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data\n */\nFramebuffer.createFloat32 = function(gl, width, height, data)\n{\n\t// create a new texture..\n var texture = new Texture.fromData(gl, data, width, height);\n texture.enableNearestScaling();\n texture.enableWrapClamp();\n\n //now create the framebuffer object and attach the texture to it.\n var fbo = new Framebuffer(gl, width, height);\n fbo.enableTexture(texture)\n\n fbo.unbind();\n\n return fbo;\n}\n\nmodule.exports = Framebuffer;\n\n},{\"./GLTexture\":5}],4:[function(require,module,exports){\n\nvar compileProgram = require('./shader/compileProgram'),\n\textractAttributes = require('./shader/extractAttributes'),\n\textractUniforms = require('./shader/extractUniforms'),\n\tgenerateUniformAccessObject = require('./shader/generateUniformAccessObject');\n\n/**\n * Helper class to create a webGL Shader\n *\n * @class\n * @memberof pixi.gl\n * @param gl {WebGLRenderingContext}\n * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.\n * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.\n */\nvar Shader = function(gl, vertexSrc, fragmentSrc)\n{\n\t/**\n\t * The current WebGL rendering context\n\t *\n\t * @member {WebGLRenderingContext}\n\t */\n\tthis.gl = gl;\n\n\t/**\n\t * The shader program\n\t *\n\t * @member {WebGLProgram}\n\t */\n\t// First compile the program..\n\tthis.program = compileProgram(gl, vertexSrc, fragmentSrc);\n\n\t/**\n\t * The attributes of the shader as an object containing the following properties\n\t * {\n\t * \ttype,\n\t * \tsize,\n\t * \tlocation,\n\t * \tpointer\n\t * }\n\t * @member {Object}\n\t */\n\t// next extract the attributes\n\tthis.attributes = extractAttributes(gl, this.program);\n\n var uniformData = extractUniforms(gl, this.program);\n\n\t/**\n\t * The uniforms of the shader as an object containing the following properties\n\t * {\n\t * \tgl,\n\t * \tdata\n\t * }\n\t * @member {Object}\n\t */\n this.uniforms = generateUniformAccessObject( gl, uniformData );\n}\n/**\n * Uses this shader\n */\nShader.prototype.bind = function()\n{\n\tthis.gl.useProgram(this.program);\n}\n\n/**\n * Destroys this shader\n * TODO\n */\nShader.prototype.destroy = function()\n{\n\tvar gl = this.gl;\n}\n\nmodule.exports = Shader;\n\n},{\"./shader/compileProgram\":9,\"./shader/extractAttributes\":11,\"./shader/extractUniforms\":12,\"./shader/generateUniformAccessObject\":13}],5:[function(require,module,exports){\n\n/**\n * Helper class to create a WebGL Texture\n *\n * @class\n * @memberof pixi.gl\n * @param gl {WebGLRenderingContext} The current WebGL context\n * @param width {number} the width of the texture\n * @param height {number} the height of the texture\n * @param format {number} the pixel format of the texture. defaults to gl.RGBA\n * @param type {number} the gl type of the texture. defaults to gl.UNSIGNED_BYTE\n */\nvar Texture = function(gl, width, height, format, type)\n{\n\t/**\n\t * The current WebGL rendering context\n\t *\n\t * @member {WebGLRenderingContext}\n\t */\n\tthis.gl = gl;\n\n\n\t/**\n\t * The WebGL texture\n\t *\n\t * @member {WebGLTexture}\n\t */\n\tthis.texture = gl.createTexture();\n\n\t/**\n\t * If mipmapping was used for this texture, enable and disable with enableMipmap()\n\t *\n\t * @member {Boolean}\n\t */\n\t// some settings..\n\tthis.mipmap = false;\n\n\n\t/**\n\t * Set to true to enable pre-multiplied alpha\n\t *\n\t * @member {Boolean}\n\t */\n\tthis.premultiplyAlpha = false;\n\n\t/**\n\t * The width of texture\n\t *\n\t * @member {Number}\n\t */\n\tthis.width = width || 0;\n\t/**\n\t * The height of texture\n\t *\n\t * @member {Number}\n\t */\n\tthis.height = height || 0;\n\n\t/**\n\t * The pixel format of the texture. defaults to gl.RGBA\n\t *\n\t * @member {Number}\n\t */\n\tthis.format = format || gl.RGBA;\n\n\t/**\n\t * The gl type of the texture. defaults to gl.UNSIGNED_BYTE\n\t *\n\t * @member {Number}\n\t */\n\tthis.type = type || gl.UNSIGNED_BYTE;\n\n\n}\n\n/**\n * Uploads this texture to the GPU\n * @param source {HTMLImageElement|ImageData|HTMLVideoElement} the source image of the texture\n */\nTexture.prototype.upload = function(source)\n{\n\tthis.bind();\n\n\tvar gl = this.gl;\n\n\t// if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect.\n\tthis.width = source.videoWidth || source.width;\n\tthis.height = source.videoHeight || source.height;\n\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);\n gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source);\n}\n\nvar FLOATING_POINT_AVAILABLE = false;\n\n/**\n * Use a data source and uploads this texture to the GPU\n * @param data {TypedArray} the data to upload to the texture\n * @param width {number} the new width of the texture\n * @param height {number} the new height of the texture\n */\nTexture.prototype.uploadData = function(data, width, height)\n{\n\tthis.bind();\n\n\tvar gl = this.gl;\n\n\tthis.width = width || this.width;\n\tthis.height = height || this.height;\n\n\tif(data instanceof Float32Array)\n\t{\n\t\tif(!FLOATING_POINT_AVAILABLE)\n\t\t{\n\t\t\tvar ext = gl.getExtension(\"OES_texture_float\");\n\n\t\t\tif(ext)\n\t\t\t{\n\t\t\t\tFLOATING_POINT_AVAILABLE = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new Error('floating point textures not available');\n\t\t\t}\n\t\t}\n\n\t\tthis.type = gl.FLOAT;\n\t}\n\telse\n\t{\n\t\t// TODO support for other types\n\t\tthis.type = gl.UNSIGNED_BYTE;\n\t}\n\n\n\n\t// what type of data?\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);\n\tgl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.width, this.height, 0, this.format, this.type, data || null);\n\n}\n\n/**\n * Binds the texture\n * @param location {@mat}\n */\nTexture.prototype.bind = function(location)\n{\n\tvar gl = this.gl;\n\n\tif(location !== undefined)\n\t{\n\t\tgl.activeTexture(gl.TEXTURE0 + location);\n\t}\n\n\tgl.bindTexture(gl.TEXTURE_2D, this.texture);\n}\n\n/**\n * Unbinds the texture\n */\nTexture.prototype.unbind = function()\n{\n\tvar gl = this.gl;\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n}\n\n/**\n * @mat\n * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation\n */\nTexture.prototype.minFilter = function( linear )\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tif(this.mipmap)\n\t{\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);\n\t}\n\telse\n\t{\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR : gl.NEAREST);\n\t}\n}\n\n/**\n * @mat\n * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation\n */\nTexture.prototype.magFilter = function( linear )\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linear ? gl.LINEAR : gl.NEAREST);\n}\n\n/**\n * Enables mipmapping\n */\nTexture.prototype.enableMipmap = function()\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tthis.mipmap = true;\n\n\tgl.generateMipmap(gl.TEXTURE_2D);\n}\n\n/**\n * Enables linear filtering\n */\nTexture.prototype.enableLinearScaling = function()\n{\n\tthis.minFilter(true);\n\tthis.magFilter(true);\n}\n\n/**\n * Enables nearest neighbour interpolation\n */\nTexture.prototype.enableNearestScaling = function()\n{\n\tthis.minFilter(false);\n\tthis.magFilter(false);\n}\n\n/**\n * Enables clamping on the texture so WebGL will not repeat it\n */\nTexture.prototype.enableWrapClamp = function()\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n}\n\n/**\n * Enable tiling on the texture\n */\nTexture.prototype.enableWrapRepeat = function()\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n}\n\n/**\n * @mat\n */\nTexture.prototype.enableWrapMirrorRepeat = function()\n{\n\tvar gl = this.gl;\n\n\tthis.bind();\n\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);\n}\n\n\n/**\n * Destroys this texture\n */\nTexture.prototype.destroy = function()\n{\n\tvar gl = this.gl;\n\t//TODO\n\tgl.deleteTexture(this.texture);\n}\n\n/**\n * @static\n * @param gl {WebGLRenderingContext} The current WebGL context\n * @param source {HTMLImageElement|ImageData} the source image of the texture\n * @param premultiplyAlpha {Boolean} If we want to use pre-multiplied alpha\n */\nTexture.fromSource = function(gl, source, premultiplyAlpha)\n{\n\tvar texture = new Texture(gl);\n\ttexture.premultiplyAlpha = premultiplyAlpha || false;\n\ttexture.upload(source);\n\n\treturn texture;\n}\n\n/**\n * @static\n * @param gl {WebGLRenderingContext} The current WebGL context\n * @param data {TypedArray} the data to upload to the texture\n * @param width {number} the new width of the texture\n * @param height {number} the new height of the texture\n */\nTexture.fromData = function(gl, data, width, height)\n{\n\t//console.log(data, width, height);\n\tvar texture = new Texture(gl);\n\ttexture.uploadData(data, width, height);\n\n\treturn texture;\n}\n\n\nmodule.exports = Texture;\n\n},{}],6:[function(require,module,exports){\n\n// state object//\nvar setVertexAttribArrays = require( './setVertexAttribArrays' );\n\n/**\n * Helper class to work with WebGL VertexArrayObjects (vaos)\n * Only works if WebGL extensions are enabled (they usually are)\n *\n * @class\n * @memberof pixi.gl\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n */\nfunction VertexArrayObject(gl, state)\n{\n\n\tthis.nativeVaoExtension = (\n gl.getExtension('OES_vertex_array_object') ||\n gl.getExtension('MOZ_OES_vertex_array_object') ||\n gl.getExtension('WEBKIT_OES_vertex_array_object')\n );\n\n\tthis.nativeState = state;\n\n\tif(this.nativeVaoExtension)\n\t{\n\t\tthis.nativeVao = this.nativeVaoExtension.createVertexArrayOES();\n\t\t\n\t\tvar maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);\n\t\t\n\t\t// VAO - overwrite the state..\n\t\tthis.nativeState = {tempAttribState:new Array(maxAttribs)\n\t\t\t\t\t\t\t,attribState:new Array(maxAttribs)};\n\t}\n\n\t/**\n\t * The current WebGL rendering context\n\t *\n\t * @member {WebGLRenderingContext}\n\t */\n\tthis.gl = gl;\n\n\t/**\n\t * An array of attributes ? @mat\n\t *\n\t * @member {Array}\n\t */\n\tthis.attributes = [];\n\n\t/**\n\t * @mat\n\t *\n\t * @member {Array}\n\t */\n\tthis.indexBuffer = null;\n\n\t/**\n\t * A boolean flag\n\t *\n\t * @member {Boolean}\n\t */\n\tthis.dirty = false;\n}\n\nVertexArrayObject.prototype.constructor = VertexArrayObject;\nmodule.exports = VertexArrayObject;\n\n\n/**\n * Binds the buffer\n */\nVertexArrayObject.prototype.bind = function()\n{\n\tif(this.nativeVao)\n\t{\n\t\tthis.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);\n\n\t\tif(this.dirty)\n\t\t{\n\t\t\tthis.dirty = false;\n\t\t\tthis.activate();\n\t\t}\n\t}\n\telse\n\t{\n\t\t\n\t\tthis.activate();\n\t}\n\n\treturn this;\n}\n\n/**\n * Unbinds the buffer\n */\nVertexArrayObject.prototype.unbind = function()\n{\n\tif(this.nativeVao)\n\t{\n\t\tthis.nativeVaoExtension.bindVertexArrayOES(null);\n\t}\n\n\treturn this;\n}\n\n/**\n * Uses this vao\n */\nVertexArrayObject.prototype.activate = function()\n{\n\t\n\tvar gl = this.gl;\n\tvar lastBuffer = null;\n\n\tfor (var i = 0; i < this.attributes.length; i++)\n\t{\n\t\tvar attrib = this.attributes[i];\n\n\t\tif(lastBuffer !== attrib.buffer)\n\t\t{\n\t\t\tattrib.buffer.bind();\n\t\t\tlastBuffer = attrib.buffer;\n\t\t}\n\n\t\t//attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start);\n\t\tgl.vertexAttribPointer(attrib.attribute.location,\n\t\t\t\t\t\t\t attrib.attribute.size, attrib.type || gl.FLOAT,\n\t\t\t\t\t\t\t attrib.normalized || false,\n\t\t\t\t\t\t\t attrib.stride || 0,\n\t\t\t\t\t\t\t attrib.start || 0);\n\n\n\t};\n\n\tsetVertexAttribArrays(gl, this.attributes, this.nativeState);\n\t\n\tthis.indexBuffer.bind();\n\n\treturn this;\n}\n\n/**\n *\n * @param buffer {WebGLBuffer}\n * @param attribute {[type]}\n * @param type {[type]}\n * @param normalized {[type]}\n * @param stride {Number}\n * @param start {Number}\n */\nVertexArrayObject.prototype.addAttribute = function(buffer, attribute, type, normalized, stride, start)\n{\n this.attributes.push({\n \tbuffer: \tbuffer,\n \tattribute: \tattribute,\n\n \tlocation: \tattribute.location,\n\t \ttype: \t\ttype || this.gl.FLOAT,\n\t \tnormalized: normalized || false,\n\t \tstride: \tstride || 0,\n\t \tstart: \t\tstart || 0\n\t})\n\n\tthis.dirty = true;\n\n\treturn this;\n}\n\n/**\n *\n * @param buffer {WebGLBuffer}\n * @param options {Object}\n */\nVertexArrayObject.prototype.addIndex = function(buffer, options)\n{\n this.indexBuffer = buffer;\n\n this.dirty = true;\n\n return this;\n}\n\n/**\n * Unbinds this vao and disables it\n */\nVertexArrayObject.prototype.clear = function()\n{\n\tvar gl = this.gl;\n\n\t// TODO - should this function unbind after clear?\n\t// for now, no but lets see what happens in the real world!\n\tif(this.nativeVao)\n\t{\n\t\tthis.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);\n\t}\n\n\tthis.attributes.length = 0;\n\tthis.indexBuffer = null;\n\n\treturn this;\n}\n\n/**\n * @mat\n * @param type {Number}\n * @param size {Number}\n * @param start {Number}\n */\nVertexArrayObject.prototype.draw = function(type, size, start)\n{\n\tvar gl = this.gl;\n\tgl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0);\n\n\treturn this;\n}\n\n},{\"./setVertexAttribArrays\":8}],7:[function(require,module,exports){\n\n/**\n * Helper class to create a webGL Context\n *\n * @class\n * @memberof pixi.gl\n * @param canvas {HTMLCanvasElement} the canvas element that we will get the context from\n * @param options {Object} An options object that gets passed in to the canvas element containing the context attributes,\n * see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext for the options available\n * @return {WebGLRenderingContext} the WebGL context\n */\nvar createContext = function(canvas, options)\n{\n var gl = canvas.getContext('webgl', options) || \n \t canvas.getContext('experimental-webgl', options);\n\n if (!gl)\n {\n // fail, not able to get a context\n throw new Error('This browser does not support webGL. Try using the canvas renderer');\n }\n\n return gl;\n}\n\nmodule.exports = createContext;\n\n},{}],8:[function(require,module,exports){\nvar GL_MAP = {};\n\n/**\n * @mat\n * @param gl {WebGLRenderingContext} The current WebGL context\n * @param attribs {[type]}\n */\nvar setVertexAttribArrays = function (gl, attribs, state)\n{\n\n if(state)\n {\n\n var i,\n tempAttribState = state.tempAttribState,\n attribState = state.attribState;\n\n for (i = 0; i < tempAttribState.length; i++)\n {\n tempAttribState[i] = false;\n }\n\n // set the new attribs\n for (i in attribs)\n {\n tempAttribState[attribs[i].attribute.location] = true;\n }\n\n for (i = 0; i < attribState.length; i++)\n {\n if (attribState[i] !== tempAttribState[i])\n {\n attribState[i] = tempAttribState[i];\n\n if (state.attribState[i])\n {\n gl.enableVertexAttribArray(i);\n }\n else\n {\n gl.disableVertexAttribArray(i);\n }\n }\n }\n\n }\n else\n {\n for (var i = 0; i < attribs.length; i++)\n {\n var attrib = attribs[i];\n gl.enableVertexAttribArray(attrib.attribute.location);\n }\n }\n};\n\nmodule.exports = setVertexAttribArrays;\n\n},{}],9:[function(require,module,exports){\n\n/**\n *\n * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}\n * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.\n * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.\n * @return {WebGLProgram} the shader program\n */\ncompileProgram = function(gl, vertexSrc, fragmentSrc)\n{\n var glVertShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);\n var glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);\n\n var program = gl.createProgram();\n\n gl.attachShader(program, glVertShader);\n gl.attachShader(program, glFragShader);\n gl.linkProgram(program);\n\n // if linking fails, then log and cleanup\n if (!gl.getProgramParameter(program, gl.LINK_STATUS))\n {\n console.error('Pixi.js Error: Could not initialize shader.');\n console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));\n console.error('gl.getError()', gl.getError());\n\n // if there is a program info log, log it\n if (gl.getProgramInfoLog(program) !== '')\n {\n console.warn('Pixi.js Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));\n }\n\n gl.deleteProgram(program);\n program = null;\n }\n\n // clean up some shaders\n gl.deleteShader(glVertShader);\n gl.deleteShader(glFragShader);\n\n return program;\n}\n\n/**\n *\n * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}\n * @param type {Number} the type, can be either VERTEX_SHADER or FRAGMENT_SHADER\n * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.\n * @return {WebGLShader} the shader\n */\nvar compileShader = function (gl, type, src)\n{\n var shader = gl.createShader(type);\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))\n {\n console.log(gl.getShaderInfoLog(shader));\n return null;\n }\n\n return shader;\n};\n\nmodule.exports = compileProgram;\n\n},{}],10:[function(require,module,exports){\n\n\nvar defaultValue = function(type, size) \n{\n switch (type)\n {\n case 'float':\n return 0;\n\n case 'vec2': \n return new Float32Array(2 * size);\n\n case 'vec3':\n return new Float32Array(3 * size);\n\n case 'vec4': \n return new Float32Array(4 * size);\n \n case 'int':\n case 'sampler2D':\n return 0;\n\n case 'ivec2': \n return new Int32Array(2 * size);\n\n case 'ivec3':\n return new Int32Array(3 * size);\n\n case 'ivec4': \n return new Int32Array(4 * size);\n\n case 'bool': \n return false;\n\n case 'bvec2':\n\n return booleanArray( 2 * size);\n\n case 'bvec3':\n return booleanArray(3 * size);\n\n case 'bvec4':\n return booleanArray(4 * size);\n\n case 'mat2':\n return new Float32Array([1, 0\n ,0, 1]);\n\n case 'mat3': \n return new Float32Array([1, 0, 0\n ,0, 1, 0\n ,0, 0, 1]);\n\n case 'mat4':\n return new Float32Array([1, 0, 0, 0\n ,0, 1, 0, 0\n ,0, 0, 1, 0\n ,0, 0, 0, 1]);\n }\n}\n\nvar booleanArray = function(size)\n{\n var array = new Array(size);\n\n for (var i = 0; i < array.length; i++) \n {\n array[i] = false;\n };\n\n return array;\n}\n\nmodule.exports = defaultValue;\n\n},{}],11:[function(require,module,exports){\n\nvar mapType = require('./mapType');\nvar mapSize = require('./mapSize');\n\n/**\n * Extracts the attributes\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param program {WebGLProgram} The shader program to get the attributes from\n * @return attributes {Object}\n */\nvar extractAttributes = function(gl, program)\n{\n var attributes = {};\n\n var totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES)\n\n for (var i = 0; i < totalAttributes; i++)\n {\n var attribData = gl.getActiveAttrib(program, i);\n var type = mapType(gl, attribData.type);\n\n attributes[attribData.name] = {\n type:type,\n size:mapSize(type),\n location:gl.getAttribLocation(program, attribData.name),\n //TODO - make an attribute object\n pointer:function(type, normalized, stride, start){\n\n // console.log(this.location)\n gl.vertexAttribPointer(this.location,this.size, type || gl.FLOAT, normalized || false, stride || 0, start || 0);\n\n }\n }\n };\n\n return attributes;\n}\n\nmodule.exports = extractAttributes;\n\n},{\"./mapSize\":14,\"./mapType\":15}],12:[function(require,module,exports){\nvar mapType = require('./mapType');\nvar defaultValue = require('./defaultValue');\n\n/**\n * Extracts the uniforms\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param program {WebGLProgram} The shader program to get the uniforms from\n * @return uniforms {Object}\n */\nvar extractUniforms = function(gl, program)\n{\n\tvar uniforms = {};\n\n var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)\n\n for (var i = 0; i < totalUniforms; i++)\n {\n \tvar uniformData = gl.getActiveUniform(program, i);\n \tvar name = uniformData.name.replace(/\\[.*?\\]/, \"\");\n var type = mapType(gl, uniformData.type );\n\n \tuniforms[name] = {\n \t\ttype:type,\n \t\tsize:uniformData.size,\n \t\tlocation:gl.getUniformLocation(program, name),\n \t\tvalue:defaultValue(type, uniformData.size)\n \t}\n };\n\n\treturn uniforms;\n}\n\nmodule.exports = extractUniforms;\n\n},{\"./defaultValue\":10,\"./mapType\":15}],13:[function(require,module,exports){\n/**\n * Extracts the attributes\n * @param gl {WebGLRenderingContext} The current WebGL rendering context\n * @param uniforms {Array} @mat ?\n * @return attributes {Object}\n */\nvar generateUniformAccessObject = function(gl, uniformData)\n{\n // this is the object we will be sending back.\n // an object hierachy will be created for structs\n var uniforms = {data:{}};\n\n uniforms.gl = gl;\n\n var uniformKeys= Object.keys(uniformData);\n\n for (var i = 0; i < uniformKeys.length; i++)\n {\n var fullName = uniformKeys[i]\n\n var nameTokens = fullName.split('.');\n var name = nameTokens[nameTokens.length - 1];\n\n var uniformGroup = getUniformGroup(nameTokens, uniforms);\n\n var uniform = uniformData[fullName];\n uniformGroup.data[name] = uniform;\n\n uniformGroup.gl = gl;\n\n Object.defineProperty(uniformGroup, name, {\n get: generateGetter(name),\n set: generateSetter(name, uniform)\n })\n };\n\n return uniforms;\n}\n\nvar generateGetter = function(name)\n{\n\tvar template = getterTemplate.replace('%%', name);\n\treturn new Function(template);\n}\n\nvar generateSetter = function(name, uniform)\n{\n var template = setterTemplate.replace(/%%/g, name);\n var setTemplate\n\n if(uniform.size === 1)\n {\n setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type];\n }\n else\n {\n setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type];\n }\n\n if(setTemplate)\n {\n template += \"\\nthis.gl.\" + setTemplate + \";\";\n }\n\n \treturn new Function('value', template);\n}\n\nvar getUniformGroup = function(nameTokens, uniform)\n{\n var cur = uniform;\n\n for (var i = 0; i < nameTokens.length - 1; i++)\n {\n var o = cur[nameTokens[i]] || {data:{}};\n cur[nameTokens[i]] = o;\n cur = o;\n };\n\n return cur\n}\n\nvar getterTemplate = [\n 'return this.data.%%.value;',\n].join('\\n');\n\nvar setterTemplate = [\n 'this.data.%%.value = value;',\n 'var location = this.data.%%.location;'\n].join('\\n');\n\n\nvar GLSL_TO_SINGLE_SETTERS = {\n\n 'float': 'uniform1f(location, value)',\n\n 'vec2': 'uniform2f(location, value[0], value[1])',\n 'vec3': 'uniform3f(location, value[0], value[1], value[2])',\n 'vec4': 'uniform4f(location, value[0], value[1], value[2], value[3])',\n\n 'int': 'uniform1i(location, value)',\n 'ivec2': 'uniform2i(location, value[0], value[1])',\n 'ivec3': 'uniform3i(location, value[0], value[1], value[2])',\n 'ivec4': 'uniform4i(location, value[0], value[1], value[2], value[3])',\n\n 'bool': 'uniform1i(location, value)',\n 'bvec2': 'uniform2i(location, value[0], value[1])',\n 'bvec3': 'uniform3i(location, value[0], value[1], value[2])',\n 'bvec4': 'uniform4i(location, value[0], value[1], value[2], value[3])',\n\n 'mat2': 'uniformMatrix2fv(location, false, value)',\n 'mat3': 'uniformMatrix3fv(location, false, value)',\n 'mat4': 'uniformMatrix4fv(location, false, value)',\n\n 'sampler2D':'uniform1i(location, value)'\n}\n\nvar GLSL_TO_ARRAY_SETTERS = {\n\n 'float': 'uniform1fv(location, value)',\n\n 'vec2': 'uniform2fv(location, value)',\n 'vec3': 'uniform3fv(location, value)',\n 'vec4': 'uniform4fv(location, value)',\n\n 'int': 'uniform1iv(location, value)',\n 'ivec2': 'uniform2iv(location, value)',\n 'ivec3': 'uniform3iv(location, value)',\n 'ivec4': 'uniform4iv(location, value)',\n\n 'bool': 'uniform1iv(location, value)',\n 'bvec2': 'uniform2iv(location, value)',\n 'bvec3': 'uniform3iv(location, value)',\n 'bvec4': 'uniform4iv(location, value)',\n\n 'sampler2D':'uniform1iv(location, value)'\n}\n\nmodule.exports = generateUniformAccessObject;\n\n},{}],14:[function(require,module,exports){\n\n\nvar mapSize = function(type) \n{ \n return GLSL_TO_SIZE[type];\n}\n\n\nvar GLSL_TO_SIZE = {\n 'float': 1,\n 'vec2': 2,\n 'vec3': 3,\n 'vec4': 4,\n\n 'int': 1,\n 'ivec2': 2,\n 'ivec3': 3,\n 'ivec4': 4,\n\n 'bool': 1,\n 'bvec2': 2,\n 'bvec3': 3,\n 'bvec4': 4,\n\n 'mat2': 4,\n 'mat3': 9,\n 'mat4': 16,\n\n 'sampler2D': 1\n}\n\nmodule.exports = mapSize;\n\n},{}],15:[function(require,module,exports){\n\n\nvar mapSize = function(gl, type) \n{\n if(!GL_TABLE) \n {\n var typeNames = Object.keys(GL_TO_GLSL_TYPES);\n\n GL_TABLE = {};\n\n for(var i = 0; i < typeNames.length; ++i) \n {\n var tn = typeNames[i];\n GL_TABLE[ gl[tn] ] = GL_TO_GLSL_TYPES[tn];\n }\n }\n\n return GL_TABLE[type];\n}\n\nvar GL_TABLE = null;\n\nvar GL_TO_GLSL_TYPES = {\n 'FLOAT': 'float',\n 'FLOAT_VEC2': 'vec2',\n 'FLOAT_VEC3': 'vec3',\n 'FLOAT_VEC4': 'vec4',\n\n 'INT': 'int',\n 'INT_VEC2': 'ivec2',\n 'INT_VEC3': 'ivec3',\n 'INT_VEC4': 'ivec4',\n \n 'BOOL': 'bool',\n 'BOOL_VEC2': 'bvec2',\n 'BOOL_VEC3': 'bvec3',\n 'BOOL_VEC4': 'bvec4',\n \n 'FLOAT_MAT2': 'mat2',\n 'FLOAT_MAT3': 'mat3',\n 'FLOAT_MAT4': 'mat4',\n \n 'SAMPLER_2D': 'sampler2D' \n}\n\nmodule.exports = mapSize;\n\n},{}],16:[function(require,module,exports){\n(function (process,global){\n/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n(function () {\n\n var async = {};\n function noop() {}\n function identity(v) {\n return v;\n }\n function toBool(v) {\n return !!v;\n }\n function notId(v) {\n return !v;\n }\n\n // global on the server, window in the browser\n var previous_async;\n\n // Establish the root object, `window` (`self`) in the browser, `global`\n // on the server, or `this` in some virtual machines. We use `self`\n // instead of `window` for `WebWorker` support.\n var root = typeof self === 'object' && self.self === self && self ||\n typeof global === 'object' && global.global === global && global ||\n this;\n\n if (root != null) {\n previous_async = root.async;\n }\n\n async.noConflict = function () {\n root.async = previous_async;\n return async;\n };\n\n function only_once(fn) {\n return function() {\n if (fn === null) throw new Error(\"Callback was already called.\");\n fn.apply(this, arguments);\n fn = null;\n };\n }\n\n function _once(fn) {\n return function() {\n if (fn === null) return;\n fn.apply(this, arguments);\n fn = null;\n };\n }\n\n //// cross-browser compatiblity functions ////\n\n var _toString = Object.prototype.toString;\n\n var _isArray = Array.isArray || function (obj) {\n return _toString.call(obj) === '[object Array]';\n };\n\n // Ported from underscore.js isObject\n var _isObject = function(obj) {\n var type = typeof obj;\n return type === 'function' || type === 'object' && !!obj;\n };\n\n function _isArrayLike(arr) {\n return _isArray(arr) || (\n // has a positive integer length property\n typeof arr.length === \"number\" &&\n arr.length >= 0 &&\n arr.length % 1 === 0\n );\n }\n\n function _arrayEach(arr, iterator) {\n var index = -1,\n length = arr.length;\n\n while (++index < length) {\n iterator(arr[index], index, arr);\n }\n }\n\n function _map(arr, iterator) {\n var index = -1,\n length = arr.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iterator(arr[index], index, arr);\n }\n return result;\n }\n\n function _range(count) {\n return _map(Array(count), function (v, i) { return i; });\n }\n\n function _reduce(arr, iterator, memo) {\n _arrayEach(arr, function (x, i, a) {\n memo = iterator(memo, x, i, a);\n });\n return memo;\n }\n\n function _forEachOf(object, iterator) {\n _arrayEach(_keys(object), function (key) {\n iterator(object[key], key);\n });\n }\n\n function _indexOf(arr, item) {\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] === item) return i;\n }\n return -1;\n }\n\n var _keys = Object.keys || function (obj) {\n var keys = [];\n for (var k in obj) {\n if (obj.hasOwnProperty(k)) {\n keys.push(k);\n }\n }\n return keys;\n };\n\n function _keyIterator(coll) {\n var i = -1;\n var len;\n var keys;\n if (_isArrayLike(coll)) {\n len = coll.length;\n return function next() {\n i++;\n return i < len ? i : null;\n };\n } else {\n keys = _keys(coll);\n len = keys.length;\n return function next() {\n i++;\n return i < len ? keys[i] : null;\n };\n }\n }\n\n // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)\n // This accumulates the arguments passed into an array, after a given index.\n // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).\n function _restParam(func, startIndex) {\n startIndex = startIndex == null ? func.length - 1 : +startIndex;\n return function() {\n var length = Math.max(arguments.length - startIndex, 0);\n var rest = Array(length);\n for (var index = 0; index < length; index++) {\n rest[index] = arguments[index + startIndex];\n }\n switch (startIndex) {\n case 0: return func.call(this, rest);\n case 1: return func.call(this, arguments[0], rest);\n }\n // Currently unused but handle cases outside of the switch statement:\n // var args = Array(startIndex + 1);\n // for (index = 0; index < startIndex; index++) {\n // args[index] = arguments[index];\n // }\n // args[startIndex] = rest;\n // return func.apply(this, args);\n };\n }\n\n function _withoutIndex(iterator) {\n return function (value, index, callback) {\n return iterator(value, callback);\n };\n }\n\n //// exported async module functions ////\n\n //// nextTick implementation with browser-compatible fallback ////\n\n // capture the global reference to guard against fakeTimer mocks\n var _setImmediate = typeof setImmediate === 'function' && setImmediate;\n\n var _delay = _setImmediate ? function(fn) {\n // not a direct alias for IE10 compatibility\n _setImmediate(fn);\n } : function(fn) {\n setTimeout(fn, 0);\n };\n\n if (typeof process === 'object' && typeof process.nextTick === 'function') {\n async.nextTick = process.nextTick;\n } else {\n async.nextTick = _delay;\n }\n async.setImmediate = _setImmediate ? _delay : async.nextTick;\n\n\n async.forEach =\n async.each = function (arr, iterator, callback) {\n return async.eachOf(arr, _withoutIndex(iterator), callback);\n };\n\n async.forEachSeries =\n async.eachSeries = function (arr, iterator, callback) {\n return async.eachOfSeries(arr, _withoutIndex(iterator), callback);\n };\n\n\n async.forEachLimit =\n async.eachLimit = function (arr, limit, iterator, callback) {\n return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);\n };\n\n async.forEachOf =\n async.eachOf = function (object, iterator, callback) {\n callback = _once(callback || noop);\n object = object || [];\n\n var iter = _keyIterator(object);\n var key, completed = 0;\n\n while ((key = iter()) != null) {\n completed += 1;\n iterator(object[key], key, only_once(done));\n }\n\n if (completed === 0) callback(null);\n\n function done(err) {\n completed--;\n if (err) {\n callback(err);\n }\n // Check key is null in case iterator isn't exhausted\n // and done resolved synchronously.\n else if (key === null && completed <= 0) {\n callback(null);\n }\n }\n };\n\n async.forEachOfSeries =\n async.eachOfSeries = function (obj, iterator, callback) {\n callback = _once(callback || noop);\n obj = obj || [];\n var nextKey = _keyIterator(obj);\n var key = nextKey();\n function iterate() {\n var sync = true;\n if (key === null) {\n return callback(null);\n }\n iterator(obj[key], key, only_once(function (err) {\n if (err) {\n callback(err);\n }\n else {\n key = nextKey();\n if (key === null) {\n return callback(null);\n } else {\n if (sync) {\n async.setImmediate(iterate);\n } else {\n iterate();\n }\n }\n }\n }));\n sync = false;\n }\n iterate();\n };\n\n\n\n async.forEachOfLimit =\n async.eachOfLimit = function (obj, limit, iterator, callback) {\n _eachOfLimit(limit)(obj, iterator, callback);\n };\n\n function _eachOfLimit(limit) {\n\n return function (obj, iterator, callback) {\n callback = _once(callback || noop);\n obj = obj || [];\n var nextKey = _keyIterator(obj);\n if (limit <= 0) {\n return callback(null);\n }\n var done = false;\n var running = 0;\n var errored = false;\n\n (function replenish () {\n if (done && running <= 0) {\n return callback(null);\n }\n\n while (running < limit && !errored) {\n var key = nextKey();\n if (key === null) {\n done = true;\n if (running <= 0) {\n callback(null);\n }\n return;\n }\n running += 1;\n iterator(obj[key], key, only_once(function (err) {\n running -= 1;\n if (err) {\n callback(err);\n errored = true;\n }\n else {\n replenish();\n }\n }));\n }\n })();\n };\n }\n\n\n function doParallel(fn) {\n return function (obj, iterator, callback) {\n return fn(async.eachOf, obj, iterator, callback);\n };\n }\n function doParallelLimit(fn) {\n return function (obj, limit, iterator, callback) {\n return fn(_eachOfLimit(limit), obj, iterator, callback);\n };\n }\n function doSeries(fn) {\n return function (obj, iterator, callback) {\n return fn(async.eachOfSeries, obj, iterator, callback);\n };\n }\n\n function _asyncMap(eachfn, arr, iterator, callback) {\n callback = _once(callback || noop);\n arr = arr || [];\n var results = _isArrayLike(arr) ? [] : {};\n eachfn(arr, function (value, index, callback) {\n iterator(value, function (err, v) {\n results[index] = v;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n\n async.map = doParallel(_asyncMap);\n async.mapSeries = doSeries(_asyncMap);\n async.mapLimit = doParallelLimit(_asyncMap);\n\n // reduce only has a series version, as doing reduce in parallel won't\n // work in many situations.\n async.inject =\n async.foldl =\n async.reduce = function (arr, memo, iterator, callback) {\n async.eachOfSeries(arr, function (x, i, callback) {\n iterator(memo, x, function (err, v) {\n memo = v;\n callback(err);\n });\n }, function (err) {\n callback(err, memo);\n });\n };\n\n async.foldr =\n async.reduceRight = function (arr, memo, iterator, callback) {\n var reversed = _map(arr, identity).reverse();\n async.reduce(reversed, memo, iterator, callback);\n };\n\n async.transform = function (arr, memo, iterator, callback) {\n if (arguments.length === 3) {\n callback = iterator;\n iterator = memo;\n memo = _isArray(arr) ? [] : {};\n }\n\n async.eachOf(arr, function(v, k, cb) {\n iterator(memo, v, k, cb);\n }, function(err) {\n callback(err, memo);\n });\n };\n\n function _filter(eachfn, arr, iterator, callback) {\n var results = [];\n eachfn(arr, function (x, index, callback) {\n iterator(x, function (v) {\n if (v) {\n results.push({index: index, value: x});\n }\n callback();\n });\n }, function () {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n }\n\n async.select =\n async.filter = doParallel(_filter);\n\n async.selectLimit =\n async.filterLimit = doParallelLimit(_filter);\n\n async.selectSeries =\n async.filterSeries = doSeries(_filter);\n\n function _reject(eachfn, arr, iterator, callback) {\n _filter(eachfn, arr, function(value, cb) {\n iterator(value, function(v) {\n cb(!v);\n });\n }, callback);\n }\n async.reject = doParallel(_reject);\n async.rejectLimit = doParallelLimit(_reject);\n async.rejectSeries = doSeries(_reject);\n\n function _createTester(eachfn, check, getResult) {\n return function(arr, limit, iterator, cb) {\n function done() {\n if (cb) cb(getResult(false, void 0));\n }\n function iteratee(x, _, callback) {\n if (!cb) return callback();\n iterator(x, function (v) {\n if (cb && check(v)) {\n cb(getResult(true, x));\n cb = iterator = false;\n }\n callback();\n });\n }\n if (arguments.length > 3) {\n eachfn(arr, limit, iteratee, done);\n } else {\n cb = iterator;\n iterator = limit;\n eachfn(arr, iteratee, done);\n }\n };\n }\n\n async.any =\n async.some = _createTester(async.eachOf, toBool, identity);\n\n async.someLimit = _createTester(async.eachOfLimit, toBool, identity);\n\n async.all =\n async.every = _createTester(async.eachOf, notId, notId);\n\n async.everyLimit = _createTester(async.eachOfLimit, notId, notId);\n\n function _findGetResult(v, x) {\n return x;\n }\n async.detect = _createTester(async.eachOf, identity, _findGetResult);\n async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);\n async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);\n\n async.sortBy = function (arr, iterator, callback) {\n async.map(arr, function (x, callback) {\n iterator(x, function (err, criteria) {\n if (err) {\n callback(err);\n }\n else {\n callback(null, {value: x, criteria: criteria});\n }\n });\n }, function (err, results) {\n if (err) {\n return callback(err);\n }\n else {\n callback(null, _map(results.sort(comparator), function (x) {\n return x.value;\n }));\n }\n\n });\n\n function comparator(left, right) {\n var a = left.criteria, b = right.criteria;\n return a < b ? -1 : a > b ? 1 : 0;\n }\n };\n\n async.auto = function (tasks, concurrency, callback) {\n if (typeof arguments[1] === 'function') {\n // concurrency is optional, shift the args.\n callback = concurrency;\n concurrency = null;\n }\n callback = _once(callback || noop);\n var keys = _keys(tasks);\n var remainingTasks = keys.length;\n if (!remainingTasks) {\n return callback(null);\n }\n if (!concurrency) {\n concurrency = remainingTasks;\n }\n\n var results = {};\n var runningTasks = 0;\n\n var hasError = false;\n\n var listeners = [];\n function addListener(fn) {\n listeners.unshift(fn);\n }\n function removeListener(fn) {\n var idx = _indexOf(listeners, fn);\n if (idx >= 0) listeners.splice(idx, 1);\n }\n function taskComplete() {\n remainingTasks--;\n _arrayEach(listeners.slice(0), function (fn) {\n fn();\n });\n }\n\n addListener(function () {\n if (!remainingTasks) {\n callback(null, results);\n }\n });\n\n _arrayEach(keys, function (k) {\n if (hasError) return;\n var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n var taskCallback = _restParam(function(err, args) {\n runningTasks--;\n if (args.length <= 1) {\n args = args[0];\n }\n if (err) {\n var safeResults = {};\n _forEachOf(results, function(val, rkey) {\n safeResults[rkey] = val;\n });\n safeResults[k] = args;\n hasError = true;\n\n callback(err, safeResults);\n }\n else {\n results[k] = args;\n async.setImmediate(taskComplete);\n }\n });\n var requires = task.slice(0, task.length - 1);\n // prevent dead-locks\n var len = requires.length;\n var dep;\n while (len--) {\n if (!(dep = tasks[requires[len]])) {\n throw new Error('Has nonexistent dependency in ' + requires.join(', '));\n }\n if (_isArray(dep) && _indexOf(dep, k) >= 0) {\n throw new Error('Has cyclic dependencies');\n }\n }\n function ready() {\n return runningTasks < concurrency && _reduce(requires, function (a, x) {\n return (a && results.hasOwnProperty(x));\n }, true) && !results.hasOwnProperty(k);\n }\n if (ready()) {\n runningTasks++;\n task[task.length - 1](taskCallback, results);\n }\n else {\n addListener(listener);\n }\n function listener() {\n if (ready()) {\n runningTasks++;\n removeListener(listener);\n task[task.length - 1](taskCallback, results);\n }\n }\n });\n };\n\n\n\n async.retry = function(times, task, callback) {\n var DEFAULT_TIMES = 5;\n var DEFAULT_INTERVAL = 0;\n\n var attempts = [];\n\n var opts = {\n times: DEFAULT_TIMES,\n interval: DEFAULT_INTERVAL\n };\n\n function parseTimes(acc, t){\n if(typeof t === 'number'){\n acc.times = parseInt(t, 10) || DEFAULT_TIMES;\n } else if(typeof t === 'object'){\n acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;\n acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;\n } else {\n throw new Error('Unsupported argument type for \\'times\\': ' + typeof t);\n }\n }\n\n var length = arguments.length;\n if (length < 1 || length > 3) {\n throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');\n } else if (length <= 2 && typeof times === 'function') {\n callback = task;\n task = times;\n }\n if (typeof times !== 'function') {\n parseTimes(opts, times);\n }\n opts.callback = callback;\n opts.task = task;\n\n function wrappedTask(wrappedCallback, wrappedResults) {\n function retryAttempt(task, finalAttempt) {\n return function(seriesCallback) {\n task(function(err, result){\n seriesCallback(!err || finalAttempt, {err: err, result: result});\n }, wrappedResults);\n };\n }\n\n function retryInterval(interval){\n return function(seriesCallback){\n setTimeout(function(){\n seriesCallback(null);\n }, interval);\n };\n }\n\n while (opts.times) {\n\n var finalAttempt = !(opts.times-=1);\n attempts.push(retryAttempt(opts.task, finalAttempt));\n if(!finalAttempt && opts.interval > 0){\n attempts.push(retryInterval(opts.interval));\n }\n }\n\n async.series(attempts, function(done, data){\n data = data[data.length - 1];\n (wrappedCallback || opts.callback)(data.err, data.result);\n });\n }\n\n // If a callback is passed, run this as a controll flow\n return opts.callback ? wrappedTask() : wrappedTask;\n };\n\n async.waterfall = function (tasks, callback) {\n callback = _once(callback || noop);\n if (!_isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n function wrapIterator(iterator) {\n return _restParam(function (err, args) {\n if (err) {\n callback.apply(null, [err].concat(args));\n }\n else {\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n ensureAsync(iterator).apply(null, args);\n }\n });\n }\n wrapIterator(async.iterator(tasks))();\n };\n\n function _parallel(eachfn, tasks, callback) {\n callback = callback || noop;\n var results = _isArrayLike(tasks) ? [] : {};\n\n eachfn(tasks, function (task, key, callback) {\n task(_restParam(function (err, args) {\n if (args.length <= 1) {\n args = args[0];\n }\n results[key] = args;\n callback(err);\n }));\n }, function (err) {\n callback(err, results);\n });\n }\n\n async.parallel = function (tasks, callback) {\n _parallel(async.eachOf, tasks, callback);\n };\n\n async.parallelLimit = function(tasks, limit, callback) {\n _parallel(_eachOfLimit(limit), tasks, callback);\n };\n\n async.series = function(tasks, callback) {\n _parallel(async.eachOfSeries, tasks, callback);\n };\n\n async.iterator = function (tasks) {\n function makeCallback(index) {\n function fn() {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n }\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n };\n return fn;\n }\n return makeCallback(0);\n };\n\n async.apply = _restParam(function (fn, args) {\n return _restParam(function (callArgs) {\n return fn.apply(\n null, args.concat(callArgs)\n );\n });\n });\n\n function _concat(eachfn, arr, fn, callback) {\n var result = [];\n eachfn(arr, function (x, index, cb) {\n fn(x, function (err, y) {\n result = result.concat(y || []);\n cb(err);\n });\n }, function (err) {\n callback(err, result);\n });\n }\n async.concat = doParallel(_concat);\n async.concatSeries = doSeries(_concat);\n\n async.whilst = function (test, iterator, callback) {\n callback = callback || noop;\n if (test()) {\n var next = _restParam(function(err, args) {\n if (err) {\n callback(err);\n } else if (test.apply(this, args)) {\n iterator(next);\n } else {\n callback.apply(null, [null].concat(args));\n }\n });\n iterator(next);\n } else {\n callback(null);\n }\n };\n\n async.doWhilst = function (iterator, test, callback) {\n var calls = 0;\n return async.whilst(function() {\n return ++calls <= 1 || test.apply(this, arguments);\n }, iterator, callback);\n };\n\n async.until = function (test, iterator, callback) {\n return async.whilst(function() {\n return !test.apply(this, arguments);\n }, iterator, callback);\n };\n\n async.doUntil = function (iterator, test, callback) {\n return async.doWhilst(iterator, function() {\n return !test.apply(this, arguments);\n }, callback);\n };\n\n async.during = function (test, iterator, callback) {\n callback = callback || noop;\n\n var next = _restParam(function(err, args) {\n if (err) {\n callback(err);\n } else {\n args.push(check);\n test.apply(this, args);\n }\n });\n\n var check = function(err, truth) {\n if (err) {\n callback(err);\n } else if (truth) {\n iterator(next);\n } else {\n callback(null);\n }\n };\n\n test(check);\n };\n\n async.doDuring = function (iterator, test, callback) {\n var calls = 0;\n async.during(function(next) {\n if (calls++ < 1) {\n next(null, true);\n } else {\n test.apply(this, arguments);\n }\n }, iterator, callback);\n };\n\n function _queue(worker, concurrency, payload) {\n if (concurrency == null) {\n concurrency = 1;\n }\n else if(concurrency === 0) {\n throw new Error('Concurrency must not be zero');\n }\n function _insert(q, data, pos, callback) {\n if (callback != null && typeof callback !== \"function\") {\n throw new Error(\"task callback must be a function\");\n }\n q.started = true;\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length === 0 && q.idle()) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n q.drain();\n });\n }\n _arrayEach(data, function(task) {\n var item = {\n data: task,\n callback: callback || noop\n };\n\n if (pos) {\n q.tasks.unshift(item);\n } else {\n q.tasks.push(item);\n }\n\n if (q.tasks.length === q.concurrency) {\n q.saturated();\n }\n });\n async.setImmediate(q.process);\n }\n function _next(q, tasks) {\n return function(){\n workers -= 1;\n\n var removed = false;\n var args = arguments;\n _arrayEach(tasks, function (task) {\n _arrayEach(workersList, function (worker, index) {\n if (worker === task && !removed) {\n workersList.splice(index, 1);\n removed = true;\n }\n });\n\n task.callback.apply(task, args);\n });\n if (q.tasks.length + workers === 0) {\n q.drain();\n }\n q.process();\n };\n }\n\n var workers = 0;\n var workersList = [];\n var q = {\n tasks: [],\n concurrency: concurrency,\n payload: payload,\n saturated: noop,\n empty: noop,\n drain: noop,\n started: false,\n paused: false,\n push: function (data, callback) {\n _insert(q, data, false, callback);\n },\n kill: function () {\n q.drain = noop;\n q.tasks = [];\n },\n unshift: function (data, callback) {\n _insert(q, data, true, callback);\n },\n process: function () {\n while(!q.paused && workers < q.concurrency && q.tasks.length){\n\n var tasks = q.payload ?\n q.tasks.splice(0, q.payload) :\n q.tasks.splice(0, q.tasks.length);\n\n var data = _map(tasks, function (task) {\n return task.data;\n });\n\n if (q.tasks.length === 0) {\n q.empty();\n }\n workers += 1;\n workersList.push(tasks[0]);\n var cb = only_once(_next(q, tasks));\n worker(data, cb);\n }\n },\n length: function () {\n return q.tasks.length;\n },\n running: function () {\n return workers;\n },\n workersList: function () {\n return workersList;\n },\n idle: function() {\n return q.tasks.length + workers === 0;\n },\n pause: function () {\n q.paused = true;\n },\n resume: function () {\n if (q.paused === false) { return; }\n q.paused = false;\n var resumeCount = Math.min(q.concurrency, q.tasks.length);\n // Need to call q.process once per concurrent\n // worker to preserve full concurrency after pause\n for (var w = 1; w <= resumeCount; w++) {\n async.setImmediate(q.process);\n }\n }\n };\n return q;\n }\n\n async.queue = function (worker, concurrency) {\n var q = _queue(function (items, cb) {\n worker(items[0], cb);\n }, concurrency, 1);\n\n return q;\n };\n\n async.priorityQueue = function (worker, concurrency) {\n\n function _compareTasks(a, b){\n return a.priority - b.priority;\n }\n\n function _binarySearch(sequence, item, compare) {\n var beg = -1,\n end = sequence.length - 1;\n while (beg < end) {\n var mid = beg + ((end - beg + 1) >>> 1);\n if (compare(item, sequence[mid]) >= 0) {\n beg = mid;\n } else {\n end = mid - 1;\n }\n }\n return beg;\n }\n\n function _insert(q, data, priority, callback) {\n if (callback != null && typeof callback !== \"function\") {\n throw new Error(\"task callback must be a function\");\n }\n q.started = true;\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length === 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n q.drain();\n });\n }\n _arrayEach(data, function(task) {\n var item = {\n data: task,\n priority: priority,\n callback: typeof callback === 'function' ? callback : noop\n };\n\n q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n if (q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n\n // Start with a normal queue\n var q = async.queue(worker, concurrency);\n\n // Override push to accept second parameter representing priority\n q.push = function (data, priority, callback) {\n _insert(q, data, priority, callback);\n };\n\n // Remove unshift function\n delete q.unshift;\n\n return q;\n };\n\n async.cargo = function (worker, payload) {\n return _queue(worker, 1, payload);\n };\n\n function _console_fn(name) {\n return _restParam(function (fn, args) {\n fn.apply(null, args.concat([_restParam(function (err, args) {\n if (typeof console === 'object') {\n if (err) {\n if (console.error) {\n console.error(err);\n }\n }\n else if (console[name]) {\n _arrayEach(args, function (x) {\n console[name](x);\n });\n }\n }\n })]));\n });\n }\n async.log = _console_fn('log');\n async.dir = _console_fn('dir');\n /*async.info = _console_fn('info');\n async.warn = _console_fn('warn');\n async.error = _console_fn('error');*/\n\n async.memoize = function (fn, hasher) {\n var memo = {};\n var queues = {};\n var has = Object.prototype.hasOwnProperty;\n hasher = hasher || identity;\n var memoized = _restParam(function memoized(args) {\n var callback = args.pop();\n var key = hasher.apply(null, args);\n if (has.call(memo, key)) { \n async.setImmediate(function () {\n callback.apply(null, memo[key]);\n });\n }\n else if (has.call(queues, key)) {\n queues[key].push(callback);\n }\n else {\n queues[key] = [callback];\n fn.apply(null, args.concat([_restParam(function (args) {\n memo[key] = args;\n var q = queues[key];\n delete queues[key];\n for (var i = 0, l = q.length; i < l; i++) {\n q[i].apply(null, args);\n }\n })]));\n }\n });\n memoized.memo = memo;\n memoized.unmemoized = fn;\n return memoized;\n };\n\n async.unmemoize = function (fn) {\n return function () {\n return (fn.unmemoized || fn).apply(null, arguments);\n };\n };\n\n function _times(mapper) {\n return function (count, iterator, callback) {\n mapper(_range(count), iterator, callback);\n };\n }\n\n async.times = _times(async.map);\n async.timesSeries = _times(async.mapSeries);\n async.timesLimit = function (count, limit, iterator, callback) {\n return async.mapLimit(_range(count), limit, iterator, callback);\n };\n\n async.seq = function (/* functions... */) {\n var fns = arguments;\n return _restParam(function (args) {\n var that = this;\n\n var callback = args[args.length - 1];\n if (typeof callback == 'function') {\n args.pop();\n } else {\n callback = noop;\n }\n\n async.reduce(fns, args, function (newargs, fn, cb) {\n fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {\n cb(err, nextargs);\n })]));\n },\n function (err, results) {\n callback.apply(that, [err].concat(results));\n });\n });\n };\n\n async.compose = function (/* functions... */) {\n return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n };\n\n\n function _applyEach(eachfn) {\n return _restParam(function(fns, args) {\n var go = _restParam(function(args) {\n var that = this;\n var callback = args.pop();\n return eachfn(fns, function (fn, _, cb) {\n fn.apply(that, args.concat([cb]));\n },\n callback);\n });\n if (args.length) {\n return go.apply(this, args);\n }\n else {\n return go;\n }\n });\n }\n\n async.applyEach = _applyEach(async.eachOf);\n async.applyEachSeries = _applyEach(async.eachOfSeries);\n\n\n async.forever = function (fn, callback) {\n var done = only_once(callback || noop);\n var task = ensureAsync(fn);\n function next(err) {\n if (err) {\n return done(err);\n }\n task(next);\n }\n next();\n };\n\n function ensureAsync(fn) {\n return _restParam(function (args) {\n var callback = args.pop();\n args.push(function () {\n var innerArgs = arguments;\n if (sync) {\n async.setImmediate(function () {\n callback.apply(null, innerArgs);\n });\n } else {\n callback.apply(null, innerArgs);\n }\n });\n var sync = true;\n fn.apply(this, args);\n sync = false;\n });\n }\n\n async.ensureAsync = ensureAsync;\n\n async.constant = _restParam(function(values) {\n var args = [null].concat(values);\n return function (callback) {\n return callback.apply(this, args);\n };\n });\n\n async.wrapSync =\n async.asyncify = function asyncify(func) {\n return _restParam(function (args) {\n var callback = args.pop();\n var result;\n try {\n result = func.apply(this, args);\n } catch (e) {\n return callback(e);\n }\n // if result is Promise object\n if (_isObject(result) && typeof result.then === \"function\") {\n result.then(function(value) {\n callback(null, value);\n })[\"catch\"](function(err) {\n callback(err.message ? err : new Error(err));\n });\n } else {\n callback(null, result);\n }\n });\n };\n\n // Node.js\n if (typeof module === 'object' && module.exports) {\n module.exports = async;\n }\n // AMD / RequireJS\n else if (typeof define === 'function' && define.amd) {\n define([], function () {\n return async;\n });\n }\n // included directly via