diff --git a/README.md b/README.md index 321a3967..770328e1 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ Change Log Version 1.1.3 - in build +* New: Added a new in-built texture. Sprites now use __default if no texture was provided (a 32x32 transparent PNG) or __missing if one was given but not found (a 32x32 black box with a green cross through it) +* New: Added Phaser.Filter. A new way to use the new WebGL shaders/filters that the new version of Pixi supports. * New: The object returned by Math.sinCosGenerator now contains a length property. * New: Phaser.BitmapData object. Can be used as a texture for a Sprite or Tiling Sprite. See the new examples and docs for details. * New: RenderTexture.render now takes a Phaser.Group. Also added renderXY for when you don't want to make a new Point object. @@ -68,6 +70,7 @@ Version 1.1.3 - in build * Fixed: Point.rotate asDegrees fixed (thanks BorisKozo) * Fixed: ArcadePhysics.separateTile wasn't returning the value, so the custom process callback wasn't getting called (thanks flameiguana) * Fixed: StageScaleMode.forceOrientation now correctly stores the forcePortrait value (thanks haden) +* Fixed: Fixes to Math and Loader (thanks theJare) * Updated: ArcadePhysics.updateMotion applies the dt to the velocity calculations as well as position now (thanks jcs) * Updated: RequestAnimationFrame now retains the callbackID which is passed to cancelRequestAnimationFrame. diff --git a/build/config.php b/build/config.php index 2739eb39..14bf6dc8 100644 --- a/build/config.php +++ b/build/config.php @@ -31,7 +31,7 @@ - + @@ -69,6 +69,7 @@ + diff --git a/examples/wip/binarySerpentsFilter.js b/examples/wip/binarySerpentsFilter.js index bb12c1f6..f8f656eb 100644 --- a/examples/wip/binarySerpentsFilter.js +++ b/examples/wip/binarySerpentsFilter.js @@ -14,10 +14,10 @@ PIXI.BinarySerpentsFilter = function(width, height, texture) ]; this.uniforms = { - iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }}, - iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, - iGlobalTime: { type: 'f', value: 1 }, - iDate: { type: 'f4', value: dates }, + iResolution: { type: '3f', value: { x: width, y: height, z: 0 }}, + iMouse: { type: '3f', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: '1f', value: 1 }, + iDate: { type: '4fv', value: dates }, iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' } }; diff --git a/examples/wip/book/part2.html b/examples/wip/book/part2.html index 2219255a..30f7099f 100644 --- a/examples/wip/book/part2.html +++ b/examples/wip/book/part2.html @@ -17,6 +17,8 @@ + + + + diff --git a/examples/wip/tunnel_demo.js b/examples/wip/tunnel_demo.js new file mode 100644 index 00000000..37a7c4bc --- /dev/null +++ b/examples/wip/tunnel_demo.js @@ -0,0 +1,35 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +var background; +var filter; + +function preload() { + + game.load.image('texture', 'wip/tex00.jpg'); + game.load.image('sea', 'assets/pics/undersea.jpg'); + +} + +function create() { + + game.add.sprite(0, 0, 'sea'); + + background = game.add.sprite(0, 0, 'texture'); + background.width = 800; + background.height = 600; + + filter = game.add.filter('Tunnel', 800, 600, background.texture); + + // filter.alpha = 0.5; + // filter.origin = 0.5; + + background.filters = [filter]; + +} + +function update() { + + filter.update(); + +} diff --git a/examples/wip/wobbleFilter.js b/examples/wip/wobbleFilter.js new file mode 100644 index 00000000..939b5897 --- /dev/null +++ b/examples/wip/wobbleFilter.js @@ -0,0 +1,103 @@ +PIXI.WobbleFilter = function(width, height, texture0, texture1) +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + var d = new Date(); + + var dates = [ + d.getFullYear(), // the year (four digits) + d.getMonth(), // the month (from 0-11) + d.getDate(), // the day of the month (from 1-31) + d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds() + ]; + + this.uniforms = { + iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture0, wrap: 'repeat' }, + iChannel1: { type: 'sampler2D', value: texture1, wrap: 'repeat' } + }; + + // Shader by deps (https://www.shadertoy.com/view/MssGDM) + this.fragmentSrc = [ + "precision mediump float;", + "uniform vec3 iResolution;", + "uniform float iGlobalTime;", + "uniform float iChannelTime[4];", + "uniform vec4 iMouse;", + "uniform vec4 iDate;", + "uniform vec3 iChannelResolution[4];", + "uniform sampler2D iChannel0;", + "uniform sampler2D iChannel1;", + "// add any extra uniforms here", + + "void main(void)", + "{", + "vec2 uv = (gl_FragCoord.xy / iResolution.xy);", + "uv.y = 1.0-uv.y;", + + "float time = iGlobalTime * 0.75;", + + "vec4 pixel2 = texture2D(iChannel1, (uv+vec2(sin(time),cos(time))) * 0.15 );", + + "float xDiff = pixel2.r * 0.02;", + "float yDiff = 0.0;", + + "vec2 diffVec = vec2( xDiff, yDiff );", + + "vec4 pixel = texture2D(iChannel0, uv + diffVec);", + + "gl_FragColor = pixel;", + "}"]; + +} + +PIXI.WobbleFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.WobbleFilter.prototype.constructor = PIXI.WobbleFilter; + +Object.defineProperty(PIXI.WobbleFilter.prototype, 'iGlobalTime', { + get: function() { + return this.uniforms.iGlobalTime.value; + }, + set: function(value) { + this.uniforms.iGlobalTime.value = value; + } +}); + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('texture0', 'wip/tex04.jpg'); + game.load.image('texture1', 'wip/tex10.png'); + +} + +var filter; +var sprite; + +function create() { + + noise = game.add.sprite(0, 0, 'texture1'); + + sprite = game.add.sprite(0, 0, 'texture0'); + sprite.width = 800; + sprite.height = 600; + + filter = new PIXI.WobbleFilter(sprite.width, sprite.height, sprite.texture, noise.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + +} + +function render() { +} diff --git a/filters/BinarySerpents.js b/filters/BinarySerpents.js new file mode 100644 index 00000000..34347d40 --- /dev/null +++ b/filters/BinarySerpents.js @@ -0,0 +1,96 @@ +/** +* Original shader by Trisomie21 (https://www.shadertoy.com/view/MslGRH) +* Tweaked, uniforms added and converted to Phaser/PIXI by Richard Davey +*/ +Phaser.Filter.BinarySerpents = function (game) { + + Phaser.Filter.call(this, game); + + this.uniforms.march = { type: '1i', value: 100 }; + this.uniforms.maxDistance = { type: '1f', value: 5.0 }; + this.uniforms.fog = { type: '1f', value: 5.0 }; + + this.fragmentSrc = [ + + "precision mediump float;", + "uniform vec3 resolution;", + "uniform float time;", + "uniform int march;", + "uniform float maxDistance;", + "uniform float fog;", + + "// With tweaks by PauloFalcao and Richard Davey", + + "float Texture3D(vec3 n, float res) {", + "n = floor(n*res+.5);", + "return fract(sin((n.x+n.y*1e5+n.z*1e7)*1e-4)*1e5);", + "}", + + "float map( vec3 p ) {", + "p.x+=sin(p.z*4.0+time*4.0)*0.1*cos(time*0.1);", + "p = mod(p,vec3(1.0, 1.0, 1.0))-0.5;", + "return length(p.xy)-.1;", + "}", + + "void main( void )", + "{", + "vec2 pos = (gl_FragCoord.xy*2.0 - resolution.xy) / resolution.y;", + "vec3 camPos = vec3(cos(time*0.3), sin(time*0.3), 1.5);", + "vec3 camTarget = vec3(0.0, 0.0, 0.0);", + + "vec3 camDir = normalize(camTarget-camPos);", + "vec3 camUp = normalize(vec3(0.0, 1.0, 0.0));", + "vec3 camSide = cross(camDir, camUp);", + "float focus = 2.0;", + + "vec3 rayDir = normalize(camSide*pos.x + camUp*pos.y + camDir*focus);", + "vec3 ray = camPos;", + "float d = 0.0, total_d = 0.0;", + "const int MAX_MARCH = 100;", + "float c = 1.0;", + + "for (int i=0; i < MAX_MARCH; ++i) {", + "if (i < march) {", + "d = map(ray);", + "total_d += d;", + "ray += rayDir * d;", + "if(abs(d)<0.001) { break; }", + "if(total_d>maxDistance) { c = 0.; total_d=maxDistance; break; }", + "}", + "}", + + "vec4 result = vec4( vec3(c*.4 , c*.6, c) * (fog - total_d) / fog, 1.0 );", + + "ray.z -= 5.+time*.5;", + "float r = Texture3D(ray, 33.);", + "gl_FragColor = result * (step(r, .3) + r * .2 + .1);", + "}" + ]; + +}; + +Phaser.Filter.BinarySerpents.prototype = Object.create(Phaser.Filter.prototype); +Phaser.Filter.BinarySerpents.prototype.constructor = Phaser.Filter.BinarySerpents; + +Phaser.Filter.BinarySerpents.prototype.init = function (width, height, march, maxDistance) { + + if (typeof march === 'undefined') { march = 100; } + if (typeof maxDistance === 'undefined') { maxDistance = 5.0; } + + this.setResolution(width, height); + this.uniforms.march.value = march; + this.uniforms.maxDistance.value = maxDistance; + +} + +Object.defineProperty(Phaser.Filter.BinarySerpents.prototype, 'fog', { + + get: function() { + return this.uniforms.fog.value; + }, + + set: function(value) { + this.uniforms.fog.value = value; + } + +}); diff --git a/filters/ColorBars.js b/filters/ColorBars.js new file mode 100644 index 00000000..33774890 --- /dev/null +++ b/filters/ColorBars.js @@ -0,0 +1,86 @@ +/** +* Original shader by thygate@gmail.com, rotation and color mix modifications by malc (mlashley@gmail.com) +* Tweaked, uniforms added and converted to Phaser/PIXI by Richard Davey +*/ +Phaser.Filter.ColorBars = function (game) { + + Phaser.Filter.call(this, game); + + this.uniforms.alpha = { type: '1f', value: 1 } + // this.uniforms.origin = { type: '1f', value: 2.0 } + + this.fragmentSrc = [ + + "// bars - thygate@gmail.com", + "// rotation and color mix modifications by malc (mlashley@gmail.com)", + "// modified by @hintz 2013-04-30", + + "precision mediump float;", + + "uniform vec3 resolution;", + "uniform float time;", + "uniform float alpha;", + + "vec2 position;", + "vec4 color;", + + "float f = 6.0;", + + "float c = cos(time / 2.0);", + "float s = sin(time / 2.0);", + "mat2 R = mat2(c, -s, s, -c);", + + "//float barsize = 0.15;", + "float barsize = 0.12;", + "//float barsangle = 200.0 * sin(time * 0.001);", + "float barsangle = 200.0 * cos(time * 0.001);", + + "vec4 bar(float pos, float r, float g, float b) {", + "return max(0.0, 1.0 - abs(pos - position.y) / barsize) * vec4(r, g, b, 1.0);", + "}", + + "void main(void)", + "{", + "position = (gl_FragCoord.xy - 0.5 * resolution.xy) / resolution.xx;", + "//position = 2.0 * position * R; // R = rotation", + "position = 2.5 * position * R;", + "//float t = time * 0.5; // 0.5 = spin speed", + "float t = time * 0.5;", + "vec4 color = vec4(0.0);", + "color += bar(sin(t), 1.0, 0.0, 0.0);", + "color += bar(sin(t + barsangle / f * 2.), 1.0, 0.5, 0.0);", + "color += bar(sin(t + barsangle / f * 4.), 1.0, 1.0, 0.0);", + "color += bar(sin(t + barsangle / f * 6.), 0.0, 1.0, 0.0);", + "color += bar(sin(t + barsangle / f * 8.), 0.0, 1.0, 1.0);", + "color += bar(sin(t + barsangle / f * 10.), 0.0, 0.0, 1.0);", + "color += bar(sin(t + barsangle / f * 12.), 0.5, 0.0, 1.0);", + "color += bar(sin(t + barsangle / f * 14.), 1.0, 0.0, 1.0);", + "color.a = alpha;", + "gl_FragColor = color;", + "}" + + ]; + +}; + +Phaser.Filter.ColorBars.prototype = Object.create(Phaser.Filter.prototype); +Phaser.Filter.ColorBars.prototype.constructor = Phaser.Filter.ColorBars; + +Phaser.Filter.ColorBars.prototype.init = function (width, height) { + + this.setResolution(width, height); + +} + +Object.defineProperty(Phaser.Filter.ColorBars.prototype, 'alpha', { + + get: function() { + return this.uniforms.alpha.value; + }, + + set: function(value) { + this.uniforms.alpha.value = value; + } + +}); + diff --git a/filters/SampleFilter.js b/filters/SampleFilter.js new file mode 100644 index 00000000..ba37a8e8 --- /dev/null +++ b/filters/SampleFilter.js @@ -0,0 +1,51 @@ +/** +* A sample demonstrating how to create new Phaser Filters. +*/ +Phaser.Filter.SampleFilter = function (game) { + + Phaser.Filter.call(this, game); + + /** + * By default the following uniforms are already created and available: + * + * uniform float time - The current number of elapsed milliseconds in the game. + * uniform vec3 resolution - The dimensions of the filter. Can be set via setSize(width, height) + * uniform vec4 mouse - The mouse / touch coordinates taken from the pointer given to the update function, if any. + * uniform sampler2D uSampler - The current texture (usually the texture of the Sprite the shader is bound to) + * + * Add in any additional vars you require. Here is a new one called 'wobble' that is a 2f: + * + * this.uniforms.wobble = { type: '2f', value: { x: 0, y: 0 }}; + * + * The supported types are: 1f, 1fv, 1i, 2f, 2fv, 2i, 2iv, 3f, 3fv, 3i, 3iv, 4f, 4fv, 4i, 4iv, mat2, mat3, mat4 and sampler2D. + */ + + this.uniforms.divisor = { type: '1f', value: 0.5 }; + + // The fragment shader source + this.fragmentSrc = [ + + "precision mediump float;", + "uniform vec3 resolution;", + "uniform float time;", + "uniform float divisor;", + + "void main(void) {", + "vec2 uv = gl_FragCoord.xy / resolution.xy;", + "gl_FragColor = vec4(uv, divisor * sin(time), 0.0);", + "}" + ]; + +}; + +Phaser.Filter.SampleFilter.prototype = Object.create(Phaser.Filter.prototype); +Phaser.Filter.SampleFilter.prototype.constructor = Phaser.Filter.SampleFilter; + +Phaser.Filter.SampleFilter.prototype.init = function (width, height, divisor) { + + if (typeof divisor == 'undefined') { divisor = 0.5 }; + + this.setResolution(width, height); + this.uniforms.divisor.value = divisor; + +} diff --git a/filters/Tunnel.js b/filters/Tunnel.js new file mode 100644 index 00000000..d7fc4680 --- /dev/null +++ b/filters/Tunnel.js @@ -0,0 +1,69 @@ +/** +* Original shader by 4rknova (https://www.shadertoy.com/view/lssGDn) +* Tweaked, uniforms added and converted to Phaser/PIXI by Richard Davey +*/ +Phaser.Filter.Tunnel = function (game) { + + Phaser.Filter.call(this, game); + + this.uniforms.alpha = { type: '1f', value: 1 } + this.uniforms.origin = { type: '1f', value: 2.0 } + this.uniforms.iChannel0 = { type: 'sampler2D', value: null, wrap: 'repeat' } + + this.fragmentSrc = [ + + "precision mediump float;", + "uniform vec3 resolution;", + "uniform float time;", + "uniform sampler2D iChannel0;", + "uniform float alpha;", + "uniform float origin;", + + "#define S 0.79577471545 // Precalculated 2.5 / PI", + "#define E 0.0001", + + "void main(void)", + "{", + "vec2 p = (origin * gl_FragCoord.xy / resolution.xy - 1.0) * vec2(resolution.x / resolution.y, 1.0);", + "vec2 t = vec2(S * atan(p.x, p.y), 1.0 / max(length(p), E));", + "vec3 c = texture2D(iChannel0, t + vec2(time * 0.1, time)).xyz;", + "gl_FragColor = vec4(c / (t.y + 0.5), alpha);", + "}" + + ]; + +}; + +Phaser.Filter.Tunnel.prototype = Object.create(Phaser.Filter.prototype); +Phaser.Filter.Tunnel.prototype.constructor = Phaser.Filter.Tunnel; + +Phaser.Filter.Tunnel.prototype.init = function (width, height, texture) { + + this.setResolution(width, height); + this.uniforms.iChannel0.value = texture; + +} + +Object.defineProperty(Phaser.Filter.Tunnel.prototype, 'alpha', { + + get: function() { + return this.uniforms.alpha.value; + }, + + set: function(value) { + this.uniforms.alpha.value = value; + } + +}); + +Object.defineProperty(Phaser.Filter.Tunnel.prototype, 'origin', { + + get: function() { + return this.uniforms.origin.value; + }, + + set: function(value) { + this.uniforms.origin.value = value.toFixed(2); + } + +}); diff --git a/resources/wip/32x32_t.png b/resources/wip/32x32_t.png new file mode 100644 index 00000000..b726a9e1 Binary files /dev/null and b/resources/wip/32x32_t.png differ diff --git a/src/Phaser.js b/src/Phaser.js index 1ec20647..0a8ea64f 100644 --- a/src/Phaser.js +++ b/src/Phaser.js @@ -30,6 +30,8 @@ var Phaser = Phaser || { EMITTER: 11, POLYGON: 12, BITMAPDATA: 13, + CANVAS_FILTER: 14, + WEBGL_FILTER: 15, NONE: 0, LEFT: 1, diff --git a/src/core/Filter.js b/src/core/Filter.js new file mode 100644 index 00000000..3d95d920 --- /dev/null +++ b/src/core/Filter.js @@ -0,0 +1,127 @@ +/** +* @author Richard Davey +* @copyright 2013 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* This is a base Filter template to use for any Phaser filter development. +* +* @class Phaser.Filter +* @classdesc Phaser - Filter +* @constructor +* @param {Phaser.Game} game - A reference to the currently running game. +* @param {Object} uniforms - Uniform mappings object +* @param {Array} fragmentSrc - The fragment shader code. +*/ +Phaser.Filter = function (game, uniforms, fragmentSrc) { + + /** + * @property {Phaser.Game} game - A reference to the currently running game. + */ + this.game = game; + + /** + * @property {number} type - The const type of this object, either Phaser.WEBGL_FILTER or Phaser.CANVAS_FILTER. + * @default + */ + this.type = Phaser.WEBGL_FILTER; + + /** + * An array of passes - some filters contain a few steps this array simply stores the steps in a linear fashion. + * For example the blur filter has two passes blurX and blurY. + * @property {array} passes - An array of filter objects. + * @private + */ + this.passes = [this]; + + /** + * @property {boolean} dirty - Internal PIXI var. + * @default + */ + this.dirty = true; + + /** + * @property {number} padding - Internal PIXI var. + * @default + */ + this.padding = 0; + + /** + * @property {object} uniforms - Default uniform mappings. + */ + this.uniforms = { + + resolution: { type: '3f', value: { x: 256, y: 256, z: 0 }}, + time: { type: '1f', value: 0 }, + mouse: { type: '4f', value: { x: 0, y: 0, z: 0, w: 0 }} + + }; + + /** + * @property {array} fragmentSrc - The fragment shader code. + */ + this.fragmentSrc = fragmentSrc || []; + +}; + +Phaser.Filter.prototype = { + + init: function () { + // This should be over-ridden. Will receive a variable number of arguments. + }, + + setResolution: function (width, height) { + + this.uniforms.resolution.value.x = width; + this.uniforms.resolution.value.y = height; + + }, + + update: function (pointer) { + + if (typeof pointer !== 'undefined') + { + this.uniforms.mouse.x = pointer.x; + this.uniforms.mouse.y = pointer.y; + } + + this.uniforms.time.value = this.game.time.totalElapsedSeconds(); + + }, + + /** + * Clear down this Filter and null out references + * @method Phaser.Filter#destroy + */ + destroy: function () { + + this.game = null; + + } + +}; + +Object.defineProperty(Phaser.Filter.prototype, 'width', { + + get: function() { + return this.uniforms.resolution.value.x; + }, + + set: function(value) { + this.uniforms.resolution.value.x = value; + } + +}); + +Object.defineProperty(Phaser.Filter.prototype, 'height', { + + get: function() { + return this.uniforms.resolution.value.y; + }, + + set: function(value) { + this.uniforms.resolution.value.y = value; + } + +}); diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js index 0b91e0f3..baabe344 100644 --- a/src/gameobjects/GameObjectFactory.js +++ b/src/gameobjects/GameObjectFactory.js @@ -288,6 +288,26 @@ Phaser.GameObjectFactory.prototype = { return new Phaser.BitmapData(this.game, width, height); + }, + + /** + * A WebGL shader/filter that can be applied to Sprites. + * + * @method Phaser.GameObjectFactory#filter + * @param {string} filter - The name of the filter you wish to create, for example "HueRotate" or "SineWave" + * @param {...} - Whatever parameters are needed to be passed to the filter init function. + * @return {Phaser.Filter} The newly created Phaser.Filter object. + */ + filter: function (filter) { + + var args = Array.prototype.splice.call(arguments, 1); + + var f = new Phaser.Filter[filter](this.game); + + f.init.apply(f, args); + + return f; + } }; \ No newline at end of file diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index 33894485..260c0a8b 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -118,11 +118,16 @@ Phaser.Sprite = function (game, x, y, key, frame) { } else { - if (key == null || this.game.cache.checkImageKey(key) == false) + if (key === null || typeof key === 'undefined') { key = '__default'; this.key = key; } + else if (typeof key === 'string' && this.game.cache.checkImageKey(key) == false) + { + key = '__missing'; + this.key = key; + } PIXI.Sprite.call(this, PIXI.TextureCache[key]); diff --git a/src/loader/Cache.js b/src/loader/Cache.js index 764666f5..c88bb776 100644 --- a/src/loader/Cache.js +++ b/src/loader/Cache.js @@ -69,6 +69,7 @@ Phaser.Cache = function (game) { this._bitmapDatas = {}; this.addDefaultImage(); + this.addMissingImage(); /** * @property {Phaser.Signal} onSoundUnlock - Description. @@ -239,14 +240,14 @@ Phaser.Cache.prototype = { }, /** - * Adds a default image to be used when a key is wrong / missing. Is mapped to the key __default. + * Adds a default image to be used in special cases such as WebGL Filters. Is mapped to the key __default. * * @method Phaser.Cache#addDefaultImage */ addDefaultImage: function () { var img = new Image(); - img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="; + img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="; this._images['__default'] = { url: null, data: img, spriteSheet: false }; this._images['__default'].frame = new Phaser.Frame(0, 0, 0, 32, 32, '', ''); @@ -256,6 +257,24 @@ Phaser.Cache.prototype = { }, + /** + * Adds an image to be used when a key is wrong / missing. Is mapped to the key __missing. + * + * @method Phaser.Cache#addMissingImage + */ + addMissingImage: function () { + + var img = new Image(); + img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="; + + this._images['__missing'] = { url: null, data: img, spriteSheet: false }; + this._images['__missing'].frame = new Phaser.Frame(0, 0, 0, 32, 32, '', ''); + + PIXI.BaseTextureCache['__missing'] = new PIXI.BaseTexture(img); + PIXI.TextureCache['__missing'] = new PIXI.Texture(PIXI.BaseTextureCache['__missing']); + + }, + /** * Add a new text data. * diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 256c8caa..4cc10273 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -368,10 +368,6 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { */ PIXI.DisplayObject.prototype.addFilter = function(data) { - //if(this.filter)return; - //this.filter = true; -// data[0].target = this; - // insert a filter block.. // TODO Onject pool thease bad boys.. diff --git a/src/pixi/filters/AbstractFilter.js b/src/pixi/filters/AbstractFilter.js index c1e22b47..4e40c653 100644 --- a/src/pixi/filters/AbstractFilter.js +++ b/src/pixi/filters/AbstractFilter.js @@ -9,9 +9,9 @@ * @class AbstractFilter * @constructor * @param fragmentSrc - * @param unifroms + * @param uniforms */ -PIXI.AbstractFilter = function(fragmentSrc, unifroms) +PIXI.AbstractFilter = function(fragmentSrc, uniforms) { /** * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. @@ -30,7 +30,7 @@ PIXI.AbstractFilter = function(fragmentSrc, unifroms) @property uniforms @private */ - this.uniforms = unifroms || {}; + this.uniforms = uniforms || {}; this.fragmentSrc = fragmentSrc || []; } diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 7fef33c3..38a99b46 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -12,7 +12,7 @@ PIXI.BlurXFilter = function() // set the uniforms this.uniforms = { - blur: {type: 'f', value: 1/512}, + blur: {type: '1f', value: 1/512}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index 4b9d352c..d472f79c 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -12,7 +12,7 @@ PIXI.BlurYFilter = function() // set the uniforms this.uniforms = { - blur: {type: 'f', value: 1/512}, + blur: {type: '1f', value: 1/512}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index d891db83..8039af84 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -17,7 +17,7 @@ PIXI.ColorStepFilter = function() // set the uniforms this.uniforms = { - step: {type: 'f', value: 5}, + step: {type: '1f', value: 5}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index cd050cb0..2d26715e 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -12,7 +12,7 @@ PIXI.CrossHatchFilter = function() // set the uniforms this.uniforms = { - blur: {type: 'f', value: 1/512}, + blur: {type: '1f', value: 1/512}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 6c05498d..5662731f 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -23,10 +23,10 @@ PIXI.DisplacementFilter = function(texture) //console.log() this.uniforms = { displacementMap: {type: 'sampler2D', value:texture}, - scale: {type: 'f2', value:{x:30, y:30}}, - offset: {type: 'f2', value:{x:0, y:0}}, - mapDimensions: {type: 'f2', value:{x:1, y:5112}}, - dimensions: {type: 'f4', value:[0,0,0,0]} + scale: {type: '2f', value:{x:30, y:30}}, + offset: {type: '2f', value:{x:0, y:0}}, + mapDimensions: {type: '2f', value:{x:1, y:5112}}, + dimensions: {type: '4fv', value:[0,0,0,0]} }; diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index f9f5452e..6c59d4c4 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -17,9 +17,9 @@ PIXI.DotScreenFilter = function() // set the uniforms this.uniforms = { - scale: {type: 'f', value:1}, - angle: {type: 'f', value:5}, - dimensions: {type: 'f4', value:[0,0,0,0]} + scale: {type: '1f', value:1}, + angle: {type: '1f', value:5}, + dimensions: {type: '4fv', value:[0,0,0,0]} }; this.fragmentSrc = [ diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index a39888f6..9b6bb61d 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -17,7 +17,7 @@ PIXI.GrayFilter = function() // set the uniforms this.uniforms = { - gray: {type: 'f', value: 1}, + gray: {type: '1f', value: 1}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/GreyFilter.js b/src/pixi/filters/GreyFilter.js deleted file mode 100644 index d182975f..00000000 --- a/src/pixi/filters/GreyFilter.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * - * This turns your displayObjects to black and white. - * @class GreyFilter - * @contructor - */ -PIXI.GreyFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - grey: {type: 'f', value: 1}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "uniform float grey;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord);", - "gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), grey);", - "gl_FragColor = gl_FragColor * vColor;", - "}" - ]; -} - -PIXI.GreyFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.GreyFilter.prototype.constructor = PIXI.GreyFilter; - -/** -The strength of the grey. 1 will make the object black and white, 0 will make the object its normal color -@property grey -*/ -Object.defineProperty(PIXI.GreyFilter.prototype, 'grey', { - get: function() { - return this.uniforms.grey.value; - }, - set: function(value) { - this.uniforms.grey.value = value; - } -}); diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index 3d6ee784..afd196e1 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -16,7 +16,7 @@ PIXI.InvertFilter = function() // set the uniforms this.uniforms = { - invert: {type: 'f', value: 1}, + invert: {type: '1f', value: 1}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/MaskFilter.js b/src/pixi/filters/MaskFilter.js deleted file mode 100644 index 1cf00ebe..00000000 --- a/src/pixi/filters/MaskFilter.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - - -PIXI.MaskFilter = function(graphics) -{ - // the graphics data that will be used for filtering - this.graphics; -} - diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index bc6eb354..d2680158 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -16,9 +16,9 @@ PIXI.PixelateFilter = function() // set the uniforms this.uniforms = { - invert: {type: 'f', value: 0}, - dimensions: {type: 'f4', value:new Float32Array([10000, 100, 10, 10])}, - pixelSize: {type: 'f2', value:{x:10, y:10}}, + invert: {type: '1f', value: 0}, + dimensions: {type: '4fv', value:new Float32Array([10000, 100, 10, 10])}, + pixelSize: {type: '2f', value:{x:10, y:10}}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 5303d646..35a837eb 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -12,10 +12,10 @@ PIXI.RGBSplitFilter = function() // set the uniforms this.uniforms = { - red: {type: 'f2', value: {x:20, y:20}}, - green: {type: 'f2', value: {x:-20, y:20}}, - blue: {type: 'f2', value: {x:20, y:-20}}, - dimensions: {type: 'f4', value:[0,0,0,0]} + red: {type: '2f', value: {x:20, y:20}}, + green: {type: '2f', value: {x:-20, y:20}}, + blue: {type: '2f', value: {x:20, y:-20}}, + dimensions: {type: '4fv', value:[0,0,0,0]} }; this.fragmentSrc = [ diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index b3209337..22f31a43 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -18,7 +18,7 @@ PIXI.SepiaFilter = function() // set the uniforms this.uniforms = { - sepia: {type: 'f', value: 1}, + sepia: {type: '1f', value: 1}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/SmartBlurFilter.js b/src/pixi/filters/SmartBlurFilter.js index b0ddf87a..93567e85 100644 --- a/src/pixi/filters/SmartBlurFilter.js +++ b/src/pixi/filters/SmartBlurFilter.js @@ -12,7 +12,7 @@ PIXI.SmartBlurFilter = function() // set the uniforms this.uniforms = { - blur: {type: 'f', value: 1/512}, + blur: {type: '1f', value: 1/512}, }; this.fragmentSrc = [ diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index b477b0b3..0dce008b 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -16,9 +16,9 @@ PIXI.TwistFilter = function() // set the uniforms this.uniforms = { - radius: {type: 'f', value:0.5}, - angle: {type: 'f', value:5}, - offset: {type: 'f2', value:{x:0.5, y:0.5}}, + radius: {type: '1f', value:0.5}, + angle: {type: '1f', value:5}, + offset: {type: '2f', value:{x:0.5, y:0.5}}, }; this.fragmentSrc = [ diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index 769edaaf..6af6f340 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -1,208 +1,294 @@ /** * @author Mat Groves http://matgroves.com/ @Doormat23 + * @author Richard Davey http://www.photonstorm.com @photonstorm */ - +/** +* @class PIXI.PixiShader +* @constructor +*/ PIXI.PixiShader = function() { - // the webGL program.. - this.program; - - this.fragmentSrc = [ - "precision lowp float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;", - "}" - ]; - + /** + * @property {any} program - The WebGL program. + */ + this.program; + + /** + * @property {array} fragmentSrc - The fragment shader. + */ + this.fragmentSrc = [ + "precision lowp float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform sampler2D uSampler;", + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;", + "}" + ]; + + /** + * @property {number} textureCount - A local texture counter for multi-texture shaders. + */ + this.textureCount = 0; + } +/** +* @method PIXI.PixiShader#init +*/ PIXI.PixiShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc) - - var gl = PIXI.gl; + var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc) + + var gl = PIXI.gl; gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, "uSampler"); - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, "uSampler"); + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + // this.dimensions = gl.getUniformLocation(program, "dimensions"); // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); - + this.colorAttribute = gl.getAttribLocation(program, "aColor"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + // add those custom shaders! for (var key in this.uniforms) { - - // get the uniform locations.. - // program[key] = + // get the uniform locations.. this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key); - - } - this.program = program; + this.program = program; } +/** +* Updates the shader uniform values. +* Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ +* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf +* +* @method PIXI.PixiShader#syncUniforms +*/ PIXI.PixiShader.prototype.syncUniforms = function() { - var gl = PIXI.gl; - - for (var key in this.uniforms) + this.textureCount = 1; + + var gl = PIXI.gl; + + for (var key in this.uniforms) { - //var - var type = this.uniforms[key].type; - - // need to grow this! + var type = this.uniforms[key].type; + var transpose = false; -/* - http://www.khronos.org/registry/webgl/specs/latest/1.0/ - http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf - - void uniform1f(WebGLUniformLocation? location, GLfloat x); - void uniform1fv(WebGLUniformLocation? location, Float32Array v); - void uniform1fv(WebGLUniformLocation? location, sequence v); - void uniform1i(WebGLUniformLocation? location, GLint x); - void uniform1iv(WebGLUniformLocation? location, Int32Array v); - void uniform1iv(WebGLUniformLocation? location, sequence v); - void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); - void uniform2fv(WebGLUniformLocation? location, Float32Array v); - void uniform2fv(WebGLUniformLocation? location, sequence v); - void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); - void uniform2iv(WebGLUniformLocation? location, Int32Array v); - void uniform2iv(WebGLUniformLocation? location, sequence v); - void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); - void uniform3fv(WebGLUniformLocation? location, Float32Array v); - void uniform3fv(WebGLUniformLocation? location, sequence v); - void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); - void uniform3iv(WebGLUniformLocation? location, Int32Array v); - void uniform3iv(WebGLUniformLocation? location, sequence v); - void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void uniform4fv(WebGLUniformLocation? location, Float32Array v); - void uniform4fv(WebGLUniformLocation? location, sequence v); - void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); - void uniform4iv(WebGLUniformLocation? location, Int32Array v); - void uniform4iv(WebGLUniformLocation? location, sequence v); - - void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); - void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); - void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); - void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); - void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); - void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); -*/ - - if(type == "f") - { - gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value); - } - if(type == "f2") - { - gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y); - } - else if(type == "f3") + if (this.uniforms[key].transpose) { + transpose = this.uniforms[key].transpose; + } + + if (type == "1f") + { + // void uniform1f(WebGLUniformLocation? location, GLfloat x); + gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "1fv") + { + // void uniform1fv(WebGLUniformLocation? location, Float32Array v); + // void uniform1fv(WebGLUniformLocation? location, sequence v); + gl.uniform1fv(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "1i") + { + // void uniform1i(WebGLUniformLocation? location, GLint x); + gl.uniform1i(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "1iv") + { + // void uniform1iv(WebGLUniformLocation? location, Int32Array v); + // void uniform1iv(WebGLUniformLocation? location, sequence v); + gl.uniform1i(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "2f") + { + // void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); + gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y); + } + else if (type == "2fv") + { + // void uniform2fv(WebGLUniformLocation? location, Float32Array v); + // void uniform2fv(WebGLUniformLocation? location, sequence v); + gl.uniform2fv(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "2i") + { + // void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); + gl.uniform2i(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y); + } + else if (type == "2iv") + { + // void uniform2iv(WebGLUniformLocation? location, Int32Array v); + // void uniform2iv(WebGLUniformLocation? location, sequence v); + gl.uniform2iv(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "3f") + { + // void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); gl.uniform3f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y, this.uniforms[key].value.z); } - else if(type == "f3v") + else if (type == "3fv") { + // void uniform3fv(WebGLUniformLocation? location, Float32Array v); + // void uniform3fv(WebGLUniformLocation? location, sequence v); gl.uniform3fv(this.uniforms[key].uniformLocation, this.uniforms[key].value); } - else if(type == "f4") + else if (type == "3i") { + // void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); + gl.uniform3i(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y, this.uniforms[key].value.z); + } + else if (type == "3iv") + { + // void uniform3iv(WebGLUniformLocation? location, Int32Array v); + // void uniform3iv(WebGLUniformLocation? location, sequence v); + gl.uniform3iv(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "4f") + { + // void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + gl.uniform4f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y, this.uniforms[key].value.z, this.uniforms[key].value.w); + } + else if (type == "4fv") + { + // void uniform4fv(WebGLUniformLocation? location, Float32Array v); + // void uniform4fv(WebGLUniformLocation? location, sequence v); gl.uniform4fv(this.uniforms[key].uniformLocation, this.uniforms[key].value); } - else if(type == "mat4") - { - gl.uniformMatrix4fv(this.uniforms[key].uniformLocation, false, this.uniforms[key].value); - } - else if(type == "sampler2D") - { - var texture = this.uniforms[key].value.baseTexture._glTexture; - var image = this.uniforms[key].value.baseTexture.source; - var format = gl.RGBA; - - if (this.uniforms[key].format && this.uniforms[key].format == 'luminance') + else if (type == "4i") + { + // void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); + gl.uniform4i(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y, this.uniforms[key].value.z, this.uniforms[key].value.w); + } + else if (type == "4iv") + { + // void uniform4iv(WebGLUniformLocation? location, Int32Array v); + // void uniform4iv(WebGLUniformLocation? location, sequence v); + gl.uniform4iv(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + else if (type == "mat2") + { + // void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + // void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + gl.uniformMatrix2fv(this.uniforms[key].uniformLocation, transpose, this.uniforms[key].value); + } + else if (type == "mat3") + { + // void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + // void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + gl.uniformMatrix3fv(this.uniforms[key].uniformLocation, transpose, this.uniforms[key].value); + } + else if (type == "mat4") + { + // void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + // void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + gl.uniformMatrix4fv(this.uniforms[key].uniformLocation, transpose, this.uniforms[key].value); + } + else if (type == "sampler2D") + { + if (this.uniforms[key].value && this.uniforms[key].value.baseTexture.hasLoaded) { - format = gl.LUMINANCE; - } + var texture = this.uniforms[key].value.baseTexture._glTexture; + var image = this.uniforms[key].value.baseTexture.source; + var format = gl.RGBA; - gl.activeTexture(gl.TEXTURE1); + if (this.uniforms[key].format && this.uniforms[key].format == 'luminance') + { + format = gl.LUMINANCE; + } - if (this.uniforms[key].wrap) - { - if (this.uniforms[key].wrap == 'no-repeat' || this.uniforms[key].wrap === false) + gl.activeTexture(gl['TEXTURE' + this.textureCount]); + + if (this.uniforms[key].wrap) + { + if (this.uniforms[key].wrap == 'no-repeat' || this.uniforms[key].wrap === false) + { + this.createGLTextureLinear(gl, image, texture); + } + else if (this.uniforms[key].wrap == 'repeat' || this.uniforms[key].wrap === true) + { + this.createGLTexture(gl, image, format, texture); + } + else if (this.uniforms[key].wrap == 'nearest-repeat') + { + this.createGLTextureNearestRepeat(gl, image, texture); + } + else if (this.uniforms[key].wrap == 'nearest') + { + this.createGLTextureNearest(gl, image, texture); + } + else if (this.uniforms[key].wrap == 'audio') + { + this.createAudioTexture(gl, texture); + } + else if (this.uniforms[key].wrap == 'keyboard') + { + this.createKeyboardTexture(gl, texture); + } + } + else { this.createGLTextureLinear(gl, image, texture); } - else if (this.uniforms[key].wrap == 'repeat' || this.uniforms[key].wrap === true) - { - this.createGLTexture(gl, image, format, texture); - } - else if (this.uniforms[key].wrap == 'nearest-repeat') - { - this.createGLTextureNearestRepeat(gl, image, texture); - } - else if (this.uniforms[key].wrap == 'nearest') - { - this.createGLTextureNearest(gl, image, texture); - } - else if (this.uniforms[key].wrap == 'audio') - { - this.createAudioTexture(gl, texture); - } - else if (this.uniforms[key].wrap == 'keyboard') - { - this.createKeyboardTexture(gl, texture); - } - } - else - { - this.createGLTextureLinear(gl, image, texture); - } - gl.uniform1i(this.uniforms[key].uniformLocation, 1); - - // activate texture.. - // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); - // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value); - } + gl.uniform1i(this.uniforms[key].uniformLocation, this.textureCount); + + this.textureCount++; + } + } } }; +/** +* Binds the given texture and image data. The texture is set to REPEAT. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createGLTexture +*/ PIXI.PixiShader.prototype.createGLTexture = function(gl, image, format, texture) { - gl.bindTexture( gl.TEXTURE_2D, texture); - gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false); - gl.texImage2D( gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, image); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.generateMipmap(gl.TEXTURE_2D); } +/** +* Binds the given texture and image data. The texture is set to CLAMP_TO_EDGE. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createGLTextureLinear +*/ PIXI.PixiShader.prototype.createGLTextureLinear = function(gl, image, texture) { - gl.bindTexture( gl.TEXTURE_2D, texture); - gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false); - gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 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); } +/** +* Binds the given texture and image data. The texture is set to REPEAT with NEAREST. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createGLTextureNearestRepeat +*/ PIXI.PixiShader.prototype.createGLTextureNearestRepeat = function(gl, image, texture) { gl.bindTexture(gl.TEXTURE_2D, texture); @@ -214,6 +300,11 @@ PIXI.PixiShader.prototype.createGLTextureNearestRepeat = function(gl, image, tex gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); } +/** +* Binds the given texture and image data. The texture is set to CLAMP_TO_EDGE with NEAREST. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createGLTextureNearest +*/ PIXI.PixiShader.prototype.createGLTextureNearest = function(gl, image, texture) { gl.bindTexture(gl.TEXTURE_2D, texture); @@ -225,41 +316,53 @@ PIXI.PixiShader.prototype.createGLTextureNearest = function(gl, image, texture) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); } +/** +* Binds the given texture data. The texture is set to CLAMP_TO_EDGE with LUMINANCE. Designed for use with real-time audio data. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createAudioTexture +*/ PIXI.PixiShader.prototype.createAudioTexture = function(gl, texture) { - gl.bindTexture( gl.TEXTURE_2D, texture ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ; - gl.texImage2D( gl.TEXTURE_2D, 0, gl.LUMINANCE, 512, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null); + gl.bindTexture(gl.TEXTURE_2D, texture ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, 512, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null); } +/** +* Binds the given texture data. The texture is set to CLAMP_TO_EDGE with LUMINANCE. Designed for use with keyboard input data. +* Code based on Effects.js from ShaderToy.com +* @method PIXI.PixiShader#createKeyboardTexture +*/ PIXI.PixiShader.prototype.createKeyboardTexture = function(gl, texture) { - gl.bindTexture( gl.TEXTURE_2D, texture ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ); - gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ; - gl.texImage2D( gl.TEXTURE_2D, 0, gl.LUMINANCE, 256, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null); + gl.bindTexture(gl.TEXTURE_2D, texture ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, 256, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null); } PIXI.PixiShader.defaultVertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", - - "uniform vec2 projectionVector;", - "uniform vec2 offsetVector;", - "varying vec2 vTextureCoord;", - - "varying float vColor;", + + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float aColor;", - "const vec2 center = vec2(-1.0, 1.0);", - "void main(void) {", - "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" + "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", + "varying vec2 vTextureCoord;", + + "varying float vColor;", + + "const vec2 center = vec2(-1.0, 1.0);", + + "void main(void) {", + "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "vColor = aColor;", + "}" ]; diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index 7a52a9f2..b0f2da76 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -25,7 +25,7 @@ PIXI.WebGLRenderGroup = function(gl, transparent) this.batchs = []; this.toRemove = []; - console.log(this.transparent) + // console.log(this.transparent) this.filterManager = new PIXI.WebGLFilterManager(this.transparent); }