diff --git a/Gruntfile.js b/Gruntfile.js index 0bdda1f2..bb57821c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,12 +27,30 @@ module.exports = function (grunt) { 'src/pixi/extras/Strip.js', 'src/pixi/extras/Rope.js', 'src/pixi/extras/TilingSprite.js', + 'src/pixi/filters/AbstractFilter.js', + 'src/pixi/filters/BlurFilter.js', + 'src/pixi/filters/BlurXFilter.js', + 'src/pixi/filters/BlurYFilter.js', + 'src/pixi/filters/ColorMatrixFilter.js', + 'src/pixi/filters/CrossHatchFilter.js', + 'src/pixi/filters/DisplacementFilter.js', + 'src/pixi/filters/DotScreenFilter.js', 'src/pixi/filters/FilterBlock.js', - 'src/pixi/filters/MaskFilter.js', + 'src/pixi/filters/GreyFilter.js', + 'src/pixi/filters/InvertFilter.js', + 'src/pixi/filters/PixelateFilter.js', + 'src/pixi/filters/RGBSplitFilter.js', + 'src/pixi/filters/SepiaFilter.js', + 'src/pixi/filters/SmartBlurFilter.js', + 'src/pixi/filters/TwistFilter.js', 'src/pixi/primitives/Graphics.js', 'src/pixi/renderers/canvas/CanvasGraphics.js', 'src/pixi/renderers/canvas/CanvasRenderer.js', + 'src/pixi/renderers/webgl/PixiShader.js', + 'src/pixi/renderers/webgl/PrimitiveShader.js', + 'src/pixi/renderers/webgl/StripShader.js', 'src/pixi/renderers/webgl/WebGLBatch.js', + 'src/pixi/renderers/webgl/WebGLFilterManager.js', 'src/pixi/renderers/webgl/WebGLGraphics.js', 'src/pixi/renderers/webgl/WebGLRenderer.js', 'src/pixi/renderers/webgl/WebGLRenderGroup.js', diff --git a/README.md b/README.md index 733212b9..06f53253 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Change Log Version 1.1.3 - in build +* New: Updated to use the latest version of Pixi.js - which means you can now use all the sexy new WebGL filters they added :) * New: Sprite.animations.getAnimation will return an animation instance which was added by name. * New: Added Mouse.button which is set to the button that was pressed: Phaser.Mouse.LEFT_BUTTON, MIDDLE_BUTTON or RIGHT_BUTTON (thanks wKLV) * New: Added Mouse.pointerLock signal which you can listen to whenever the browser enters or leaves pointer lock mode. @@ -54,8 +55,6 @@ Version 1.1.3 - in build You can view the complete Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md -![Tanks](http://www.photonstorm.com/wp-content/uploads/2013/10/phaser_tanks-640x480.png) - How to Build ------------ @@ -65,6 +64,8 @@ We also provide a Grunt script that will build Phaser from source along with all Run `grunt` in the phaser folder for a list of command-line options. +![Tanks](http://www.photonstorm.com/wp-content/uploads/2013/10/phaser_tanks-640x480.png) + Requirements ------------ diff --git a/build/config.php b/build/config.php index e41fb353..f6d76bc4 100644 --- a/build/config.php +++ b/build/config.php @@ -2,41 +2,67 @@ // All JS files in build order. // Much easier for debugging re: line numbers ?> - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/phaser.d.ts b/build/phaser.d.ts index 249e9d2a..0a29e288 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -1,5 +1,6 @@ declare class Phaser { static VERSION: string; + static DEV_VERSION: string; static GAMES: Array; static AUTO: number; static CANVAS: number; @@ -252,7 +253,7 @@ declare module Phaser { } class Game { - constructor(width: number, height: number, renderer: number, parent: string, state: Phaser.StateManager, transparent: boolean, antialias: boolean); + constructor(width: number, height: number, renderer: number, parent: string, state: object, transparent: boolean, antialias: boolean); id: number; width: number; height: number; diff --git a/examples/_site/view_full.html b/examples/_site/view_full.html index f8c2cd99..ce7a420b 100644 --- a/examples/_site/view_full.html +++ b/examples/_site/view_full.html @@ -15,34 +15,64 @@ + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + diff --git a/examples/_site/view_lite.html b/examples/_site/view_lite.html index 2768996c..8e51476a 100644 --- a/examples/_site/view_lite.html +++ b/examples/_site/view_lite.html @@ -15,32 +15,61 @@ + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + diff --git a/examples/assets/games/orbit/background.png b/examples/assets/games/orbit/background.png new file mode 100644 index 00000000..8b4f9d69 Binary files /dev/null and b/examples/assets/games/orbit/background.png differ diff --git a/examples/assets/games/orbit/ball.png b/examples/assets/games/orbit/ball.png new file mode 100644 index 00000000..d3b30f67 Binary files /dev/null and b/examples/assets/games/orbit/ball.png differ diff --git a/examples/assets/games/orbit/bg.png b/examples/assets/games/orbit/bg.png new file mode 100644 index 00000000..6bb3c369 Binary files /dev/null and b/examples/assets/games/orbit/bg.png differ diff --git a/examples/assets/games/orbit/bricks.png b/examples/assets/games/orbit/bricks.png new file mode 100644 index 00000000..1a29cbbb Binary files /dev/null and b/examples/assets/games/orbit/bricks.png differ diff --git a/examples/assets/games/orbit/lazer.png b/examples/assets/games/orbit/lazer.png new file mode 100644 index 00000000..a8478589 Binary files /dev/null and b/examples/assets/games/orbit/lazer.png differ diff --git a/examples/assets/games/orbit/levels.json b/examples/assets/games/orbit/levels.json new file mode 100644 index 00000000..54f1847d --- /dev/null +++ b/examples/assets/games/orbit/levels.json @@ -0,0 +1,72 @@ +{ "height":30, + "layers":[ + { + "height":30, + "image":"background.png", + "name":"background", + "opacity":1, + "type":"imagelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 0, 0, 0, 0, 0, 0, 0, 14, 3, 3, 14, 0, 0, 0, 0, 0, 14, 13, 3, 3, 13, 14, 0, 0, 0, 0, 13, 3, 3, 3, 3, 13, 0, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 2, 3, 3, 2, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 5, 5, 5, 5, 13, 14, 0, 0, 14, 13, 1, 1, 1, 1, 13, 14, 0, 0, 0, 14, 1, 1, 1, 1, 14, 0, 0, 0, 0, 14, 13, 1, 1, 13, 14, 0, 0, 0, 0, 0, 14, 13, 13, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":30, + "name":"level 02", + "opacity":1, + "type":"tilelayer", + "visible":false, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":30, + "name":"level 01", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "height":30, + "image":"wall.png", + "name":"walls", + "opacity":1, + "type":"imagelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "image":"bricks.png", + "imageheight":32, + "imagewidth":224, + "margin":0, + "name":"bricks", + "properties": + { + + }, + "spacing":0, + "tileheight":16, + "tilewidth":32 + }], + "tilewidth":32, + "version":1, + "width":10 +} \ No newline at end of file diff --git a/examples/assets/games/orbit/levels.tmx b/examples/assets/games/orbit/levels.tmx new file mode 100644 index 00000000..fecf95da --- /dev/null +++ b/examples/assets/games/orbit/levels.tmx @@ -0,0 +1,22 @@ + + + + + + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAADAAAAAwAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAANAAAAAwAAAAMAAAANAAAADgAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAwAAAAMAAAADAAAAAwAAAA0AAAAAAAAAAAAAAAAAAAAOAAAADQAAAAMAAAADAAAAAwAAAAMAAAANAAAADgAAAAAAAAAAAAAADgAAAA0AAAADAAAAAwAAAAMAAAADAAAADQAAAA4AAAAAAAAAAAAAAA4AAAANAAAAAgAAAAMAAAADAAAAAgAAAA0AAAAOAAAAAAAAAAAAAAAOAAAADQAAAAMAAAADAAAAAwAAAAMAAAANAAAADgAAAAAAAAAAAAAADgAAAA0AAAADAAAAAwAAAAMAAAADAAAADQAAAA4AAAAAAAAAAAAAAA4AAAANAAAAAwAAAAMAAAADAAAAAwAAAA0AAAAOAAAAAAAAAAAAAAAOAAAADQAAAAUAAAAFAAAABQAAAAUAAAANAAAADgAAAAAAAAAAAAAADgAAAA0AAAABAAAAAQAAAAEAAAABAAAADQAAAA4AAAAAAAAAAAAAAAAAAAAOAAAAAQAAAAEAAAABAAAAAQAAAA4AAAAAAAAAAAAAAAAAAAAAAAAADgAAAA0AAAABAAAAAQAAAA0AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADQAAAA0AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + + + + diff --git a/examples/assets/games/orbit/orbit.png b/examples/assets/games/orbit/orbit.png new file mode 100644 index 00000000..9b5ff378 Binary files /dev/null and b/examples/assets/games/orbit/orbit.png differ diff --git a/examples/assets/games/orbit/paddle1.png b/examples/assets/games/orbit/paddle1.png new file mode 100644 index 00000000..a9ded501 Binary files /dev/null and b/examples/assets/games/orbit/paddle1.png differ diff --git a/examples/assets/games/orbit/paddle2.png b/examples/assets/games/orbit/paddle2.png new file mode 100644 index 00000000..ca54849f Binary files /dev/null and b/examples/assets/games/orbit/paddle2.png differ diff --git a/examples/assets/games/orbit/powerup_ball.png b/examples/assets/games/orbit/powerup_ball.png new file mode 100644 index 00000000..fea3374b Binary files /dev/null and b/examples/assets/games/orbit/powerup_ball.png differ diff --git a/examples/assets/games/orbit/powerup_lazer.png b/examples/assets/games/orbit/powerup_lazer.png new file mode 100644 index 00000000..323e5a89 Binary files /dev/null and b/examples/assets/games/orbit/powerup_lazer.png differ diff --git a/examples/assets/games/orbit/powerup_multiball.png b/examples/assets/games/orbit/powerup_multiball.png new file mode 100644 index 00000000..5e050eee Binary files /dev/null and b/examples/assets/games/orbit/powerup_multiball.png differ diff --git a/examples/assets/games/orbit/powerup_p.png b/examples/assets/games/orbit/powerup_p.png new file mode 100644 index 00000000..5e5fa6fc Binary files /dev/null and b/examples/assets/games/orbit/powerup_p.png differ diff --git a/examples/assets/games/orbit/powerup_s.png b/examples/assets/games/orbit/powerup_s.png new file mode 100644 index 00000000..30ae8f6b Binary files /dev/null and b/examples/assets/games/orbit/powerup_s.png differ diff --git a/examples/assets/games/orbit/powerup_x.png b/examples/assets/games/orbit/powerup_x.png new file mode 100644 index 00000000..74dcc831 Binary files /dev/null and b/examples/assets/games/orbit/powerup_x.png differ diff --git a/examples/assets/games/orbit/wall.png b/examples/assets/games/orbit/wall.png new file mode 100644 index 00000000..1739a4a7 Binary files /dev/null and b/examples/assets/games/orbit/wall.png differ diff --git a/package.json b/package.json index 185b6722..e8eab2d6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,13 @@ { "name": "Phaser", "version": "1.1.3", - "description": "HTML5 game framework", + "description": "A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.", + "author": "Richard Davey", + "logo": "https://raw.github.com/photonstorm/phaser/master/phaser-logo-small.png", + "homepage": "http://phaser.io", + "bugs": "https://github.com/photonstorm/phaser/issues", + "license": "MIT", + "licenseUrl": "http://www.opensource.org/licenses/mit-license.php", "repository": { "type": "git", "url": "https://photonstorm@github.com/photonstorm/phaser.git" @@ -10,10 +16,14 @@ "HTML5", "game", "canvas", - "2d" + "2d", + "WebGL", + "web audio", + "physics", + "tweens", + "javascript", + "typescript" ], - "author": "Richard Davey", - "license": "MIT", "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-concat": "~0.3.0", diff --git a/src/core/Stage.js b/src/core/Stage.js index cff07d74..c19b69c0 100644 --- a/src/core/Stage.js +++ b/src/core/Stage.js @@ -45,6 +45,7 @@ Phaser.Stage = function (game, width, height) { */ this._stage = new PIXI.Stage(0x000000, false); this._stage.name = '_stage_root'; + this._stage.interactive = false; /** * @property {number} scaleMode - The current scaleMode. diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js index bd803339..ad111752 100644 --- a/src/pixi/InteractionManager.js +++ b/src/pixi/InteractionManager.js @@ -1,10 +1,8 @@ /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - - -/** + + /** * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive * This manager also supports multitouch. * @@ -50,6 +48,17 @@ PIXI.InteractionManager = function(stage) this.pool = []; this.interactiveItems = []; + this.interactionDOMElement = null; + + //this will make it so that you dont have to call bind all the time + this.onMouseMove = this.onMouseMove.bind( this ); + this.onMouseDown = this.onMouseDown.bind(this); + this.onMouseOut = this.onMouseOut.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); + + this.onTouchStart = this.onTouchStart.bind(this); + this.onTouchEnd = this.onTouchEnd.bind(this); + this.onTouchMove = this.onTouchMove.bind(this); this.last = 0; @@ -111,27 +120,68 @@ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObj */ PIXI.InteractionManager.prototype.setTarget = function(target) { + this.target = target; + + //check if the dom element has been set. If it has don't do anything + if( this.interactionDOMElement === null ) { + + this.setTargetDomElement( target.view ); + } + + document.body.addEventListener('mouseup', this.onMouseUp, true); +} + + +/** + * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM + * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element + * to receive those events + * + * @method setTargetDomElement + * @param domElement {DOMElement} the dom element which will receive mouse and touch events + * @private + */ +PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) +{ + //remove previouse listeners + if( this.interactionDOMElement !== null ) + { + this.interactionDOMElement.style['-ms-content-zooming'] = ''; + this.interactionDOMElement.style['-ms-touch-action'] = ''; + + this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true); + this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true); + this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true); + + // aint no multi touch just yet! + this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true); + this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true); + this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true); + } + + if (window.navigator.msPointerEnabled) { // time to remove some of that zoom in ja.. - target.view.style["-ms-content-zooming"] = "none"; - target.view.style["-ms-touch-action"] = "none" + domElement.style['-ms-content-zooming'] = 'none'; + domElement.style['-ms-touch-action'] = 'none'; // DO some window specific touch! } - - this.target = target; - target.view.addEventListener('mousemove', this.onMouseMove.bind(this), true); - target.view.addEventListener('mousedown', this.onMouseDown.bind(this), true); - document.body.addEventListener('mouseup', this.onMouseUp.bind(this), true); - target.view.addEventListener('mouseout', this.onMouseOut.bind(this), true); - - // aint no multi touch just yet! - target.view.addEventListener("touchstart", this.onTouchStart.bind(this), true); - target.view.addEventListener("touchend", this.onTouchEnd.bind(this), true); - target.view.addEventListener("touchmove", this.onTouchMove.bind(this), true); + + this.interactionDOMElement = domElement; + + domElement.addEventListener('mousemove', this.onMouseMove, true); + domElement.addEventListener('mousedown', this.onMouseDown, true); + domElement.addEventListener('mouseout', this.onMouseOut, true); + + // aint no multi touch just yet! + domElement.addEventListener('touchstart', this.onTouchStart, true); + domElement.addEventListener('touchend', this.onTouchEnd, true); + domElement.addEventListener('touchmove', this.onTouchMove, true); } + /** * updates the state of interactive objects * @@ -173,7 +223,7 @@ PIXI.InteractionManager.prototype.update = function() // loop through interactive objects! var length = this.interactiveItems.length; - this.target.view.style.cursor = "default"; + this.interactionDOMElement.style.cursor = "default"; for (var i = 0; i < length; i++) { @@ -196,7 +246,7 @@ PIXI.InteractionManager.prototype.update = function() // loks like there was a hit! if(item.__hit) { - if(item.buttonMode)this.target.view.style.cursor = "pointer"; + if(item.buttonMode) this.interactionDOMElement.style.cursor = "pointer"; if(!item.__isOver) { @@ -231,7 +281,7 @@ PIXI.InteractionManager.prototype.onMouseMove = function(event) { this.mouse.originalEvent = event || window.event; //IE uses window.event // TODO optimize by not check EVERY TIME! maybe half as often? // - var rect = this.target.view.getBoundingClientRect(); + var rect = this.interactionDOMElement.getBoundingClientRect(); this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); @@ -302,7 +352,7 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event) { var length = this.interactiveItems.length; - this.target.view.style.cursor = "default"; + this.interactionDOMElement.style.cursor = "default"; for (var i = 0; i < length; i++) { @@ -451,7 +501,7 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) */ PIXI.InteractionManager.prototype.onTouchMove = function(event) { - var rect = this.target.view.getBoundingClientRect(); + var rect = this.interactionDOMElement.getBoundingClientRect(); var changedTouches = event.changedTouches; for (var i=0; i < changedTouches.length; i++) @@ -482,7 +532,7 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event) */ PIXI.InteractionManager.prototype.onTouchStart = function(event) { - var rect = this.target.view.getBoundingClientRect(); + var rect = this.interactionDOMElement.getBoundingClientRect(); var changedTouches = event.changedTouches; for (var i=0; i < changedTouches.length; i++) @@ -532,7 +582,7 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event) PIXI.InteractionManager.prototype.onTouchEnd = function(event) { //this.mouse.originalEvent = event || window.event; //IE uses window.event - var rect = this.target.view.getBoundingClientRect(); + var rect = this.interactionDOMElement.getBoundingClientRect(); var changedTouches = event.changedTouches; for (var i=0; i < changedTouches.length; i++) diff --git a/src/pixi/Outro.js b/src/pixi/Outro.js index e53cad5e..bf38bbc7 100644 --- a/src/pixi/Outro.js +++ b/src/pixi/Outro.js @@ -2,14 +2,14 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = PIXI; + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = PIXI; + } + exports.PIXI = PIXI; + } else if (typeof define !== 'undefined' && define.amd) { + define(PIXI); + } else { + root.PIXI = PIXI; } - exports.PIXI = PIXI; - } else { - root.PIXI = PIXI; - } - - }).call(this); \ No newline at end of file diff --git a/src/pixi/core/Circle.js b/src/pixi/core/Circle.js index e36abe74..e2728335 100644 --- a/src/pixi/core/Circle.js +++ b/src/pixi/core/Circle.js @@ -7,9 +7,9 @@ * * @class Circle * @constructor - * @param x {number} The X coord of the upper-left corner of the framing rectangle of this circle - * @param y {number} The Y coord of the upper-left corner of the framing rectangle of this circle - * @param radius {number} The radius of the circle + * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle + * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle + * @param radius {Number} The radius of the circle */ PIXI.Circle = function(x, y, radius) { @@ -19,7 +19,7 @@ PIXI.Circle = function(x, y, radius) * @default 0 */ this.x = x || 0; - + /** * @property y * @type Number @@ -50,8 +50,8 @@ PIXI.Circle.prototype.clone = function() * Checks if the x, and y coords passed to this function are contained within this circle * * @method contains - * @param x {number} The X coord of the point to test - * @param y {number} The Y coord of the point to test + * @param x {Number} The X coord of the point to test + * @param y {Number} The Y coord of the point to test * @return {Boolean} if the x/y coords are within this polygon */ PIXI.Circle.prototype.contains = function(x, y) @@ -69,5 +69,6 @@ PIXI.Circle.prototype.contains = function(x, y) return (dx + dy <= r2); } +// constructor PIXI.Circle.prototype.constructor = PIXI.Circle; diff --git a/src/pixi/core/Ellipse.js b/src/pixi/core/Ellipse.js index 27428d39..1a95d20a 100644 --- a/src/pixi/core/Ellipse.js +++ b/src/pixi/core/Ellipse.js @@ -7,10 +7,10 @@ * * @class Ellipse * @constructor - * @param x {number} The X coord of the upper-left corner of the framing rectangle of this ellipse - * @param y {number} The Y coord of the upper-left corner of the framing rectangle of this ellipse - * @param width {number} The overall height of this ellipse - * @param height {number} The overall width of this ellipse + * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse + * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse + * @param width {Number} The overall width of this ellipse + * @param height {Number} The overall height of this ellipse */ PIXI.Ellipse = function(x, y, width, height) { @@ -20,21 +20,21 @@ PIXI.Ellipse = function(x, y, width, height) * @default 0 */ this.x = x || 0; - + /** * @property y * @type Number * @default 0 */ this.y = y || 0; - + /** * @property width * @type Number * @default 0 */ this.width = width || 0; - + /** * @property height * @type Number @@ -58,8 +58,8 @@ PIXI.Ellipse.prototype.clone = function() * Checks if the x, and y coords passed to this function are contained within this ellipse * * @method contains - * @param x {number} The X coord of the point to test - * @param y {number} The Y coord of the point to test + * @param x {Number} The X coord of the point to test + * @param y {Number} The Y coord of the point to test * @return {Boolean} if the x/y coords are within this ellipse */ PIXI.Ellipse.prototype.contains = function(x, y) @@ -83,5 +83,5 @@ PIXI.Ellipse.getBounds = function() return new PIXI.Rectangle(this.x, this.y, this.width, this.height); } +// constructor PIXI.Ellipse.prototype.constructor = PIXI.Ellipse; - diff --git a/src/pixi/core/Matrix.js b/src/pixi/core/Matrix.js index 780fcd68..923682c6 100644 --- a/src/pixi/core/Matrix.js +++ b/src/pixi/core/Matrix.js @@ -27,7 +27,7 @@ PIXI.mat3.create = function() matrix[6] = 0; matrix[7] = 0; matrix[8] = 1; - + return matrix; } @@ -43,7 +43,7 @@ PIXI.mat3.identity = function(matrix) matrix[6] = 0; matrix[7] = 0; matrix[8] = 1; - + return matrix; } @@ -70,35 +70,35 @@ PIXI.mat4.create = function() matrix[13] = 0; matrix[14] = 0; matrix[15] = 1; - + return matrix; } -PIXI.mat3.multiply = function (mat, mat2, dest) +PIXI.mat3.multiply = function (mat, mat2, dest) { if (!dest) { dest = mat; } - + // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a10 = mat[3], a11 = mat[4], a12 = mat[5], a20 = mat[6], a21 = mat[7], a22 = mat[8], - + b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b10 = mat2[3], b11 = mat2[4], b12 = mat2[5], b20 = mat2[6], b21 = mat2[7], b22 = mat2[8]; - + dest[0] = b00 * a00 + b01 * a10 + b02 * a20; dest[1] = b00 * a01 + b01 * a11 + b02 * a21; dest[2] = b00 * a02 + b01 * a12 + b02 * a22; - + dest[3] = b10 * a00 + b11 * a10 + b12 * a20; dest[4] = b10 * a01 + b11 * a11 + b12 * a21; dest[5] = b10 * a02 + b11 * a12 + b12 * a22; - + dest[6] = b20 * a00 + b21 * a10 + b22 * a20; dest[7] = b20 * a01 + b21 * a11 + b22 * a21; dest[8] = b20 * a02 + b21 * a12 + b22 * a22; - + return dest; } @@ -115,11 +115,11 @@ PIXI.mat3.clone = function(mat) matrix[6] = mat[6]; matrix[7] = mat[7]; matrix[8] = mat[8]; - + return matrix; } -PIXI.mat3.transpose = function (mat, dest) +PIXI.mat3.transpose = function (mat, dest) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (!dest || mat === dest) { @@ -147,30 +147,30 @@ PIXI.mat3.transpose = function (mat, dest) return dest; } -PIXI.mat3.toMat4 = function (mat, dest) +PIXI.mat3.toMat4 = function (mat, dest) { if (!dest) { dest = PIXI.mat4.create(); } - + dest[15] = 1; dest[14] = 0; dest[13] = 0; dest[12] = 0; - + dest[11] = 0; dest[10] = mat[8]; dest[9] = mat[7]; dest[8] = mat[6]; - + dest[7] = 0; dest[6] = mat[5]; dest[5] = mat[4]; dest[4] = mat[3]; - + dest[3] = 0; dest[2] = mat[2]; dest[1] = mat[1]; dest[0] = mat[0]; - + return dest; } @@ -198,19 +198,19 @@ PIXI.mat4.create = function() matrix[13] = 0; matrix[14] = 0; matrix[15] = 1; - + return matrix; } -PIXI.mat4.transpose = function (mat, dest) +PIXI.mat4.transpose = function (mat, dest) { // If we are transposing ourselves we can skip a few steps but have to cache some values - if (!dest || mat === dest) + if (!dest || mat === dest) { var a01 = mat[1], a02 = mat[2], a03 = mat[3], a12 = mat[6], a13 = mat[7], a23 = mat[11]; - + mat[1] = mat[4]; mat[2] = mat[8]; mat[3] = mat[12]; @@ -225,7 +225,7 @@ PIXI.mat4.transpose = function (mat, dest) mat[14] = a23; return mat; } - + dest[0] = mat[0]; dest[1] = mat[4]; dest[2] = mat[8]; @@ -245,18 +245,18 @@ PIXI.mat4.transpose = function (mat, dest) return dest; } -PIXI.mat4.multiply = function (mat, mat2, dest) +PIXI.mat4.multiply = function (mat, mat2, dest) { if (!dest) { dest = mat; } - + // Cache the matrix values (makes for huge speed increases!) var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3]; var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7]; var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11]; var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; - + // Cache only the current line of the second matrix - var b0 = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3]; + var b0 = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3]; dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32; diff --git a/src/pixi/core/Point.js b/src/pixi/core/Point.js index d68175aa..7c7fe2d7 100644 --- a/src/pixi/core/Point.js +++ b/src/pixi/core/Point.js @@ -6,19 +6,19 @@ * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. * * @class Point - * @constructor - * @param x {number} position of the point - * @param y {number} position of the point + * @constructor + * @param x {Number} position of the point + * @param y {Number} position of the point */ PIXI.Point = function(x, y) { /** - * @property x + * @property x * @type Number * @default 0 */ this.x = x || 0; - + /** * @property y * @type Number diff --git a/src/pixi/core/Polygon.js b/src/pixi/core/Polygon.js index e40f13aa..4ef74f11 100644 --- a/src/pixi/core/Polygon.js +++ b/src/pixi/core/Polygon.js @@ -6,7 +6,7 @@ * @class Polygon * @constructor * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon, - * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arugments passed can be + * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are * Numbers. @@ -52,8 +52,8 @@ PIXI.Polygon.prototype.clone = function() * Checks if the x, and y coords passed to this function are contained within this polygon * * @method contains - * @param x {number} The X coord of the point to test - * @param y {number} The Y coord of the point to test + * @param x {Number} The X coord of the point to test + * @param y {Number} The Y coord of the point to test * @return {Boolean} if the x/y coords are within this polygon */ PIXI.Polygon.prototype.contains = function(x, y) @@ -73,5 +73,5 @@ PIXI.Polygon.prototype.contains = function(x, y) return inside; } +// constructor PIXI.Polygon.prototype.constructor = PIXI.Polygon; - diff --git a/src/pixi/core/Rectangle.js b/src/pixi/core/Rectangle.js index 7a7ba086..8a0e0402 100644 --- a/src/pixi/core/Rectangle.js +++ b/src/pixi/core/Rectangle.js @@ -6,11 +6,11 @@ * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height. * * @class Rectangle - * @constructor - * @param x {number} The X coord of the upper-left corner of the rectangle - * @param y {number} The Y coord of the upper-left corner of the rectangle - * @param width {number} The overall wisth of this rectangle - * @param height {number} The overall height of this rectangle + * @constructor + * @param x {Number} The X coord of the upper-left corner of the rectangle + * @param y {Number} The Y coord of the upper-left corner of the rectangle + * @param width {Number} The overall width of this rectangle + * @param height {Number} The overall height of this rectangle */ PIXI.Rectangle = function(x, y, width, height) { @@ -20,21 +20,21 @@ PIXI.Rectangle = function(x, y, width, height) * @default 0 */ this.x = x || 0; - + /** * @property y * @type Number * @default 0 */ this.y = y || 0; - + /** * @property width * @type Number * @default 0 */ this.width = width || 0; - + /** * @property height * @type Number @@ -58,8 +58,8 @@ PIXI.Rectangle.prototype.clone = function() * Checks if the x, and y coords passed to this function are contained within this Rectangle * * @method contains - * @param x {number} The X coord of the point to test - * @param y {number} The Y coord of the point to test + * @param x {Number} The X coord of the point to test + * @param y {Number} The Y coord of the point to test * @return {Boolean} if the x/y coords are within this Rectangle */ PIXI.Rectangle.prototype.contains = function(x, y) @@ -71,7 +71,7 @@ PIXI.Rectangle.prototype.contains = function(x, y) if(x >= x1 && x <= x1 + this.width) { var y1 = this.y; - + if(y >= y1 && y <= y1 + this.height) { return true; diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index 82d53663..256c8caa 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -12,7 +12,6 @@ PIXI.DisplayObject = function() { this.last = this; this.first = this; - /** * The coordinate of the object relative to the local coordinates of the parent. * @@ -165,6 +164,9 @@ PIXI.DisplayObject = function() this._sr = 0; this._cr = 1; + + this.filterArea = new PIXI.Rectangle(0,0,1,1); + /* * MOUSE Callbacks */ @@ -289,16 +291,71 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { }, set: function(value) { - this._mask = value; - + if(value) { - this.addFilter(value) + if(this._mask) + { + value.start = this._mask.start; + value.end = this._mask.end; + } + else + { + this.addFilter(value); + value.renderable = false; + } } else { - this.removeFilter(); + this.removeFilter(this._mask); + this._mask.renderable = true; } + + this._mask = value; + } +}); + +/** + * Sets the filters for the displayObject. + * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. + * To remove filters simply set this property to 'null' + * @property filters + * @type Array An array of filters + */ +Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { + get: function() { + return this._filters; + }, + set: function(value) { + + if(value) + { + if(this._filters)this.removeFilter(this._filters); + this.addFilter(value); + + // now put all the passes in one place.. + var passes = []; + for (var i = 0; i < value.length; i++) + { + var filterPasses = value[i].passes; + for (var j = 0; j < filterPasses.length; j++) + { + passes.push(filterPasses[j]); + }; + }; + + value.start.filterPasses = passes; + } + else + { + if(this._filters)this.removeFilter(this._filters); + } + + this._filters = value; + + + + } }); @@ -309,23 +366,31 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { * @param mask {Graphics} the graphics object to use as a filter * @private */ -PIXI.DisplayObject.prototype.addFilter = function(mask) +PIXI.DisplayObject.prototype.addFilter = function(data) { - if(this.filter)return; - this.filter = true; + //if(this.filter)return; + //this.filter = true; +// data[0].target = this; + // insert a filter block.. + // TODO Onject pool thease bad boys.. var start = new PIXI.FilterBlock(); var end = new PIXI.FilterBlock(); - start.mask = mask; - end.mask = mask; + data.start = start; + data.end = end; + + start.data = data; + end.data = data; start.first = start.last = this; end.first = end.last = this; start.open = true; + start.target = this; + /* * insert start */ @@ -397,8 +462,6 @@ PIXI.DisplayObject.prototype.addFilter = function(mask) this.__renderGroup.addFilterBlocks(start, end); } - mask.renderable = false; - } /* @@ -407,13 +470,14 @@ PIXI.DisplayObject.prototype.addFilter = function(mask) * @method removeFilter * @private */ -PIXI.DisplayObject.prototype.removeFilter = function() +PIXI.DisplayObject.prototype.removeFilter = function(data) { - if(!this.filter)return; - this.filter = false; - + //if(!this.filter)return; + //this.filter = false; + console.log("YUOIO") // modify the list.. - var startBlock = this.first; + var startBlock = data.start; + var nextObject = startBlock._iNext; var previousObject = startBlock._iPrev; @@ -423,9 +487,8 @@ PIXI.DisplayObject.prototype.removeFilter = function() this.first = startBlock._iNext; - // remove the end filter - var lastBlock = this.last; + var lastBlock = data.end; var nextObject = lastBlock._iNext; var previousObject = lastBlock._iPrev; @@ -444,9 +507,6 @@ PIXI.DisplayObject.prototype.removeFilter = function() if(!updateLast)break; } - var mask = startBlock.mask - mask.renderable = true; - // if webGL... if(this.__renderGroup) { diff --git a/src/pixi/display/DisplayObjectContainer.js b/src/pixi/display/DisplayObjectContainer.js index 43891296..09d5b0ce 100644 --- a/src/pixi/display/DisplayObjectContainer.js +++ b/src/pixi/display/DisplayObjectContainer.js @@ -29,18 +29,6 @@ PIXI.DisplayObjectContainer = function() PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; -//TODO make visible a getter setter -/* -Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'visible', { - get: function() { - return this._visible; - }, - set: function(value) { - this._visible = value; - - } -});*/ - /** * Adds a child to the container. * @@ -84,7 +72,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child) var previousObject; // this could be wrong if there is a filter?? - if(this.filter) + if(this._filters || this._mask) { previousObject = this.last._iPrev; } @@ -134,7 +122,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child) * * @method addChildAt * @param child {DisplayObject} The child to add - * @param index {number} The index to place the child in + * @param index {Number} The index to place the child in */ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) { @@ -269,7 +257,7 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) * Returns the Child at the specified index * * @method getChildAt - * @param index {number} The index to get the child from + * @param index {Number} The index to get the child from */ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) { @@ -365,4 +353,4 @@ PIXI.DisplayObjectContainer.prototype.updateTransform = function() { this.children[i].updateTransform(); } -} +} \ No newline at end of file diff --git a/src/pixi/display/MovieClip.js b/src/pixi/display/MovieClip.js index 5f984078..8a669d92 100644 --- a/src/pixi/display/MovieClip.js +++ b/src/pixi/display/MovieClip.js @@ -13,7 +13,7 @@ PIXI.MovieClip = function(textures) { PIXI.Sprite.call(this, textures[0]); - + /** * The array of textures that make up the animation * @@ -21,7 +21,7 @@ PIXI.MovieClip = function(textures) * @type Array */ this.textures = textures; - + /** * The speed that the MovieClip will play at. Higher is faster, lower is slower * @@ -47,7 +47,7 @@ PIXI.MovieClip = function(textures) * @type Function */ this.onComplete = null; - + /** * [read-only] The index MovieClips current frame (this may not have to be a whole number) * @@ -56,8 +56,8 @@ PIXI.MovieClip = function(textures) * @default 0 * @readOnly */ - this.currentFrame = 0; - + this.currentFrame = 0; + /** * [read-only] Indicates if the MovieClip is currently playing * @@ -72,6 +72,23 @@ PIXI.MovieClip = function(textures) PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype ); PIXI.MovieClip.prototype.constructor = PIXI.MovieClip; +/** +* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures +* assigned to the MovieClip. +* +* @property totalFrames +* @type Number +* @default 0 +* @readOnly +*/ +Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', { + get: function() { + + return this.textures.length; + } +}); + + /** * Stops the MovieClip * @@ -96,7 +113,7 @@ PIXI.MovieClip.prototype.play = function() * Stops the MovieClip and goes to a specific frame * * @method gotoAndStop - * @param frameNumber {number} frame index to stop at + * @param frameNumber {Number} frame index to stop at */ PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber) { @@ -110,7 +127,7 @@ PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber) * Goes to a specific frame and begins playing the MovieClip * * @method gotoAndPlay - * @param frameNumber {number} frame index to start at + * @param frameNumber {Number} frame index to start at */ PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber) { @@ -127,13 +144,13 @@ PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber) PIXI.MovieClip.prototype.updateTransform = function() { PIXI.Sprite.prototype.updateTransform.call(this); - + if(!this.playing)return; - + this.currentFrame += this.animationSpeed; - + var round = (this.currentFrame + 0.5) | 0; - + if(this.loop || round < this.textures.length) { this.setTexture(this.textures[round % this.textures.length]); diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index 4041d43c..e567c795 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -152,7 +152,7 @@ PIXI.Sprite.prototype.setTexture = function(texture) PIXI.Sprite.prototype.onTextureUpdate = function(event) { //this.texture.removeEventListener( 'update', this.onTextureUpdateBind ); - + // so if _width is 0 then width was not set.. if(this._width)this.scale.x = this._width / this.texture.frame.width; if(this._height)this.scale.y = this._height / this.texture.frame.height; @@ -194,4 +194,3 @@ PIXI.Sprite.fromImage = function(imageId) var texture = PIXI.Texture.fromImage(imageId); return new PIXI.Sprite(texture); } - diff --git a/src/pixi/display/Stage.js b/src/pixi/display/Stage.js index 02830cfe..513c0ad0 100644 --- a/src/pixi/display/Stage.js +++ b/src/pixi/display/Stage.js @@ -8,11 +8,10 @@ * @class Stage * @extends DisplayObjectContainer * @constructor - * @param backgroundColor {number} the background color of the stage, easiest way to pass this in is in hex format + * @param backgroundColor {Number} the background color of the stage, easiest way to pass this in is in hex format * like: 0xFFFFFF for white - * @param interactive {Boolean} enable / disable interaction (default is false) */ -PIXI.Stage = function(backgroundColor, interactive) +PIXI.Stage = function(backgroundColor) { PIXI.DisplayObjectContainer.call( this ); @@ -32,7 +31,7 @@ PIXI.Stage = function(backgroundColor, interactive) * @property interactive * @type Boolean */ - this.interactive = interactive; + this.interactive = true; /** * The interaction manage for this stage, manages all interactive activity on the stage @@ -68,6 +67,18 @@ PIXI.Stage = function(backgroundColor, interactive) PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); PIXI.Stage.prototype.constructor = PIXI.Stage; +/** + * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element. + * This is useful for when you have other DOM elements ontop of the Canvas element. + * + * @method setInteractionDelegate + * @param domElement {DOMElement} This new domElement which will receive mouse/touch events + */ +PIXI.Stage.prototype.setInteractionDelegate = function(domElement) +{ + this.interactionManager.setTargetDomElement( domElement ); +} + /* * Updates the object transform for rendering * @@ -99,7 +110,7 @@ PIXI.Stage.prototype.updateTransform = function() * Sets the background color for the stage * * @method setBackgroundColor - * @param backgroundColor {number} the color of the background, easiest way to pass this in is in hex format + * @param backgroundColor {Number} the color of the background, easiest way to pass this in is in hex format * like: 0xFFFFFF for white */ PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor) diff --git a/src/pixi/extras/CustomRenderable.js b/src/pixi/extras/CustomRenderable.js index eb0dc5bf..24b2258b 100644 --- a/src/pixi/extras/CustomRenderable.js +++ b/src/pixi/extras/CustomRenderable.js @@ -6,7 +6,7 @@ /** * This object is one that will allow you to specify custom rendering functions based on render type * - * @class CustomRenderable + * @class CustomRenderable * @extends DisplayObject * @constructor */ @@ -14,6 +14,7 @@ PIXI.CustomRenderable = function() { PIXI.DisplayObject.call( this ); + this.renderable = true; } // constructor diff --git a/src/pixi/extras/Rope.js b/src/pixi/extras/Rope.js index 1c057c84..754306db 100644 --- a/src/pixi/extras/Rope.js +++ b/src/pixi/extras/Rope.js @@ -7,7 +7,7 @@ PIXI.Rope = function(texture, points) { PIXI.Strip.call( this, texture ); this.points = points; - + try { this.verticies = new Float32Array( points.length * 4); @@ -18,12 +18,12 @@ PIXI.Rope = function(texture, points) catch(error) { this.verticies = verticies - + this.uvs = uvs this.colors = colors this.indices = indices } - + this.refresh(); } @@ -36,99 +36,99 @@ PIXI.Rope.prototype.refresh = function() { var points = this.points; if(points.length < 1)return; - + var uvs = this.uvs var indices = this.indices; var colors = this.colors; - + var lastPoint = points[0]; var nextPoint; var perp = {x:0, y:0}; var point = points[0]; - + this.count-=0.2; - - + + uvs[0] = 0 uvs[1] = 1 uvs[2] = 0 uvs[3] = 1 - + colors[0] = 1; colors[1] = 1; - + indices[0] = 0; indices[1] = 1; - + var total = points.length; - - for (var i = 1; i < total; i++) + + for (var i = 1; i < total; i++) { - + var point = points[i]; var index = i * 4; // time to do some smart drawing! var amount = i/(total-1) - + if(i%2) { uvs[index] = amount; uvs[index+1] = 0; - + uvs[index+2] = amount uvs[index+3] = 1 - + } else { uvs[index] = amount uvs[index+1] = 0 - + uvs[index+2] = amount uvs[index+3] = 1 } - + index = i * 2; colors[index] = 1; colors[index+1] = 1; - + index = i * 2; indices[index] = index; indices[index + 1] = index + 1; - + lastPoint = point; } } PIXI.Rope.prototype.updateTransform = function() { - + var points = this.points; if(points.length < 1)return; - - var verticies = this.verticies - + + var verticies = this.verticies + var lastPoint = points[0]; var nextPoint; var perp = {x:0, y:0}; var point = points[0]; - + this.count-=0.2; - - verticies[0] = point.x + perp.x + + verticies[0] = point.x + perp.x verticies[1] = point.y + perp.y //+ 200 - verticies[2] = point.x - perp.x + verticies[2] = point.x - perp.x verticies[3] = point.y - perp.y//+200 // time to do some smart drawing! - + var total = points.length; - - for (var i = 1; i < total; i++) + + for (var i = 1; i < total; i++) { - + var point = points[i]; var index = i * 4; - + if(i < points.length-1) { nextPoint = points[i+1]; @@ -137,35 +137,35 @@ PIXI.Rope.prototype.updateTransform = function() { nextPoint = point } - + perp.y = -(nextPoint.x - lastPoint.x); perp.x = nextPoint.y - lastPoint.y; - + var ratio = (1 - (i / (total-1))) * 10; if(ratio > 1)ratio = 1; - + var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; perp.x /= perpLength; perp.y /= perpLength; - + perp.x *= num; perp.y *= num; - - verticies[index] = point.x + perp.x + + verticies[index] = point.x + perp.x verticies[index+1] = point.y + perp.y - verticies[index+2] = point.x - perp.x + verticies[index+2] = point.x - perp.x verticies[index+3] = point.y - perp.y lastPoint = point; } - + PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); } PIXI.Rope.prototype.setTexture = function(texture) { - // stop current texture + // stop current texture this.texture = texture; this.updateFrame = true; } diff --git a/src/pixi/extras/Spine.js b/src/pixi/extras/Spine.js index 8dda8c1f..27995ae6 100644 --- a/src/pixi/extras/Spine.js +++ b/src/pixi/extras/Spine.js @@ -125,9 +125,9 @@ PIXI.Spine.prototype.createSprite = function (slot, descriptor) { /* * Awesome JS run time provided by EsotericSoftware - * + * * https://github.com/EsotericSoftware/spine-runtimes - * + * */ var spine = {}; diff --git a/src/pixi/extras/Strip.js b/src/pixi/extras/Strip.js index 1e5ba3bf..857e4129 100644 --- a/src/pixi/extras/Strip.js +++ b/src/pixi/extras/Strip.js @@ -7,20 +7,20 @@ PIXI.Strip = function(texture, width, height) PIXI.DisplayObjectContainer.call( this ); this.texture = texture; this.blendMode = PIXI.blendModes.NORMAL; - + try { this.uvs = new Float32Array([0, 1, 1, 1, 1, 0, 0,1]); - + this.verticies = new Float32Array([0, 0, 0,0, 0,0, 0, 0, 0]); - + this.colors = new Float32Array([1, 1, 1, 1]); - + this.indices = new Uint16Array([0, 1, 2, 3]); } catch(error) @@ -28,18 +28,18 @@ PIXI.Strip = function(texture, width, height) this.uvs = [0, 1, 1, 1, 1, 0, 0,1]; - + this.verticies = [0, 0, 0,0, 0,0, 0, 0, 0]; - + this.colors = [1, 1, 1, 1]; - + this.indices = [0, 1, 2, 3]; } - - + + /* this.uvs = new Float32Array() this.verticies = new Float32Array() @@ -48,7 +48,7 @@ PIXI.Strip = function(texture, width, height) */ this.width = width; this.height = height; - + // load the texture! if(texture.baseTexture.hasLoaded) { @@ -61,7 +61,7 @@ PIXI.Strip = function(texture, width, height) this.onTextureUpdateBind = this.onTextureUpdate.bind(this); this.texture.addEventListener( 'update', this.onTextureUpdateBind ); } - + this.renderable = true; } @@ -73,8 +73,8 @@ PIXI.Strip.prototype.setTexture = function(texture) { //TODO SET THE TEXTURES //TODO VISIBILITY - - // stop current texture + + // stop current texture this.texture = texture; this.width = texture.frame.width; this.height = texture.frame.height; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index f52465c7..be2e93fa 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -9,8 +9,8 @@ * @extends DisplayObjectContainer * @constructor * @param texture {Texture} the texture of the tiling sprite - * @param width {number} the width of the tiling sprite - * @param height {number} the height of the tiling sprite + * @param width {Number} the width of the tiling sprite + * @param height {Number} the height of the tiling sprite */ PIXI.TilingSprite = function(texture, width, height) { @@ -45,7 +45,7 @@ PIXI.TilingSprite = function(texture, width, height) * * @property tileScale * @type Point - */ + */ this.tileScale = new PIXI.Point(1,1); /** @@ -53,11 +53,11 @@ PIXI.TilingSprite = function(texture, width, height) * * @property tilePosition * @type Point - */ + */ this.tilePosition = new PIXI.Point(0,0); this.renderable = true; - + this.blendMode = PIXI.blendModes.NORMAL } @@ -75,8 +75,8 @@ PIXI.TilingSprite.prototype.setTexture = function(texture) { //TODO SET THE TEXTURES //TODO VISIBILITY - - // stop current texture + + // stop current texture this.texture = texture; this.updateFrame = true; } diff --git a/src/pixi/filters/AbstractFilter.js b/src/pixi/filters/AbstractFilter.js new file mode 100644 index 00000000..c1e22b47 --- /dev/null +++ b/src/pixi/filters/AbstractFilter.js @@ -0,0 +1,37 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * This is the base class for creating a pixi.js filter. Currently only webGL supports filters. + * If you want to make a custom filter this should be your base class. + * @class AbstractFilter + * @constructor + * @param fragmentSrc + * @param unifroms + */ +PIXI.AbstractFilter = function(fragmentSrc, unifroms) +{ + /** + * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. + * For example the blur filter has two passes blurX and blurY. + * @property passes + * @type Array an array of filter objects + * @private + */ + this.passes = [this]; + + + this.dirty = true; + this.padding = 0; + + /** + @property uniforms + @private + */ + this.uniforms = unifroms || {}; + + this.fragmentSrc = fragmentSrc || []; +} + diff --git a/src/pixi/filters/BlurFilter.js b/src/pixi/filters/BlurFilter.js new file mode 100644 index 00000000..43caa0c4 --- /dev/null +++ b/src/pixi/filters/BlurFilter.js @@ -0,0 +1,70 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * + * The BlurFilter applies a Gaussian blur to an object. + * The strength of the blur can be set for x- and y-axis separately (always relative to the stage). + * + * @class BlurFilter + * @contructor + */ +PIXI.BlurFilter = function() +{ + + this.blurXFilter = new PIXI.BlurXFilter(); + this.blurYFilter = new PIXI.BlurYFilter(); + + this.passes =[this.blurXFilter, this.blurYFilter]; + +} + +/** + * Sets the strength of both the blurX and blurY properties simultaneously + * + * @property blur + * @type Number the strength of the blur + * @default 2 + */ +Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', { + get: function() { + return this.blurXFilter.blur; + }, + set: function(value) { + this.blurXFilter.blur = this.blurYFilter.blur = value; + } +}); + +/** + * Sets the strength of the blurX property simultaneously + * + * @property blurX + * @type Number the strength of the blurX + * @default 2 + */ +Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', { + get: function() { + return this.blurXFilter.blur; + }, + set: function(value) { + this.blurXFilter.blur = value; + } +}); + +/** + * Sets the strength of the blurX property simultaneously + * + * @property blurY + * @type Number the strength of the blurY + * @default 2 + */ +Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', { + get: function() { + return this.blurYFilter.blur; + }, + set: function(value) { + this.blurYFilter.blur = value; + } +}); diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js new file mode 100644 index 00000000..7fef33c3 --- /dev/null +++ b/src/pixi/filters/BlurXFilter.js @@ -0,0 +1,56 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + + +PIXI.BlurXFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: 'f', value: 1/512}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float blur;", + "uniform sampler2D uSampler;", + "void main(void) {", + "vec4 sum = vec4(0.0);", + + "sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;", + + "gl_FragColor = sum;", + + "}" + ]; +} + +PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter; + + +Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', { + get: function() { + return this.uniforms.blur.value / (1/7000); + }, + set: function(value) { + + this.dirty = true; + this.uniforms.blur.value = (1/7000) * value; + } +}); diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js new file mode 100644 index 00000000..4b9d352c --- /dev/null +++ b/src/pixi/filters/BlurYFilter.js @@ -0,0 +1,54 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + + +PIXI.BlurYFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: 'f', value: 1/512}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float blur;", + "uniform sampler2D uSampler;", + "void main(void) {", + "vec4 sum = vec4(0.0);", + + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;", + "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;", + + "gl_FragColor = sum;", + + "}" + ]; +} + +PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter; + +Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', { + get: function() { + return this.uniforms.blur.value / (1/7000); + }, + set: function(value) { + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; + } +}); diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js new file mode 100644 index 00000000..1386f8b2 --- /dev/null +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -0,0 +1,59 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * + * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA + * color and alpha values of every pixel on your displayObject to produce a result + * with a new set of RGBA color and alpha values. Its pretty powerful! + * @class ColorMatrixFilter + * @contructor + */ +PIXI.ColorMatrixFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + matrix: {type: 'mat4', value: [1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1]}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float invert;", + "uniform mat4 matrix;", + "uniform sampler2D uSampler;", + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;", + "gl_FragColor = gl_FragColor * vColor;", + "}" + ]; + +} + +PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter; + +/** + * Sets the matrix of the color matrix filter + * + * @property matrix + * @type Array and array of 26 numbers + * @default [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] + */ +Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', { + get: function() { + return this.uniforms.matrix.value; + }, + set: function(value) { + this.uniforms.matrix.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js new file mode 100644 index 00000000..ebf040bd --- /dev/null +++ b/src/pixi/filters/ColorStepFilter.js @@ -0,0 +1,51 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * + * This turns your displayObjects to black and white. + * @class GreyFilter + * @contructor + */ +PIXI.ColorStepFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + step: {type: 'f', value: 5}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform sampler2D uSampler;", + "uniform float step;", + "void main(void) {", + "vec4 color = texture2D(uSampler, vTextureCoord);", + "color = floor(color * step) / step;", + "gl_FragColor = color * vColor;", + "}" + ]; +} + +PIXI.ColorStepFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.ColorStepFilter.prototype.constructor = PIXI.ColorStepFilter; + +/** +The number of steps. +@property step +*/ +Object.defineProperty(PIXI.ColorStepFilter.prototype, 'step', { + get: function() { + return this.uniforms.step.value; + }, + set: function(value) { + this.uniforms.step.value = value; + } +}); diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js new file mode 100644 index 00000000..cd050cb0 --- /dev/null +++ b/src/pixi/filters/CrossHatchFilter.js @@ -0,0 +1,69 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + + +PIXI.CrossHatchFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: 'f', value: 1/512}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float blur;", + "uniform sampler2D uSampler;", + "void main(void) {", + + + " float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);", + " ", + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);", + " ", + " if (lum < 1.00) {", + " if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {", + " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", + " }", + " }", + " ", + " if (lum < 0.75) {", + " if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {", + " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", + " }", + " }", + " ", + " if (lum < 0.50) {", + " if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {", + " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", + " }", + " }", + " ", + " if (lum < 0.3) {", + " if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {", + " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", + " }", + " }", + "}" + ]; +} + +PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.CrossHatchFilter.prototype.constructor = PIXI.BlurYFilter; + +Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', { + get: function() { + return this.uniforms.blur.value / (1/7000); + }, + set: function(value) { + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; + } +}); diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js new file mode 100644 index 00000000..6c05498d --- /dev/null +++ b/src/pixi/filters/DisplacementFilter.js @@ -0,0 +1,135 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * + * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. + * You can use this filter to apply all manor of crazy warping effects + * Currently the r property of the texture is used offset the x and the g propery of the texture is used to offset the y. + * @class DisplacementFilter + * @contructor + * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment + */ +PIXI.DisplacementFilter = function(texture) +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + texture.baseTexture._powerOf2 = true; + + // set the uniforms + //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]} + }; + + + if(texture.baseTexture.hasLoaded) + { + this.uniforms.mapDimensions.value.x = texture.width; + this.uniforms.mapDimensions.value.y = texture.height; + } + else + { + this.boundLoadedFunction = this.onTextureLoaded.bind(this); + + texture.baseTexture.on("loaded", this.boundLoadedFunction); + } + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform sampler2D displacementMap;", + "uniform sampler2D uSampler;", + "uniform vec2 scale;", + "uniform vec2 offset;", + "uniform vec4 dimensions;", + "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", + // "const vec2 textureDimensions = vec2(750.0, 750.0);", + + "void main(void) {", + "vec2 mapCords = vTextureCoord.xy;", +// "mapCords -= ;", + "mapCords += (dimensions.zw + offset)/ dimensions.xy ;", + "mapCords.y *= -1.0;", + "mapCords.y += 1.0;", + "vec2 matSample = texture2D(displacementMap, mapCords).xy;", + "matSample -= 0.5;", + "matSample *= scale;", + "matSample /= mapDimensions;", + "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));", + "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);", + "vec2 cord = vTextureCoord;", + + //"gl_FragColor = texture2D(displacementMap, cord);", + "gl_FragColor = gl_FragColor * vColor;", + + "}" + ]; + +} + +PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter; + +PIXI.DisplacementFilter.prototype.onTextureLoaded = function() +{ + + this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; + this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; + + this.uniforms.displacementMap.value.baseTexture.off("loaded", this.boundLoadedFunction) + +} + +/** + * The texture used for the displacemtent map * must be power of 2 texture at the moment + * + * @property map + * @type Texture + */ +Object.defineProperty(PIXI.DisplacementFilter.prototype, 'map', { + get: function() { + return this.uniforms.displacementMap.value; + }, + set: function(value) { + this.uniforms.displacementMap.value = value; + } +}); + +/** + * The multiplier used to scale the displacement result from the map calculation. + * + * @property scale + * @type Point + */ +Object.defineProperty(PIXI.DisplacementFilter.prototype, 'scale', { + get: function() { + return this.uniforms.scale.value; + }, + set: function(value) { + this.uniforms.scale.value = value; + } +}); + +/** + * The offset used to move the displacement map. + * + * @property offset + * @type Point + */ +Object.defineProperty(PIXI.DisplacementFilter.prototype, 'offset', { + get: function() { + return this.uniforms.offset.value; + }, + set: function(value) { + this.uniforms.offset.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js new file mode 100644 index 00000000..f9f5452e --- /dev/null +++ b/src/pixi/filters/DotScreenFilter.js @@ -0,0 +1,86 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js + */ + +/** + * + * This filter applies a pixlate effect making display objects appear "blocky" + * @class PixelateFilter + * @contructor + */ +PIXI.DotScreenFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + scale: {type: 'f', value:1}, + angle: {type: 'f', value:5}, + dimensions: {type: 'f4', value:[0,0,0,0]} + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform vec4 dimensions;", + "uniform sampler2D uSampler;", + + "uniform float angle;", + "uniform float scale;", + + "float pattern() {", + "float s = sin(angle), c = cos(angle);", + "vec2 tex = vTextureCoord * dimensions.xy;", + "vec2 point = vec2(", + "c * tex.x - s * tex.y,", + "s * tex.x + c * tex.y", + ") * scale;", + "return (sin(point.x) * sin(point.y)) * 4.0;", + "}", + + "void main() {", + "vec4 color = texture2D(uSampler, vTextureCoord);", + "float average = (color.r + color.g + color.b) / 3.0;", + "gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);", + "}", + ]; +} + +PIXI.DotScreenFilter.prototype = Object.create( PIXI.DotScreenFilter.prototype ); +PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter; + +/** + * + * This describes the the scale + * @property scale + * @type Number + */ +Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', { + get: function() { + return this.uniforms.scale.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.scale.value = value; + } +}); + +/** + * + * This radius describes angle + * @property angle + * @type Number + */ +Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', { + get: function() { + return this.uniforms.angle.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.angle.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/filters/FilterBlock.js b/src/pixi/filters/FilterBlock.js index c4732338..bfcfdb77 100644 --- a/src/pixi/filters/FilterBlock.js +++ b/src/pixi/filters/FilterBlock.js @@ -4,10 +4,8 @@ -PIXI.FilterBlock = function(mask) +PIXI.FilterBlock = function() { - this.graphics = mask this.visible = true; this.renderable = true; -} - +} \ No newline at end of file diff --git a/src/pixi/filters/GreyFilter.js b/src/pixi/filters/GreyFilter.js new file mode 100644 index 00000000..d182975f --- /dev/null +++ b/src/pixi/filters/GreyFilter.js @@ -0,0 +1,51 @@ +/** + * @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 new file mode 100644 index 00000000..3d6ee784 --- /dev/null +++ b/src/pixi/filters/InvertFilter.js @@ -0,0 +1,52 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * + * This inverts your displayObjects colors. + * @class InvertFilter + * @contructor + */ +PIXI.InvertFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + invert: {type: 'f', value: 1}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float invert;", + "uniform sampler2D uSampler;", + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord);", + "gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);", + //"gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;", + "gl_FragColor = gl_FragColor * vColor;", + "}" + ]; + +} + +PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter; + +/** +The strength of the invert. 1 will fully invert the colors, 0 will make the object its normal color +@property invert +*/ +Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', { + get: function() { + return this.uniforms.invert.value; + }, + set: function(value) { + this.uniforms.invert.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js new file mode 100644 index 00000000..bc6eb354 --- /dev/null +++ b/src/pixi/filters/PixelateFilter.js @@ -0,0 +1,62 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * + * This filter applies a pixlate effect making display objects appear "blocky" + * @class PixelateFilter + * @contructor + */ +PIXI.PixelateFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // 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}}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform vec2 testDim;", + "uniform vec4 dimensions;", + "uniform vec2 pixelSize;", + "uniform sampler2D uSampler;", + "void main(void) {", + "vec2 coord = vTextureCoord;", + + "vec2 size = dimensions.xy/pixelSize;", + + "vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;", + "gl_FragColor = texture2D(uSampler, color);", + "}" + ]; + + +} + +PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter; + +/** + * + * This a point that describes the size of the blocs. x is the width of the block and y is the the height + * @property size + * @type Point + */ +Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', { + get: function() { + return this.uniforms.pixelSize.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.pixelSize.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js new file mode 100644 index 00000000..5303d646 --- /dev/null +++ b/src/pixi/filters/RGBSplitFilter.js @@ -0,0 +1,50 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + + +PIXI.RGBSplitFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // 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]} + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform vec2 red;", + "uniform vec2 green;", + "uniform vec2 blue;", + "uniform vec4 dimensions;", + "uniform sampler2D uSampler;", + "void main(void) {", + "gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;", + "gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;", + "gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;", + "gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;", + "}" + ]; +} + +PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter; + +Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'angle', { + get: function() { + return this.uniforms.blur.value / (1/7000); + }, + set: function(value) { + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; + } +}); diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js new file mode 100644 index 00000000..b3209337 --- /dev/null +++ b/src/pixi/filters/SepiaFilter.js @@ -0,0 +1,55 @@ +/** +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * + * This applies a sepia effect to your displayObjects. + * @class SepiaFilter + * @contructor + */ +PIXI.SepiaFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + sepia: {type: 'f', value: 1}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float sepia;", + "uniform sampler2D uSampler;", + + "const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);", + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vTextureCoord);", + "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);", + "gl_FragColor = gl_FragColor * vColor;", + "}" + ]; + +} + +PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter; + +/** +The strength of the sepia. 1 will apply the full sepia effect, 0 will make the object its normal color +@property sepia +*/ +Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', { + get: function() { + return this.uniforms.sepia.value; + }, + set: function(value) { + this.uniforms.sepia.value = value; + } +}); diff --git a/src/pixi/filters/SmartBlurFilter.js b/src/pixi/filters/SmartBlurFilter.js new file mode 100644 index 00000000..b0ddf87a --- /dev/null +++ b/src/pixi/filters/SmartBlurFilter.js @@ -0,0 +1,64 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + + +PIXI.SmartBlurFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: 'f', value: 1/512}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "uniform sampler2D uSampler;", + // "uniform vec2 delta;", + "const vec2 delta = vec2(1.0/10.0, 0.0);", + // "uniform float darkness;", + + "float random(vec3 scale, float seed) {", + "return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);", + "}", + + + "void main(void) {", + + "vec4 color = vec4(0.0);", + "float total = 0.0;", + + "float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);", + + "for (float t = -30.0; t <= 30.0; t++) {", + "float percent = (t + offset - 0.5) / 30.0;", + "float weight = 1.0 - abs(percent);", + "vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);", + "sample.rgb *= sample.a;", + "color += sample * weight;", + "total += weight;", + "}", + + "gl_FragColor = color / total;", + "gl_FragColor.rgb /= gl_FragColor.a + 0.00001;", + // "gl_FragColor.rgb *= darkness;", + "}" + ]; +} + +PIXI.SmartBlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.SmartBlurFilter.prototype.constructor = PIXI.SmartBlurFilter; + +Object.defineProperty(PIXI.SmartBlurFilter.prototype, 'blur', { + get: function() { + return this.uniforms.blur.value; + }, + set: function(value) { + this.uniforms.blur.value = value; + } +}); diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js new file mode 100644 index 00000000..b477b0b3 --- /dev/null +++ b/src/pixi/filters/TwistFilter.js @@ -0,0 +1,103 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * + * This filter applies a pixlate effect making display objects appear "blocky" + * @class PixelateFilter + * @contructor + */ +PIXI.TwistFilter = function() +{ + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // 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}}, + }; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform vec4 dimensions;", + "uniform sampler2D uSampler;", + + "uniform float radius;", + "uniform float angle;", + "uniform vec2 offset;", + + "void main(void) {", + "vec2 coord = vTextureCoord - offset;", + "float distance = length(coord);", + + "if (distance < radius){", + + "float ratio = (radius - distance) / radius;", + "float angleMod = ratio * ratio * angle;", + "float s = sin(angleMod);", + "float c = cos(angleMod);", + "coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);", + + "}", + + "gl_FragColor = texture2D(uSampler, coord+offset);", + "}" + ]; +} + +PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter; + +/** + * + * This point describes the the offset of the twist + * @property size + * @type Point + */ +Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', { + get: function() { + return this.uniforms.offset.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.offset.value = value; + } +}); + +/** + * + * This radius describes size of the twist + * @property size + * @type Number + */ +Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', { + get: function() { + return this.uniforms.radius.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.radius.value = value; + } +}); + +/** + * + * This radius describes angle of the twist + * @property angle + * @type Number + */ +Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', { + get: function() { + return this.uniforms.angle.value; + }, + set: function(value) { + this.dirty = true; + this.uniforms.angle.value = value; + } +}); \ No newline at end of file diff --git a/src/pixi/loaders/AssetLoader.js b/src/pixi/loaders/AssetLoader.js index 168a5f86..02e02a96 100644 --- a/src/pixi/loaders/AssetLoader.js +++ b/src/pixi/loaders/AssetLoader.js @@ -54,8 +54,8 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) "xml": PIXI.BitmapFontLoader, "fnt": PIXI.BitmapFontLoader }; - - + + }; /** @@ -65,7 +65,7 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) /** * Fired when all the assets have loaded - * @event onComplete + * @event onComplete */ // constructor @@ -112,7 +112,7 @@ PIXI.AssetLoader.prototype.onAssetLoaded = function() this.loadCount--; this.dispatchEvent({type: "onProgress", content: this}); if(this.onProgress) this.onProgress(); - + if(this.loadCount == 0) { this.dispatchEvent({type: "onComplete", content: this}); diff --git a/src/pixi/loaders/BitmapFontLoader.js b/src/pixi/loaders/BitmapFontLoader.js index 4afd8aa2..ef050943 100644 --- a/src/pixi/loaders/BitmapFontLoader.js +++ b/src/pixi/loaders/BitmapFontLoader.js @@ -110,20 +110,19 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() { var charCode = parseInt(letters[i].attributes.getNamedItem("id").nodeValue, 10); - var textureRect = { - x: parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10), - y: parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10), - width: parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10), - height: parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10) - }; - PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect); + var textureRect = new PIXI.Rectangle( + parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10) + ); data.chars[charCode] = { xOffset: parseInt(letters[i].attributes.getNamedItem("xoffset").nodeValue, 10), yOffset: parseInt(letters[i].attributes.getNamedItem("yoffset").nodeValue, 10), xAdvance: parseInt(letters[i].attributes.getNamedItem("xadvance").nodeValue, 10), kerning: {}, - texture:new PIXI.Texture(this.texture, textureRect) + texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect) }; } diff --git a/src/pixi/loaders/ImageLoader.js b/src/pixi/loaders/ImageLoader.js index 971c0129..d8a41374 100644 --- a/src/pixi/loaders/ImageLoader.js +++ b/src/pixi/loaders/ImageLoader.js @@ -24,6 +24,13 @@ PIXI.ImageLoader = function(url, crossorigin) * @type Texture */ this.texture = PIXI.Texture.fromImage(url, crossorigin); + + /** + * if the image is loaded with loadFramedSpriteSheet + * frames will contain the sprite sheet frames + * + */ + this.frames = []; }; // constructor @@ -60,3 +67,48 @@ PIXI.ImageLoader.prototype.onLoaded = function() { this.dispatchEvent({type: "loaded", content: this}); }; + +/** + * Loads image and split it to uniform sized frames + * + * + * @method loadFramedSpriteSheet + * @param frameWidth {Number} with of each frame + * @param frameHeight {Number} height of each frame + * @param textureName {String} if given, the frames will be cached in - format + */ +PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName) +{ + this.frames = []; + var cols = Math.floor(this.texture.width / frameWidth); + var rows = Math.floor(this.texture.height / frameHeight); + + var i=0; + for (var y=0; y maxX ? x + width : maxX; + + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; + + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; + + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { + + x = points[j]; + y = points[j+1]; + + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + }; + } + + }; + + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + + } + +// console.log(this.bounds); } // SOME TYPES: diff --git a/src/pixi/renderers/canvas/CanvasGraphics.js b/src/pixi/renderers/canvas/CanvasGraphics.js index 7f1093b9..f5352b9b 100644 --- a/src/pixi/renderers/canvas/CanvasGraphics.js +++ b/src/pixi/renderers/canvas/CanvasGraphics.js @@ -10,7 +10,7 @@ */ PIXI.CanvasGraphics = function() { - + } @@ -26,33 +26,33 @@ PIXI.CanvasGraphics = function() PIXI.CanvasGraphics.renderGraphics = function(graphics, context) { var worldAlpha = graphics.worldAlpha; - - for (var i=0; i < graphics.graphicsData.length; i++) + + for (var i=0; i < graphics.graphicsData.length; i++) { var data = graphics.graphicsData[i]; var points = data.points; - + context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); context.lineWidth = data.lineWidth; - + if(data.type == PIXI.Graphics.POLY) { context.beginPath(); - + context.moveTo(points[0], points[1]); - + for (var j=1; j < points.length/2; j++) { context.lineTo(points[j * 2], points[j * 2 + 1]); - } - + } + // if the first and last point are the same close the path - much neater :) if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) { context.closePath(); } - + if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; @@ -67,21 +67,20 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) } else if(data.type == PIXI.Graphics.RECT) { - - // TODO - need to be Undefined! - if(data.fillColor) + + if(data.fillColor || data.fillColor === 0) { context.globalAlpha = data.fillAlpha * worldAlpha; context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); context.fillRect(points[0], points[1], points[2], points[3]); - + } if(data.lineWidth) { context.globalAlpha = data.lineAlpha * worldAlpha; context.strokeRect(points[0], points[1], points[2], points[3]); } - + } else if(data.type == PIXI.Graphics.CIRC) { @@ -89,7 +88,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) context.beginPath(); context.arc(points[0], points[1], points[2],0,2*Math.PI); context.closePath(); - + if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; @@ -104,19 +103,19 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) } else if(data.type == PIXI.Graphics.ELIP) { - + // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - + var elipseData = data.points; - + var w = elipseData[2] * 2; var h = elipseData[3] * 2; - + var x = elipseData[0] - w/2; var y = elipseData[1] - h/2; - + context.beginPath(); - + var kappa = .5522848, ox = (w / 2) * kappa, // control point offset horizontal oy = (h / 2) * kappa, // control point offset vertical @@ -124,15 +123,15 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) ye = y + h, // y-end xm = x + w / 2, // x-middle ym = y + h / 2; // y-middle - + context.moveTo(x, ym); context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - + context.closePath(); - + if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; @@ -145,7 +144,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) context.stroke(); } } - + }; } @@ -161,35 +160,37 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) { var worldAlpha = graphics.worldAlpha; - + var len = graphics.graphicsData.length; + if(len === 0)return; + if(len > 1) { len = 1; console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object") } - - for (var i=0; i < 1; i++) + + for (var i=0; i < 1; i++) { var data = graphics.graphicsData[i]; var points = data.points; - + if(data.type == PIXI.Graphics.POLY) { context.beginPath(); context.moveTo(points[0], points[1]); - + for (var j=1; j < points.length/2; j++) { context.lineTo(points[j * 2], points[j * 2 + 1]); - } - + } + // if the first and last point are the same close the path - much neater :) if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) { context.closePath(); } - + } else if(data.type == PIXI.Graphics.RECT) { @@ -206,18 +207,18 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) } else if(data.type == PIXI.Graphics.ELIP) { - + // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas var elipseData = data.points; - + var w = elipseData[2] * 2; var h = elipseData[3] * 2; - + var x = elipseData[0] - w/2; var y = elipseData[1] - h/2; - + context.beginPath(); - + var kappa = .5522848, ox = (w / 2) * kappa, // control point offset horizontal oy = (h / 2) * kappa, // control point offset vertical @@ -225,7 +226,7 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) ye = y + h, // y-end xm = x + w / 2, // x-middle ym = y + h / 2; // y-middle - + context.moveTo(x, ym); context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); @@ -233,7 +234,7 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); context.closePath(); } - - + + }; } diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index 8dbb6256..1e927d30 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -9,8 +9,8 @@ * * @class CanvasRenderer * @constructor - * @param width=0 {number} the width of the canvas view - * @param height=0 {number} the height of the canvas view + * @param width=0 {Number} the width of the canvas view + * @param height=0 {Number} the height of the canvas view * @param view {Canvas} the canvas to use as a view, optional * @param transparent=false {Boolean} the transparency of the render view, default false */ @@ -114,8 +114,8 @@ PIXI.CanvasRenderer.prototype.render = function(stage) * resizes the canvas view to the specified width and height * * @method resize - * @param width {number} the new width of the canvas view - * @param height {number} the new height of the canvas view + * @param width {Number} the new width of the canvas view + * @param height {Number} the new height of the canvas view */ PIXI.CanvasRenderer.prototype.resize = function(width, height) { @@ -163,9 +163,10 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) if(displayObject instanceof PIXI.Sprite) { + var frame = displayObject.texture.frame; - if(frame) + if(frame && frame.width && frame.height) { context.globalAlpha = displayObject.worldAlpha; @@ -194,6 +195,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) } else if(displayObject instanceof PIXI.CustomRenderable) { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); displayObject.renderCanvas(this); } else if(displayObject instanceof PIXI.Graphics) @@ -203,27 +205,36 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) } else if(displayObject instanceof PIXI.FilterBlock) { - if(displayObject.open) - { - context.save(); - - var cacheAlpha = displayObject.mask.alpha; - var maskTransform = displayObject.mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]) - - displayObject.mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context); - context.clip(); - - displayObject.mask.worldAlpha = cacheAlpha; + if(displayObject.data instanceof PIXI.Graphics) + { + var mask = displayObject.data; + + if(displayObject.open) + { + context.save(); + + var cacheAlpha = mask.alpha; + var maskTransform = mask.worldTransform; + + context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]) + + mask.worldAlpha = 0.5; + + context.worldAlpha = 0; + + PIXI.CanvasGraphics.renderGraphicsMask(mask, context); + context.clip(); + + mask.worldAlpha = cacheAlpha; + } + else + { + context.restore(); + } } else { - context.restore(); + // only masks supported right now! } } // count++ diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js new file mode 100644 index 00000000..7b6a50f9 --- /dev/null +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -0,0 +1,119 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +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;", + "}" + ]; + +} + +PIXI.PixiShader.prototype.init = function() +{ + 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 attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + 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] = + this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key); + + + } + + this.program = program; +} + +PIXI.PixiShader.prototype.syncUniforms = function() +{ + var gl = PIXI.gl; + + for (var key in this.uniforms) + { + //var + var type = this.uniforms[key].type; + + // need to grow this! + if(type == "f") + { + gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value); + } + if(type == "f2") + { + // console.log(this.program[key]) + gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y); + } + else if(type == "f4") + { + // console.log(this.uniforms[key].value) + 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") + { + // first texture... + var texture = this.uniforms[key].value; + + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture); + + 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); + } + } + +} + +PIXI.PixiShader.defaultVertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float 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/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js new file mode 100644 index 00000000..1089d84d --- /dev/null +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -0,0 +1,57 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.PrimitiveShader = function() +{ + // the webGL program.. + this.program; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec4 vColor;", + "void main(void) {", + "gl_FragColor = vColor;", + "}" + ]; + + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec4 aColor;", + "uniform mat3 translationMatrix;", + "uniform vec2 projectionVector;", + "uniform vec2 offsetVector;", + "uniform float alpha;", + "varying vec4 vColor;", + "void main(void) {", + "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", + "v -= offsetVector.xyx;", + "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", + "vColor = aColor * alpha;", + "}" + ]; + +} + +PIXI.PrimitiveShader.prototype.init = function() +{ + var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + + gl.useProgram(program); + + // get and store the uniforms for the shader + this.projectionVector = gl.getUniformLocation(program, "projectionVector"); + this.offsetVector = gl.getUniformLocation(program, "offsetVector"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.colorAttribute = gl.getAttribLocation(program, "aColor"); + + this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); + this.alpha = gl.getUniformLocation(program, "alpha"); + + this.program = program; +} diff --git a/src/pixi/renderers/webgl/StripShader.js b/src/pixi/renderers/webgl/StripShader.js new file mode 100644 index 00000000..80d8394c --- /dev/null +++ b/src/pixi/renderers/webgl/StripShader.js @@ -0,0 +1,65 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.StripShader = function() +{ + // the webGL program.. + this.program; + + this.fragmentSrc = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float vColor;", + "uniform float alpha;", + "uniform sampler2D uSampler;", + "void main(void) {", + "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));", + "gl_FragColor = gl_FragColor * alpha;", + "}" + ]; + + this.vertexSrc = [ + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "attribute float aColor;", + "uniform mat3 translationMatrix;", + "uniform vec2 projectionVector;", + "varying vec2 vTextureCoord;", + "varying vec2 offsetVector;", + "varying float vColor;", + "void main(void) {", + "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", + "v -= offsetVector.xyx;", + "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);", + "vTextureCoord = aTextureCoord;", + "vColor = aColor;", + "}" + ]; +} + +PIXI.StripShader.prototype.init = function() +{ + var program = PIXI.compileProgram(this.vertexSrc, 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.colorAttribute = gl.getAttribLocation(program, "aColor"); + //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + + this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); + this.alpha = gl.getUniformLocation(program, "alpha"); + + this.program = program; +} diff --git a/src/pixi/renderers/webgl/WebGLBatch.js b/src/pixi/renderers/webgl/WebGLBatch.js index 410884b8..fa09fc43 100644 --- a/src/pixi/renderers/webgl/WebGLBatch.js +++ b/src/pixi/renderers/webgl/WebGLBatch.js @@ -415,7 +415,10 @@ PIXI.WebGLBatch.prototype.update = function() var indexRun = 0; var displayObject = this.head; - + var verticies = this.verticies; + var uvs = this.uvs; + var colors = this.colors; + while(displayObject) { if(displayObject.vcount === PIXI.visibleCount) @@ -443,17 +446,17 @@ PIXI.WebGLBatch.prototype.update = function() tx = worldTransform[2]; ty = worldTransform[5]; - this.verticies[index + 0 ] = a * w1 + c * h1 + tx; - this.verticies[index + 1 ] = d * h1 + b * w1 + ty; + verticies[index + 0 ] = a * w1 + c * h1 + tx; + verticies[index + 1 ] = d * h1 + b * w1 + ty; - this.verticies[index + 2 ] = a * w0 + c * h1 + tx; - this.verticies[index + 3 ] = d * h1 + b * w0 + ty; + verticies[index + 2 ] = a * w0 + c * h1 + tx; + verticies[index + 3 ] = d * h1 + b * w0 + ty; - this.verticies[index + 4 ] = a * w0 + c * h0 + tx; - this.verticies[index + 5 ] = d * h0 + b * w0 + ty; + verticies[index + 4 ] = a * w0 + c * h0 + tx; + verticies[index + 5 ] = d * h0 + b * w0 + ty; - this.verticies[index + 6] = a * w1 + c * h0 + tx; - this.verticies[index + 7] = d * h0 + b * w1 + ty; + verticies[index + 6] = a * w1 + c * h0 + tx; + verticies[index + 7] = d * h0 + b * w1 + ty; if(displayObject.updateFrame || displayObject.texture.updateFrame) { @@ -465,17 +468,17 @@ PIXI.WebGLBatch.prototype.update = function() var tw = texture.baseTexture.width; var th = texture.baseTexture.height; - this.uvs[index + 0] = frame.x / tw; - this.uvs[index +1] = frame.y / th; + uvs[index + 0] = frame.x / tw; + uvs[index +1] = frame.y / th; - this.uvs[index +2] = (frame.x + frame.width) / tw; - this.uvs[index +3] = frame.y / th; + uvs[index +2] = (frame.x + frame.width) / tw; + uvs[index +3] = frame.y / th; - this.uvs[index +4] = (frame.x + frame.width) / tw; - this.uvs[index +5] = (frame.y + frame.height) / th; + uvs[index +4] = (frame.x + frame.width) / tw; + uvs[index +5] = (frame.y + frame.height) / th; - this.uvs[index +6] = frame.x / tw; - this.uvs[index +7] = (frame.y + frame.height) / th; + uvs[index +6] = frame.x / tw; + uvs[index +7] = (frame.y + frame.height) / th; displayObject.updateFrame = false; } @@ -486,7 +489,7 @@ PIXI.WebGLBatch.prototype.update = function() displayObject.cacheAlpha = displayObject.worldAlpha; var colorIndex = indexRun * 4; - this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; + colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha; this.dirtyColors = true; } } @@ -494,17 +497,7 @@ PIXI.WebGLBatch.prototype.update = function() { index = indexRun * 8; - this.verticies[index + 0 ] = 0; - this.verticies[index + 1 ] = 0; - - this.verticies[index + 2 ] = 0; - this.verticies[index + 3 ] = 0; - - this.verticies[index + 4 ] = 0; - this.verticies[index + 5 ] = 0; - - this.verticies[index + 6] = 0; - this.verticies[index + 7] = 0; + verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] = verticies[index + 7] = 0; } indexRun++; @@ -536,15 +529,18 @@ PIXI.WebGLBatch.prototype.render = function(start, end) //TODO optimize this! - var shaderProgram = PIXI.shaderProgram; - gl.useProgram(shaderProgram); + var shaderProgram = PIXI.defaultShader; + + //gl.useProgram(shaderProgram); // update the verts.. gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); // ok.. gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies) - gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shaderProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0); // update the uvs + //var isDefault = (shaderProgram == PIXI.shaderProgram) + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); if(this.dirtyUVS) @@ -553,7 +549,7 @@ PIXI.WebGLBatch.prototype.render = function(start, end) gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); } - gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture); @@ -568,7 +564,6 @@ PIXI.WebGLBatch.prototype.render = function(start, end) } gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); - // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); diff --git a/src/pixi/renderers/webgl/WebGLFilterManager.js b/src/pixi/renderers/webgl/WebGLFilterManager.js new file mode 100644 index 00000000..f3e9027c --- /dev/null +++ b/src/pixi/renderers/webgl/WebGLFilterManager.js @@ -0,0 +1,519 @@ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +PIXI.WebGLFilterManager = function(transparent) +{ + this.transparent = transparent; + + this.filterStack = []; + this.texturePool = []; + + this.offsetX = 0; + this.offsetY = 0; + + this.initShaderBuffers(); +} + +// API + +PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer) +{ + this.width = projection.x * 2; + this.height = -projection.y * 2; + this.buffer = buffer; +} + +PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) +{ + var gl = PIXI.gl; + + // filter program + // OPTIMISATION - the first filter is free if its a simple color change? + this.filterStack.push(filterBlock); + + var filter = filterBlock.filterPasses[0]; + + + + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; + + + + + + var texture = this.texturePool.pop(); + if(!texture)texture = new PIXI.FilterTexture(this.width, this.height); + + gl.bindTexture(gl.TEXTURE_2D, texture.texture); + + this.getBounds(filterBlock.target); + + // addpadding? + //displayObject.filterArea.x + + var filterArea = filterBlock.target.filterArea; + + var padidng = filter.padding; + filterArea.x -= padidng; + filterArea.y -= padidng; + filterArea.width += padidng * 2; + filterArea.height += padidng * 2; + + // cap filter to screen size.. + if(filterArea.x < 0)filterArea.x = 0; + if(filterArea.width > this.width)filterArea.width = this.width; + if(filterArea.y < 0)filterArea.y = 0; + if(filterArea.height > this.height)filterArea.height = this.height; + + + //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); + + // console.log(filterArea) + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); + + PIXI.projection.x = filterArea.width/2; + PIXI.projection.y = -filterArea.height/2; + + PIXI.offset.x = -filterArea.x; + PIXI.offset.y = -filterArea.y; + + //console.log(PIXI.defaultShader.projectionVector) + // update projection + gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y); + //PIXI.primitiveProgram + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + //filter.texture = texture; + filterBlock._glFilterTexture = texture; + + //console.log("PUSH") +} + + +PIXI.WebGLFilterManager.prototype.popFilter = function() +{ + + var gl = PIXI.gl; + + var filterBlock = this.filterStack.pop(); + + + + var filterArea = filterBlock.target.filterArea; + + var texture = filterBlock._glFilterTexture; + + if(filterBlock.filterPasses.length > 1) + { + gl.viewport(0, 0, filterArea.width, filterArea.height); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + + this.vertexArray[0] = 0; + this.vertexArray[1] = filterArea.height; + + this.vertexArray[2] = filterArea.width; + this.vertexArray[3] = filterArea.height; + + this.vertexArray[4] = 0; + this.vertexArray[5] = 0; + + this.vertexArray[6] = filterArea.width; + this.vertexArray[7] = 0; + + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + // nnow set the uvs.. + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + + var inputTexture = texture; + var outputTexture = this.texturePool.pop(); + if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height); + + // need to clear this FBO as it may have some left over elements from a prvious filter. + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.disable(gl.BLEND); + + for (var i = 0; i < filterBlock.filterPasses.length-1; i++) + { + var filterPass = filterBlock.filterPasses[i]; + + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); + + // draw texture.. + //filterPass.applyFilterPass(filterArea.width, filterArea.height); + this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); + + // swap the textures.. + var temp = inputTexture; + inputTexture = outputTexture; + outputTexture = temp; + + }; + + gl.enable(gl.BLEND); + + texture = inputTexture; + this.texturePool.push(outputTexture); + } + + var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; + + this.offsetX -= filterArea.x; + this.offsetY -= filterArea.y; + + + var sizeX = this.width; + var sizeY = this.height; + + var offsetX = 0; + var offsetY = 0; + + var buffer = this.buffer; + + // time to render the filters texture to the previous scene + if(this.filterStack.length === 0) + { + gl.colorMask(true, true, true, this.transparent); + } + else + { + var currentFilter = this.filterStack[this.filterStack.length-1]; + var filterArea = currentFilter.target.filterArea; + + sizeX = filterArea.width; + sizeY = filterArea.height; + + offsetX = filterArea.x; + offsetY = filterArea.y; + + buffer = currentFilter._glFilterTexture.frameBuffer; + } + + + + // TODO need toremove thease global elements.. + PIXI.projection.x = sizeX/2; + PIXI.projection.y = -sizeY/2; + + PIXI.offset.x = offsetX; + PIXI.offset.y = offsetY; + + + var filterArea = filterBlock.target.filterArea; + var x = filterArea.x-offsetX; + var y = filterArea.y-offsetY; + + // update the buffers.. + // make sure to flip the y! + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + + this.vertexArray[0] = x; + this.vertexArray[1] = y + filterArea.height; + + this.vertexArray[2] = x + filterArea.width; + this.vertexArray[3] = y + filterArea.height; + + this.vertexArray[4] = x; + this.vertexArray[5] = y; + + this.vertexArray[6] = x + filterArea.width; + this.vertexArray[7] = y; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + + gl.viewport(0, 0, sizeX, sizeY); + // bind the buffer + gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture.texture); + + // apply! + //filter.applyFilterPass(sizeX, sizeY); + this.applyFilterPass(filter, filterArea, sizeX, sizeY); + + // now restore the regular shader.. + gl.useProgram(PIXI.defaultShader.program); + gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY); + + // return the texture to the pool + this.texturePool.push(texture); + filterBlock._glFilterTexture = null; +} + +PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height) +{ + // use program + var gl = PIXI.gl; + + if(!filter.shader) + { + var shader = new PIXI.PixiShader(); + + shader.fragmentSrc = filter.fragmentSrc; + shader.uniforms = filter.uniforms; + shader.init(); + + filter.shader = shader; + } + + var shader = filter.shader; + + // set the shader + gl.useProgram(shader.program); + + gl.uniform2f(shader.projectionVector, width/2, -height/2); + gl.uniform2f(shader.offsetVector, 0,0) + + if(filter.uniforms.dimensions) + { + //console.log(filter.uniforms.dimensions) + filter.uniforms.dimensions.value[0] = this.width;//width; + filter.uniforms.dimensions.value[1] = this.height;//height; + filter.uniforms.dimensions.value[2] = this.vertexArray[0]; + filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; + // console.log(this.vertexArray[5]) + } + + shader.syncUniforms(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // draw the filter... + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); +} + +PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() +{ + var gl = PIXI.gl; + + // create some buffers + this.vertexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + // bind and upload the vertexs.. + // keep a refferance to the vertexFloatData.. + this.vertexArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.vertexArray, + gl.STATIC_DRAW); + + + // bind and upload the uv buffer + this.uvArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.uvArray, + gl.STATIC_DRAW); + + // bind and upload the index + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array([0, 1, 2, 1, 3, 2]), + gl.STATIC_DRAW); +} + +PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject) +{ + // time to get the width and height of the object! + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest; + var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; + + var tempObject = displayObject.first; + var testObject = displayObject.last._iNext; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + do + { + // TODO can be optimized! - what if there is no scale / rotation? + + if(tempObject.visible) + { + if(tempObject instanceof PIXI.Sprite) + { + width = tempObject.texture.frame.width; + height = tempObject.texture.frame.height; + + // TODO trim?? + aX = tempObject.anchor.x; + aY = tempObject.anchor.y; + w0 = width * (1-aX); + w1 = width * -aX; + + h0 = height * (1-aY); + h1 = height * -aY; + + doTest = true; + } + else if(tempObject instanceof PIXI.Graphics) + { + tempObject.updateFilterBounds(); + + var bounds = tempObject.bounds; + + width = bounds.width; + height = bounds.height; + + w0 = bounds.x + w1 = bounds.x + bounds.width; + + h0 = bounds.y + h1 = bounds.y + bounds.height; + + doTest = true; + } + } + + if(doTest) + { + worldTransform = tempObject.worldTransform; + + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; + + x1 = a * w1 + c * h1 + tx; + y1 = d * h1 + b * w1 + ty; + + x2 = a * w0 + c * h1 + tx; + y2 = d * h1 + b * w0 + ty; + + x3 = a * w0 + c * h0 + tx; + y3 = d * h0 + b * w0 + ty; + + x4 = a * w1 + c * h0 + tx; + y4 = d * h0 + b * w1 + ty; + + minX = x1 < minX ? x1 : minX; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; + + minY = y1 < minY ? y1 : minY; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; + + maxX = x1 > maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; + + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + } + + doTest = false; + tempObject = tempObject._iNext; + + } + while(tempObject != testObject) + + // maximum bounds is the size of the screen.. + //minX = minX > 0 ? minX : 0; + //minY = minY > 0 ? minY : 0; + + displayObject.filterArea.x = minX; + displayObject.filterArea.y = minY; + +// console.log(maxX+ " : " + minX) + displayObject.filterArea.width = maxX - minX; + displayObject.filterArea.height = maxY - minY; +} + +PIXI.FilterTexture = function(width, height) +{ + var gl = PIXI.gl; + + // next time to create a frame buffer and texture + this.frameBuffer = gl.createFramebuffer(); + this.texture = gl.createTexture(); + + gl.bindTexture(gl.TEXTURE_2D, this.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.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); + + this.resize(width, height); +} + +PIXI.FilterTexture.prototype.resize = function(width, height) +{ + this.width = width; + this.height = height; + + var gl = PIXI.gl; + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + +} \ No newline at end of file diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index bcddb142..1d949853 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -46,7 +46,6 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) PIXI.WebGLGraphics.updateGraphics(graphics); } - PIXI.activatePrimitiveShader(); // This could be speeded up fo sure! @@ -56,30 +55,29 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) // set the matrix transform for the gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - - gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m); - - gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y); - - gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha); + gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m); + + gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); - // WHY DOES THIS LINE NEED TO BE THERE??? - gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); - // its not even used.. but need to be set or it breaks? - // only on pc though.. - - gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(PIXI.primitiveProgram.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); + gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); + gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); + gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); + PIXI.deactivatePrimitiveShader(); + + // return to default shader... - PIXI.activateDefaultShader(); +// PIXI.activateShader(PIXI.defaultShader); } /** @@ -284,6 +282,14 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) var points = graphicsData.points; if(points.length == 0)return; + // if the line width is an odd number add 0.5 to align to a whole pixel + if(graphicsData.lineWidth%2) + { + for (var i = 0; i < points.length; i++) { + points[i] += 0.5; + }; + } + // get first and last point.. figure out the middle! var firstPoint = new PIXI.Point( points[0], points[1] ); var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); @@ -385,16 +391,27 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); denom = a1*b2 - a2*b1; - - if (denom == 0) { - denom+=1; - } + + if(Math.abs(denom) < 0.1 ) + { + + denom+=10.1; + verts.push(p2x - perpx , p2y - perpy, + r, g, b, alpha); + + verts.push(p2x + perpx , p2y + perpy, + r, g, b, alpha); + + continue; + } px = (b1*c2 - b2*c1)/denom; py = (a2*c1 - a1*c2)/denom; + pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); + if(pdist > 140 * 140) { perp3x = perpx - perp2x; @@ -419,6 +436,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) } else { + verts.push(px , py); verts.push(r, g, b, alpha); diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index a66ce6b6..7a52a9f2 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -15,14 +15,18 @@ * @contructor * @param gl {WebGLContext} An instance of the webGL context */ -PIXI.WebGLRenderGroup = function(gl) +PIXI.WebGLRenderGroup = function(gl, transparent) { this.gl = gl; this.root; this.backgroundColor; + this.transparent = transparent == undefined ? true : transparent; + this.batchs = []; this.toRemove = []; + console.log(this.transparent) + this.filterManager = new PIXI.WebGLFilterManager(this.transparent); } // constructor @@ -56,19 +60,20 @@ PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject) * @method render * @param projection {Object} */ -PIXI.WebGLRenderGroup.prototype.render = function(projection) +PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer) { PIXI.WebGLRenderer.updateTextures(); var gl = this.gl; + gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); - gl.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - // will render all the elements in the group var renderable; - + for (var i=0; i < this.batchs.length; i++) { @@ -79,61 +84,12 @@ PIXI.WebGLRenderGroup.prototype.render = function(projection) continue; } - // non sprite batch.. - var worldVisible = renderable.vcount === PIXI.visibleCount; - - if(renderable instanceof PIXI.TilingSprite) - { - if(worldVisible)this.renderTilingSprite(renderable, projection); - } - else if(renderable instanceof PIXI.Strip) - { - if(worldVisible)this.renderStrip(renderable, projection); - } - else if(renderable instanceof PIXI.Graphics) - { - if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix); - } - else if(renderable instanceof PIXI.FilterBlock) - { - /* - * for now only masks are supported.. - */ - if(renderable.open) - { - gl.enable(gl.STENCIL_TEST); - - gl.colorMask(false, false, false, false); - gl.stencilFunc(gl.ALWAYS,1,0xff); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - - PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection); - - gl.colorMask(true, true, true, false); - gl.stencilFunc(gl.NOTEQUAL,0,0xff); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - } - else - { - gl.disable(gl.STENCIL_TEST); - } - } + // render special + this.renderSpecial(renderable, projection); } } -/** - * Renders the stage to its webgl view - * - * @method handleFilter - * @param filter {FilterBlock} - * @private - */ -PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection) -{ - -} - /** * Renders a specific displayObject * @@ -142,13 +98,14 @@ PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection) * @param projection {Object} * @private */ -PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection) +PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer) { PIXI.WebGLRenderer.updateTextures(); - var gl = this.gl; - gl.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y); + gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y); + + this.filterManager.begin(projection, buffer); // to do! // render part of the scene... @@ -168,11 +125,13 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project var nextRenderable = displayObject.first; while(nextRenderable._iNext) { - nextRenderable = nextRenderable._iNext; if(nextRenderable.renderable && nextRenderable.__renderGroup)break; + nextRenderable = nextRenderable._iNext; } var startBatch = nextRenderable.batch; + //console.log(nextRenderable); + //console.log(renderable) if(nextRenderable instanceof PIXI.Sprite) { startBatch = nextRenderable.batch; @@ -202,13 +161,11 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project } // Get the LAST renderable object - var lastRenderable = displayObject; - var endBatch; - var lastItem = displayObject; - while(lastItem.children.length > 0) + var lastRenderable = displayObject.last; + while(lastRenderable._iPrev) { - lastItem = lastItem.children[lastItem.children.length-1]; - if(lastItem.renderable)lastRenderable = lastItem; + if(lastRenderable.renderable && lastRenderable.__renderGroup)break; + lastRenderable = lastRenderable._iNext; } if(lastRenderable instanceof PIXI.Sprite) @@ -237,6 +194,7 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project endBatch = lastRenderable; } + //console.log(endBatch); // TODO - need to fold this up a bit! if(startBatch == endBatch) @@ -302,8 +260,10 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project */ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection) { + var worldVisible = renderable.vcount === PIXI.visibleCount + if(renderable instanceof PIXI.TilingSprite) { if(worldVisible)this.renderTilingSprite(renderable, projection); @@ -322,29 +282,76 @@ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection) } else if(renderable instanceof PIXI.FilterBlock) { - /* - * for now only masks are supported.. - */ + this.handleFilterBlock(renderable, projection); + } +} - var gl = PIXI.gl; +flip = false; +var maskStack = []; +var maskPosition = 0; - if(renderable.open) +//var usedMaskStack = []; + +PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection) +{ + /* + * for now only masks are supported.. + */ + var gl = PIXI.gl; + + if(filterBlock.open) + { + if(filterBlock.data instanceof Array) { - gl.enable(gl.STENCIL_TEST); - - gl.colorMask(false, false, false, false); - gl.stencilFunc(gl.ALWAYS,1,0xff); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE); - - PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection); + this.filterManager.pushFilter(filterBlock); + // ok so.. + + } + else + { + maskPosition++; + + maskStack.push(filterBlock) + + gl.enable(gl.STENCIL_TEST); + + gl.colorMask(false, false, false, false); + + gl.stencilFunc(gl.ALWAYS,1,1); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); + + PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection); - // we know this is a render texture so enable alpha too.. gl.colorMask(true, true, true, true); - gl.stencilFunc(gl.NOTEQUAL,0,0xff); + gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length); gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); } + } + else + { + if(filterBlock.data instanceof Array) + { + this.filterManager.popFilter(); + } else { + var maskData = maskStack.pop(filterBlock) + + + if(maskData) + { + gl.colorMask(false, false, false, false); + + gl.stencilFunc(gl.ALWAYS,1,1); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); + + PIXI.WebGLGraphics.renderGraphics(maskData.data, projection); + + gl.colorMask(true, true, true, true); + gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); + }; + gl.disable(gl.STENCIL_TEST); } } @@ -410,7 +417,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end) * It keeps going back until it finds a sprite or the stage */ var previousRenderable = start; - while(previousRenderable != this.root) + while(previousRenderable != this.root.first) { previousRenderable = previousRenderable._iPrev; if(previousRenderable.renderable && previousRenderable.__renderGroup)break; @@ -424,7 +431,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end) * scene graph */ var previousRenderable2 = end; - while(previousRenderable2 != this.root) + while(previousRenderable2 != this.root.first) { previousRenderable2 = previousRenderable2._iPrev; if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break; @@ -796,6 +803,7 @@ PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject) } } + /** * Initializes a tiling sprite * @@ -866,25 +874,26 @@ PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite) PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection) { var gl = this.gl; - var shaderProgram = PIXI.shaderProgram; -// mat - //var mat4Real = PIXI.mat3.toMat4(strip.worldTransform); - //PIXI.mat4.transpose(mat4Real); - //PIXI.mat4.multiply(projectionMatrix, mat4Real, mat4Real ) + PIXI.activateStripShader(); + + var shader = PIXI.stripShader; + + var program = shader.program; - gl.useProgram(PIXI.stripShaderProgram); - var m = PIXI.mat3.clone(strip.worldTransform); PIXI.mat3.transpose(m); +// console.log(projection) // set the matrix transform for the - gl.uniformMatrix3fv(PIXI.stripShaderProgram.translationMatrix, false, m); - gl.uniform2f(PIXI.stripShaderProgram.projectionVector, projection.x, projection.y); - gl.uniform1f(PIXI.stripShaderProgram.alpha, strip.worldAlpha); + gl.uniformMatrix3fv(shader.translationMatrix, false, m); + gl.uniform2f(shader.projectionVector, projection.x, projection.y); + gl.uniform2f(shader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + + gl.uniform1f(shader.alpha, strip.worldAlpha); -/* + /* if(strip.blendMode == PIXI.blendModes.NORMAL) { gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); @@ -895,23 +904,22 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection) } */ - + //console.log("!!") if(!strip.dirty) - { - + { gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer); gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies) - gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); // update the uvs gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer); - gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture); gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer); - gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0); // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); @@ -921,30 +929,30 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection) strip.dirty = false; gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW) - gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); // update the uvs gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer); gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW) - gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture); - + // console.log(strip.texture.baseTexture._glTexture) gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW) - gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0); // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW); } - //console.log(gl.TRIANGLE_STRIP); gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0); - gl.useProgram(PIXI.shaderProgram); + PIXI.deactivateStripShader(); + //gl.useProgram(PIXI.currentProgram); } /** @@ -958,6 +966,8 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection) PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix) { var gl = this.gl; + + var shaderProgram = PIXI.shaderProgram; var tilePosition = sprite.tilePosition; @@ -1018,3 +1028,4 @@ PIXI.WebGLRenderGroup.prototype.initStrip = function(strip) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW); } + diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e192cfb7..e11cd44f 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -16,8 +16,8 @@ PIXI.gl; * * @class WebGLRenderer * @constructor - * @param width=0 {number} the width of the canvas view - * @param height=0 {number} the height of the canvas view + * @param width=0 {Number} the width of the canvas view + * @param height=0 {Number} the height of the canvas view * @param view {Canvas} the canvas to use as a view, optional * @param transparent=false {Boolean} the transparency of the render view, default false * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment) @@ -43,27 +43,38 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) this.batchs = []; - try - { - PIXI.gl = this.gl = this.view.getContext("experimental-webgl", { - alpha: this.transparent, - antialias:!!antialias, // SPEED UP?? - premultipliedAlpha:false, - stencil:true - }); - } - catch (e) - { - throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this); - } + var options = { + alpha: this.transparent, + antialias:!!antialias, // SPEED UP?? + premultipliedAlpha:false, + stencil:true + } - PIXI.initPrimitiveShader(); - PIXI.initDefaultShader(); - PIXI.initDefaultStripShader(); + //try 'experimental-webgl' + try { + PIXI.gl = this.gl = this.view.getContext("experimental-webgl", options); + } catch (e) { + //try 'webgl' + try { + PIXI.gl = this.gl = this.view.getContext("webgl", options); + } catch (e) { + // fail, not able to get a context + throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this); + } + } - PIXI.activateDefaultShader(); + PIXI.initDefaultShaders(); + + + + + // PIXI.activateDefaultShader(); var gl = this.gl; + + gl.useProgram(PIXI.defaultShader.program); + + PIXI.WebGLRenderer.gl = gl; this.batch = new PIXI.WebGLBatch(gl); @@ -74,11 +85,17 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); + PIXI.offset = new PIXI.Point(0, 0); + + // TODO remove thease globals.. this.resize(this.width, this.height); this.contextLost = false; - this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl); + //PIXI.pushShader(PIXI.defaultShader); + + this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent); + // this.stageRenderGroup. = this.transparent } // constructor @@ -137,15 +154,6 @@ PIXI.WebGLRenderer.prototype.render = function(stage) this.__stage = stage; this.stageRenderGroup.setRenderable(stage); } - - // TODO not needed now... - // update children if need be - // best to remove first! - /*for (var i=0; i < stage.__childrenRemoved.length; i++) - { - var group = stage.__childrenRemoved[i].__renderGroup - if(group)group.removeDisplayObject(stage.__childrenRemoved[i]); - }*/ // update any textures PIXI.WebGLRenderer.updateTextures(); @@ -168,6 +176,10 @@ PIXI.WebGLRenderer.prototype.render = function(stage) // HACK TO TEST this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + this.stageRenderGroup.render(PIXI.projection); // interaction @@ -277,8 +289,8 @@ PIXI.WebGLRenderer.destroyTexture = function(texture) * resizes the webGL view to the specified width and height * * @method resize - * @param width {number} the new width of the webGL view - * @param height {number} the new height of the webGL view + * @param width {Number} the new width of the webGL view + * @param height {Number} the new height of the webGL view */ PIXI.WebGLRenderer.prototype.resize = function(width, height) { @@ -293,7 +305,10 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height) //var projectionMatrix = this.projectionMatrix; PIXI.projection.x = this.width/2; - PIXI.projection.y = this.height/2; + PIXI.projection.y = -this.height/2; + + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; // projectionMatrix[0] = 2/this.width; // projectionMatrix[5] = -2/this.height; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index 68e5b0b1..44123d27 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -1,159 +1,79 @@ - /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ -/* - * the default suoer fast shader! - */ +PIXI.initDefaultShaders = function() +{ + PIXI.primitiveShader = new PIXI.PrimitiveShader(); + PIXI.primitiveShader.init(); -PIXI.shaderFragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));", - "gl_FragColor = gl_FragColor * vColor;", - "}" -]; + PIXI.stripShader = new PIXI.StripShader(); + PIXI.stripShader.init(); -PIXI.shaderVertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", - //"uniform mat4 uMVMatrix;", + PIXI.defaultShader = new PIXI.PixiShader(); + PIXI.defaultShader.init(); + + var gl = PIXI.gl; + var shaderProgram = PIXI.defaultShader.program; + + + gl.useProgram(shaderProgram); - "uniform vec2 projectionVector;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "void main(void) {", - // "gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0, 1.0);", - "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" -]; + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +} + +PIXI.activatePrimitiveShader = function() +{ + var gl = PIXI.gl; + + gl.useProgram(PIXI.primitiveShader.program); + + gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + + gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute); +} + +PIXI.deactivatePrimitiveShader = function() +{ + var gl = PIXI.gl; + + gl.useProgram(PIXI.defaultShader.program); + + gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute); + + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + +} + +PIXI.activateStripShader = function() +{ + var gl = PIXI.gl; + + gl.useProgram(PIXI.stripShader.program); + // gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +} + +PIXI.deactivateStripShader = function() +{ + var gl = PIXI.gl; + + gl.useProgram(PIXI.defaultShader.program); + //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +} /* - * the triangle strip shader.. - */ -PIXI.stripShaderFragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float alpha;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));", - "gl_FragColor = gl_FragColor * alpha;", - "}" -]; - - -PIXI.stripShaderVertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" -]; - - -/* - * primitive shader.. - */ - -PIXI.primitiveShaderFragmentSrc = [ - "precision mediump float;", - "varying vec4 vColor;", - "void main(void) {", - "gl_FragColor = vColor;", - "}" -]; - -PIXI.primitiveShaderVertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec4 aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "uniform float alpha;", - "varying vec4 vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", - "vColor = aColor * alpha;", - "}" -]; - -PIXI.initPrimitiveShader = function() -{ - var gl = PIXI.gl; - - var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc) - - gl.useProgram(shaderProgram); - - shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); - shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); - - shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); - shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); - - shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha"); - - PIXI.primitiveProgram = shaderProgram; -} - -PIXI.initDefaultShader = function() -{ - var gl = this.gl; - var shaderProgram = PIXI.compileProgram(PIXI.shaderVertexSrc, PIXI.shaderFragmentSrc) - - gl.useProgram(shaderProgram); - - shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); - shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); - shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); - shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); - - // shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); - shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); - - PIXI.shaderProgram = shaderProgram; -} - -PIXI.initDefaultStripShader = function() -{ - var gl = this.gl; - var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc) - - gl.useProgram(shaderProgram); - - shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); - shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); - shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); - shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix"); - shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha"); - - shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor"); - - shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector"); - - shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); - - PIXI.stripShaderProgram = shaderProgram; -} +SHADER COMPILER HELPERS +*/ PIXI.CompileVertexShader = function(gl, shaderSrc) { @@ -173,7 +93,7 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType) gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - alert(gl.getShaderInfoLog(shader)); + console.log(gl.getShaderInfoLog(shader)); return null; } @@ -194,38 +114,8 @@ PIXI.compileProgram = function(vertexSrc, fragmentSrc) gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - alert("Could not initialise shaders"); + console.log("Could not initialise shaders"); } return shaderProgram; } - - -PIXI.activateDefaultShader = function() -{ - var gl = PIXI.gl; - var shaderProgram = PIXI.shaderProgram; - - gl.useProgram(shaderProgram); - - - gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); - gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); - gl.enableVertexAttribArray(shaderProgram.colorAttribute); -} - - - -PIXI.activatePrimitiveShader = function() -{ - var gl = PIXI.gl; - - gl.disableVertexAttribArray(PIXI.shaderProgram.textureCoordAttribute); - gl.disableVertexAttribArray(PIXI.shaderProgram.colorAttribute); - - gl.useProgram(PIXI.primitiveProgram); - - gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute); - gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute); -} - diff --git a/src/pixi/text/BitmapText.js b/src/pixi/text/BitmapText.js index d2890c78..db4ec3b5 100644 --- a/src/pixi/text/BitmapText.js +++ b/src/pixi/text/BitmapText.js @@ -4,7 +4,7 @@ /** * A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n" - * You can generate the fnt files using + * You can generate the fnt files using * http://www.angelcode.com/products/bmfont/ for windows or * http://www.bmglyph.com/ for mac. * @@ -94,7 +94,7 @@ PIXI.BitmapText.prototype.updateText = function() prevCharCode = null; continue; } - + var charData = data.chars[charCode]; if(!charData) continue; @@ -135,7 +135,7 @@ PIXI.BitmapText.prototype.updateText = function() this.addChild(c); } - this.width = maxLineWidth * scale; + this.width = pos.x * scale; this.height = (pos.y + data.lineHeight) * scale; }; @@ -157,7 +157,7 @@ PIXI.BitmapText.prototype.updateTransform = function() this.dirty = false; } - + PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); }; diff --git a/src/pixi/text/Text.js b/src/pixi/text/Text.js index aaf6a431..df1d12d9 100644 --- a/src/pixi/text/Text.js +++ b/src/pixi/text/Text.js @@ -14,9 +14,9 @@ * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") * @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) + * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap + * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap */ PIXI.Text = function(text, style) { @@ -26,7 +26,7 @@ PIXI.Text = function(text, style) this.setText(text); this.setStyle(style); - + this.updateText(); this.dirty = false; }; @@ -44,9 +44,9 @@ PIXI.Text.prototype.constructor = PIXI.Text; * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") * @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) + * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap + * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap */ PIXI.Text.prototype.setStyle = function(style) { @@ -68,7 +68,7 @@ PIXI.Text.prototype.setStyle = function(style) * @methos setText * @param {String} text The copy that you would like the text to display */ -PIXI.Sprite.prototype.setText = function(text) +PIXI.Text.prototype.setText = function(text) { this.text = text.toString() || " "; this.dirty = true; @@ -83,9 +83,9 @@ PIXI.Sprite.prototype.setText = function(text) PIXI.Text.prototype.updateText = function() { this.context.font = this.style.font; - + var outputText = this.text; - + // word wrap // preserve original text if(this.style.wordWrap)outputText = this.wordWrap(this.text); @@ -103,7 +103,7 @@ PIXI.Text.prototype.updateText = function() maxLineWidth = Math.max(maxLineWidth, lineWidth); } this.canvas.width = maxLineWidth + this.style.strokeThickness; - + //calculate text height var lineHeight = this.determineFontHeight("font: " + this.style.font + ";") + this.style.strokeThickness; this.canvas.height = lineHeight * lines.length; @@ -111,7 +111,7 @@ PIXI.Text.prototype.updateText = function() //set canvas text styles this.context.fillStyle = this.style.fill; this.context.font = this.style.font; - + this.context.strokeStyle = this.style.stroke; this.context.lineWidth = this.style.strokeThickness; @@ -121,7 +121,7 @@ PIXI.Text.prototype.updateText = function() for (i = 0; i < lines.length; i++) { var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); - + if(this.style.align == "right") { linePosition.x += maxLineWidth - lineWidths[i]; @@ -141,7 +141,7 @@ PIXI.Text.prototype.updateText = function() this.context.fillText(lines[i], linePosition.x, linePosition.y); } } - + this.updateTexture(); }; @@ -157,10 +157,10 @@ PIXI.Text.prototype.updateTexture = function() this.texture.baseTexture.height = this.canvas.height; this.texture.frame.width = this.canvas.width; this.texture.frame.height = this.canvas.height; - + this._width = this.canvas.width; this._height = this.canvas.height; - + PIXI.texturesToUpdate.push(this.texture.baseTexture); }; @@ -174,10 +174,10 @@ PIXI.Text.prototype.updateTransform = function() { if(this.dirty) { - this.updateText(); + this.updateText(); this.dirty = false; } - + PIXI.Sprite.prototype.updateTransform.call(this); }; @@ -189,12 +189,12 @@ PIXI.Text.prototype.updateTransform = function() * @param fontStyle {Object} * @private */ -PIXI.Text.prototype.determineFontHeight = function(fontStyle) +PIXI.Text.prototype.determineFontHeight = function(fontStyle) { // build a little reference dictionary so if the font style has been used return a // cached version... var result = PIXI.Text.heightCache[fontStyle]; - + if(!result) { var body = document.getElementsByTagName("body")[0]; @@ -203,18 +203,19 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle) dummy.appendChild(dummyText); dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0'); body.appendChild(dummy); - + result = dummy.offsetHeight; PIXI.Text.heightCache[fontStyle] = result; - + body.removeChild(dummy); } - + return result; }; /** - * A Text Object will apply wordwrap + * Applies newlines to a string to have it optimally fit into the horizontal + * bounds set by the Text object's wordWrapWidth property. * * @method wordWrap * @param text {String} @@ -222,48 +223,37 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle) */ PIXI.Text.prototype.wordWrap = function(text) { - // search good wrap position - var searchWrapPos = function(ctx, text, start, end, wrapWidth) - { - var p = Math.floor((end-start) / 2) + start; - if(p == start) { - return 1; - } - - if(ctx.measureText(text.substring(0,p)).width <= wrapWidth) - { - if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth) - { - return p; - } - else - { - return arguments.callee(ctx, text, p, end, wrapWidth); - } - } - else - { - return arguments.callee(ctx, text, start, p, wrapWidth); - } - }; - - var lineWrap = function(ctx, text, wrapWidth) - { - if(ctx.measureText(text).width <= wrapWidth || text.length < 1) - { - return text; - } - var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth); - return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth); - }; - + // Greedy wrapping algorithm that will wrap words as the line grows longer + // than its horizontal bounds. var result = ""; var lines = text.split("\n"); for (var i = 0; i < lines.length; i++) { - result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n"; + var spaceLeft = this.style.wordWrapWidth; + var words = lines[i].split(" "); + for (var j = 0; j < words.length; j++) + { + var wordWidth = this.context.measureText(words[j]).width; + var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width; + if(wordWidthWithSpace > spaceLeft) + { + // Skip printing the newline if it's the first word of the line that is + // greater than the word wrap width. + if(j > 0) + { + result += "\n"; + } + result += words[j] + " "; + spaceLeft = this.style.wordWrapWidth - wordWidth; + } + else + { + spaceLeft -= wordWidthWithSpace; + result += words[j] + " "; + } + } + result += "\n"; } - return result; }; @@ -279,7 +269,7 @@ PIXI.Text.prototype.destroy = function(destroyTexture) { this.texture.destroy(); } - + }; PIXI.Text.heightCache = {}; diff --git a/src/pixi/textures/BaseTexture.js b/src/pixi/textures/BaseTexture.js index 4b7e7acb..22ac5a03 100644 --- a/src/pixi/textures/BaseTexture.js +++ b/src/pixi/textures/BaseTexture.js @@ -62,19 +62,19 @@ PIXI.BaseTexture = function(source) this.hasLoaded = true; this.width = this.source.width; this.height = this.source.height; - + PIXI.texturesToUpdate.push(this); } else { - + var scope = this; this.source.onload = function(){ - + scope.hasLoaded = true; scope.width = scope.source.width; scope.height = scope.source.height; - + // add it to somewhere... PIXI.texturesToUpdate.push(scope); scope.dispatchEvent( { type: 'loaded', content: scope } ); @@ -87,7 +87,7 @@ PIXI.BaseTexture = function(source) this.hasLoaded = true; this.width = this.source.width; this.height = this.source.height; - + PIXI.texturesToUpdate.push(this); } @@ -127,7 +127,7 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin) { // new Image() breaks tex loading in some versions of Chrome. // See https://code.google.com/p/chromium/issues/detail?id=238071 - var image = new Image();//document.createElement('img'); + var image = new Image();//document.createElement('img'); if (crossorigin) { image.crossOrigin = ''; diff --git a/src/pixi/textures/RenderTexture.js b/src/pixi/textures/RenderTexture.js index 788fc8ef..ec35c189 100644 --- a/src/pixi/textures/RenderTexture.js +++ b/src/pixi/textures/RenderTexture.js @@ -27,8 +27,8 @@ @class RenderTexture @extends Texture @constructor - @param width {number} The width of the render texture - @param height {number} The height of the render texture + @param width {Number} The width of the render texture + @param height {Number} The height of the render texture */ PIXI.RenderTexture = function(width, height) { @@ -91,12 +91,10 @@ PIXI.RenderTexture.prototype.initWebGL = function() gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); // create a projection matrix.. - this.projection = new PIXI.Point(this.width/2 , this.height/2); + this.projection = new PIXI.Point(this.width/2 , -this.height/2); // set the correct render function.. this.render = this.renderWebGL; - - } @@ -109,7 +107,7 @@ PIXI.RenderTexture.prototype.resize = function(width, height) if(PIXI.gl) { this.projection.x = this.width/2 - this.projection.y = this.height/2; + this.projection.y = -this.height/2; var gl = PIXI.gl; gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); @@ -173,9 +171,8 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; // modify to flip... displayObject.worldTransform[4] = -1; - displayObject.worldTransform[5] = this.projection.y * 2; + displayObject.worldTransform[5] = this.projection.y * -2; - if(position) { displayObject.worldTransform[2] = position.x; @@ -196,20 +193,20 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle { if(displayObject == renderGroup.root) { - renderGroup.render(this.projection); + renderGroup.render(this.projection, this.glFramebuffer); } else { - renderGroup.renderSpecific(displayObject, this.projection); + renderGroup.renderSpecific(displayObject, this.projection, this.glFramebuffer); } } else { if(!this.renderGroup)this.renderGroup = new PIXI.WebGLRenderGroup(gl); this.renderGroup.setRenderable(displayObject); - this.renderGroup.render(this.projection); + this.renderGroup.render(this.projection, this.glFramebuffer); } - + displayObject.worldTransform = originalWorldTransform; } @@ -249,4 +246,3 @@ PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, cl // PIXI.texturesToUpdate.push(this.baseTexture); } - diff --git a/src/pixi/textures/Texture.js b/src/pixi/textures/Texture.js index 419c7b2f..11d82a0b 100644 --- a/src/pixi/textures/Texture.js +++ b/src/pixi/textures/Texture.js @@ -13,7 +13,7 @@ PIXI.FrameCache = {}; * @uses EventTarget * @constructor * @param baseTexture {BaseTexture} The base texture source to create the texture from - * @param frmae {Rectangle} The rectangle frame of the texture to show + * @param frame {Rectangle} The rectangle frame of the texture to show */ PIXI.Texture = function(baseTexture, frame) { @@ -58,7 +58,7 @@ PIXI.Texture = function(baseTexture, frame) { if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); //console.log(frame) - + this.setFrame(frame); } else @@ -137,13 +137,13 @@ PIXI.Texture.prototype.setFrame = function(frame) PIXI.Texture.fromImage = function(imageUrl, crossorigin) { var texture = PIXI.TextureCache[imageUrl]; - + if(!texture) { texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin)); PIXI.TextureCache[imageUrl] = texture; } - + return texture; } @@ -193,7 +193,7 @@ PIXI.Texture.addTextureToCache = function(texture, id) } /** - * Remove a texture from the textureCache. + * Remove a texture from the textureCache. * * @static * @method removeTextureFromCache diff --git a/src/pixi/utils/Detector.js b/src/pixi/utils/Detector.js index f3256256..e955e497 100644 --- a/src/pixi/utils/Detector.js +++ b/src/pixi/utils/Detector.js @@ -9,12 +9,12 @@ * * @method autoDetectRenderer * @static - * @param width {number} the width of the renderers view - * @param height {number} the height of the renderers view + * @param width {Number} the width of the renderers view + * @param height {Number} the height of the renderers view * @param view {Canvas} the canvas to use as a view, optional * @param transparent=false {Boolean} the transparency of the render view, default false * @param antialias=false {Boolean} sets antialias (only applicable in webGL chrome at the moment) - * + * * antialias */ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias) @@ -23,8 +23,14 @@ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias) if(!height)height = 600; // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(); + var webgl = ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )(); + if(webgl) + { + var ie = (navigator.userAgent.toLowerCase().indexOf('msie') != -1); + webgl = !ie; + } + //console.log(webgl); if( webgl ) { diff --git a/src/pixi/utils/EventTarget.js b/src/pixi/utils/EventTarget.js index 8dc54a5f..73da516d 100644 --- a/src/pixi/utils/EventTarget.js +++ b/src/pixi/utils/EventTarget.js @@ -18,14 +18,14 @@ PIXI.EventTarget = function () { var listeners = {}; - + this.addEventListener = this.on = function ( type, listener ) { - - + + if ( listeners[ type ] === undefined ) { listeners[ type ] = []; - + } if ( listeners[ type ].indexOf( listener ) === - 1 ) { @@ -36,11 +36,17 @@ PIXI.EventTarget = function () { }; this.dispatchEvent = this.emit = function ( event ) { - - for ( var listener in listeners[ event.type ] ) { - listeners[ event.type ][ listener ]( event ); - + if ( !listeners[ event.type ] || !listeners[ event.type ].length ) { + + return; + + } + + for(var i = 0, l = listeners[ event.type ].length; i < l; i++) { + + listeners[ event.type ][ i ]( event ); + } }; diff --git a/src/pixi/utils/Polyk.js b/src/pixi/utils/Polyk.js index 84d290f1..e29d77da 100644 --- a/src/pixi/utils/Polyk.js +++ b/src/pixi/utils/Polyk.js @@ -2,7 +2,7 @@ PolyK library url: http://polyk.ivank.net Released under MIT licence. - + Copyright (c) 2012 Ivan Kuckir Permission is hereby granted, free of charge, to any person @@ -26,8 +26,8 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - This is an amazing lib! - + This is an amazing lib! + slightly modified by mat groves (matgroves.com); */ @@ -43,13 +43,13 @@ PIXI.PolyK = {}; PIXI.PolyK.Triangulate = function(p) { var sign = true; - + var n = p.length>>1; if(n<3) return []; var tgs = []; var avl = []; for(var i=0; i 3) @@ -57,11 +57,11 @@ PIXI.PolyK.Triangulate = function(p) var i0 = avl[(i+0)%al]; var i1 = avl[(i+1)%al]; var i2 = avl[(i+2)%al]; - + var ax = p[2*i0], ay = p[2*i0+1]; var bx = p[2*i1], by = p[2*i1+1]; var cx = p[2*i2], cy = p[2*i2+1]; - + var earFound = false; if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign)) { @@ -80,7 +80,7 @@ PIXI.PolyK.Triangulate = function(p) al--; i = 0; } - else if(i++ > 3*al) + else if(i++ > 3*al) { // need to flip flip reverse it! // reset! @@ -89,17 +89,17 @@ PIXI.PolyK.Triangulate = function(p) var tgs = []; avl = []; for(var i=0; i> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; @@ -60,19 +60,19 @@ if (typeof Function.prototype.bind != 'function') { var slice = Array.prototype.slice; return function (thisArg) { var target = this, boundArgs = slice.call(arguments, 1); - + if (typeof target != 'function') throw new TypeError(); - + function bound() { var args = boundArgs.concat(slice.call(arguments)); target.apply(this instanceof bound ? this : thisArg, args); } - + bound.prototype = (function F(proto) { proto && (F.prototype = proto); - if (!(this instanceof F)) return new F; + if (!(this instanceof F)) return new F; })(target.prototype); - + return bound; }; })(); @@ -86,8 +86,8 @@ if (typeof Function.prototype.bind != 'function') { */ var AjaxRequest = PIXI.AjaxRequest = function() { - var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE - + var activexmodes = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Microsoft.XMLHTTP"] //activeX versions to check for in IE + if (window.ActiveXObject) { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) for (var i=0; i 100) { console.log("BREAK") break } - } + } }