mirror of
https://github.com/wassname/phaser.git
synced 2026-07-10 00:30:50 +08:00
Upgraded to Pixi.js 1.4.4
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||

|
||||
|
||||
Phaser 1.1.5-dev
|
||||
================
|
||||
Phaser 1.2-dev
|
||||
==============
|
||||
|
||||
Phaser is a fast, free and fun open source game framework for making desktop and mobile browser HTML5 games. It uses [Pixi.js](https://github.com/GoodBoyDigital/pixi.js/) internally for fast 2D Canvas and WebGL rendering.
|
||||
|
||||
Version: 1.1.5 "Saldaea" - Released: -in development-
|
||||
Version: 1.2 "Shienar" - Released: -in development-
|
||||
|
||||
By Richard Davey, [Photon Storm](http://www.photonstorm.com)
|
||||
|
||||
@@ -57,10 +57,11 @@ There is also an [un-official Getting Started Guide](http://www.antonoffplus.com
|
||||
Change Log
|
||||
----------
|
||||
|
||||
Version 1.1.5 - "Saldaea" - -in development-
|
||||
Version 1.2 - "Shienar" - -in development-
|
||||
|
||||
Significant API changes:
|
||||
|
||||
* Upgraded to Pixi.js 1.4.4
|
||||
|
||||
New features:
|
||||
|
||||
@@ -224,10 +225,6 @@ Road Map
|
||||
|
||||
Here is what's on our road map for the coming months:
|
||||
|
||||
Version 1.2 ("Shienar")
|
||||
|
||||
* Update to Pixi 1.4 - this newly released build has lots of internal changes and new features we want to take advantage of.
|
||||
|
||||
Version 1.3 ("Tarabon")
|
||||
|
||||
* Enhance the State Management, so you can perform non-destructive State swaps and persistence.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds all information related to an Interaction event
|
||||
*
|
||||
* @class InteractionData
|
||||
* @constructor
|
||||
*/
|
||||
PIXI.InteractionData = function()
|
||||
{
|
||||
/**
|
||||
* This point stores the global coords of where the touch/mouse event happened
|
||||
*
|
||||
* @property global
|
||||
* @type Point
|
||||
*/
|
||||
this.global = new PIXI.Point();
|
||||
|
||||
// this is here for legacy... but will remove
|
||||
this.local = new PIXI.Point();
|
||||
|
||||
/**
|
||||
* The target Sprite that was interacted with
|
||||
*
|
||||
* @property target
|
||||
* @type Sprite
|
||||
*/
|
||||
this.target = null;
|
||||
|
||||
/**
|
||||
* When passed to an event handler, this will be the original DOM Event that was captured
|
||||
*
|
||||
* @property originalEvent
|
||||
* @type Event
|
||||
*/
|
||||
this.originalEvent = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* This will return the local coordinates of the specified displayObject for this InteractionData
|
||||
*
|
||||
* @method getLocalPosition
|
||||
* @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
|
||||
* @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
|
||||
*/
|
||||
PIXI.InteractionData.prototype.getLocalPosition = function(displayObject)
|
||||
{
|
||||
var worldTransform = displayObject.worldTransform;
|
||||
var global = this.global;
|
||||
|
||||
// do a cheeky transform to get the mouse coords;
|
||||
var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
|
||||
a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
|
||||
id = 1 / (a00 * a11 + a01 * -a10);
|
||||
// set the mouse coords...
|
||||
return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
|
||||
a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
|
||||
+139
-137
@@ -4,6 +4,7 @@
|
||||
|
||||
/**
|
||||
* The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive
|
||||
* if its interactive parameter is set to true
|
||||
* This manager also supports multitouch.
|
||||
*
|
||||
* @class InteractionManager
|
||||
@@ -13,7 +14,7 @@
|
||||
PIXI.InteractionManager = function(stage)
|
||||
{
|
||||
/**
|
||||
* a refference to the stage
|
||||
* a reference to the stage
|
||||
*
|
||||
* @property stage
|
||||
* @type Stage
|
||||
@@ -38,7 +39,6 @@ PIXI.InteractionManager = function(stage)
|
||||
|
||||
// helpers
|
||||
this.tempPoint = new PIXI.Point();
|
||||
//this.tempMatrix = mat3.create();
|
||||
|
||||
this.mouseoverEnabled = true;
|
||||
|
||||
@@ -58,6 +58,10 @@ PIXI.InteractionManager = function(stage)
|
||||
this.onTouchEnd = this.onTouchEnd.bind(this);
|
||||
this.onTouchMove = this.onTouchMove.bind(this);
|
||||
this.last = 0;
|
||||
|
||||
this.currentCursorStyle = 'inherit';
|
||||
|
||||
this.mouseOut = false;
|
||||
};
|
||||
|
||||
// constructor
|
||||
@@ -124,36 +128,24 @@ PIXI.InteractionManager.prototype.setTarget = function(target)
|
||||
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
|
||||
* Sets the DOM element which will receive mouse/touch events. This is useful for when you have other DOM
|
||||
* elements on top 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
|
||||
* @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);
|
||||
}
|
||||
this.removeEvents();
|
||||
|
||||
|
||||
if (window.navigator.msPointerEnabled)
|
||||
@@ -175,6 +167,30 @@ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement)
|
||||
domElement.addEventListener('touchstart', this.onTouchStart, true);
|
||||
domElement.addEventListener('touchend', this.onTouchEnd, true);
|
||||
domElement.addEventListener('touchmove', this.onTouchMove, true);
|
||||
|
||||
document.body.addEventListener('mouseup', this.onMouseUp, true);
|
||||
};
|
||||
|
||||
|
||||
PIXI.InteractionManager.prototype.removeEvents = function()
|
||||
{
|
||||
if(!this.interactionDOMElement)return;
|
||||
|
||||
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);
|
||||
|
||||
this.interactionDOMElement = null;
|
||||
|
||||
document.body.removeEventListener('mouseup', this.onMouseUp, true);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -190,7 +206,7 @@ PIXI.InteractionManager.prototype.update = function()
|
||||
// frequency of 30fps??
|
||||
var now = Date.now();
|
||||
var diff = now - this.last;
|
||||
diff = (diff * 30) / 1000;
|
||||
diff = (diff * PIXI.INTERACTION_FREQUENCY ) / 1000;
|
||||
if(diff < 1)return;
|
||||
this.last = now;
|
||||
//
|
||||
@@ -199,7 +215,7 @@ PIXI.InteractionManager.prototype.update = function()
|
||||
|
||||
// ok.. so mouse events??
|
||||
// yes for now :)
|
||||
// OPTIMSE - how often to check??
|
||||
// OPTIMISE - how often to check??
|
||||
if(this.dirty)
|
||||
{
|
||||
this.dirty = false;
|
||||
@@ -220,7 +236,10 @@ PIXI.InteractionManager.prototype.update = function()
|
||||
// loop through interactive objects!
|
||||
var length = this.interactiveItems.length;
|
||||
|
||||
this.interactionDOMElement.style.cursor = 'inherit';
|
||||
|
||||
|
||||
var cursor = 'inherit';
|
||||
var over = false;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@@ -232,42 +251,55 @@ PIXI.InteractionManager.prototype.update = function()
|
||||
// OPTIMISATION - only calculate every time if the mousemove function exists..
|
||||
// OK so.. does the object have any other interactive functions?
|
||||
// hit-test the clip!
|
||||
|
||||
|
||||
if(item.mouseover || item.mouseout || item.buttonMode)
|
||||
// if(item.mouseover || item.mouseout || item.buttonMode)
|
||||
// {
|
||||
// ok so there are some functions so lets hit test it..
|
||||
item.__hit = this.hitTest(item, this.mouse);
|
||||
this.mouse.target = item;
|
||||
// ok so deal with interactions..
|
||||
// looks like there was a hit!
|
||||
if(item.__hit && !over)
|
||||
{
|
||||
// ok so there are some functions so lets hit test it..
|
||||
item.__hit = this.hitTest(item, this.mouse);
|
||||
this.mouse.target = item;
|
||||
// ok so deal with interactions..
|
||||
// loks like there was a hit!
|
||||
if(item.__hit)
|
||||
if(item.buttonMode) cursor = item.defaultCursor;
|
||||
|
||||
if(!item.interactiveChildren)over = true;
|
||||
|
||||
if(!item.__isOver)
|
||||
{
|
||||
if(item.buttonMode) this.interactionDOMElement.style.cursor = item.defaultCursor;
|
||||
|
||||
if(!item.__isOver)
|
||||
{
|
||||
if(item.mouseover)item.mouseover(this.mouse);
|
||||
item.__isOver = true;
|
||||
|
||||
// just the one!
|
||||
//break;
|
||||
|
||||
|
||||
if(item.mouseover)item.mouseover(this.mouse);
|
||||
item.__isOver = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
//break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(item.__isOver)
|
||||
{
|
||||
if(item.__isOver)
|
||||
{
|
||||
// roll out!
|
||||
if(item.mouseout)item.mouseout(this.mouse);
|
||||
item.__isOver = false;
|
||||
}
|
||||
// roll out!
|
||||
if(item.mouseout)item.mouseout(this.mouse);
|
||||
item.__isOver = false;
|
||||
}
|
||||
}
|
||||
// }
|
||||
// --->
|
||||
}
|
||||
|
||||
if( this.currentCursorStyle !== cursor )
|
||||
{
|
||||
this.currentCursorStyle = cursor;
|
||||
this.interactionDOMElement.style.cursor = cursor;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Is called when the mouse moves accross the renderer element
|
||||
* Is called when the mouse moves across the renderer element
|
||||
*
|
||||
* @method onMouseMove
|
||||
* @param event {Event} The DOM event of the mouse moving
|
||||
@@ -307,7 +339,9 @@ PIXI.InteractionManager.prototype.onMouseDown = function(event)
|
||||
{
|
||||
this.mouse.originalEvent = event || window.event; //IE uses window.event
|
||||
|
||||
// loop through inteaction tree...
|
||||
if(PIXI.AUTO_PREVENT_DEFAULT)this.mouse.originalEvent.preventDefault();
|
||||
|
||||
// loop through interaction tree...
|
||||
// hit test each item! ->
|
||||
// get interactive items under point??
|
||||
//stage.__i
|
||||
@@ -337,7 +371,13 @@ PIXI.InteractionManager.prototype.onMouseDown = function(event)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Is called when the mouse button is moved out of the renderer element
|
||||
*
|
||||
* @method onMouseDown
|
||||
* @param event {Event} The DOM event of a mouse button being moved out
|
||||
* @private
|
||||
*/
|
||||
PIXI.InteractionManager.prototype.onMouseOut = function()
|
||||
{
|
||||
var length = this.interactiveItems.length;
|
||||
@@ -347,7 +387,6 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var item = this.interactiveItems[i];
|
||||
|
||||
if(item.__isOver)
|
||||
{
|
||||
this.mouse.target = item;
|
||||
@@ -355,6 +394,12 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
|
||||
item.__isOver = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.mouseOut = true;
|
||||
|
||||
// move the mouse to an impossible position
|
||||
this.mouse.global.x = -10000;
|
||||
this.mouse.global.y = -10000;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -366,6 +411,7 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
|
||||
*/
|
||||
PIXI.InteractionManager.prototype.onMouseUp = function(event)
|
||||
{
|
||||
|
||||
this.mouse.originalEvent = event || window.event; //IE uses window.event
|
||||
|
||||
var length = this.interactiveItems.length;
|
||||
@@ -375,55 +421,57 @@ PIXI.InteractionManager.prototype.onMouseUp = function(event)
|
||||
{
|
||||
var item = this.interactiveItems[i];
|
||||
|
||||
if(item.mouseup || item.mouseupoutside || item.click)
|
||||
//if(item.mouseup || item.mouseupoutside || item.click)
|
||||
//{
|
||||
item.__hit = this.hitTest(item, this.mouse);
|
||||
|
||||
if(item.__hit && !up)
|
||||
{
|
||||
item.__hit = this.hitTest(item, this.mouse);
|
||||
|
||||
if(item.__hit && !up)
|
||||
//call the function!
|
||||
if(item.mouseup)
|
||||
{
|
||||
//call the function!
|
||||
if(item.mouseup)
|
||||
{
|
||||
item.mouseup(this.mouse);
|
||||
}
|
||||
if(item.__isDown)
|
||||
{
|
||||
if(item.click)item.click(this.mouse);
|
||||
}
|
||||
|
||||
if(!item.interactiveChildren)up = true;
|
||||
item.mouseup(this.mouse);
|
||||
}
|
||||
else
|
||||
if(item.__isDown)
|
||||
{
|
||||
if(item.__isDown)
|
||||
{
|
||||
if(item.mouseupoutside)item.mouseupoutside(this.mouse);
|
||||
}
|
||||
if(item.click)item.click(this.mouse);
|
||||
}
|
||||
|
||||
item.__isDown = false;
|
||||
if(!item.interactiveChildren)up = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(item.__isDown)
|
||||
{
|
||||
if(item.mouseupoutside)item.mouseupoutside(this.mouse);
|
||||
}
|
||||
}
|
||||
|
||||
item.__isDown = false;
|
||||
//}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests if the current mouse coords hit a sprite
|
||||
* Tests if the current mouse coordinates hit a sprite
|
||||
*
|
||||
* @method hitTest
|
||||
* @param item {DisplayObject} The displayObject to test for a hit
|
||||
* @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
|
||||
* @param interactionData {InteractionData} The interactionData object to update in the case there is a hit
|
||||
* @private
|
||||
*/
|
||||
PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
|
||||
{
|
||||
var global = interactionData.global;
|
||||
|
||||
if(item.vcount !== PIXI.visibleCount)return false;
|
||||
if( !item.worldVisible )return false;
|
||||
|
||||
// temp fix for if the element is in a non visible
|
||||
|
||||
var isSprite = (item instanceof PIXI.Sprite),
|
||||
worldTransform = item.worldTransform,
|
||||
a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
|
||||
a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
|
||||
a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
|
||||
a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
|
||||
id = 1 / (a00 * a11 + a01 * -a10),
|
||||
x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
|
||||
y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
|
||||
@@ -480,10 +528,10 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
|
||||
};
|
||||
|
||||
/**
|
||||
* Is called when a touch is moved accross the renderer element
|
||||
* Is called when a touch is moved across the renderer element
|
||||
*
|
||||
* @method onTouchMove
|
||||
* @param event {Event} The DOM event of a touch moving accross the renderer view
|
||||
* @param event {Event} The DOM event of a touch moving across the renderer view
|
||||
* @private
|
||||
*/
|
||||
PIXI.InteractionManager.prototype.onTouchMove = function(event)
|
||||
@@ -502,6 +550,10 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event)
|
||||
// update the touch position
|
||||
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
|
||||
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
|
||||
if(navigator.isCocoonJS) {
|
||||
touchData.global.x = touchEvent.clientX;
|
||||
touchData.global.y = touchEvent.clientY;
|
||||
}
|
||||
}
|
||||
|
||||
var length = this.interactiveItems.length;
|
||||
@@ -524,6 +576,8 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event)
|
||||
{
|
||||
var rect = this.interactionDOMElement.getBoundingClientRect();
|
||||
|
||||
if(PIXI.AUTO_PREVENT_DEFAULT)event.preventDefault();
|
||||
|
||||
var changedTouches = event.changedTouches;
|
||||
for (var i=0; i < changedTouches.length; i++)
|
||||
{
|
||||
@@ -537,6 +591,10 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event)
|
||||
this.touchs[touchEvent.identifier] = touchData;
|
||||
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
|
||||
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
|
||||
if(navigator.isCocoonJS) {
|
||||
touchData.global.x = touchEvent.clientX;
|
||||
touchData.global.y = touchEvent.clientY;
|
||||
}
|
||||
|
||||
var length = this.interactiveItems.length;
|
||||
|
||||
@@ -582,6 +640,10 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event)
|
||||
var up = false;
|
||||
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
|
||||
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
|
||||
if(navigator.isCocoonJS) {
|
||||
touchData.global.x = touchEvent.clientX;
|
||||
touchData.global.y = touchEvent.clientY;
|
||||
}
|
||||
|
||||
var length = this.interactiveItems.length;
|
||||
for (var j = 0; j < length; j++)
|
||||
@@ -633,64 +695,4 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event)
|
||||
this.pool.push(touchData);
|
||||
this.touchs[touchEvent.identifier] = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds all information related to an Interaction event
|
||||
*
|
||||
* @class InteractionData
|
||||
* @constructor
|
||||
*/
|
||||
PIXI.InteractionData = function()
|
||||
{
|
||||
/**
|
||||
* This point stores the global coords of where the touch/mouse event happened
|
||||
*
|
||||
* @property global
|
||||
* @type Point
|
||||
*/
|
||||
this.global = new PIXI.Point();
|
||||
|
||||
// this is here for legacy... but will remove
|
||||
this.local = new PIXI.Point();
|
||||
|
||||
/**
|
||||
* The target Sprite that was interacted with
|
||||
*
|
||||
* @property target
|
||||
* @type Sprite
|
||||
*/
|
||||
this.target = null;
|
||||
|
||||
/**
|
||||
* When passed to an event handler, this will be the original DOM Event that was captured
|
||||
*
|
||||
* @property originalEvent
|
||||
* @type Event
|
||||
*/
|
||||
this.originalEvent = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* This will return the local coords of the specified displayObject for this InteractionData
|
||||
*
|
||||
* @method getLocalPosition
|
||||
* @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
|
||||
* @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
|
||||
*/
|
||||
PIXI.InteractionData.prototype.getLocalPosition = function(displayObject)
|
||||
{
|
||||
var worldTransform = displayObject.worldTransform;
|
||||
var global = this.global;
|
||||
|
||||
// do a cheeky transform to get the mouse coords;
|
||||
var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
|
||||
a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
|
||||
id = 1 / (a00 * a11 + a01 * -a10);
|
||||
// set the mouse coords...
|
||||
return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
|
||||
a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
|
||||
};
|
||||
@@ -6,3 +6,41 @@
|
||||
* @module PIXI
|
||||
*/
|
||||
var PIXI = PIXI || {};
|
||||
|
||||
PIXI.WEBGL_RENDERER = 0;
|
||||
PIXI.CANVAS_RENDERER = 1;
|
||||
|
||||
// useful for testing against if your lib is using pixi.
|
||||
PIXI.VERSION = "v1.4.4";
|
||||
|
||||
// the various blend modes supported by pixi
|
||||
PIXI.blendModes = {
|
||||
NORMAL:0,
|
||||
ADD:1,
|
||||
MULTIPLY:2,
|
||||
SCREEN:3,
|
||||
OVERLAY:4,
|
||||
DARKEN:5,
|
||||
LIGHTEN:6,
|
||||
COLOR_DODGE:7,
|
||||
COLOR_BURN:8,
|
||||
HARD_LIGHT:9,
|
||||
SOFT_LIGHT:10,
|
||||
DIFFERENCE:11,
|
||||
EXCLUSION:12,
|
||||
HUE:13,
|
||||
SATURATION:14,
|
||||
COLOR:15,
|
||||
LUMINOSITY:16
|
||||
};
|
||||
|
||||
// the scale modes
|
||||
PIXI.scaleModes = {
|
||||
DEFAULT:0,
|
||||
LINEAR:0,
|
||||
NEAREST:1
|
||||
};
|
||||
|
||||
// interaction frequency
|
||||
PIXI.INTERACTION_FREQUENCY = 30;
|
||||
PIXI.AUTO_PREVENT_DEFAULT = true;
|
||||
@@ -3,12 +3,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Circle object can be used to specify a hit area for displayobjects
|
||||
* The Circle object can be used to specify a hit area for displayObjects
|
||||
*
|
||||
* @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 x {Number} The X coordinate of the upper-left corner of the framing rectangle of this circle
|
||||
* @param y {Number} The Y coordinate 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)
|
||||
@@ -47,12 +47,12 @@ PIXI.Circle.prototype.clone = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the x, and y coords passed to this function are contained within this circle
|
||||
* Checks whether the x, and y coordinates 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
|
||||
* @return {Boolean} if the x/y coords are within this polygon
|
||||
* @param x {Number} The X coordinate of the point to test
|
||||
* @param y {Number} The Y coordinate of the point to test
|
||||
* @return {Boolean} Whether the x/y coordinates are within this polygon
|
||||
*/
|
||||
PIXI.Circle.prototype.contains = function(x, y)
|
||||
{
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Ellipse object can be used to specify a hit area for displayobjects
|
||||
* The Ellipse object can be used to specify a hit area for displayObjects
|
||||
*
|
||||
* @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 x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse
|
||||
* @param y {Number} The Y coordinate 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
|
||||
*/
|
||||
@@ -55,12 +55,12 @@ PIXI.Ellipse.prototype.clone = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the x, and y coords passed to this function are contained within this ellipse
|
||||
* Checks whether the x and y coordinates 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
|
||||
* @return {Boolean} if the x/y coords are within this ellipse
|
||||
* @param x {Number} The X coordinate of the point to test
|
||||
* @param y {Number} The Y coordinate of the point to test
|
||||
* @return {Boolean} Whether the x/y coords are within this ellipse
|
||||
*/
|
||||
PIXI.Ellipse.prototype.contains = function(x, y)
|
||||
{
|
||||
@@ -78,6 +78,12 @@ PIXI.Ellipse.prototype.contains = function(x, y)
|
||||
return (normx + normy < 0.25);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the framing rectangle of the ellipse as a PIXI.Rectangle object
|
||||
*
|
||||
* @method getBounds
|
||||
* @return {Rectangle} the framing rectangle
|
||||
*/
|
||||
PIXI.Ellipse.prototype.getBounds = function()
|
||||
{
|
||||
return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
|
||||
|
||||
+52
-275
@@ -1,293 +1,70 @@
|
||||
|
||||
|
||||
/*
|
||||
* A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
|
||||
* you both rock!
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
function determineMatrixArrayType() {
|
||||
PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
|
||||
return PIXI.Matrix;
|
||||
}
|
||||
|
||||
determineMatrixArrayType();
|
||||
|
||||
PIXI.mat3 = {};
|
||||
|
||||
PIXI.mat3.create = function()
|
||||
{
|
||||
var matrix = new PIXI.Matrix(9);
|
||||
|
||||
matrix[0] = 1;
|
||||
matrix[1] = 0;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 0;
|
||||
matrix[4] = 1;
|
||||
matrix[5] = 0;
|
||||
matrix[6] = 0;
|
||||
matrix[7] = 0;
|
||||
matrix[8] = 1;
|
||||
|
||||
return matrix;
|
||||
/*
|
||||
* @class Matrix
|
||||
* The Matrix class will choose the best type of array to use between
|
||||
* a regular javascript Array and a Float32Array if the latter is available
|
||||
*
|
||||
*/
|
||||
PIXI.determineMatrixArrayType = function() {
|
||||
return (typeof Float32Array !== 'undefined') ? Float32Array : Array;
|
||||
};
|
||||
|
||||
PIXI.Matrix2 = PIXI.determineMatrixArrayType();
|
||||
|
||||
PIXI.mat3.identity = function(matrix)
|
||||
PIXI.Matrix = function()
|
||||
{
|
||||
matrix[0] = 1;
|
||||
matrix[1] = 0;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 0;
|
||||
matrix[4] = 1;
|
||||
matrix[5] = 0;
|
||||
matrix[6] = 0;
|
||||
matrix[7] = 0;
|
||||
matrix[8] = 1;
|
||||
|
||||
return matrix;
|
||||
this.a = 1;
|
||||
this.b = 0;
|
||||
this.c = 0;
|
||||
this.d = 1;
|
||||
this.tx = 0;
|
||||
this.ty = 0;
|
||||
};
|
||||
|
||||
|
||||
PIXI.mat4 = {};
|
||||
|
||||
PIXI.mat4.create = function()
|
||||
PIXI.Matrix.prototype.fromArray = function(array)
|
||||
{
|
||||
var matrix = new PIXI.Matrix(16);
|
||||
|
||||
matrix[0] = 1;
|
||||
matrix[1] = 0;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 0;
|
||||
matrix[4] = 0;
|
||||
matrix[5] = 1;
|
||||
matrix[6] = 0;
|
||||
matrix[7] = 0;
|
||||
matrix[8] = 0;
|
||||
matrix[9] = 0;
|
||||
matrix[10] = 1;
|
||||
matrix[11] = 0;
|
||||
matrix[12] = 0;
|
||||
matrix[13] = 0;
|
||||
matrix[14] = 0;
|
||||
matrix[15] = 1;
|
||||
|
||||
return matrix;
|
||||
this.a = array[0];
|
||||
this.b = array[1];
|
||||
this.c = array[3];
|
||||
this.d = array[4];
|
||||
this.tx = array[2];
|
||||
this.ty = array[5];
|
||||
};
|
||||
|
||||
PIXI.mat3.multiply = function (mat, mat2, dest)
|
||||
PIXI.Matrix.prototype.toArray = function(transpose)
|
||||
{
|
||||
if (!dest) { dest = mat; }
|
||||
if(!this.array) this.array = new Float32Array(9);
|
||||
var array = this.array;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
PIXI.mat3.clone = function(mat)
|
||||
{
|
||||
var matrix = new PIXI.Matrix(9);
|
||||
|
||||
matrix[0] = mat[0];
|
||||
matrix[1] = mat[1];
|
||||
matrix[2] = mat[2];
|
||||
matrix[3] = mat[3];
|
||||
matrix[4] = mat[4];
|
||||
matrix[5] = mat[5];
|
||||
matrix[6] = mat[6];
|
||||
matrix[7] = mat[7];
|
||||
matrix[8] = mat[8];
|
||||
|
||||
return matrix;
|
||||
};
|
||||
|
||||
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) {
|
||||
var a01 = mat[1], a02 = mat[2],
|
||||
a12 = mat[5];
|
||||
|
||||
mat[1] = mat[3];
|
||||
mat[2] = mat[6];
|
||||
mat[3] = a01;
|
||||
mat[5] = mat[7];
|
||||
mat[6] = a02;
|
||||
mat[7] = a12;
|
||||
return mat;
|
||||
}
|
||||
|
||||
dest[0] = mat[0];
|
||||
dest[1] = mat[3];
|
||||
dest[2] = mat[6];
|
||||
dest[3] = mat[1];
|
||||
dest[4] = mat[4];
|
||||
dest[5] = mat[7];
|
||||
dest[6] = mat[2];
|
||||
dest[7] = mat[5];
|
||||
dest[8] = mat[8];
|
||||
return 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;
|
||||
};
|
||||
|
||||
|
||||
/////
|
||||
|
||||
|
||||
PIXI.mat4.create = function()
|
||||
{
|
||||
var matrix = new PIXI.Matrix(16);
|
||||
|
||||
matrix[0] = 1;
|
||||
matrix[1] = 0;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 0;
|
||||
matrix[4] = 0;
|
||||
matrix[5] = 1;
|
||||
matrix[6] = 0;
|
||||
matrix[7] = 0;
|
||||
matrix[8] = 0;
|
||||
matrix[9] = 0;
|
||||
matrix[10] = 1;
|
||||
matrix[11] = 0;
|
||||
matrix[12] = 0;
|
||||
matrix[13] = 0;
|
||||
matrix[14] = 0;
|
||||
matrix[15] = 1;
|
||||
|
||||
return matrix;
|
||||
};
|
||||
|
||||
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(transpose)
|
||||
{
|
||||
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];
|
||||
mat[4] = a01;
|
||||
mat[6] = mat[9];
|
||||
mat[7] = mat[13];
|
||||
mat[8] = a02;
|
||||
mat[9] = a12;
|
||||
mat[11] = mat[14];
|
||||
mat[12] = a03;
|
||||
mat[13] = a13;
|
||||
mat[14] = a23;
|
||||
return mat;
|
||||
this.array[0] = this.a;
|
||||
this.array[1] = this.c;
|
||||
this.array[2] = 0;
|
||||
this.array[3] = this.b;
|
||||
this.array[4] = this.d;
|
||||
this.array[5] = 0;
|
||||
this.array[6] = this.tx;
|
||||
this.array[7] = this.ty;
|
||||
this.array[8] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.array[0] = this.a;
|
||||
this.array[1] = this.b;
|
||||
this.array[2] = this.tx;
|
||||
this.array[3] = this.c;
|
||||
this.array[4] = this.d;
|
||||
this.array[5] = this.ty;
|
||||
this.array[6] = 0;
|
||||
this.array[7] = 0;
|
||||
this.array[8] = 1;
|
||||
}
|
||||
|
||||
dest[0] = mat[0];
|
||||
dest[1] = mat[4];
|
||||
dest[2] = mat[8];
|
||||
dest[3] = mat[12];
|
||||
dest[4] = mat[1];
|
||||
dest[5] = mat[5];
|
||||
dest[6] = mat[9];
|
||||
dest[7] = mat[13];
|
||||
dest[8] = mat[2];
|
||||
dest[9] = mat[6];
|
||||
dest[10] = mat[10];
|
||||
dest[11] = mat[14];
|
||||
dest[12] = mat[3];
|
||||
dest[13] = mat[7];
|
||||
dest[14] = mat[11];
|
||||
dest[15] = mat[15];
|
||||
return dest;
|
||||
return array;//[this.a, this.b, this.tx, this.c, this.d, this.ty, 0, 0, 1];
|
||||
};
|
||||
|
||||
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];
|
||||
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;
|
||||
dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = mat2[4];
|
||||
b1 = mat2[5];
|
||||
b2 = mat2[6];
|
||||
b3 = mat2[7];
|
||||
dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = mat2[8];
|
||||
b1 = mat2[9];
|
||||
b2 = mat2[10];
|
||||
b3 = mat2[11];
|
||||
dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
b0 = mat2[12];
|
||||
b1 = mat2[13];
|
||||
b2 = mat2[14];
|
||||
b3 = mat2[15];
|
||||
dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
|
||||
dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
|
||||
dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
|
||||
dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
|
||||
|
||||
return dest;
|
||||
};
|
||||
PIXI.identityMatrix = new PIXI.Matrix();
|
||||
@@ -7,8 +7,8 @@
|
||||
*
|
||||
* @class Point
|
||||
* @constructor
|
||||
* @param x {Number} position of the point
|
||||
* @param y {Number} position of the point
|
||||
* @param x {Number} position of the point on the x axis
|
||||
* @param y {Number} position of the point on the y axis
|
||||
*/
|
||||
PIXI.Point = function(x, y)
|
||||
{
|
||||
@@ -41,3 +41,9 @@ PIXI.Point.prototype.clone = function()
|
||||
// constructor
|
||||
PIXI.Point.prototype.constructor = PIXI.Point;
|
||||
|
||||
PIXI.Point.prototype.set = function(x, y)
|
||||
{
|
||||
this.x = x || 0;
|
||||
this.y = y || ( (y !== 0) ? this.x : 0 ) ;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,12 +49,12 @@ PIXI.Polygon.prototype.clone = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the x, and y coords passed to this function are contained within this polygon
|
||||
* Checks whether the x and y coordinates 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
|
||||
* @return {Boolean} if the x/y coords are within this polygon
|
||||
* @param x {Number} The X coordinate of the point to test
|
||||
* @param y {Number} The Y coordinate of the point to test
|
||||
* @return {Boolean} Whether the x/y coordinates are within this polygon
|
||||
*/
|
||||
PIXI.Polygon.prototype.contains = function(x, y)
|
||||
{
|
||||
|
||||
@@ -55,12 +55,12 @@ PIXI.Rectangle.prototype.clone = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the x, and y coords passed to this function are contained within this Rectangle
|
||||
* Checks whether the x and y coordinates 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
|
||||
* @return {Boolean} if the x/y coords are within this Rectangle
|
||||
* @param x {Number} The X coordinate of the point to test
|
||||
* @param y {Number} The Y coordinate of the point to test
|
||||
* @return {Boolean} Whether the x/y coords are within this Rectangle
|
||||
*/
|
||||
PIXI.Rectangle.prototype.contains = function(x, y)
|
||||
{
|
||||
@@ -84,3 +84,4 @@ PIXI.Rectangle.prototype.contains = function(x, y)
|
||||
// constructor
|
||||
PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
|
||||
|
||||
PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0);
|
||||
+190
-230
@@ -104,7 +104,7 @@ PIXI.DisplayObject = function()
|
||||
this.stage = null;
|
||||
|
||||
/**
|
||||
* [read-only] The multiplied alpha of the displayobject
|
||||
* [read-only] The multiplied alpha of the displayObject
|
||||
*
|
||||
* @property worldAlpha
|
||||
* @type Number
|
||||
@@ -122,6 +122,13 @@ PIXI.DisplayObject = function()
|
||||
*/
|
||||
this._interactive = false;
|
||||
|
||||
/**
|
||||
* This is the cursor that will be used when the mouse is over this object. To enable this the element must have interaction = true and buttonMode = true
|
||||
*
|
||||
* @property defaultCursor
|
||||
* @type String
|
||||
*
|
||||
*/
|
||||
this.defaultCursor = 'pointer';
|
||||
|
||||
/**
|
||||
@@ -132,20 +139,10 @@ PIXI.DisplayObject = function()
|
||||
* @readOnly
|
||||
* @private
|
||||
*/
|
||||
this.worldTransform = PIXI.mat3.create(); //mat3.identity();
|
||||
this.worldTransform = new PIXI.Matrix();
|
||||
|
||||
/**
|
||||
* [read-only] Current transform of the object locally
|
||||
*
|
||||
* @property localTransform
|
||||
* @type Mat3
|
||||
* @readOnly
|
||||
* @private
|
||||
*/
|
||||
this.localTransform = PIXI.mat3.create(); //mat3.identity();
|
||||
|
||||
/**
|
||||
* [NYI] Unkown
|
||||
* [NYI] Unknown
|
||||
*
|
||||
* @property color
|
||||
* @type Array<>
|
||||
@@ -162,13 +159,43 @@ PIXI.DisplayObject = function()
|
||||
*/
|
||||
this.dynamic = true;
|
||||
|
||||
// chach that puppy!
|
||||
// cached sin rotation and cos rotation
|
||||
this._sr = 0;
|
||||
this._cr = 1;
|
||||
|
||||
|
||||
/**
|
||||
* The area the filter is applied to
|
||||
*
|
||||
* @property filterArea
|
||||
* @type Rectangle
|
||||
*/
|
||||
this.filterArea = new PIXI.Rectangle(0,0,1,1);
|
||||
|
||||
/**
|
||||
* The original, cached bounds of the object
|
||||
*
|
||||
* @property _bounds
|
||||
* @type Rectangle
|
||||
* @private
|
||||
*/
|
||||
this._bounds = new PIXI.Rectangle(0, 0, 1, 1);
|
||||
/**
|
||||
* The most up-to-date bounds of the object
|
||||
*
|
||||
* @property _currentBounds
|
||||
* @type Rectangle
|
||||
* @private
|
||||
*/
|
||||
this._currentBounds = null;
|
||||
/**
|
||||
* The original, cached mask of the object
|
||||
*
|
||||
* @property _currentBounds
|
||||
* @type Rectangle
|
||||
* @private
|
||||
*/
|
||||
this._mask = null;
|
||||
|
||||
/*
|
||||
* MOUSE Callbacks
|
||||
*/
|
||||
@@ -224,7 +251,7 @@ PIXI.DisplayObject = function()
|
||||
*/
|
||||
|
||||
/**
|
||||
* A callback that is used when the user touch's over the displayObject
|
||||
* A callback that is used when the user touches over the displayObject
|
||||
* @method touchstart
|
||||
* @param interactionData {InteractionData}
|
||||
*/
|
||||
@@ -279,9 +306,30 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [read-only] Indicates if the sprite is globaly visible.
|
||||
*
|
||||
* @property worldVisible
|
||||
* @type Boolean
|
||||
*/
|
||||
Object.defineProperty(PIXI.DisplayObject.prototype, 'worldVisible', {
|
||||
get: function() {
|
||||
var item = this;
|
||||
|
||||
do
|
||||
{
|
||||
if(!item.visible)return false;
|
||||
item = item.parent;
|
||||
}
|
||||
while(item);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
|
||||
* In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
|
||||
* In PIXI a regular mask must be a PIXI.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping.
|
||||
* To remove a mask, set this property to null.
|
||||
*
|
||||
* @property mask
|
||||
@@ -293,27 +341,9 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
|
||||
},
|
||||
set: function(value) {
|
||||
|
||||
|
||||
if(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._mask);
|
||||
this._mask.renderable = true;
|
||||
}
|
||||
|
||||
if(this._mask)this._mask.isMask = false;
|
||||
this._mask = value;
|
||||
if(this._mask)this._mask.isMask = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -332,9 +362,6 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
|
||||
|
||||
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++)
|
||||
@@ -346,172 +373,14 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
|
||||
}
|
||||
}
|
||||
|
||||
value.start.filterPasses = passes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this._filters) {
|
||||
this.removeFilter(this._filters);
|
||||
}
|
||||
// TODO change this as it is legacy
|
||||
this._filterBlock = {target:this, filterPasses:passes};
|
||||
}
|
||||
|
||||
this._filters = value;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Adds a filter to this displayObject
|
||||
*
|
||||
* @method addFilter
|
||||
* @param mask {Graphics} the graphics object to use as a filter
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObject.prototype.addFilter = function(data)
|
||||
{
|
||||
//if(this.filter)return;
|
||||
//this.filter = true;
|
||||
// data[0].target = this;
|
||||
|
||||
|
||||
// insert a filter block..
|
||||
// TODO Onject pool thease bad boys..
|
||||
var start = new PIXI.FilterBlock();
|
||||
var end = new PIXI.FilterBlock();
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
var childFirst = start;
|
||||
var childLast = start;
|
||||
var nextObject;
|
||||
var previousObject;
|
||||
|
||||
previousObject = this.first._iPrev;
|
||||
|
||||
if(previousObject)
|
||||
{
|
||||
nextObject = previousObject._iNext;
|
||||
childFirst._iPrev = previousObject;
|
||||
previousObject._iNext = childFirst;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextObject = this;
|
||||
}
|
||||
|
||||
if(nextObject)
|
||||
{
|
||||
nextObject._iPrev = childLast;
|
||||
childLast._iNext = nextObject;
|
||||
}
|
||||
|
||||
// now insert the end filter block..
|
||||
|
||||
/*
|
||||
* insert end filter
|
||||
*/
|
||||
childFirst = end;
|
||||
childLast = end;
|
||||
nextObject = null;
|
||||
previousObject = null;
|
||||
|
||||
previousObject = this.last;
|
||||
nextObject = previousObject._iNext;
|
||||
|
||||
if(nextObject)
|
||||
{
|
||||
nextObject._iPrev = childLast;
|
||||
childLast._iNext = nextObject;
|
||||
}
|
||||
|
||||
childFirst._iPrev = previousObject;
|
||||
previousObject._iNext = childFirst;
|
||||
|
||||
var updateLast = this;
|
||||
|
||||
var prevLast = this.last;
|
||||
while(updateLast)
|
||||
{
|
||||
if(updateLast.last === prevLast)
|
||||
{
|
||||
updateLast.last = end;
|
||||
}
|
||||
updateLast = updateLast.parent;
|
||||
}
|
||||
|
||||
this.first = start;
|
||||
|
||||
// if webGL...
|
||||
if(this.__renderGroup)
|
||||
{
|
||||
this.__renderGroup.addFilterBlocks(start, end);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Removes the filter to this displayObject
|
||||
*
|
||||
* @method removeFilter
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObject.prototype.removeFilter = function(data)
|
||||
{
|
||||
//if(!this.filter)return;
|
||||
//this.filter = false;
|
||||
// console.log('YUOIO')
|
||||
// modify the list..
|
||||
var startBlock = data.start;
|
||||
|
||||
|
||||
var nextObject = startBlock._iNext;
|
||||
var previousObject = startBlock._iPrev;
|
||||
|
||||
if(nextObject)nextObject._iPrev = previousObject;
|
||||
if(previousObject)previousObject._iNext = nextObject;
|
||||
|
||||
this.first = startBlock._iNext;
|
||||
|
||||
// remove the end filter
|
||||
var lastBlock = data.end;
|
||||
|
||||
nextObject = lastBlock._iNext;
|
||||
previousObject = lastBlock._iPrev;
|
||||
|
||||
if(nextObject)nextObject._iPrev = previousObject;
|
||||
previousObject._iNext = nextObject;
|
||||
|
||||
// this is always true too!
|
||||
var tempLast = lastBlock._iPrev;
|
||||
// need to make sure the parents last is updated too
|
||||
var updateLast = this;
|
||||
while(updateLast.last === lastBlock)
|
||||
{
|
||||
updateLast.last = tempLast;
|
||||
updateLast = updateLast.parent;
|
||||
if(!updateLast)break;
|
||||
}
|
||||
|
||||
// if webGL...
|
||||
if(this.__renderGroup)
|
||||
{
|
||||
this.__renderGroup.removeFilterBlocks(startBlock, lastBlock);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates the object transform for rendering
|
||||
*
|
||||
@@ -523,48 +392,139 @@ PIXI.DisplayObject.prototype.updateTransform = function()
|
||||
// TODO OPTIMIZE THIS!! with dirty
|
||||
if(this.rotation !== this.rotationCache)
|
||||
{
|
||||
if(isNaN(parseFloat(this.rotation)))
|
||||
throw new Error('DisplayObject rotation values must be numeric.');
|
||||
|
||||
this.rotationCache = this.rotation;
|
||||
this._sr = Math.sin(this.rotation);
|
||||
this._cr = Math.cos(this.rotation);
|
||||
}
|
||||
|
||||
var localTransform = this.localTransform;
|
||||
var parentTransform = this.parent.worldTransform;
|
||||
var worldTransform = this.worldTransform;
|
||||
// var localTransform = this.localTransform//.toArray();
|
||||
var parentTransform = this.parent.worldTransform;//.toArray();
|
||||
var worldTransform = this.worldTransform;//.toArray();
|
||||
//console.log(localTransform)
|
||||
localTransform[0] = this._cr * this.scale.x;
|
||||
localTransform[1] = -this._sr * this.scale.y;
|
||||
localTransform[3] = this._sr * this.scale.x;
|
||||
localTransform[4] = this._cr * this.scale.y;
|
||||
|
||||
// TODO --> do we even need a local matrix???
|
||||
|
||||
var px = this.pivot.x;
|
||||
var py = this.pivot.y;
|
||||
|
||||
// Cache the matrix values (makes for huge speed increases!)
|
||||
var a00 = localTransform[0], a01 = localTransform[1], a02 = this.position.x - localTransform[0] * px - py * localTransform[1],
|
||||
a10 = localTransform[3], a11 = localTransform[4], a12 = this.position.y - localTransform[4] * py - px * localTransform[3],
|
||||
var a00 = this._cr * this.scale.x,
|
||||
a01 = -this._sr * this.scale.y,
|
||||
a10 = this._sr * this.scale.x,
|
||||
a11 = this._cr * this.scale.y,
|
||||
a02 = this.position.x + a00 * px - py * a01,
|
||||
a12 = this.position.y + a11 * py - px * a10,
|
||||
b00 = parentTransform.a, b01 = parentTransform.b, b02 = parentTransform.tx,
|
||||
b10 = parentTransform.c, b11 = parentTransform.d, b12 = parentTransform.ty;
|
||||
|
||||
b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
|
||||
b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
|
||||
worldTransform.a = b00 * a00 + b01 * a10;
|
||||
worldTransform.b = b00 * a01 + b01 * a11;
|
||||
worldTransform.tx = b00 * a02 + b01 * a12 + b02;
|
||||
|
||||
localTransform[2] = a02;
|
||||
localTransform[5] = a12;
|
||||
worldTransform.c = b10 * a00 + b11 * a10;
|
||||
worldTransform.d = b10 * a01 + b11 * a11;
|
||||
worldTransform.ty = b10 * a02 + b11 * a12 + b12;
|
||||
|
||||
worldTransform[0] = b00 * a00 + b01 * a10;
|
||||
worldTransform[1] = b00 * a01 + b01 * a11;
|
||||
worldTransform[2] = b00 * a02 + b01 * a12 + b02;
|
||||
|
||||
worldTransform[3] = b10 * a00 + b11 * a10;
|
||||
worldTransform[4] = b10 * a01 + b11 * a11;
|
||||
worldTransform[5] = b10 * a02 + b11 * a12 + b12;
|
||||
|
||||
// because we are using affine transformation, we can optimise the matrix concatenation process.. wooo!
|
||||
// mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform);
|
||||
this.worldAlpha = this.alpha * this.parent.worldAlpha;
|
||||
|
||||
this.vcount = PIXI.visibleCount;
|
||||
};
|
||||
|
||||
PIXI.visibleCount = 0;
|
||||
/**
|
||||
* Retrieves the bounds of the displayObject as a rectangle object
|
||||
*
|
||||
* @method getBounds
|
||||
* @return {Rectangle} the rectangular bounding area
|
||||
*/
|
||||
PIXI.DisplayObject.prototype.getBounds = function()
|
||||
{
|
||||
return PIXI.EmptyRectangle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the local bounds of the displayObject as a rectangle object
|
||||
*
|
||||
* @method getLocalBounds
|
||||
* @return {Rectangle} the rectangular bounding area
|
||||
*/
|
||||
PIXI.DisplayObject.prototype.getLocalBounds = function()
|
||||
{
|
||||
var matrixCache = this.worldTransform;
|
||||
|
||||
this.worldTransform = PIXI.identityMatrix;
|
||||
|
||||
this.updateTransform();
|
||||
|
||||
var bounds = this.getBounds();
|
||||
|
||||
this.worldTransform = matrixCache;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the object's stage reference, the stage this object is connected to
|
||||
*
|
||||
* @method setStageReference
|
||||
* @param stage {Stage} the stage that the object will have as its current stage reference
|
||||
*/
|
||||
PIXI.DisplayObject.prototype.setStageReference = function(stage)
|
||||
{
|
||||
this.stage = stage;
|
||||
if(this._interactive)this.stage.dirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObject.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
// OVERWRITE;
|
||||
// this line is just here to pass jshinting :)
|
||||
renderSession = renderSession;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObject.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
// OVERWRITE;
|
||||
// this line is just here to pass jshinting :)
|
||||
renderSession = renderSession;
|
||||
};
|
||||
|
||||
/**
|
||||
* The position of the displayObject on the x axis relative to the local coordinates of the parent.
|
||||
*
|
||||
* @property x
|
||||
* @type Number
|
||||
*/
|
||||
Object.defineProperty(PIXI.DisplayObject.prototype, 'x', {
|
||||
get: function() {
|
||||
return this.position.x;
|
||||
},
|
||||
set: function(value) {
|
||||
this.position.x = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The position of the displayObject on the y axis relative to the local coordinates of the parent.
|
||||
*
|
||||
* @property y
|
||||
* @type Number
|
||||
*/
|
||||
Object.defineProperty(PIXI.DisplayObject.prototype, 'y', {
|
||||
get: function() {
|
||||
return this.position.y;
|
||||
},
|
||||
set: function(value) {
|
||||
this.position.y = value;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,6 +29,44 @@ PIXI.DisplayObjectContainer = function()
|
||||
PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
|
||||
PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
|
||||
|
||||
/**
|
||||
* The width of the displayObjectContainer, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @property width
|
||||
* @type Number
|
||||
*/
|
||||
|
||||
/*
|
||||
Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', {
|
||||
get: function() {
|
||||
return this.scale.x * this.getLocalBounds().width;
|
||||
},
|
||||
set: function(value) {
|
||||
this.scale.x = value / (this.getLocalBounds().width/this.scale.x);
|
||||
this._width = value;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* The height of the displayObjectContainer, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
*/
|
||||
|
||||
/*
|
||||
Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'height', {
|
||||
get: function() {
|
||||
return this.scale.y * this.getLocalBounds().height;
|
||||
},
|
||||
set: function(value) {
|
||||
this.scale.y = value / (this.getLocalBounds().height/this.scale.y);
|
||||
this._height = value;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a child to the container.
|
||||
*
|
||||
@@ -37,82 +75,7 @@ PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype.addChild = function(child)
|
||||
{
|
||||
if(child.parent && child.parent !== this)
|
||||
{
|
||||
//// COULD BE THIS???
|
||||
child.parent.removeChild(child);
|
||||
// return;
|
||||
}
|
||||
|
||||
child.parent = this;
|
||||
|
||||
this.children.push(child);
|
||||
|
||||
// update the stage refference..
|
||||
|
||||
if(this.stage)
|
||||
{
|
||||
var tmpChild = child;
|
||||
do
|
||||
{
|
||||
if(tmpChild.interactive)this.stage.dirty = true;
|
||||
tmpChild.stage = this.stage;
|
||||
tmpChild = tmpChild._iNext;
|
||||
}
|
||||
while(tmpChild);
|
||||
}
|
||||
|
||||
// LINKED LIST //
|
||||
|
||||
// modify the list..
|
||||
var childFirst = child.first;
|
||||
var childLast = child.last;
|
||||
var nextObject;
|
||||
var previousObject;
|
||||
|
||||
// this could be wrong if there is a filter??
|
||||
if(this._filters || this._mask)
|
||||
{
|
||||
previousObject = this.last._iPrev;
|
||||
}
|
||||
else
|
||||
{
|
||||
previousObject = this.last;
|
||||
}
|
||||
|
||||
nextObject = previousObject._iNext;
|
||||
|
||||
// always true in this case
|
||||
// need to make sure the parents last is updated too
|
||||
var updateLast = this;
|
||||
var prevLast = previousObject;
|
||||
|
||||
while(updateLast)
|
||||
{
|
||||
if(updateLast.last === prevLast)
|
||||
{
|
||||
updateLast.last = child.last;
|
||||
}
|
||||
updateLast = updateLast.parent;
|
||||
}
|
||||
|
||||
if(nextObject)
|
||||
{
|
||||
nextObject._iPrev = childLast;
|
||||
childLast._iNext = nextObject;
|
||||
}
|
||||
|
||||
childFirst._iPrev = previousObject;
|
||||
previousObject._iNext = childFirst;
|
||||
|
||||
// need to remove any render groups..
|
||||
if(this.__renderGroup)
|
||||
{
|
||||
// being used by a renderTexture.. if it exists then it must be from a render texture;
|
||||
if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child);
|
||||
// add them to the new render group..
|
||||
this.__renderGroup.addDisplayObjectAndChildren(child);
|
||||
}
|
||||
this.addChildAt(child, this.children.length);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -126,76 +89,16 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
|
||||
{
|
||||
if(index >= 0 && index <= this.children.length)
|
||||
{
|
||||
if(child.parent !== undefined)
|
||||
if(child.parent)
|
||||
{
|
||||
child.parent.removeChild(child);
|
||||
}
|
||||
|
||||
child.parent = this;
|
||||
|
||||
if(this.stage)
|
||||
{
|
||||
var tmpChild = child;
|
||||
do
|
||||
{
|
||||
if(tmpChild.interactive)this.stage.dirty = true;
|
||||
tmpChild.stage = this.stage;
|
||||
tmpChild = tmpChild._iNext;
|
||||
}
|
||||
while(tmpChild);
|
||||
}
|
||||
|
||||
// modify the list..
|
||||
var childFirst = child.first;
|
||||
var childLast = child.last;
|
||||
var nextObject;
|
||||
var previousObject;
|
||||
|
||||
if(index === this.children.length)
|
||||
{
|
||||
previousObject = this.last;
|
||||
var updateLast = this;
|
||||
var prevLast = this.last;
|
||||
while(updateLast)
|
||||
{
|
||||
if(updateLast.last === prevLast)
|
||||
{
|
||||
updateLast.last = child.last;
|
||||
}
|
||||
updateLast = updateLast.parent;
|
||||
}
|
||||
}
|
||||
else if(index === 0)
|
||||
{
|
||||
previousObject = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
previousObject = this.children[index-1].last;
|
||||
}
|
||||
|
||||
nextObject = previousObject._iNext;
|
||||
|
||||
// always true in this case
|
||||
if(nextObject)
|
||||
{
|
||||
nextObject._iPrev = childLast;
|
||||
childLast._iNext = nextObject;
|
||||
}
|
||||
|
||||
childFirst._iPrev = previousObject;
|
||||
previousObject._iNext = childFirst;
|
||||
|
||||
this.children.splice(index, 0, child);
|
||||
// need to remove any render groups..
|
||||
if(this.__renderGroup)
|
||||
{
|
||||
// being used by a renderTexture.. if it exists then it must be from a render texture;
|
||||
if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child);
|
||||
// add them to the new render group..
|
||||
this.__renderGroup.addDisplayObjectAndChildren(child);
|
||||
}
|
||||
|
||||
if(this.stage)child.setStageReference(this.stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -224,23 +127,13 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
|
||||
throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.');
|
||||
}
|
||||
|
||||
this.removeChild(child);
|
||||
this.removeChild(child2);
|
||||
|
||||
if(index1 < index2)
|
||||
{
|
||||
this.addChildAt(child2, index1);
|
||||
this.addChildAt(child, index2);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addChildAt(child, index2);
|
||||
this.addChildAt(child2, index1);
|
||||
}
|
||||
this.children[index1] = child2;
|
||||
this.children[index2] = child;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the Child at the specified index
|
||||
* Returns the child at the specified index
|
||||
*
|
||||
* @method getChildAt
|
||||
* @param index {Number} The index to get the child from
|
||||
@@ -253,7 +146,7 @@ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Error('Both the supplied DisplayObjects must be a child of the caller ' + this);
|
||||
throw new Error('The supplied DisplayObjects must be a child of the caller ' + this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -268,53 +161,8 @@ PIXI.DisplayObjectContainer.prototype.removeChild = function(child)
|
||||
var index = this.children.indexOf( child );
|
||||
if ( index !== -1 )
|
||||
{
|
||||
// unlink //
|
||||
// modify the list..
|
||||
var childFirst = child.first;
|
||||
var childLast = child.last;
|
||||
|
||||
var nextObject = childLast._iNext;
|
||||
var previousObject = childFirst._iPrev;
|
||||
|
||||
if(nextObject)nextObject._iPrev = previousObject;
|
||||
previousObject._iNext = nextObject;
|
||||
|
||||
if(this.last === childLast)
|
||||
{
|
||||
var tempLast = childFirst._iPrev;
|
||||
// need to make sure the parents last is updated too
|
||||
var updateLast = this;
|
||||
|
||||
while(updateLast.last === childLast)
|
||||
{
|
||||
updateLast.last = tempLast;
|
||||
updateLast = updateLast.parent;
|
||||
if(!updateLast)break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
childLast._iNext = null;
|
||||
childFirst._iPrev = null;
|
||||
|
||||
// update the stage reference..
|
||||
if(this.stage)
|
||||
{
|
||||
var tmpChild = child;
|
||||
do
|
||||
{
|
||||
if(tmpChild.interactive)this.stage.dirty = true;
|
||||
tmpChild.stage = null;
|
||||
tmpChild = tmpChild._iNext;
|
||||
}
|
||||
while(tmpChild);
|
||||
}
|
||||
|
||||
// webGL trim
|
||||
if(child.__renderGroup)
|
||||
{
|
||||
child.__renderGroup.removeDisplayObjectAndChildren(child);
|
||||
}
|
||||
if(this.stage)child.removeStageReference();
|
||||
|
||||
child.parent = undefined;
|
||||
this.children.splice( index, 1 );
|
||||
@@ -326,13 +174,15 @@ PIXI.DisplayObjectContainer.prototype.removeChild = function(child)
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates the container's children's transform for rendering
|
||||
* Updates the container's childrens transform for rendering
|
||||
*
|
||||
* @method updateTransform
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype.updateTransform = function()
|
||||
{
|
||||
//this._currentBounds = null;
|
||||
|
||||
if(!this.visible)return;
|
||||
|
||||
PIXI.DisplayObject.prototype.updateTransform.call( this );
|
||||
@@ -342,3 +192,181 @@ PIXI.DisplayObjectContainer.prototype.updateTransform = function()
|
||||
this.children[i].updateTransform();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the bounds of the displayObjectContainer as a rectangle object
|
||||
*
|
||||
* @method getBounds
|
||||
* @return {Rectangle} the rectangular bounding area
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype.getBounds = function()
|
||||
{
|
||||
if(this.children.length === 0)return PIXI.EmptyRectangle;
|
||||
|
||||
// TODO the bounds have already been calculated this render session so return what we have
|
||||
|
||||
|
||||
var minX = Infinity;
|
||||
var minY = Infinity;
|
||||
|
||||
var maxX = -Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var childBounds;
|
||||
var childMaxX;
|
||||
var childMaxY;
|
||||
|
||||
var childVisible = false;
|
||||
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
var child = this.children[i];
|
||||
|
||||
if(!child.visible)continue;
|
||||
|
||||
childVisible = true;
|
||||
|
||||
childBounds = this.children[i].getBounds();
|
||||
|
||||
minX = minX < childBounds.x ? minX : childBounds.x;
|
||||
minY = minY < childBounds.y ? minY : childBounds.y;
|
||||
|
||||
childMaxX = childBounds.width + childBounds.x;
|
||||
childMaxY = childBounds.height + childBounds.y;
|
||||
|
||||
maxX = maxX > childMaxX ? maxX : childMaxX;
|
||||
maxY = maxY > childMaxY ? maxY : childMaxY;
|
||||
}
|
||||
|
||||
if(!childVisible)
|
||||
return PIXI.EmptyRectangle;
|
||||
|
||||
var bounds = this._bounds;
|
||||
|
||||
bounds.x = minX;
|
||||
bounds.y = minY;
|
||||
bounds.width = maxX - minX;
|
||||
bounds.height = maxY - minY;
|
||||
|
||||
// TODO: store a reference so that if this function gets called again in the render cycle we do not have to recalculate
|
||||
//this._currentBounds = bounds;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the container's stage reference, the stage this object is connected to
|
||||
*
|
||||
* @method setStageReference
|
||||
* @param stage {Stage} the stage that the container will have as its current stage reference
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype.setStageReference = function(stage)
|
||||
{
|
||||
this.stage = stage;
|
||||
if(this._interactive)this.stage.dirty = true;
|
||||
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
var child = this.children[i];
|
||||
child.setStageReference(stage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* removes the current stage reference of the container
|
||||
*
|
||||
* @method removeStageReference
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype.removeStageReference = function()
|
||||
{
|
||||
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
var child = this.children[i];
|
||||
child.removeStageReference();
|
||||
}
|
||||
|
||||
if(this._interactive)this.stage.dirty = true;
|
||||
|
||||
this.stage = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
if(!this.visible || this.alpha <= 0)return;
|
||||
|
||||
var i,j;
|
||||
|
||||
if(this._mask || this._filters)
|
||||
{
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.spriteBatch.stop();
|
||||
renderSession.maskManager.pushMask(this.mask, renderSession);
|
||||
renderSession.spriteBatch.start();
|
||||
}
|
||||
|
||||
if(this._filters)
|
||||
{
|
||||
renderSession.spriteBatch.flush();
|
||||
renderSession.filterManager.pushFilter(this._filterBlock);
|
||||
}
|
||||
|
||||
// simple render children!
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
|
||||
renderSession.spriteBatch.stop();
|
||||
|
||||
if(this._filters)renderSession.filterManager.popFilter();
|
||||
if(this._mask)renderSession.maskManager.popMask(renderSession);
|
||||
|
||||
renderSession.spriteBatch.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
// simple render children!
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.DisplayObjectContainer.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
if(this.visible === false || this.alpha === 0)return;
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.pushMask(this._mask, renderSession.context);
|
||||
}
|
||||
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
var child = this.children[i];
|
||||
child._renderCanvas(renderSession);
|
||||
}
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession.context);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ PIXI.MovieClip = function(textures)
|
||||
this.onComplete = null;
|
||||
|
||||
/**
|
||||
* [read-only] The index MovieClips current frame (this may not have to be a whole number)
|
||||
* [read-only] The MovieClips current frame index (this may not have to be a whole number)
|
||||
*
|
||||
* @property currentFrame
|
||||
* @type Number
|
||||
|
||||
+296
-29
@@ -2,19 +2,18 @@
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
PIXI.blendModes = {};
|
||||
PIXI.blendModes.NORMAL = 0;
|
||||
PIXI.blendModes.SCREEN = 1;
|
||||
|
||||
|
||||
/**
|
||||
* The SPrite object is the base for all textured objects that are rendered to the screen
|
||||
* The Sprite object is the base for all textured objects that are rendered to the screen
|
||||
*
|
||||
* @class Sprite
|
||||
* @extends DisplayObjectContainer
|
||||
* @constructor
|
||||
* @param texture {Texture} The texture for this sprite
|
||||
* @type String
|
||||
*
|
||||
* A sprite can be created directly from an image like this :
|
||||
* var sprite = nex PIXI.Sprite.FromImage('assets/image.png');
|
||||
* yourStage.addChild(sprite);
|
||||
* then obviously don't forget to add it to the stage you have already created
|
||||
*/
|
||||
PIXI.Sprite = function(texture)
|
||||
{
|
||||
@@ -22,9 +21,9 @@ PIXI.Sprite = function(texture)
|
||||
|
||||
/**
|
||||
* The anchor sets the origin point of the texture.
|
||||
* The default is 0,0 this means the textures origin is the top left
|
||||
* Setting than anchor to 0.5,0.5 means the textures origin is centered
|
||||
* Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
|
||||
* The default is 0,0 this means the texture's origin is the top left
|
||||
* Setting than anchor to 0.5,0.5 means the textures origin is centred
|
||||
* Setting the anchor to 1,1 would mean the textures origin points will be the bottom right corner
|
||||
*
|
||||
* @property anchor
|
||||
* @type Point
|
||||
@@ -39,15 +38,6 @@ PIXI.Sprite = function(texture)
|
||||
*/
|
||||
this.texture = texture;
|
||||
|
||||
/**
|
||||
* The blend mode of sprite.
|
||||
* currently supports PIXI.blendModes.NORMAL and PIXI.blendModes.SCREEN
|
||||
*
|
||||
* @property blendMode
|
||||
* @type Number
|
||||
*/
|
||||
this.blendMode = PIXI.blendModes.NORMAL;
|
||||
|
||||
/**
|
||||
* The width of the sprite (this is initially set by the texture)
|
||||
*
|
||||
@@ -66,9 +56,28 @@ PIXI.Sprite = function(texture)
|
||||
*/
|
||||
this._height = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The tint applied to the sprite. This is a hex value
|
||||
*
|
||||
* @property tint
|
||||
* @type Number
|
||||
* @default 0xFFFFFF
|
||||
*/
|
||||
this.tint = 0xFFFFFF;// * Math.random();
|
||||
|
||||
/**
|
||||
* The blend mode to be applied to the sprite
|
||||
*
|
||||
* @property blendMode
|
||||
* @type Number
|
||||
* @default PIXI.blendModes.NORMAL;
|
||||
*/
|
||||
this.blendMode = PIXI.blendModes.NORMAL;
|
||||
|
||||
if(texture.baseTexture.hasLoaded)
|
||||
{
|
||||
this.updateFrame = true;
|
||||
this.onTextureUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -84,7 +93,7 @@ PIXI.Sprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
|
||||
PIXI.Sprite.prototype.constructor = PIXI.Sprite;
|
||||
|
||||
/**
|
||||
* The width of the sprite, setting this will actually modify the scale to acheive the value set
|
||||
* The width of the sprite, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @property width
|
||||
* @type Number
|
||||
@@ -100,7 +109,7 @@ Object.defineProperty(PIXI.Sprite.prototype, 'width', {
|
||||
});
|
||||
|
||||
/**
|
||||
* The height of the sprite, setting this will actually modify the scale to acheive the value set
|
||||
* The height of the sprite, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
@@ -128,17 +137,13 @@ PIXI.Sprite.prototype.setTexture = function(texture)
|
||||
{
|
||||
this.textureChange = true;
|
||||
this.texture = texture;
|
||||
|
||||
if(this.__renderGroup)
|
||||
{
|
||||
this.__renderGroup.updateTexture(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
this.cachedTint = 0xFFFFFF;
|
||||
this.updateFrame = true;
|
||||
};
|
||||
|
||||
@@ -151,15 +156,277 @@ PIXI.Sprite.prototype.setTexture = function(texture)
|
||||
*/
|
||||
PIXI.Sprite.prototype.onTextureUpdate = function()
|
||||
{
|
||||
//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;
|
||||
|
||||
|
||||
this.updateFrame = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the bounds of the sprite as a rectangle object
|
||||
*
|
||||
* @method getBounds
|
||||
* @return {Rectangle} the rectangular bounding area
|
||||
*/
|
||||
PIXI.Sprite.prototype.getBounds = function()
|
||||
{
|
||||
|
||||
var width = this.texture.frame.width;
|
||||
var height = this.texture.frame.height;
|
||||
|
||||
var w0 = width * (1-this.anchor.x);
|
||||
var w1 = width * -this.anchor.x;
|
||||
|
||||
var h0 = height * (1-this.anchor.y);
|
||||
var h1 = height * -this.anchor.y;
|
||||
|
||||
var worldTransform = this.worldTransform;
|
||||
|
||||
var a = worldTransform.a;
|
||||
var b = worldTransform.c;
|
||||
var c = worldTransform.b;
|
||||
var d = worldTransform.d;
|
||||
var tx = worldTransform.tx;
|
||||
var ty = worldTransform.ty;
|
||||
|
||||
var x1 = a * w1 + c * h1 + tx;
|
||||
var y1 = d * h1 + b * w1 + ty;
|
||||
|
||||
var x2 = a * w0 + c * h1 + tx;
|
||||
var y2 = d * h1 + b * w0 + ty;
|
||||
|
||||
var x3 = a * w0 + c * h0 + tx;
|
||||
var y3 = d * h0 + b * w0 + ty;
|
||||
|
||||
var x4 = a * w1 + c * h0 + tx;
|
||||
var y4 = d * h0 + b * w1 + ty;
|
||||
|
||||
var maxX = -Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var minX = Infinity;
|
||||
var minY = Infinity;
|
||||
|
||||
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;
|
||||
|
||||
var bounds = this._bounds;
|
||||
|
||||
bounds.x = minX;
|
||||
bounds.width = maxX - minX;
|
||||
|
||||
bounds.y = minY;
|
||||
bounds.height = maxY - minY;
|
||||
|
||||
// store a reference so that if this function gets called again in the render cycle we do not have to recalculate
|
||||
this._currentBounds = bounds;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.Sprite.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
// if the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if(!this.visible || this.alpha <= 0)return;
|
||||
|
||||
var i,j;
|
||||
|
||||
// do a quick check to see if this element has a mask or a filter.
|
||||
if(this._mask || this._filters)
|
||||
{
|
||||
var spriteBatch = renderSession.spriteBatch;
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
spriteBatch.stop();
|
||||
renderSession.maskManager.pushMask(this.mask, renderSession);
|
||||
spriteBatch.start();
|
||||
}
|
||||
|
||||
if(this._filters)
|
||||
{
|
||||
spriteBatch.flush();
|
||||
renderSession.filterManager.pushFilter(this._filterBlock);
|
||||
}
|
||||
|
||||
// add this sprite to the batch
|
||||
spriteBatch.render(this);
|
||||
|
||||
// now loop through the children and make sure they get rendered
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
|
||||
// time to stop the sprite batch as either a mask element or a filter draw will happen next
|
||||
spriteBatch.stop();
|
||||
|
||||
if(this._filters)renderSession.filterManager.popFilter();
|
||||
if(this._mask)renderSession.maskManager.popMask(renderSession);
|
||||
|
||||
spriteBatch.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderSession.spriteBatch.render(this);
|
||||
|
||||
// simple render children!
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO check culling
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.Sprite.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
// if the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if(this.visible === false || this.alpha === 0)return;
|
||||
|
||||
var frame = this.texture.frame;
|
||||
var context = renderSession.context;
|
||||
var texture = this.texture;
|
||||
|
||||
if(this.blendMode !== renderSession.currentBlendMode)
|
||||
{
|
||||
renderSession.currentBlendMode = this.blendMode;
|
||||
context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode];
|
||||
}
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.pushMask(this._mask, renderSession.context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ignore null sources
|
||||
if(frame && frame.width && frame.height && texture.baseTexture.source)
|
||||
{
|
||||
context.globalAlpha = this.worldAlpha;
|
||||
|
||||
var transform = this.worldTransform;
|
||||
|
||||
// allow for trimming
|
||||
|
||||
context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
|
||||
//if smoothingEnabled is supported and we need to change the smoothing property for this texture
|
||||
if(renderSession.smoothProperty && renderSession.scaleMode !== this.texture.baseTexture.scaleMode) {
|
||||
renderSession.scaleMode = this.texture.baseTexture.scaleMode;
|
||||
context[renderSession.smoothProperty] = (renderSession.scaleMode === PIXI.scaleModes.LINEAR);
|
||||
}
|
||||
|
||||
if(this.tint !== 0xFFFFFF)
|
||||
{
|
||||
|
||||
if(this.cachedTint !== this.tint)
|
||||
{
|
||||
// no point tinting an image that has not loaded yet!
|
||||
if(!texture.baseTexture.hasLoaded)return;
|
||||
|
||||
this.cachedTint = this.tint;
|
||||
|
||||
//TODO clean up caching - how to clean up the caches?
|
||||
this.tintedTexture = PIXI.CanvasTinter.getTintedTexture(this, this.tint);
|
||||
|
||||
}
|
||||
|
||||
context.drawImage(this.tintedTexture,
|
||||
0,
|
||||
0,
|
||||
frame.width,
|
||||
frame.height,
|
||||
(this.anchor.x) * -frame.width,
|
||||
(this.anchor.y) * -frame.height,
|
||||
frame.width,
|
||||
frame.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
|
||||
if(texture.trimmed)
|
||||
{
|
||||
var trim = texture.trim;
|
||||
|
||||
context.drawImage(this.texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
trim.x - this.anchor.x * trim.realWidth,
|
||||
trim.y - this.anchor.y * trim.realHeight,
|
||||
frame.width,
|
||||
frame.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
context.drawImage(this.texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
(this.anchor.x) * -frame.width,
|
||||
(this.anchor.y) * -frame.height,
|
||||
frame.width,
|
||||
frame.height);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// OVERWRITE
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
var child = this.children[i];
|
||||
child._renderCanvas(renderSession);
|
||||
}
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession.context);
|
||||
}
|
||||
};
|
||||
|
||||
// some helper functions..
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
|
||||
|
||||
PIXI.ParticleBatch = function(texture)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.call( this);
|
||||
|
||||
this.textureThing = texture;
|
||||
|
||||
this.ready = false;
|
||||
}
|
||||
|
||||
PIXI.ParticleBatch.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
|
||||
PIXI.ParticleBatch.constructor = PIXI.ParticleBatch;
|
||||
|
||||
PIXI.ParticleBatch.prototype.initWebGL = function(gl)
|
||||
{
|
||||
|
||||
var vecShaderSrc = [
|
||||
|
||||
"attribute vec2 aVertexPosition;",
|
||||
"attribute vec2 aMovement;",
|
||||
"attribute vec2 aTexture;",
|
||||
|
||||
"uniform mat3 translationMatrix;",
|
||||
|
||||
"uniform float time;",
|
||||
// "uniform float pos;",
|
||||
|
||||
"uniform vec2 projectionVector;",
|
||||
"varying vec2 vTextureCoord;",
|
||||
"const float PI = 3.14159265358;",
|
||||
|
||||
"void main(void) {",
|
||||
|
||||
"vec2 v = aVertexPosition;",
|
||||
"float x = aMovement.x * 0.01;",
|
||||
"vec2 scaledVertex = aVertexPosition;",
|
||||
"v.x = (scaledVertex.x) * cos(x) - (scaledVertex.y) * sin(x);",
|
||||
"v.y = (scaledVertex.x) * sin(x) + (scaledVertex.y) * cos(x);",
|
||||
|
||||
//"float pos = p * p * ((this._p1 + 1) * p - this._p1);"
|
||||
|
||||
//"v.y = sin(-time*PI * 2.0) * -aMovement.y;",
|
||||
"v += aMovement;",
|
||||
|
||||
// "v += aVertexPosition;",
|
||||
// "v.y *= 1.0 + smoothstep(time, 0.5, 1.0) * 3.0;",
|
||||
// "v.y += aMovement.y * time + aVertexPosition.y;",
|
||||
// "v.y = time * aMovement.y;;",
|
||||
// "v.y += aVertexPosition.y;",
|
||||
//"v.x += aMovement.x ;",
|
||||
|
||||
// "v.y *= -1.0;",
|
||||
|
||||
"v.x += 1280.0/2.0;",
|
||||
"v.y += 800.0/2.0;",
|
||||
|
||||
|
||||
"gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);",
|
||||
|
||||
// "gl_Position = vec4(aVertexPosition, 0.0, 1.0);",
|
||||
"vTextureCoord = aTexture;",
|
||||
|
||||
"}"
|
||||
|
||||
];
|
||||
|
||||
var fragShaderSrc = [
|
||||
"precision lowp float;",
|
||||
"varying vec2 vTextureCoord;",
|
||||
|
||||
"uniform sampler2D uSampler;",
|
||||
"void main(void) {",
|
||||
"gl_FragColor = texture2D(uSampler, vTextureCoord);",
|
||||
"}"
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
this.program = PIXI.compileProgram(gl, vecShaderSrc, fragShaderSrc)
|
||||
|
||||
gl.useProgram(this.program);
|
||||
|
||||
|
||||
this.translationMatrix = gl.getUniformLocation(this.program, "translationMatrix");
|
||||
this.projectionVector = gl.getUniformLocation(this.program, "projectionVector");
|
||||
this.time = gl.getUniformLocation(this.program, "time");
|
||||
|
||||
|
||||
this.aVertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
|
||||
this.aMovement = gl.getAttribLocation(this.program, "aMovement");
|
||||
this.aTexture = gl.getAttribLocation(this.program, "aTexture");
|
||||
|
||||
// console.log(":::" + this.aMovement)
|
||||
this.totalItems = 10000;
|
||||
|
||||
|
||||
this.verticies = new Float32Array( this.totalItems * 8 );
|
||||
this.movement = new Float32Array( this.totalItems * 8 );
|
||||
|
||||
this.posData = new Float32Array( this.totalItems * 3 );
|
||||
|
||||
this.texture = new Float32Array( this.totalItems * 8 );
|
||||
|
||||
this.indices = new Uint16Array( this.totalItems * 6);
|
||||
|
||||
for (var i = 0; i < this.totalItems * 8; i+=8) {
|
||||
|
||||
var scale = 1// + Math.random()
|
||||
// position..
|
||||
this.verticies[i] = -20 * scale;
|
||||
this.verticies[i+1] = -20 * scale;
|
||||
|
||||
this.verticies[i+2] = 20 * scale;
|
||||
this.verticies[i+3] = -20 * scale;
|
||||
|
||||
this.verticies[i+4] = 20 * scale;
|
||||
this.verticies[i+5] = 20 * scale;
|
||||
|
||||
this.verticies[i+6] = -20 * scale;
|
||||
this.verticies[i+7] = 20 * scale;
|
||||
};
|
||||
|
||||
var fullWidth = 142;
|
||||
var fullHeight= 157;
|
||||
|
||||
var simpleFrame = new PIXI.Rectangle(0, 0, 142, 157);
|
||||
|
||||
var gemCount = 0;
|
||||
|
||||
for (var i = 0; i < this.totalItems * 8; i+=8) {
|
||||
|
||||
gemCount++
|
||||
var gemFrame = this.texture.frame || simpleFrame;//this.gems[gemCount % this.gems.length].frame;
|
||||
// console.log(gemFrame);
|
||||
// position..
|
||||
|
||||
var xoff = gemFrame.x / fullWidth;
|
||||
var yoff = gemFrame.y / fullHeight;
|
||||
|
||||
this.texture[i] = xoff;
|
||||
this.texture[i+1] = yoff;
|
||||
|
||||
this.texture[i+2] = xoff + gemFrame.width / fullWidth;
|
||||
this.texture[i+3] = yoff;
|
||||
|
||||
this.texture[i+4] = xoff + gemFrame.width / fullWidth;
|
||||
this.texture[i+5] = yoff + gemFrame.height / fullHeight;
|
||||
|
||||
this.texture[i+6] = xoff;
|
||||
this.texture[i+7] = yoff + gemFrame.height / fullHeight;
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.totalItems* 8; i+=8) {
|
||||
|
||||
var pos = 0//Math.random() * 200;
|
||||
|
||||
var angle = Math.random() * Math.PI * 2;
|
||||
|
||||
var speed = (0.3 + Math.random() * 0.9) * 0.01;
|
||||
|
||||
var pos = Math.sin(angle) * speed;//Math.random() * 10 - 5;
|
||||
var posY = Math.cos(angle) * speed;
|
||||
|
||||
var scale = 1;
|
||||
// var posY = 0.5 + Math.random()// * 200
|
||||
|
||||
// console.log(pos);
|
||||
this.movement[i] = pos;
|
||||
this.movement[i+1] = posY;
|
||||
|
||||
this.movement[i+2] = scale;
|
||||
this.movement[i+3] = scale;
|
||||
|
||||
this.movement[i+4] = rotation;
|
||||
|
||||
this.movement[i+5] = scale;
|
||||
|
||||
this.movement[i+2] = pos;
|
||||
this.movement[i+3] = posY;
|
||||
|
||||
this.movement[i+4] = pos;
|
||||
this.movement[i+5] = posY;
|
||||
|
||||
this.movement[i+6] = pos;
|
||||
this.movement[i+7] = posY;
|
||||
}
|
||||
|
||||
this.reset();
|
||||
|
||||
for (var i = 0; i < this.totalItems * 6; i+=6) {
|
||||
|
||||
var i3 = (i / 6) * 4;
|
||||
|
||||
this.indices[i] = i3;
|
||||
this.indices[i+1] = i3+1;
|
||||
this.indices[i+2] = i3+2;
|
||||
this.indices[i+3] = i3;
|
||||
this.indices[i+4] = i3+2;
|
||||
this.indices[i+5] = i3+3;
|
||||
|
||||
}
|
||||
|
||||
// console.log(this);
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.textureBuffer = gl.createBuffer();
|
||||
this.movementBuffer = gl.createBuffer();
|
||||
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.verticies, gl.STATIC_DRAW);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.texture, gl.STATIC_DRAW);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.movement, gl.DYNAMIC_DRAW);
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
|
||||
|
||||
this.count = 0;
|
||||
this.speed = 18;
|
||||
this.posy = 0;
|
||||
|
||||
this.ready = true;
|
||||
// alert("!")
|
||||
}
|
||||
|
||||
PIXI.ParticleBatch.prototype.addChild = function(child)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.prototype.addChild.call(child);
|
||||
|
||||
|
||||
}
|
||||
|
||||
PIXI.ParticleBatch.prototype.reset = function()
|
||||
{
|
||||
for (var i = 0; i < this.totalItems* 4; i+=4) {
|
||||
|
||||
this.posData[i] = 0; // pos x
|
||||
this.posData[i + 1] = 0; // pos y
|
||||
|
||||
var angle = Math.random() * Math.PI * 2;
|
||||
|
||||
var speed = 10 + Math.random() * 15;
|
||||
|
||||
var pos = Math.sin(angle) * speed;//Math.random() * 10 - 5;
|
||||
var posY = Math.cos(angle) *speed;
|
||||
|
||||
|
||||
this.posData[i + 2] = pos; // speed x
|
||||
this.posData[i + 3] = posY - 10; // speed y
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PIXI.ParticleBatch.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
if(!this.visible)return;
|
||||
|
||||
renderSession.shaderManager.deactivateDefaultShader()
|
||||
if(!this.ready)this.initWebGL( renderSession.gl );
|
||||
|
||||
renderSession.spriteBatch.stop();
|
||||
|
||||
this.speed -= 0.4;
|
||||
|
||||
this.count += this.speed;
|
||||
|
||||
|
||||
var gl = renderSession.gl;
|
||||
var glTexture = this.textureThing.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.textureThing.baseTexture, gl)
|
||||
|
||||
gl.useProgram(this.program);
|
||||
|
||||
|
||||
gl.enableVertexAttribArray(this.aVertexPosition);
|
||||
gl.enableVertexAttribArray(this.aMovement);
|
||||
gl.enableVertexAttribArray(this.aTexture);
|
||||
|
||||
|
||||
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, glTexture);
|
||||
|
||||
gl.uniform1f(this.time, this.count);
|
||||
gl.uniform2f(this.projectionVector, renderSession.projection.x, renderSession.projection.y);
|
||||
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureBuffer);
|
||||
gl.vertexAttribPointer(this.aTexture, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
|
||||
|
||||
for (var i = 0; i < this.totalItems* 8; i+=8) {
|
||||
|
||||
var val = ( i / 8 ) * 4;
|
||||
|
||||
this.posData[val + 3] += 0.02;
|
||||
|
||||
this.posData[val] += this.posData[val + 2];
|
||||
this.posData[val + 1] += this.posData[val + 3];
|
||||
|
||||
var pos = this.posData[val];
|
||||
var posY = this.posData[val + 1];
|
||||
|
||||
//pos += this.posData[val + 2];
|
||||
//posY += this.posData[val + 3];
|
||||
|
||||
this.movement[i] = pos;
|
||||
this.movement[i+1] = posY;
|
||||
|
||||
this.movement[i+2] = pos;
|
||||
this.movement[i+3] = posY;
|
||||
|
||||
this.movement[i+4] = pos;
|
||||
this.movement[i+5] = posY;
|
||||
|
||||
this.movement[i+6] = pos;
|
||||
this.movement[i+7] = posY;
|
||||
}
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.movement);
|
||||
|
||||
gl.vertexAttribPointer(this.aMovement, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
//gl.bindBuffer(gl.ARRAY_BUFFER, this.movementBuffer);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
|
||||
gl.drawElements(gl.TRIANGLES, 6 * this.totalItems , gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// not sure if both needed? but ya have for now!
|
||||
// override!
|
||||
// disable the current stuff..
|
||||
|
||||
|
||||
// gl.disableVertexAttribArray(PIXI.stripShader.aVertexPosition);
|
||||
//gl.disableVertexAttribArray(PIXI.stripShader.colorAttribute);
|
||||
//gl.disableVertexAttribArray(PIXI.stripShader.aTextureCoord);
|
||||
gl.disableVertexAttribArray(this.aVertexPosition);
|
||||
gl.disableVertexAttribArray(this.aMovement);
|
||||
gl.disableVertexAttribArray(this.aTexture);
|
||||
|
||||
|
||||
renderSession.shaderManager.activateDefaultShader()
|
||||
|
||||
renderSession.spriteBatch.start();
|
||||
/*
|
||||
gl.useProgram(PIXI.defaultShader.program);
|
||||
|
||||
gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
|
||||
gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
|
||||
gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @class SpriteBatch
|
||||
* @constructor
|
||||
* @param texture {Texture}
|
||||
*/
|
||||
PIXI.SpriteBatch = function(texture)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.call( this);
|
||||
|
||||
this.textureThing = texture;
|
||||
|
||||
this.ready = false;
|
||||
};
|
||||
|
||||
PIXI.SpriteBatch.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
|
||||
PIXI.SpriteBatch.constructor = PIXI.SpriteBatch;
|
||||
|
||||
|
||||
/*
|
||||
* Initialises the spriteBatch
|
||||
*
|
||||
* @method initWebGL
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.SpriteBatch.prototype.initWebGL = function(gl)
|
||||
{
|
||||
this.fastSpriteBatch = new PIXI.WebGLFastSpriteBatch(gl);
|
||||
|
||||
this.ready = true;
|
||||
// alert("!")
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates the object transform for rendering
|
||||
*
|
||||
* @method updateTransform
|
||||
* @private
|
||||
*/
|
||||
PIXI.SpriteBatch.prototype.updateTransform = function()
|
||||
{
|
||||
// dont need to!
|
||||
PIXI.DisplayObject.prototype.updateTransform.call( this );
|
||||
// PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.SpriteBatch.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
if(!this.visible || this.alpha <= 0 || !this.children.length)return;
|
||||
|
||||
if(!this.ready)this.initWebGL( renderSession.gl );
|
||||
|
||||
renderSession.spriteBatch.stop();
|
||||
|
||||
renderSession.shaderManager.activateShader(renderSession.shaderManager.fastShader);
|
||||
|
||||
this.fastSpriteBatch.begin(this, renderSession);
|
||||
this.fastSpriteBatch.render(this);
|
||||
|
||||
renderSession.shaderManager.activateShader(renderSession.shaderManager.defaultShader);
|
||||
|
||||
renderSession.spriteBatch.start();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
var context = renderSession.context;
|
||||
context.globalAlpha = this.worldAlpha;
|
||||
|
||||
var transform = this.worldTransform;
|
||||
|
||||
// alow for trimming
|
||||
|
||||
context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
context.save();
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
|
||||
var child = this.children[i];
|
||||
var texture = child.texture;
|
||||
var frame = texture.frame;
|
||||
|
||||
context.globalAlpha = this.worldAlpha * child.alpha;
|
||||
|
||||
if(child.rotation % (Math.PI * 2) === 0)
|
||||
{
|
||||
|
||||
// this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
((child.anchor.x) * (-frame.width * child.scale.x) + child.position.x + 0.5) | 0,
|
||||
((child.anchor.y) * (-frame.height * child.scale.y) + child.position.y + 0.5) | 0,
|
||||
frame.width * child.scale.x,
|
||||
frame.height * child.scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIXI.DisplayObject.prototype.updateTransform.call(child);
|
||||
|
||||
transform = child.localTransform;
|
||||
|
||||
if(this.rotation !== this.rotationCache)
|
||||
{
|
||||
this.rotationCache = this.rotation;
|
||||
this._sr = Math.sin(this.rotation);
|
||||
this._cr = Math.cos(this.rotation);
|
||||
}
|
||||
|
||||
var a = child._cr * child.scale.x,
|
||||
b = -child._sr * child.scale.y,
|
||||
c = child._sr * child.scale.x,
|
||||
d = child._cr * child.scale.y;
|
||||
|
||||
context.setTransform(a, c, b, d, child.position.x, child.position.y);
|
||||
|
||||
//context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
((child.anchor.x) * (-frame.width) + 0.5) | 0,
|
||||
((child.anchor.y) * (-frame.height) + 0.5) | 0,
|
||||
frame.width,
|
||||
frame.height);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
context.restore();
|
||||
};
|
||||
|
||||
+11
-10
@@ -8,8 +8,15 @@
|
||||
* @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, you have to pass this in is in hex format
|
||||
* like: 0xFFFFFF for white
|
||||
*
|
||||
* Creating a stage is a mandatory process when you use Pixi, which is as simple as this :
|
||||
* var stage = new PIXI.Stage(0xFFFFFF);
|
||||
* where the parameter given is the background colour of the stage, in hex
|
||||
* you will use this stage instance to add your sprites to it and therefore to the renderer
|
||||
* Here is how to add a sprite to the stage :
|
||||
* stage.addChild(sprite);
|
||||
*/
|
||||
PIXI.Stage = function(backgroundColor)
|
||||
{
|
||||
@@ -23,7 +30,7 @@ PIXI.Stage = function(backgroundColor)
|
||||
* @readOnly
|
||||
* @private
|
||||
*/
|
||||
this.worldTransform = PIXI.mat3.create();
|
||||
this.worldTransform = new PIXI.Matrix();
|
||||
|
||||
/**
|
||||
* Whether or not the stage is interactive
|
||||
@@ -50,17 +57,13 @@ PIXI.Stage = function(backgroundColor)
|
||||
*/
|
||||
this.dirty = true;
|
||||
|
||||
this.__childrenAdded = [];
|
||||
this.__childrenRemoved = [];
|
||||
|
||||
//the stage is it's own stage
|
||||
//the stage is its own stage
|
||||
this.stage = this;
|
||||
|
||||
//optimize hit detection a bit
|
||||
this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000);
|
||||
|
||||
this.setBackgroundColor(backgroundColor);
|
||||
this.worldVisible = true;
|
||||
};
|
||||
|
||||
// constructor
|
||||
@@ -69,7 +72,7 @@ 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.
|
||||
* This is useful for when you have other DOM elements on top of the Canvas element.
|
||||
*
|
||||
* @method setInteractionDelegate
|
||||
* @param domElement {DOMElement} This new domElement which will receive mouse/touch events
|
||||
@@ -88,7 +91,6 @@ PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
|
||||
PIXI.Stage.prototype.updateTransform = function()
|
||||
{
|
||||
this.worldAlpha = 1;
|
||||
this.vcount = PIXI.visibleCount;
|
||||
|
||||
for(var i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
@@ -102,7 +104,6 @@ PIXI.Stage.prototype.updateTransform = function()
|
||||
this.interactionManager.dirty = true;
|
||||
}
|
||||
|
||||
|
||||
if(this.interactive)this.interactionManager.update();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This object is one that will allow you to specify custom rendering functions based on render type
|
||||
*
|
||||
* @class CustomRenderable
|
||||
* @extends DisplayObject
|
||||
* @constructor
|
||||
*/
|
||||
PIXI.CustomRenderable = function()
|
||||
{
|
||||
PIXI.DisplayObject.call( this );
|
||||
|
||||
this.renderable = true;
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
|
||||
PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
|
||||
|
||||
/**
|
||||
* If this object is being rendered by a CanvasRenderer it will call this callback
|
||||
*
|
||||
* @method renderCanvas
|
||||
* @param renderer {CanvasRenderer} The renderer instance
|
||||
*/
|
||||
PIXI.CustomRenderable.prototype.renderCanvas = function()
|
||||
{
|
||||
// override!
|
||||
};
|
||||
|
||||
/**
|
||||
* If this object is being rendered by a WebGLRenderer it will call this callback to initialize
|
||||
*
|
||||
* @method initWebGL
|
||||
* @param renderer {WebGLRenderer} The renderer instance
|
||||
*/
|
||||
PIXI.CustomRenderable.prototype.initWebGL = function()
|
||||
{
|
||||
// override!
|
||||
};
|
||||
|
||||
/**
|
||||
* If this object is being rendered by a WebGLRenderer it will call this callback
|
||||
*
|
||||
* @method renderWebGL
|
||||
* @param rendererGroup {WebGLRenderGroup} The renderer group instance
|
||||
* @param projectionMatrix {Matrix} The object's projection matrix
|
||||
*/
|
||||
PIXI.CustomRenderable.prototype.renderWebGL = function()
|
||||
{
|
||||
// not sure if both needed? but ya have for now!
|
||||
// override!
|
||||
};
|
||||
|
||||
+27
-3
@@ -1,7 +1,14 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/
|
||||
/* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @class Rope
|
||||
* @constructor
|
||||
* @param texture {Texture} TODO-Alvin
|
||||
* @param y {Array} TODO-Alvin
|
||||
*
|
||||
*/
|
||||
PIXI.Rope = function(texture, points)
|
||||
{
|
||||
PIXI.Strip.call( this, texture );
|
||||
@@ -30,6 +37,11 @@ PIXI.Rope = function(texture, points)
|
||||
PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
|
||||
PIXI.Rope.prototype.constructor = PIXI.Rope;
|
||||
|
||||
/*
|
||||
* Refreshes TODO-Alvin
|
||||
*
|
||||
* @method refresh
|
||||
*/
|
||||
PIXI.Rope.prototype.refresh = function()
|
||||
{
|
||||
var points = this.points;
|
||||
@@ -96,6 +108,12 @@ PIXI.Rope.prototype.refresh = function()
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates the object transform for rendering
|
||||
*
|
||||
* @method updateTransform
|
||||
* @private
|
||||
*/
|
||||
PIXI.Rope.prototype.updateTransform = function()
|
||||
{
|
||||
|
||||
@@ -157,7 +175,13 @@ PIXI.Rope.prototype.updateTransform = function()
|
||||
|
||||
PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
|
||||
};
|
||||
|
||||
/*
|
||||
* Sets the texture that the Rope will use
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @method setTexture
|
||||
* @param texture {Texture} the texture that will be used
|
||||
*/
|
||||
PIXI.Rope.prototype.setTexture = function(texture)
|
||||
{
|
||||
// stop current texture
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
* @author Mat Groves http://matgroves.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @class Strip
|
||||
* @constructor
|
||||
* @param texture {Texture} TODO-Alvin
|
||||
* @param width {Number} the width of the TODO-Alvin
|
||||
* @param height {Number} the height of the TODO-Alvin
|
||||
*
|
||||
*/
|
||||
|
||||
PIXI.Strip = function(texture, width, height)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.call( this );
|
||||
@@ -69,6 +79,14 @@ PIXI.Strip = function(texture, width, height)
|
||||
PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
|
||||
PIXI.Strip.prototype.constructor = PIXI.Strip;
|
||||
|
||||
/*
|
||||
* Sets the texture that the Strip will use
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @method setTexture
|
||||
* @param texture {Texture} the texture that will be used
|
||||
* @private
|
||||
*/
|
||||
PIXI.Strip.prototype.setTexture = function(texture)
|
||||
{
|
||||
//TODO SET THE TEXTURES
|
||||
@@ -81,6 +99,13 @@ PIXI.Strip.prototype.setTexture = function(texture)
|
||||
this.updateFrame = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* When the texture is updated, this event will fire to update the scale and frame
|
||||
*
|
||||
* @method onTextureUpdate
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
PIXI.Strip.prototype.onTextureUpdate = function()
|
||||
{
|
||||
this.updateFrame = true;
|
||||
|
||||
+315
-27
@@ -14,31 +14,22 @@
|
||||
*/
|
||||
PIXI.TilingSprite = function(texture, width, height)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.call( this );
|
||||
PIXI.Sprite.call( this, texture);
|
||||
|
||||
/**
|
||||
* The texture that the sprite is using
|
||||
*
|
||||
* @property texture
|
||||
* @type Texture
|
||||
*/
|
||||
this.texture = texture;
|
||||
|
||||
/**
|
||||
* The width of the tiling sprite
|
||||
* The with of the tiling sprite
|
||||
*
|
||||
* @property width
|
||||
* @type Number
|
||||
*/
|
||||
this.width = width;
|
||||
|
||||
this.width = width || 100;
|
||||
/**
|
||||
* The height of the tiling sprite
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
*/
|
||||
this.height = height;
|
||||
this.height = height || 100;
|
||||
|
||||
/**
|
||||
* The scaling of the image that is being tiled
|
||||
@@ -48,6 +39,14 @@ PIXI.TilingSprite = function(texture, width, height)
|
||||
*/
|
||||
this.tileScale = new PIXI.Point(1,1);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @property tileScaleOffset
|
||||
* @type Point
|
||||
*/
|
||||
this.tileScaleOffset = new PIXI.Point(1,1);
|
||||
|
||||
/**
|
||||
* The offset position of the image that is being tiled
|
||||
*
|
||||
@@ -58,31 +57,63 @@ PIXI.TilingSprite = function(texture, width, height)
|
||||
|
||||
this.renderable = true;
|
||||
|
||||
/**
|
||||
* The tint applied to the sprite. This is a hex value
|
||||
*
|
||||
* @property tint
|
||||
* @type Number
|
||||
* @default 0xFFFFFF
|
||||
*/
|
||||
this.tint = 0xFFFFFF;
|
||||
|
||||
/**
|
||||
* The blend mode to be applied to the sprite
|
||||
*
|
||||
* @property blendMode
|
||||
* @type Number
|
||||
* @default PIXI.blendModes.NORMAL;
|
||||
*/
|
||||
this.blendMode = PIXI.blendModes.NORMAL;
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
|
||||
PIXI.TilingSprite.prototype = Object.create( PIXI.Sprite.prototype );
|
||||
PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the texture of the tiling sprite
|
||||
* The width of the sprite, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @method setTexture
|
||||
* @param texture {Texture} The PIXI texture that is displayed by the sprite
|
||||
* @property width
|
||||
* @type Number
|
||||
*/
|
||||
PIXI.TilingSprite.prototype.setTexture = function(texture)
|
||||
{
|
||||
//TODO SET THE TEXTURES
|
||||
//TODO VISIBILITY
|
||||
|
||||
// stop current texture
|
||||
this.texture = texture;
|
||||
this.updateFrame = true;
|
||||
};
|
||||
Object.defineProperty(PIXI.TilingSprite.prototype, 'width', {
|
||||
get: function() {
|
||||
return this._width;
|
||||
},
|
||||
set: function(value) {
|
||||
|
||||
this._width = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* When the texture is updated, this event will fire to update the frame
|
||||
* The height of the TilingSprite, setting this will actually modify the scale to achieve the value set
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
*/
|
||||
Object.defineProperty(PIXI.TilingSprite.prototype, 'height', {
|
||||
get: function() {
|
||||
return this._height;
|
||||
},
|
||||
set: function(value) {
|
||||
this._height = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* When the texture is updated, this event will fire to update the scale and frame
|
||||
*
|
||||
* @method onTextureUpdate
|
||||
* @param event
|
||||
@@ -90,5 +121,262 @@ PIXI.TilingSprite.prototype.setTexture = function(texture)
|
||||
*/
|
||||
PIXI.TilingSprite.prototype.onTextureUpdate = function()
|
||||
{
|
||||
// so if _width is 0 then width was not set..
|
||||
//console.log("HI MUM")
|
||||
|
||||
|
||||
this.updateFrame = true;
|
||||
};
|
||||
|
||||
PIXI.TilingSprite.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
|
||||
if(this.visible === false || this.alpha === 0)return;
|
||||
|
||||
var i,j;
|
||||
|
||||
if(this.mask || this.filters)
|
||||
{
|
||||
if(this.mask)
|
||||
{
|
||||
renderSession.spriteBatch.stop();
|
||||
renderSession.maskManager.pushMask(this.mask, renderSession);
|
||||
renderSession.spriteBatch.start();
|
||||
}
|
||||
|
||||
if(this.filters)
|
||||
{
|
||||
renderSession.spriteBatch.flush();
|
||||
renderSession.filterManager.pushFilter(this._filterBlock);
|
||||
}
|
||||
|
||||
if(!this.tilingTexture)this.generateTilingTexture(true);
|
||||
else renderSession.spriteBatch.renderTilingSprite(this);
|
||||
|
||||
// simple render children!
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
|
||||
renderSession.spriteBatch.stop();
|
||||
|
||||
if(this.filters)renderSession.filterManager.popFilter();
|
||||
if(this.mask)renderSession.maskManager.popMask(renderSession);
|
||||
|
||||
renderSession.spriteBatch.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!this.tilingTexture)this.generateTilingTexture(true);
|
||||
else renderSession.spriteBatch.renderTilingSprite(this);
|
||||
|
||||
// simple render children!
|
||||
for(i=0,j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
PIXI.TilingSprite.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
if(this.visible === false || this.alpha === 0)return;
|
||||
|
||||
var context = renderSession.context;
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.pushMask(this._mask, context);
|
||||
}
|
||||
|
||||
context.globalAlpha = this.worldAlpha;
|
||||
|
||||
|
||||
var transform = this.worldTransform;
|
||||
|
||||
// allow for trimming
|
||||
|
||||
context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
|
||||
|
||||
if(!this.__tilePattern)
|
||||
{
|
||||
this.generateTilingTexture(false);
|
||||
|
||||
if(this.tilingTexture)
|
||||
{
|
||||
this.__tilePattern = context.createPattern(this.tilingTexture.baseTexture.source, 'repeat');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check blend mode
|
||||
if(this.blendMode !== renderSession.currentBlendMode)
|
||||
{
|
||||
renderSession.currentBlendMode = this.blendMode;
|
||||
context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode];
|
||||
}
|
||||
|
||||
context.beginPath();
|
||||
|
||||
var tilePosition = this.tilePosition;
|
||||
var tileScale = this.tileScale;
|
||||
|
||||
tilePosition.x %= this.tilingTexture.baseTexture.width;
|
||||
tilePosition.y %= this.tilingTexture.baseTexture.height;
|
||||
|
||||
// console.log(tileScale.x)
|
||||
// offset
|
||||
context.scale(tileScale.x,tileScale.y);
|
||||
context.translate(tilePosition.x, tilePosition.y);
|
||||
|
||||
context.fillStyle = this.__tilePattern;
|
||||
context.fillRect(-tilePosition.x,-tilePosition.y,this.width / tileScale.x, this.height / tileScale.y);
|
||||
|
||||
context.scale(1/tileScale.x, 1/tileScale.y);
|
||||
context.translate(-tilePosition.x, -tilePosition.y);
|
||||
|
||||
context.closePath();
|
||||
|
||||
if(this._mask)
|
||||
{
|
||||
renderSession.maskManager.popMask(renderSession.context);
|
||||
}
|
||||
};
|
||||
|
||||
PIXI.TilingSprite.prototype.getBounds = function()
|
||||
{
|
||||
|
||||
var width = this._width;
|
||||
var height = this._height;
|
||||
|
||||
var w0 = width * (1-this.anchor.x);
|
||||
var w1 = width * -this.anchor.x;
|
||||
|
||||
var h0 = height * (1-this.anchor.y);
|
||||
var h1 = height * -this.anchor.y;
|
||||
|
||||
var worldTransform = this.worldTransform;
|
||||
|
||||
var a = worldTransform.a;
|
||||
var b = worldTransform.c;
|
||||
var c = worldTransform.b;
|
||||
var d = worldTransform.d;
|
||||
var tx = worldTransform.tx;
|
||||
var ty = worldTransform.ty;
|
||||
|
||||
var x1 = a * w1 + c * h1 + tx;
|
||||
var y1 = d * h1 + b * w1 + ty;
|
||||
|
||||
var x2 = a * w0 + c * h1 + tx;
|
||||
var y2 = d * h1 + b * w0 + ty;
|
||||
|
||||
var x3 = a * w0 + c * h0 + tx;
|
||||
var y3 = d * h0 + b * w0 + ty;
|
||||
|
||||
var x4 = a * w1 + c * h0 + tx;
|
||||
var y4 = d * h0 + b * w1 + ty;
|
||||
|
||||
var maxX = -Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var minX = Infinity;
|
||||
var minY = Infinity;
|
||||
|
||||
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;
|
||||
|
||||
var bounds = this._bounds;
|
||||
|
||||
bounds.x = minX;
|
||||
bounds.width = maxX - minX;
|
||||
|
||||
bounds.y = minY;
|
||||
bounds.height = maxY - minY;
|
||||
|
||||
// store a reference so that if this function gets called again in the render cycle we do not have to recalculate
|
||||
this._currentBounds = bounds;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
|
||||
PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo)
|
||||
{
|
||||
var texture = this.texture;
|
||||
|
||||
if(!texture.baseTexture.hasLoaded)return;
|
||||
|
||||
var baseTexture = texture.baseTexture;
|
||||
var frame = texture.frame;
|
||||
|
||||
var targetWidth, targetHeight;
|
||||
|
||||
// check that the frame is the same size as the base texture.
|
||||
|
||||
var isFrame = frame.width !== baseTexture.width || frame.height !== baseTexture.height;
|
||||
|
||||
this.tilingTexture = texture;
|
||||
|
||||
var newTextureRequired = false;
|
||||
|
||||
if(!forcePowerOfTwo)
|
||||
{
|
||||
if(isFrame)
|
||||
{
|
||||
targetWidth = frame.width;
|
||||
targetHeight = frame.height;
|
||||
|
||||
newTextureRequired = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetWidth = PIXI.getNextPowerOfTwo(texture.frame.width);
|
||||
targetHeight = PIXI.getNextPowerOfTwo(texture.frame.height);
|
||||
|
||||
if(frame.width !== targetWidth && frame.height !== targetHeight)newTextureRequired = true;
|
||||
}
|
||||
|
||||
if(newTextureRequired)
|
||||
{
|
||||
var canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight);
|
||||
|
||||
canvasBuffer.context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
0,
|
||||
0,
|
||||
targetWidth,
|
||||
targetHeight);
|
||||
|
||||
this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
|
||||
|
||||
this.tileScaleOffset.x = frame.width / targetWidth;
|
||||
this.tileScaleOffset.y = frame.height / targetHeight;
|
||||
}
|
||||
|
||||
|
||||
this.tilingTexture.baseTexture._powerOf2 = true;
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the base class for creating a pixi.js filter. Currently only webGL supports filters.
|
||||
* 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
|
||||
@@ -21,15 +21,26 @@ PIXI.AbstractFilter = function(fragmentSrc, uniforms)
|
||||
*/
|
||||
this.passes = [this];
|
||||
|
||||
|
||||
/**
|
||||
* @property shaders
|
||||
* @type Array an array of shaders
|
||||
* @private
|
||||
*/
|
||||
this.shaders = [];
|
||||
|
||||
this.dirty = true;
|
||||
this.padding = 0;
|
||||
|
||||
/**
|
||||
@property uniforms
|
||||
@private
|
||||
* @property uniforms
|
||||
* @type object
|
||||
* @private
|
||||
*/
|
||||
this.uniforms = uniforms || {};
|
||||
|
||||
/**
|
||||
* @property fragmentSrc
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
this.fragmentSrc = fragmentSrc || [];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* The AlphaMaskFilter 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 to offset the x and the g propery of the texture is used to offset the y.
|
||||
* @class AlphaMaskFilter
|
||||
* @contructor
|
||||
* @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
|
||||
*/
|
||||
PIXI.AlphaMaskFilter = function(texture)
|
||||
{
|
||||
PIXI.AbstractFilter.call( this );
|
||||
|
||||
this.passes = [this];
|
||||
texture.baseTexture._powerOf2 = true;
|
||||
|
||||
// set the uniforms
|
||||
//console.log()
|
||||
this.uniforms = {
|
||||
mask: {type: 'sampler2D', value:texture},
|
||||
mapDimensions: {type: '2f', value:{x:1, y:5112}},
|
||||
dimensions: {type: '4fv', value:[0,0,0,0]}
|
||||
};
|
||||
|
||||
if(texture.baseTexture.hasLoaded)
|
||||
{
|
||||
this.uniforms.mask.value.x = texture.width;
|
||||
this.uniforms.mask.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 vec4 vColor;',
|
||||
'uniform sampler2D mask;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform vec2 offset;',
|
||||
'uniform vec4 dimensions;',
|
||||
'uniform vec2 mapDimensions;',
|
||||
|
||||
'void main(void) {',
|
||||
' vec2 mapCords = vTextureCoord.xy;',
|
||||
' mapCords += (dimensions.zw + offset)/ dimensions.xy ;',
|
||||
' mapCords.y *= -1.0;',
|
||||
' mapCords.y += 1.0;',
|
||||
' mapCords *= dimensions.xy / mapDimensions;',
|
||||
|
||||
' vec4 original = texture2D(uSampler, vTextureCoord);',
|
||||
' float maskAlpha = texture2D(mask, mapCords).r;',
|
||||
' original *= maskAlpha;',
|
||||
//' original.rgb *= maskAlpha;',
|
||||
' gl_FragColor = original;',
|
||||
//' gl_FragColor = gl_FragColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
PIXI.AlphaMaskFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
|
||||
PIXI.AlphaMaskFilter.prototype.constructor = PIXI.AlphaMaskFilter;
|
||||
|
||||
PIXI.AlphaMaskFilter.prototype.onTextureLoaded = function()
|
||||
{
|
||||
this.uniforms.mapDimensions.value.x = this.uniforms.mask.value.width;
|
||||
this.uniforms.mapDimensions.value.y = this.uniforms.mask.value.height;
|
||||
|
||||
this.uniforms.mask.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.AlphaMaskFilter.prototype, 'map', {
|
||||
get: function() {
|
||||
return this.uniforms.mask.value;
|
||||
},
|
||||
set: function(value) {
|
||||
this.uniforms.mask.value = value;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', {
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the strength of the blurX property simultaneously
|
||||
* Sets the strength of the blurX property
|
||||
*
|
||||
* @property blurX
|
||||
* @type Number the strength of the blurX
|
||||
@@ -51,7 +51,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', {
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the strength of the blurX property simultaneously
|
||||
* Sets the strength of the blurX property
|
||||
*
|
||||
* @property blurY
|
||||
* @type Number the strength of the blurY
|
||||
|
||||
@@ -16,7 +16,7 @@ PIXI.BlurXFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float blur;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ PIXI.BlurYFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float blur;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
|
||||
@@ -27,14 +27,14 @@ PIXI.ColorMatrixFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float invert;',
|
||||
'uniform mat4 matrix;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;',
|
||||
' gl_FragColor = gl_FragColor * vColor;',
|
||||
// ' gl_FragColor = gl_FragColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* This turns your displayObjects to black and white.
|
||||
* This lowers the color depth of your image by the given amount, producing an image with a smaller palette.
|
||||
* @class ColorStepFilter
|
||||
* @contructor
|
||||
*/
|
||||
@@ -22,14 +22,14 @@ PIXI.ColorStepFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float step;',
|
||||
|
||||
'void main(void) {',
|
||||
' vec4 color = texture2D(uSampler, vTextureCoord);',
|
||||
' color = floor(color * step) / step;',
|
||||
' gl_FragColor = color * vColor;',
|
||||
' gl_FragColor = color;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ PIXI.CrossHatchFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float blur;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ PIXI.DisplacementFilter = function(texture)
|
||||
texture.baseTexture._powerOf2 = true;
|
||||
|
||||
// set the uniforms
|
||||
//console.log()
|
||||
this.uniforms = {
|
||||
displacementMap: {type: 'sampler2D', value:texture},
|
||||
scale: {type: '2f', value:{x:30, y:30}},
|
||||
@@ -42,7 +43,7 @@ PIXI.DisplacementFilter = function(texture)
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D displacementMap;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform vec2 scale;',
|
||||
@@ -66,7 +67,7 @@ PIXI.DisplacementFilter = function(texture)
|
||||
' vec2 cord = vTextureCoord;',
|
||||
|
||||
//' gl_FragColor = texture2D(displacementMap, cord);',
|
||||
' gl_FragColor = gl_FragColor * vColor;',
|
||||
// ' gl_FragColor = gl_FragColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* This filter applies a pixlate effect making display objects appear 'blocky'
|
||||
* @class PixelateFilter
|
||||
* This filter applies a dotscreen effect making display objects appear to be made out of black and white halftone dots like an old printer
|
||||
* @class DotScreenFilter
|
||||
* @contructor
|
||||
*/
|
||||
PIXI.DotScreenFilter = function()
|
||||
@@ -25,7 +25,7 @@ PIXI.DotScreenFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform vec4 dimensions;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@ PIXI.GrayFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float gray;',
|
||||
|
||||
'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), gray);',
|
||||
' gl_FragColor = gl_FragColor * vColor;',
|
||||
// ' gl_FragColor = gl_FragColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ PIXI.InvertFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float invert;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
@@ -30,7 +30,7 @@ PIXI.InvertFilter = function()
|
||||
' 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;',
|
||||
// ' gl_FragColor = gl_FragColor * vColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The NormalMapFilter 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 NormalMapFilter
|
||||
* @contructor
|
||||
* @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
|
||||
*/
|
||||
PIXI.NormalMapFilter = 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: '2f', value:{x:15, y:15}},
|
||||
offset: {type: '2f', value:{x:0, y:0}},
|
||||
mapDimensions: {type: '2f', value:{x:1, y:1}},
|
||||
dimensions: {type: '4f', value:[0,0,0,0]},
|
||||
// LightDir: {type: 'f3', value:[0, 1, 0]},
|
||||
LightPos: {type: '3f', value:[0, 1, 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 vec4 dimensions;",
|
||||
|
||||
"const vec2 Resolution = vec2(1.0,1.0);", //resolution of screen
|
||||
"uniform vec3 LightPos;", //light position, normalized
|
||||
"const vec4 LightColor = vec4(1.0, 1.0, 1.0, 1.0);", //light RGBA -- alpha is intensity
|
||||
"const vec4 AmbientColor = vec4(1.0, 1.0, 1.0, 0.5);", //ambient RGBA -- alpha is intensity
|
||||
"const vec3 Falloff = vec3(0.0, 1.0, 0.2);", //attenuation coefficients
|
||||
|
||||
"uniform vec3 LightDir;",//" = vec3(1.0, 0.0, 1.0);",
|
||||
|
||||
|
||||
"uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
|
||||
|
||||
|
||||
"void main(void) {",
|
||||
"vec2 mapCords = vTextureCoord.xy;",
|
||||
|
||||
"vec4 color = texture2D(uSampler, vTextureCoord.st);",
|
||||
"vec3 nColor = texture2D(displacementMap, vTextureCoord.st).rgb;",
|
||||
|
||||
|
||||
"mapCords *= vec2(dimensions.x/512.0, dimensions.y/512.0);",
|
||||
|
||||
"mapCords.y *= -1.0;",
|
||||
"mapCords.y += 1.0;",
|
||||
|
||||
//RGBA of our diffuse color
|
||||
"vec4 DiffuseColor = texture2D(uSampler, vTextureCoord);",
|
||||
|
||||
//RGB of our normal map
|
||||
"vec3 NormalMap = texture2D(displacementMap, mapCords).rgb;",
|
||||
|
||||
//The delta position of light
|
||||
//"vec3 LightDir = vec3(LightPos.xy - (gl_FragCoord.xy / Resolution.xy), LightPos.z);",
|
||||
"vec3 LightDir = vec3(LightPos.xy - (mapCords.xy), LightPos.z);",
|
||||
//Correct for aspect ratio
|
||||
//"LightDir.x *= Resolution.x / Resolution.y;",
|
||||
|
||||
//Determine distance (used for attenuation) BEFORE we normalize our LightDir
|
||||
"float D = length(LightDir);",
|
||||
|
||||
//normalize our vectors
|
||||
"vec3 N = normalize(NormalMap * 2.0 - 1.0);",
|
||||
"vec3 L = normalize(LightDir);",
|
||||
|
||||
//Pre-multiply light color with intensity
|
||||
//Then perform "N dot L" to determine our diffuse term
|
||||
"vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0);",
|
||||
|
||||
//pre-multiply ambient color with intensity
|
||||
"vec3 Ambient = AmbientColor.rgb * AmbientColor.a;",
|
||||
|
||||
//calculate attenuation
|
||||
"float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D) );",
|
||||
|
||||
//the calculation which brings it all together
|
||||
"vec3 Intensity = Ambient + Diffuse * Attenuation;",
|
||||
"vec3 FinalColor = DiffuseColor.rgb * Intensity;",
|
||||
"gl_FragColor = vColor * vec4(FinalColor, DiffuseColor.a);",
|
||||
//"gl_FragColor = vec4(1.0, 0.0, 0.0, Attenuation);",//vColor * vec4(FinalColor, DiffuseColor.a);",
|
||||
/*
|
||||
// normalise color
|
||||
"vec3 normal = normalize(nColor * 2.0 - 1.0);",
|
||||
|
||||
"vec3 deltaPos = vec3( (light.xy - gl_FragCoord.xy) / resolution.xy, light.z );",
|
||||
|
||||
"float lambert = clamp(dot(normal, lightDir), 0.0, 1.0);",
|
||||
|
||||
"float d = sqrt(dot(deltaPos, deltaPos));",
|
||||
"float att = 1.0 / ( attenuation.x + (attenuation.y*d) + (attenuation.z*d*d) );",
|
||||
|
||||
"vec3 result = (ambientColor * ambientIntensity) + (lightColor.rgb * lambert) * att;",
|
||||
"result *= color.rgb;",
|
||||
|
||||
"gl_FragColor = vec4(result, 1.0);",*/
|
||||
|
||||
|
||||
|
||||
"}"
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void main() {
|
||||
//sample color & normals from our textures
|
||||
vec4 color = texture2D(u_texture, v_texCoords.st);
|
||||
vec3 nColor = texture2D(u_normals, v_texCoords.st).rgb;
|
||||
|
||||
//some bump map programs will need the Y value flipped..
|
||||
nColor.g = yInvert ? 1.0 - nColor.g : nColor.g;
|
||||
|
||||
//this is for debugging purposes, allowing us to lower the intensity of our bump map
|
||||
vec3 nBase = vec3(0.5, 0.5, 1.0);
|
||||
nColor = mix(nBase, nColor, strength);
|
||||
|
||||
//normals need to be converted to [-1.0, 1.0] range and normalized
|
||||
vec3 normal = normalize(nColor * 2.0 - 1.0);
|
||||
|
||||
//here we do a simple distance calculation
|
||||
vec3 deltaPos = vec3( (light.xy - gl_FragCoord.xy) / resolution.xy, light.z );
|
||||
|
||||
vec3 lightDir = normalize(deltaPos);
|
||||
float lambert = useNormals ? clamp(dot(normal, lightDir), 0.0, 1.0) : 1.0;
|
||||
|
||||
//now let's get a nice little falloff
|
||||
float d = sqrt(dot(deltaPos, deltaPos));
|
||||
float att = useShadow ? 1.0 / ( attenuation.x + (attenuation.y*d) + (attenuation.z*d*d) ) : 1.0;
|
||||
|
||||
vec3 result = (ambientColor * ambientIntensity) + (lightColor.rgb * lambert) * att;
|
||||
result *= color.rgb;
|
||||
|
||||
gl_FragColor = v_color * vec4(result, color.a);
|
||||
}
|
||||
*/
|
||||
PIXI.NormalMapFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
|
||||
PIXI.NormalMapFilter.prototype.constructor = PIXI.NormalMapFilter;
|
||||
|
||||
PIXI.NormalMapFilter.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.NormalMapFilter.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.NormalMapFilter.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.NormalMapFilter.prototype, 'offset', {
|
||||
get: function() {
|
||||
return this.uniforms.offset.value;
|
||||
},
|
||||
set: function(value) {
|
||||
this.uniforms.offset.value = value;
|
||||
}
|
||||
});
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* This filter applies a pixlate effect making display objects appear 'blocky'
|
||||
* This filter applies a pixelate effect making display objects appear 'blocky'
|
||||
* @class PixelateFilter
|
||||
* @contructor
|
||||
*/
|
||||
@@ -24,7 +24,7 @@ PIXI.PixelateFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform vec2 testDim;',
|
||||
'uniform vec4 dimensions;',
|
||||
'uniform vec2 pixelSize;',
|
||||
|
||||
@@ -19,7 +19,7 @@ PIXI.RGBSplitFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform vec2 red;',
|
||||
'uniform vec2 green;',
|
||||
'uniform vec2 blue;',
|
||||
|
||||
@@ -22,7 +22,7 @@ PIXI.SepiaFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform float sepia;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
@@ -31,7 +31,7 @@ PIXI.SepiaFilter = function()
|
||||
'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;',
|
||||
// ' gl_FragColor = gl_FragColor * vColor;',
|
||||
'}'
|
||||
];
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* This filter applies a pixlate effect making display objects appear 'blocky'
|
||||
* @class PixelateFilter
|
||||
* This filter applies a twist effect making display objects appear twisted in the given direction
|
||||
* @class TwistFilter
|
||||
* @contructor
|
||||
*/
|
||||
PIXI.TwistFilter = function()
|
||||
@@ -24,7 +24,7 @@ PIXI.TwistFilter = function()
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform vec4 dimensions;',
|
||||
'uniform sampler2D uSampler;',
|
||||
|
||||
|
||||
@@ -70,7 +70,12 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
|
||||
// constructor
|
||||
PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Given a filename, returns its extension, wil
|
||||
*
|
||||
* @method _getDataType
|
||||
* @param str {String} the name of the asset
|
||||
*/
|
||||
PIXI.AssetLoader.prototype._getDataType = function(str)
|
||||
{
|
||||
var test = 'data:';
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The atlas file loader is used to load in Atlas data and parsing it
|
||||
* The atlas file loader is used to load in Atlas data and parse it
|
||||
* When loaded this class will dispatch a 'loaded' event
|
||||
* If load failed this class will dispatch a 'error' event
|
||||
* If loading fails this class will dispatch an 'error' event
|
||||
* @class AtlasLoader
|
||||
* @extends EventTarget
|
||||
* @constructor
|
||||
@@ -25,8 +25,11 @@ PIXI.AtlasLoader = function (url, crossorigin) {
|
||||
// constructor
|
||||
PIXI.AtlasLoader.constructor = PIXI.AtlasLoader;
|
||||
|
||||
/**
|
||||
* This will begin loading the JSON file
|
||||
|
||||
/**
|
||||
* Starts loading the JSON file
|
||||
*
|
||||
* @method load
|
||||
*/
|
||||
PIXI.AtlasLoader.prototype.load = function () {
|
||||
this.ajaxRequest = new PIXI.AjaxRequest();
|
||||
@@ -39,6 +42,7 @@ PIXI.AtlasLoader.prototype.load = function () {
|
||||
|
||||
/**
|
||||
* Invoke when JSON file is loaded
|
||||
* @method onAtlasLoaded
|
||||
* @private
|
||||
*/
|
||||
PIXI.AtlasLoader.prototype.onAtlasLoaded = function () {
|
||||
@@ -156,7 +160,8 @@ PIXI.AtlasLoader.prototype.onAtlasLoaded = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke when json file loaded
|
||||
* Invoke when json file has loaded
|
||||
* @method onLoaded
|
||||
* @private
|
||||
*/
|
||||
PIXI.AtlasLoader.prototype.onLoaded = function () {
|
||||
@@ -174,6 +179,7 @@ PIXI.AtlasLoader.prototype.onLoaded = function () {
|
||||
|
||||
/**
|
||||
* Invoke when error occured
|
||||
* @method onError
|
||||
* @private
|
||||
*/
|
||||
PIXI.AtlasLoader.prototype.onError = function () {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
PIXI.BitmapFontLoader = function(url, crossorigin)
|
||||
{
|
||||
/*
|
||||
* i use texture packer to load the assets..
|
||||
* I use texture packer to load the assets..
|
||||
* http://www.codeandweb.com/texturepacker
|
||||
* make sure to set the format as 'JSON'
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ PIXI.BitmapFontLoader.prototype.constructor = PIXI.BitmapFontLoader;
|
||||
*/
|
||||
PIXI.BitmapFontLoader.prototype.load = function()
|
||||
{
|
||||
this.ajaxRequest = new XMLHttpRequest();
|
||||
this.ajaxRequest = new PIXI.AjaxRequest();
|
||||
var scope = this;
|
||||
this.ajaxRequest.onreadystatechange = function()
|
||||
{
|
||||
@@ -80,7 +80,7 @@ PIXI.BitmapFontLoader.prototype.load = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoked when XML file is loaded, parses the data
|
||||
* Invoked when the XML file is loaded, parses the data
|
||||
*
|
||||
* @method onXMLLoaded
|
||||
* @private
|
||||
@@ -91,36 +91,48 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
|
||||
{
|
||||
if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1)
|
||||
{
|
||||
var textureUrl = this.baseUrl + this.ajaxRequest.responseXML.getElementsByTagName('page')[0].attributes.getNamedItem('file').nodeValue;
|
||||
var responseXML = this.ajaxRequest.responseXML;
|
||||
if(!responseXML || /MSIE 9/i.test(navigator.userAgent) || navigator.isCocoonJS) {
|
||||
if(typeof(window.DOMParser) === 'function') {
|
||||
var domparser = new DOMParser();
|
||||
responseXML = domparser.parseFromString(this.ajaxRequest.responseText, 'text/xml');
|
||||
} else {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = this.ajaxRequest.responseText;
|
||||
responseXML = div;
|
||||
}
|
||||
}
|
||||
|
||||
var textureUrl = this.baseUrl + responseXML.getElementsByTagName('page')[0].getAttribute('file');
|
||||
var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
|
||||
this.texture = image.texture.baseTexture;
|
||||
|
||||
var data = {};
|
||||
var info = this.ajaxRequest.responseXML.getElementsByTagName('info')[0];
|
||||
var common = this.ajaxRequest.responseXML.getElementsByTagName('common')[0];
|
||||
data.font = info.attributes.getNamedItem('face').nodeValue;
|
||||
data.size = parseInt(info.attributes.getNamedItem('size').nodeValue, 10);
|
||||
data.lineHeight = parseInt(common.attributes.getNamedItem('lineHeight').nodeValue, 10);
|
||||
var info = responseXML.getElementsByTagName('info')[0];
|
||||
var common = responseXML.getElementsByTagName('common')[0];
|
||||
data.font = info.getAttribute('face');
|
||||
data.size = parseInt(info.getAttribute('size'), 10);
|
||||
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10);
|
||||
data.chars = {};
|
||||
|
||||
//parse letters
|
||||
var letters = this.ajaxRequest.responseXML.getElementsByTagName('char');
|
||||
var letters = responseXML.getElementsByTagName('char');
|
||||
|
||||
for (var i = 0; i < letters.length; i++)
|
||||
{
|
||||
var charCode = parseInt(letters[i].attributes.getNamedItem('id').nodeValue, 10);
|
||||
var charCode = parseInt(letters[i].getAttribute('id'), 10);
|
||||
|
||||
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)
|
||||
parseInt(letters[i].getAttribute('x'), 10),
|
||||
parseInt(letters[i].getAttribute('y'), 10),
|
||||
parseInt(letters[i].getAttribute('width'), 10),
|
||||
parseInt(letters[i].getAttribute('height'), 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),
|
||||
xOffset: parseInt(letters[i].getAttribute('xoffset'), 10),
|
||||
yOffset: parseInt(letters[i].getAttribute('yoffset'), 10),
|
||||
xAdvance: parseInt(letters[i].getAttribute('xadvance'), 10),
|
||||
kerning: {},
|
||||
texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect)
|
||||
|
||||
@@ -128,12 +140,12 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
|
||||
}
|
||||
|
||||
//parse kernings
|
||||
var kernings = this.ajaxRequest.responseXML.getElementsByTagName('kerning');
|
||||
var kernings = responseXML.getElementsByTagName('kerning');
|
||||
for (i = 0; i < kernings.length; i++)
|
||||
{
|
||||
var first = parseInt(kernings[i].attributes.getNamedItem('first').nodeValue, 10);
|
||||
var second = parseInt(kernings[i].attributes.getNamedItem('second').nodeValue, 10);
|
||||
var amount = parseInt(kernings[i].attributes.getNamedItem('amount').nodeValue, 10);
|
||||
var first = parseInt(kernings[i].getAttribute('first'), 10);
|
||||
var second = parseInt(kernings[i].getAttribute('second'), 10);
|
||||
var amount = parseInt(kernings[i].getAttribute('amount'), 10);
|
||||
|
||||
data.chars[second].kerning[first] = amount;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/**
|
||||
* The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif')
|
||||
* Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
|
||||
* Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId()
|
||||
* When loaded this class will dispatch a 'loaded' event
|
||||
*
|
||||
* @class ImageLoader
|
||||
@@ -73,7 +73,7 @@ PIXI.ImageLoader.prototype.onLoaded = function()
|
||||
*
|
||||
*
|
||||
* @method loadFramedSpriteSheet
|
||||
* @param frameWidth {Number} with of each frame
|
||||
* @param frameWidth {Number} width of each frame
|
||||
* @param frameHeight {Number} height of each frame
|
||||
* @param textureName {String} if given, the frames will be cached in <textureName>-<ord> format
|
||||
*/
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The json file loader is used to load in JSON data and parsing it
|
||||
* The json file loader is used to load in JSON data and parse it
|
||||
* When loaded this class will dispatch a 'loaded' event
|
||||
* If load failed this class will dispatch a 'error' event
|
||||
* If loading fails this class will dispatch an 'error' event
|
||||
*
|
||||
* @class JsonLoader
|
||||
* @uses EventTarget
|
||||
@@ -61,7 +61,7 @@ PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
|
||||
* @method load
|
||||
*/
|
||||
PIXI.JsonLoader.prototype.load = function () {
|
||||
this.ajaxRequest = new PIXI.AjaxRequest();
|
||||
this.ajaxRequest = new PIXI.AjaxRequest(this.crossorigin);
|
||||
var scope = this;
|
||||
this.ajaxRequest.onreadystatechange = function () {
|
||||
scope.onJSONLoaded();
|
||||
@@ -105,11 +105,21 @@ PIXI.JsonLoader.prototype.onJSONLoaded = function () {
|
||||
width: rect.w,
|
||||
height: rect.h
|
||||
});
|
||||
|
||||
// check to see ifthe sprite ha been trimmed..
|
||||
if (frameData[i].trimmed) {
|
||||
//var realSize = frameData[i].spriteSourceSize;
|
||||
PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
|
||||
PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
|
||||
// calculate the offset!
|
||||
|
||||
var texture = PIXI.TextureCache[i];
|
||||
|
||||
texture.trimmed = true;
|
||||
|
||||
var actualSize = frameData[i].sourceSize;
|
||||
var realSize = frameData[i].spriteSourceSize;
|
||||
|
||||
texture.trim.x = realSize.x;
|
||||
texture.trim.y = realSize.y;
|
||||
texture.trim.realWidth = actualSize.w;
|
||||
texture.trim.realHeight = actualSize.h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/**
|
||||
* The Spine loader is used to load in JSON spine data
|
||||
* To generate the data you need to use http://esotericsoftware.com/ and export the "JSON" format
|
||||
* To generate the data you need to use http://esotericsoftware.com/ and export in the "JSON" format
|
||||
* Due to a clash of names You will need to change the extension of the spine file from *.json to *.anim for it to load
|
||||
* See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
|
||||
* You will need to generate a sprite sheet to accompany the spine data
|
||||
@@ -64,26 +64,11 @@ PIXI.SpineLoader.prototype.load = function () {
|
||||
var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
|
||||
jsonLoader.addEventListener("loaded", function (event) {
|
||||
scope.json = event.content.json;
|
||||
scope.onJSONLoaded();
|
||||
scope.onLoaded();
|
||||
});
|
||||
jsonLoader.load();
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke when JSON file is loaded
|
||||
*
|
||||
* @method onJSONLoaded
|
||||
* @private
|
||||
*/
|
||||
PIXI.SpineLoader.prototype.onJSONLoaded = function () {
|
||||
var spineJsonParser = new spine.SkeletonJson();
|
||||
var skeletonData = spineJsonParser.readSkeletonData(this.json);
|
||||
|
||||
PIXI.AnimCache[this.url] = skeletonData;
|
||||
|
||||
this.onLoaded();
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke when JSON file is loaded
|
||||
*
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
/**
|
||||
* The sprite sheet loader is used to load in JSON sprite sheet data
|
||||
* To generate the data you can use http://www.codeandweb.com/texturepacker and publish the 'JSON' format
|
||||
* To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format
|
||||
* There is a free version so thats nice, although the paid version is great value for money.
|
||||
* It is highly recommended to use Sprite sheets (also know as texture atlas') as it means sprite's can be batched and drawn together for highly increased rendering speed.
|
||||
* Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
|
||||
* This loader will also load the image file that the Spritesheet points to as well as the data.
|
||||
* It is highly recommended to use Sprite sheets (also know as a 'texture atlas') as it means sprites can be batched and drawn together for highly increased rendering speed.
|
||||
* Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId()
|
||||
* This loader will load the image file that the Spritesheet points to as well as the data.
|
||||
* When loaded this class will dispatch a 'loaded' event
|
||||
*
|
||||
* @class SpriteSheetLoader
|
||||
@@ -80,47 +80,9 @@ PIXI.SpriteSheetLoader.prototype.load = function () {
|
||||
var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
|
||||
jsonLoader.addEventListener('loaded', function (event) {
|
||||
scope.json = event.content.json;
|
||||
scope.onJSONLoaded();
|
||||
});
|
||||
jsonLoader.load();
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke when JSON file is loaded
|
||||
*
|
||||
* @method onJSONLoaded
|
||||
* @private
|
||||
*/
|
||||
PIXI.SpriteSheetLoader.prototype.onJSONLoaded = function () {
|
||||
var scope = this;
|
||||
var textureUrl = this.baseUrl + this.json.meta.image;
|
||||
var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
|
||||
var frameData = this.json.frames;
|
||||
|
||||
this.texture = image.texture.baseTexture;
|
||||
image.addEventListener('loaded', function () {
|
||||
scope.onLoaded();
|
||||
});
|
||||
|
||||
for (var i in frameData) {
|
||||
var rect = frameData[i].frame;
|
||||
if (rect) {
|
||||
PIXI.TextureCache[i] = new PIXI.Texture(this.texture, {
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
width: rect.w,
|
||||
height: rect.h
|
||||
});
|
||||
if (frameData[i].trimmed) {
|
||||
//var realSize = frameData[i].spriteSourceSize;
|
||||
PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
|
||||
PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
|
||||
// calculate the offset!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image.load();
|
||||
jsonLoader.load();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+406
-76
@@ -5,8 +5,8 @@
|
||||
|
||||
/**
|
||||
* The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
|
||||
* It is important to know that with the webGL renderer only simple polys can be filled at this stage
|
||||
* Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
|
||||
* It is important to know that with the webGL renderer only simple polygons can be filled at this stage
|
||||
* Complex polygons will not be filled. Heres an example of a complex polygon: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
|
||||
*
|
||||
* @class Graphics
|
||||
* @extends DisplayObjectContainer
|
||||
@@ -51,6 +51,25 @@ PIXI.Graphics = function()
|
||||
*/
|
||||
this.graphicsData = [];
|
||||
|
||||
|
||||
/**
|
||||
* The tint applied to the graphic shape. This is a hex value
|
||||
*
|
||||
* @property tint
|
||||
* @type Number
|
||||
* @default 0xFFFFFF
|
||||
*/
|
||||
this.tint = 0xFFFFFF;// * Math.random();
|
||||
|
||||
/**
|
||||
* The blend mode to be applied to the graphic shape
|
||||
*
|
||||
* @property blendMode
|
||||
* @type Number
|
||||
* @default PIXI.blendModes.NORMAL;
|
||||
*/
|
||||
this.blendMode = PIXI.blendModes.NORMAL;
|
||||
|
||||
/**
|
||||
* Current path
|
||||
*
|
||||
@@ -59,6 +78,39 @@ PIXI.Graphics = function()
|
||||
* @private
|
||||
*/
|
||||
this.currentPath = {points:[]};
|
||||
|
||||
/**
|
||||
* WebGL lines ? TODO-Alvin
|
||||
*
|
||||
* @property _webGL
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
this._webGL = [];
|
||||
|
||||
/**
|
||||
* Whether this shape is used as a mask
|
||||
*
|
||||
* @property isMask
|
||||
* @type isMask
|
||||
*/
|
||||
this.isMask = false;
|
||||
|
||||
/**
|
||||
* The bounds of the graphic shape as rectangle object
|
||||
*
|
||||
* @property bounds
|
||||
* @type Rectangle
|
||||
*/
|
||||
this.bounds = null;
|
||||
|
||||
/**
|
||||
* the bound padding TODO-Alvin
|
||||
*
|
||||
* @property bounds
|
||||
* @type Number
|
||||
*/
|
||||
this.boundsPadding = 10;
|
||||
};
|
||||
|
||||
// constructor
|
||||
@@ -66,7 +118,39 @@ PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype )
|
||||
PIXI.Graphics.prototype.constructor = PIXI.Graphics;
|
||||
|
||||
/**
|
||||
* Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
|
||||
* If cacheAsBitmap is true the graphics object will then be rendered as if it was a sprite.
|
||||
* This is useful if your graphics element does not change often as it will speed up the rendering of the object
|
||||
* It is also usful as the graphics object will always be antialiased because it will be rendered using canvas
|
||||
* Not recommended if you are constanly redrawing the graphics element.
|
||||
*
|
||||
* @property cacheAsBitmap
|
||||
* @default false
|
||||
* @type Boolean
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", {
|
||||
get: function() {
|
||||
return this._cacheAsBitmap;
|
||||
},
|
||||
set: function(value) {
|
||||
this._cacheAsBitmap = value;
|
||||
|
||||
if(this._cacheAsBitmap)
|
||||
{
|
||||
this._generateCachedSprite();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.destroyCachedSprite();
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
|
||||
*
|
||||
* @method lineStyle
|
||||
* @param lineWidth {Number} width of the line to draw, will update the object's stored style
|
||||
@@ -91,8 +175,8 @@ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
|
||||
* Moves the current drawing position to (x, y).
|
||||
*
|
||||
* @method moveTo
|
||||
* @param x {Number} the X coord to move to
|
||||
* @param y {Number} the Y coord to move to
|
||||
* @param x {Number} the X coordinate to move to
|
||||
* @param y {Number} the Y coordinate to move to
|
||||
*/
|
||||
PIXI.Graphics.prototype.moveTo = function(x, y)
|
||||
{
|
||||
@@ -111,8 +195,8 @@ PIXI.Graphics.prototype.moveTo = function(x, y)
|
||||
* the current drawing position is then set to (x, y).
|
||||
*
|
||||
* @method lineTo
|
||||
* @param x {Number} the X coord to draw to
|
||||
* @param y {Number} the Y coord to draw to
|
||||
* @param x {Number} the X coordinate to draw to
|
||||
* @param y {Number} the Y coordinate to draw to
|
||||
*/
|
||||
PIXI.Graphics.prototype.lineTo = function(x, y)
|
||||
{
|
||||
@@ -125,11 +209,12 @@ PIXI.Graphics.prototype.lineTo = function(x, y)
|
||||
* (such as lineTo() or drawCircle()) use when drawing.
|
||||
*
|
||||
* @method beginFill
|
||||
* @param color {uint} the color of the fill
|
||||
* @param alpha {Number} the alpha
|
||||
* @param color {Number} the color of the fill
|
||||
* @param alpha {Number} the alpha of the fill
|
||||
*/
|
||||
PIXI.Graphics.prototype.beginFill = function(color, alpha)
|
||||
{
|
||||
|
||||
this.filling = true;
|
||||
this.fillColor = color || 0;
|
||||
this.fillAlpha = (arguments.length < 2) ? 1 : alpha;
|
||||
@@ -171,12 +256,13 @@ PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
|
||||
* Draws a circle.
|
||||
*
|
||||
* @method drawCircle
|
||||
* @param x {Number} The X coord of the center of the circle
|
||||
* @param y {Number} The Y coord of the center of the circle
|
||||
* @param x {Number} The X coordinate of the center of the circle
|
||||
* @param y {Number} The Y coordinate of the center of the circle
|
||||
* @param radius {Number} The radius of the circle
|
||||
*/
|
||||
PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
|
||||
{
|
||||
|
||||
if (!this.currentPath.points.length) this.graphicsData.pop();
|
||||
|
||||
this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
|
||||
@@ -191,13 +277,14 @@ PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
|
||||
* Draws an ellipse.
|
||||
*
|
||||
* @method drawEllipse
|
||||
* @param x {Number}
|
||||
* @param y {Number}
|
||||
* @param width {Number}
|
||||
* @param height {Number}
|
||||
* @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse
|
||||
* @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse
|
||||
* @param width {Number} The width of the ellipse
|
||||
* @param height {Number} The height of the ellipse
|
||||
*/
|
||||
PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height)
|
||||
{
|
||||
|
||||
if (!this.currentPath.points.length) this.graphicsData.pop();
|
||||
|
||||
this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
|
||||
@@ -225,74 +312,317 @@ PIXI.Graphics.prototype.clear = function()
|
||||
this.bounds = null; //new PIXI.Rectangle();
|
||||
};
|
||||
|
||||
|
||||
PIXI.Graphics.prototype.updateFilterBounds = function()
|
||||
/**
|
||||
* Useful function that returns a texture of the graphics object that can then be used to create sprites
|
||||
* This can be quite useful if your geometry is complicated and needs to be reused multiple times.
|
||||
*
|
||||
* @method generateTexture
|
||||
* @return {Texture} a texture of the graphics object
|
||||
*/
|
||||
PIXI.Graphics.prototype.generateTexture = function()
|
||||
{
|
||||
if(!this.bounds)
|
||||
var bounds = this.getBounds();
|
||||
|
||||
var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height);
|
||||
var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
|
||||
|
||||
canvasBuffer.context.translate(-bounds.x,-bounds.y);
|
||||
|
||||
PIXI.CanvasGraphics.renderGraphics(this, canvasBuffer.context);
|
||||
|
||||
return texture;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.Graphics.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
// if the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if(this.visible === false || this.alpha === 0 || this.isMask === true)return;
|
||||
|
||||
if(this._cacheAsBitmap)
|
||||
{
|
||||
var minX = Infinity;
|
||||
var maxX = -Infinity;
|
||||
|
||||
var minY = Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var points, x, y;
|
||||
|
||||
for (var i = 0; i < this.graphicsData.length; i++) {
|
||||
var data = this.graphicsData[i];
|
||||
var type = data.type;
|
||||
var lineWidth = data.lineWidth;
|
||||
|
||||
points = data.points;
|
||||
|
||||
if(type === PIXI.Graphics.RECT)
|
||||
{
|
||||
x = points.x - lineWidth/2;
|
||||
y = points.y - lineWidth/2;
|
||||
var width = points.width + lineWidth;
|
||||
var height = points.height + lineWidth;
|
||||
|
||||
minX = x < minX ? x : minX;
|
||||
maxX = x + width > 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;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.dirty)
|
||||
{
|
||||
this._generateCachedSprite();
|
||||
// we will also need to update the texture on the gpu too!
|
||||
PIXI.updateWebGLTexture(this._cachedSprite.texture.baseTexture, renderSession.gl);
|
||||
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderSession.spriteBatch.stop();
|
||||
|
||||
if(this._mask)renderSession.maskManager.pushMask(this.mask, renderSession);
|
||||
if(this._filters)renderSession.filterManager.pushFilter(this._filterBlock);
|
||||
|
||||
// check blend mode
|
||||
if(this.blendMode !== renderSession.spriteBatch.currentBlendMode)
|
||||
{
|
||||
renderSession.spriteBatch.currentBlendMode = this.blendMode;
|
||||
var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode];
|
||||
renderSession.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
|
||||
}
|
||||
|
||||
PIXI.WebGLGraphics.renderGraphics(this, renderSession);
|
||||
|
||||
// only render if it has children!
|
||||
if(this.children.length)
|
||||
{
|
||||
renderSession.spriteBatch.start();
|
||||
|
||||
// simple render children!
|
||||
for(var i=0, j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderWebGL(renderSession);
|
||||
}
|
||||
|
||||
renderSession.spriteBatch.stop();
|
||||
}
|
||||
|
||||
if(this._filters)renderSession.filterManager.popFilter();
|
||||
if(this._mask)renderSession.maskManager.popMask(renderSession);
|
||||
|
||||
renderSession.drawCount++;
|
||||
|
||||
renderSession.spriteBatch.start();
|
||||
}
|
||||
// console.log(this.bounds);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the object using the Canvas renderer
|
||||
*
|
||||
* @method _renderCanvas
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.Graphics.prototype._renderCanvas = function(renderSession)
|
||||
{
|
||||
// if the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if(this.visible === false || this.alpha === 0 || this.isMask === true)return;
|
||||
|
||||
var context = renderSession.context;
|
||||
var transform = this.worldTransform;
|
||||
|
||||
if(this.blendMode !== renderSession.currentBlendMode)
|
||||
{
|
||||
renderSession.currentBlendMode = this.blendMode;
|
||||
context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode];
|
||||
}
|
||||
|
||||
context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
PIXI.CanvasGraphics.renderGraphics(this, context);
|
||||
|
||||
// simple render children!
|
||||
for(var i=0, j=this.children.length; i<j; i++)
|
||||
{
|
||||
this.children[i]._renderCanvas(renderSession);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the bounds of the graphic shape as a rectangle object
|
||||
*
|
||||
* @method getBounds
|
||||
* @return {Rectangle} the rectangular bounding area
|
||||
*/
|
||||
PIXI.Graphics.prototype.getBounds = function()
|
||||
{
|
||||
if(!this.bounds)this.updateBounds();
|
||||
|
||||
var w0 = this.bounds.x;
|
||||
var w1 = this.bounds.width + this.bounds.x;
|
||||
|
||||
var h0 = this.bounds.y;
|
||||
var h1 = this.bounds.height + this.bounds.y;
|
||||
|
||||
var worldTransform = this.worldTransform;
|
||||
|
||||
var a = worldTransform.a;
|
||||
var b = worldTransform.c;
|
||||
var c = worldTransform.b;
|
||||
var d = worldTransform.d;
|
||||
var tx = worldTransform.tx;
|
||||
var ty = worldTransform.ty;
|
||||
|
||||
var x1 = a * w1 + c * h1 + tx;
|
||||
var y1 = d * h1 + b * w1 + ty;
|
||||
|
||||
var x2 = a * w0 + c * h1 + tx;
|
||||
var y2 = d * h1 + b * w0 + ty;
|
||||
|
||||
var x3 = a * w0 + c * h0 + tx;
|
||||
var y3 = d * h0 + b * w0 + ty;
|
||||
|
||||
var x4 = a * w1 + c * h0 + tx;
|
||||
var y4 = d * h0 + b * w1 + ty;
|
||||
|
||||
var maxX = -Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var minX = Infinity;
|
||||
var minY = Infinity;
|
||||
|
||||
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;
|
||||
|
||||
var bounds = this._bounds;
|
||||
|
||||
bounds.x = minX;
|
||||
bounds.width = maxX - minX;
|
||||
|
||||
bounds.y = minY;
|
||||
bounds.height = maxY - minY;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the bounds of the object
|
||||
*
|
||||
* @method updateBounds
|
||||
*/
|
||||
PIXI.Graphics.prototype.updateBounds = function()
|
||||
{
|
||||
|
||||
var minX = Infinity;
|
||||
var maxX = -Infinity;
|
||||
|
||||
var minY = Infinity;
|
||||
var maxY = -Infinity;
|
||||
|
||||
var points, x, y, w, h;
|
||||
|
||||
for (var i = 0; i < this.graphicsData.length; i++) {
|
||||
var data = this.graphicsData[i];
|
||||
var type = data.type;
|
||||
var lineWidth = data.lineWidth;
|
||||
|
||||
points = data.points;
|
||||
|
||||
if(type === PIXI.Graphics.RECT)
|
||||
{
|
||||
x = points[0] - lineWidth/2;
|
||||
y = points[1] - lineWidth/2;
|
||||
w = points[2] + lineWidth;
|
||||
h = points[3] + lineWidth;
|
||||
|
||||
minX = x < minX ? x : minX;
|
||||
maxX = x + w > maxX ? x + w : maxX;
|
||||
|
||||
minY = y < minY ? x : minY;
|
||||
maxY = y + h > maxY ? y + h : maxY;
|
||||
}
|
||||
else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP)
|
||||
{
|
||||
x = points[0];
|
||||
y = points[1];
|
||||
w = points[2] + lineWidth/2;
|
||||
h = points[3] + lineWidth/2;
|
||||
|
||||
minX = x - w < minX ? x - w : minX;
|
||||
maxX = x + w > maxX ? x + w : maxX;
|
||||
|
||||
minY = y - h < minY ? y - h : minY;
|
||||
maxY = y + h > maxY ? y + h : 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var padding = this.boundsPadding;
|
||||
this.bounds = new PIXI.Rectangle(minX - padding, minY - padding, (maxX - minX) + padding * 2, (maxY - minY) + padding * 2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates the cached sprite that was made using the generate TODO-Alvin
|
||||
*
|
||||
* @method _generateCachedSprite
|
||||
* @private
|
||||
*/
|
||||
PIXI.Graphics.prototype._generateCachedSprite = function()
|
||||
{
|
||||
var bounds = this.getBounds();
|
||||
|
||||
if(!this._cachedSprite)
|
||||
{
|
||||
var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height);
|
||||
var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
|
||||
|
||||
this._cachedSprite = new PIXI.Sprite(texture);
|
||||
this._cachedSprite.buffer = canvasBuffer;
|
||||
|
||||
this._cachedSprite.worldTransform = this.worldTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._cachedSprite.buffer.resize(bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
// leverage the anchor to account for the offset of the element
|
||||
this._cachedSprite.anchor.x = -( bounds.x / bounds.width );
|
||||
this._cachedSprite.anchor.y = -( bounds.y / bounds.height );
|
||||
|
||||
// this._cachedSprite.buffer.context.save();
|
||||
this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y);
|
||||
|
||||
PIXI.CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context);
|
||||
// this._cachedSprite.buffer.context.restore();
|
||||
};
|
||||
|
||||
PIXI.Graphics.prototype.destroyCachedSprite = function()
|
||||
{
|
||||
this._cachedSprite.texture.destroy(true);
|
||||
|
||||
// let the gc collect the unused sprite
|
||||
// TODO could be object pooled!
|
||||
this._cachedSprite = null;
|
||||
};
|
||||
|
||||
|
||||
// SOME TYPES:
|
||||
PIXI.Graphics.POLY = 0;
|
||||
PIXI.Graphics.RECT = 1;
|
||||
|
||||
@@ -20,8 +20,8 @@ PIXI.CanvasGraphics = function()
|
||||
* @static
|
||||
* @private
|
||||
* @method renderGraphics
|
||||
* @param graphics {Graphics}
|
||||
* @param context {Context2D}
|
||||
* @param graphics {Graphics} the actual graphics object to render
|
||||
* @param context {Context2D} the 2d drawing method of the canvas
|
||||
*/
|
||||
PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
|
||||
{
|
||||
@@ -154,8 +154,8 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
|
||||
* @static
|
||||
* @private
|
||||
* @method renderGraphicsMask
|
||||
* @param graphics {Graphics}
|
||||
* @param context {Context2D}
|
||||
* @param graphics {Graphics} the graphics which will be used as a mask
|
||||
* @param context {Context2D} the context 2d method of the canvas
|
||||
*/
|
||||
PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
|
||||
{
|
||||
|
||||
@@ -8,14 +8,72 @@
|
||||
*
|
||||
* @class CanvasRenderer
|
||||
* @constructor
|
||||
* @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 width=800 {Number} the width of the canvas view
|
||||
* @param height=600 {Number} the height of the canvas view
|
||||
* @param [view] {HTMLCanvasElement} the canvas to use as a view, optional
|
||||
* @param [transparent=false] {Boolean} the transparency of the render view, default false
|
||||
*/
|
||||
PIXI.CanvasRenderer = function(width, height, view, transparent)
|
||||
{
|
||||
this.transparent = transparent;
|
||||
PIXI.defaultRenderer = PIXI.defaultRenderer || this;
|
||||
|
||||
this.type = PIXI.CANVAS_RENDERER;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the render view is transparent
|
||||
*
|
||||
* @property transparent
|
||||
* @type Boolean
|
||||
*/
|
||||
this.transparent = !!transparent;
|
||||
|
||||
if(!PIXI.blendModesCanvas)
|
||||
{
|
||||
PIXI.blendModesCanvas = [];
|
||||
|
||||
if(PIXI.canUseNewCanvasBlendModes())
|
||||
{
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK???
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "overlay";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "darken";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "lighten";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "hue";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "color";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity";
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough"
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK???
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "source-over";
|
||||
PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The width of the canvas view
|
||||
@@ -36,33 +94,19 @@ PIXI.CanvasRenderer = function(width, height, view, transparent)
|
||||
this.height = height || 600;
|
||||
|
||||
/**
|
||||
* The canvas element that the everything is drawn to
|
||||
* The canvas element that everything is drawn to
|
||||
*
|
||||
* @property view
|
||||
* @type Canvas
|
||||
* @type HTMLCanvasElement
|
||||
*/
|
||||
this.view = view || document.createElement( 'canvas' );
|
||||
this.view = view || document.createElement( "canvas" );
|
||||
|
||||
/**
|
||||
* The canvas context that the everything is drawn to
|
||||
* The canvas 2d context that everything is drawn with
|
||||
* @property context
|
||||
* @type Canvas 2d Context
|
||||
* @type HTMLCanvasElement 2d Context
|
||||
*/
|
||||
this.context = this.view.getContext( '2d' );
|
||||
|
||||
//some filter variables
|
||||
this.smoothProperty = null;
|
||||
|
||||
if('imageSmoothingEnabled' in this.context)
|
||||
this.smoothProperty = 'imageSmoothingEnabled';
|
||||
else if('webkitImageSmoothingEnabled' in this.context)
|
||||
this.smoothProperty = 'webkitImageSmoothingEnabled';
|
||||
else if('mozImageSmoothingEnabled' in this.context)
|
||||
this.smoothProperty = 'mozImageSmoothingEnabled';
|
||||
else if('oImageSmoothingEnabled' in this.context)
|
||||
this.smoothProperty = 'oImageSmoothingEnabled';
|
||||
|
||||
this.scaleMode = null;
|
||||
this.context = this.view.getContext( "2d", { alpha: this.transparent } );
|
||||
|
||||
this.refresh = true;
|
||||
// hack to enable some hardware acceleration!
|
||||
@@ -71,6 +115,34 @@ PIXI.CanvasRenderer = function(width, height, view, transparent)
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
this.count = 0;
|
||||
|
||||
/**
|
||||
* Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer
|
||||
* @property CanvasMaskManager
|
||||
* @type CanvasMaskManager
|
||||
*/
|
||||
this.maskManager = new PIXI.CanvasMaskManager();
|
||||
|
||||
/**
|
||||
* RenderSession TODO-Alvin
|
||||
* @property renderSession
|
||||
* @type Object
|
||||
*/
|
||||
this.renderSession = {
|
||||
context: this.context,
|
||||
maskManager: this.maskManager,
|
||||
scaleMode: null,
|
||||
smoothProperty: null
|
||||
};
|
||||
|
||||
if("imageSmoothingEnabled" in this.context)
|
||||
this.renderSession.smoothProperty = "imageSmoothingEnabled";
|
||||
else if("webkitImageSmoothingEnabled" in this.context)
|
||||
this.renderSession.smoothProperty = "webkitImageSmoothingEnabled";
|
||||
else if("mozImageSmoothingEnabled" in this.context)
|
||||
this.renderSession.smoothProperty = "mozImageSmoothingEnabled";
|
||||
else if("oImageSmoothingEnabled" in this.context)
|
||||
this.renderSession.smoothProperty = "oImageSmoothingEnabled";
|
||||
};
|
||||
|
||||
// constructor
|
||||
@@ -88,20 +160,34 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
|
||||
//stage.__childrenRemoved = [];
|
||||
|
||||
// update textures if need be
|
||||
PIXI.texturesToUpdate = [];
|
||||
PIXI.texturesToDestroy = [];
|
||||
PIXI.texturesToUpdate.length = 0;
|
||||
PIXI.texturesToDestroy.length = 0;
|
||||
|
||||
PIXI.visibleCount++;
|
||||
stage.updateTransform();
|
||||
|
||||
// update the background color
|
||||
if(this.view.style.backgroundColor !== stage.backgroundColorString && !this.transparent)
|
||||
this.view.style.backgroundColor = stage.backgroundColorString;
|
||||
/* if(this.view.style.backgroundColor !== stage.backgroundColorString && !this.transparent)
|
||||
this.view.style.backgroundColor = stage.backgroundColorString; */
|
||||
|
||||
this.context.setTransform(1,0,0,1,0,0);
|
||||
this.context.clearRect(0, 0, this.width, this.height);
|
||||
|
||||
if(this.view.style.backgroundColor !== stage.backgroundColorString )
|
||||
{
|
||||
if(!this.transparent)
|
||||
{
|
||||
this.context.globalAlpha = 1;
|
||||
this.context.fillStyle = stage.backgroundColorString;
|
||||
this.context.fillRect(0, 0, this.width, this.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.context.clearRect(0, 0, this.width, this.height);
|
||||
}
|
||||
}
|
||||
|
||||
//console.log(this.view.style.backgroundColor)
|
||||
|
||||
this.renderDisplayObject(stage);
|
||||
//as
|
||||
|
||||
// run interaction!
|
||||
if(stage.interactive)
|
||||
@@ -117,12 +203,12 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
|
||||
// remove frame updates..
|
||||
if(PIXI.Texture.frameUpdates.length > 0)
|
||||
{
|
||||
PIXI.Texture.frameUpdates = [];
|
||||
PIXI.Texture.frameUpdates.length = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* resizes the canvas view to the specified width and height
|
||||
* Resizes the canvas view to the specified width and height
|
||||
*
|
||||
* @method resize
|
||||
* @param width {Number} the new width of the canvas view
|
||||
@@ -142,119 +228,17 @@ PIXI.CanvasRenderer.prototype.resize = function(width, height)
|
||||
*
|
||||
* @method renderDisplayObject
|
||||
* @param displayObject {DisplayObject} The displayObject to render
|
||||
* @param context {Context2D} the context 2d method of the canvas
|
||||
* @private
|
||||
*/
|
||||
PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
|
||||
PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context)
|
||||
{
|
||||
// no loger recurrsive!
|
||||
var transform;
|
||||
var context = this.context;
|
||||
// no longer recursive!
|
||||
//var transform;
|
||||
//var context = this.context;
|
||||
|
||||
context.globalCompositeOperation = 'source-over';
|
||||
|
||||
// one the display object hits this. we can break the loop
|
||||
var testObject = displayObject.last._iNext;
|
||||
displayObject = displayObject.first;
|
||||
|
||||
do
|
||||
{
|
||||
transform = displayObject.worldTransform;
|
||||
|
||||
if(!displayObject.visible)
|
||||
{
|
||||
displayObject = displayObject.last._iNext;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!displayObject.renderable)
|
||||
{
|
||||
displayObject = displayObject._iNext;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(displayObject instanceof PIXI.Sprite)
|
||||
{
|
||||
|
||||
var frame = displayObject.texture.frame;
|
||||
|
||||
//ignore null sources
|
||||
if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source)
|
||||
{
|
||||
context.globalAlpha = displayObject.worldAlpha;
|
||||
|
||||
context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
|
||||
|
||||
//if smoothingEnabled is supported and we need to change the smoothing property for this texture
|
||||
if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) {
|
||||
this.scaleMode = displayObject.texture.baseTexture.scaleMode;
|
||||
context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR);
|
||||
}
|
||||
|
||||
context.drawImage(displayObject.texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
(displayObject.anchor.x) * -frame.width,
|
||||
(displayObject.anchor.y) * -frame.height,
|
||||
frame.width,
|
||||
frame.height);
|
||||
}
|
||||
}
|
||||
else if(displayObject instanceof PIXI.Strip)
|
||||
{
|
||||
context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
|
||||
this.renderStrip(displayObject);
|
||||
}
|
||||
else if(displayObject instanceof PIXI.TilingSprite)
|
||||
{
|
||||
context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
|
||||
this.renderTilingSprite(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)
|
||||
{
|
||||
context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
|
||||
PIXI.CanvasGraphics.renderGraphics(displayObject, context);
|
||||
}
|
||||
else if(displayObject instanceof PIXI.FilterBlock)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
//count++
|
||||
displayObject = displayObject._iNext;
|
||||
}
|
||||
while(displayObject !== testObject);
|
||||
this.renderSession.context = context || this.context;
|
||||
displayObject._renderCanvas(this.renderSession);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -286,45 +270,11 @@ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip)
|
||||
context.lineTo(x2, y2);
|
||||
}
|
||||
|
||||
context.fillStyle = '#FF0000';
|
||||
context.fillStyle = "#FF0000";
|
||||
context.fill();
|
||||
context.closePath();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a tiling sprite
|
||||
*
|
||||
* @method renderTilingSprite
|
||||
* @param sprite {TilingSprite} The tilingsprite to render
|
||||
* @private
|
||||
*/
|
||||
PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite)
|
||||
{
|
||||
var context = this.context;
|
||||
|
||||
context.globalAlpha = sprite.worldAlpha;
|
||||
|
||||
if(!sprite.__tilePattern)
|
||||
sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat');
|
||||
|
||||
context.beginPath();
|
||||
|
||||
var tilePosition = sprite.tilePosition;
|
||||
var tileScale = sprite.tileScale;
|
||||
|
||||
// offset
|
||||
context.scale(tileScale.x,tileScale.y);
|
||||
context.translate(tilePosition.x, tilePosition.y);
|
||||
|
||||
context.fillStyle = sprite.__tilePattern;
|
||||
context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y);
|
||||
|
||||
context.scale(1/tileScale.x, 1/tileScale.y);
|
||||
context.translate(-tilePosition.x, -tilePosition.y);
|
||||
|
||||
context.closePath();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a strip
|
||||
*
|
||||
@@ -380,3 +330,51 @@ PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
|
||||
context.restore();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Canvas element of the given size
|
||||
*
|
||||
* @method CanvasBuffer
|
||||
* @param width {Number} the width for the newly created canvas
|
||||
* @param height {Number} the height for the newly created canvas
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
PIXI.CanvasBuffer = function(width, height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.canvas = document.createElement( "canvas" );
|
||||
this.context = this.canvas.getContext( "2d" );
|
||||
|
||||
this.canvas.width = width;
|
||||
this.canvas.height = height;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the canvas that was created by the CanvasBuffer class
|
||||
*
|
||||
* @method clear
|
||||
* @private
|
||||
*/
|
||||
PIXI.CanvasBuffer.prototype.clear = function()
|
||||
{
|
||||
this.context.clearRect(0,0, this.width, this.height);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resizes the canvas that was created by the CanvasBuffer class to the specified width and height
|
||||
*
|
||||
* @method resize
|
||||
* @param width {Number} the new width of the canvas
|
||||
* @param height {Number} the new height of the canvas
|
||||
* @private
|
||||
*/
|
||||
|
||||
PIXI.CanvasBuffer.prototype.resize = function(width, height)
|
||||
{
|
||||
this.width = this.canvas.width = width;
|
||||
this.height = this.canvas.height = height;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @author Mat Groves
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* A set of functions used to handle masking
|
||||
*
|
||||
* @class CanvasMaskManager
|
||||
*/
|
||||
PIXI.CanvasMaskManager = function()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @method pushMask
|
||||
* @param maskData TODO-Alvin
|
||||
* @param context {Context2D} the 2d drawing method of the canvas
|
||||
*/
|
||||
PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, context)
|
||||
{
|
||||
context.save();
|
||||
|
||||
//maskData.visible = false;
|
||||
// maskData.alpha = 0;
|
||||
|
||||
var cacheAlpha = maskData.alpha;
|
||||
var transform = maskData.worldTransform;
|
||||
|
||||
context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
|
||||
|
||||
PIXI.CanvasGraphics.renderGraphicsMask(maskData, context);
|
||||
|
||||
context.clip();
|
||||
|
||||
maskData.worldAlpha = cacheAlpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Restores the current drawing context to the state it was before the mask was applied
|
||||
*
|
||||
* @method popMask
|
||||
* @param context {Context2D} the 2d drawing method of the canvas
|
||||
*/
|
||||
PIXI.CanvasMaskManager.prototype.popMask = function(context)
|
||||
{
|
||||
context.restore();
|
||||
};
|
||||
@@ -0,0 +1,243 @@
|
||||
|
||||
/**
|
||||
* @author Mat Groves
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class CanvasTinter
|
||||
* @constructor
|
||||
* @static
|
||||
*/
|
||||
PIXI.CanvasTinter = function()
|
||||
{
|
||||
/// this.textureCach
|
||||
};
|
||||
|
||||
//PIXI.CanvasTinter.cachTint = true;
|
||||
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
* @method getTintedTexture
|
||||
* @param sprite {Sprite} the sprite to tint
|
||||
* @param color {Number} the color to use to tint the sprite with
|
||||
*/
|
||||
PIXI.CanvasTinter.getTintedTexture = function(sprite, color)
|
||||
{
|
||||
//
|
||||
// cache on sprite
|
||||
// cache on texture
|
||||
// no cache
|
||||
|
||||
var texture = sprite.texture;
|
||||
|
||||
color = PIXI.CanvasTinter.roundColor(color);
|
||||
|
||||
var stringColor = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
|
||||
|
||||
texture.tintCache = texture.tintCache || {};
|
||||
|
||||
if(texture.tintCache[stringColor]) return texture.tintCache[stringColor];
|
||||
|
||||
// clone texture..
|
||||
var canvas = PIXI.CanvasTinter.canvas || document.createElement("canvas");
|
||||
|
||||
//PIXI.CanvasTinter.tintWithPerPixel(texture, stringColor, canvas);
|
||||
|
||||
|
||||
PIXI.CanvasTinter.tintMethod(texture, color, canvas);
|
||||
|
||||
if(PIXI.CanvasTinter.convertTintToImage)
|
||||
{
|
||||
// is this better?
|
||||
var tintImage = new Image();
|
||||
tintImage.src = canvas.toDataURL();
|
||||
|
||||
texture.tintCache[stringColor] = tintImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
texture.tintCache[stringColor] = canvas;
|
||||
// if we are not converting the texture to an image then we need to lose the reference to the canvas
|
||||
PIXI.CanvasTinter.canvas = null;
|
||||
|
||||
}
|
||||
|
||||
return canvas;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tint a texture using the "multiply" operation
|
||||
* @method tintWithMultiply
|
||||
* @param texture {texture} the texture to tint
|
||||
* @param color {Number} the color to use to tint the sprite with
|
||||
* @param canvas {HTMLCanvasElement} the current canvas
|
||||
*/
|
||||
PIXI.CanvasTinter.tintWithMultiply = function(texture, color, canvas)
|
||||
{
|
||||
var context = canvas.getContext( "2d" );
|
||||
|
||||
var frame = texture.frame;
|
||||
|
||||
canvas.width = frame.width;
|
||||
canvas.height = frame.height;
|
||||
|
||||
context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
|
||||
|
||||
context.fillRect(0, 0, frame.width, frame.height);
|
||||
|
||||
context.globalCompositeOperation = "multiply";
|
||||
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
0,
|
||||
0,
|
||||
frame.width,
|
||||
frame.height);
|
||||
|
||||
context.globalCompositeOperation = "destination-atop";
|
||||
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
0,
|
||||
0,
|
||||
frame.width,
|
||||
frame.height);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tint a texture using the "overlay" operation
|
||||
* @method tintWithOverlay
|
||||
* @param texture {texture} the texture to tint
|
||||
* @param color {Number} the color to use to tint the sprite with
|
||||
* @param canvas {HTMLCanvasElement} the current canvas
|
||||
*/
|
||||
PIXI.CanvasTinter.tintWithOverlay = function(texture, color, canvas)
|
||||
{
|
||||
var context = canvas.getContext( "2d" );
|
||||
|
||||
var frame = texture.frame;
|
||||
|
||||
canvas.width = frame.width;
|
||||
canvas.height = frame.height;
|
||||
|
||||
|
||||
|
||||
context.globalCompositeOperation = "copy";
|
||||
context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
|
||||
context.fillRect(0, 0, frame.width, frame.height);
|
||||
|
||||
context.globalCompositeOperation = "destination-atop";
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
0,
|
||||
0,
|
||||
frame.width,
|
||||
frame.height);
|
||||
|
||||
|
||||
//context.globalCompositeOperation = "copy";
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Tint a texture pixel per pixel
|
||||
* @method tintPerPixel
|
||||
* @param texture {texture} the texture to tint
|
||||
* @param color {Number} the color to use to tint the sprite with
|
||||
* @param canvas {HTMLCanvasElement} the current canvas
|
||||
*/
|
||||
PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas)
|
||||
{
|
||||
var context = canvas.getContext( "2d" );
|
||||
|
||||
var frame = texture.frame;
|
||||
|
||||
canvas.width = frame.width;
|
||||
canvas.height = frame.height;
|
||||
|
||||
context.globalCompositeOperation = "copy";
|
||||
context.drawImage(texture.baseTexture.source,
|
||||
frame.x,
|
||||
frame.y,
|
||||
frame.width,
|
||||
frame.height,
|
||||
0,
|
||||
0,
|
||||
frame.width,
|
||||
frame.height);
|
||||
|
||||
var rgbValues = PIXI.hex2rgb(color);
|
||||
var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2];
|
||||
|
||||
var pixelData = context.getImageData(0, 0, frame.width, frame.height);
|
||||
|
||||
var pixels = pixelData.data;
|
||||
|
||||
for (var i = 0; i < pixels.length; i += 4)
|
||||
{
|
||||
pixels[i+0] *= r;
|
||||
pixels[i+1] *= g;
|
||||
pixels[i+2] *= b;
|
||||
}
|
||||
|
||||
context.putImageData(pixelData, 0, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel
|
||||
* @method roundColor
|
||||
* @param color {number} the color to round, should be a hex color
|
||||
*/
|
||||
PIXI.CanvasTinter.roundColor = function(color)
|
||||
{
|
||||
var step = PIXI.CanvasTinter.cacheStepsPerColorChannel;
|
||||
|
||||
var rgbValues = PIXI.hex2rgb(color);
|
||||
|
||||
rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
|
||||
rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
|
||||
rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
|
||||
|
||||
return PIXI.rgb2hex(rgbValues);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Number of steps which will be used as a cap when rounding colors
|
||||
*
|
||||
* @property cacheStepsPerColorChannel
|
||||
* @type Number
|
||||
*/
|
||||
PIXI.CanvasTinter.cacheStepsPerColorChannel = 8;
|
||||
/**
|
||||
*
|
||||
* Number of steps which will be used as a cap when rounding colors
|
||||
*
|
||||
* @property convertTintToImage
|
||||
* @type Boolean
|
||||
*/
|
||||
PIXI.CanvasTinter.convertTintToImage = false;
|
||||
|
||||
/**
|
||||
* Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method
|
||||
*
|
||||
* @property canUseMultiply
|
||||
* @type Boolean
|
||||
*/
|
||||
PIXI.CanvasTinter.canUseMultiply = PIXI.canUseNewCanvasBlendModes();
|
||||
|
||||
PIXI.CanvasTinter.tintMethod = PIXI.CanvasTinter.canUseMultiply ? PIXI.CanvasTinter.tintWithMultiply : PIXI.CanvasTinter.tintWithPerPixel;
|
||||
|
||||
@@ -1,572 +0,0 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
PIXI._batchs = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
PIXI._getBatch = function(gl)
|
||||
{
|
||||
if(PIXI._batchs.length === 0)
|
||||
{
|
||||
return new PIXI.WebGLBatch(gl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PIXI._batchs.pop();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
PIXI._returnBatch = function(batch)
|
||||
{
|
||||
batch.clean();
|
||||
PIXI._batchs.push(batch);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
PIXI._restoreBatchs = function(gl)
|
||||
{
|
||||
for (var i=0; i < PIXI._batchs.length; i++)
|
||||
{
|
||||
PIXI._batchs[i].restoreLostContext(gl);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A WebGLBatch Enables a group of sprites to be drawn using the same settings.
|
||||
* if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
|
||||
* All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
|
||||
* in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
|
||||
* automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
|
||||
* the webGL renderer will run.
|
||||
*
|
||||
* @class WebGLBatch
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} an instance of the webGL context
|
||||
*/
|
||||
PIXI.WebGLBatch = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
|
||||
this.size = 0;
|
||||
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
this.uvBuffer = gl.createBuffer();
|
||||
this.colorBuffer = gl.createBuffer();
|
||||
this.blendMode = PIXI.blendModes.NORMAL;
|
||||
this.dynamicSize = 1;
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch;
|
||||
|
||||
/**
|
||||
* Cleans the batch so that is can be returned to an object pool and reused
|
||||
*
|
||||
* @method clean
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.clean = function()
|
||||
{
|
||||
this.verticies = [];
|
||||
this.uvs = [];
|
||||
this.indices = [];
|
||||
this.colors = [];
|
||||
this.dynamicSize = 1;
|
||||
this.texture = null;
|
||||
this.last = null;
|
||||
this.size = 0;
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recreates the buffers in the event of a context loss
|
||||
*
|
||||
* @method restoreLostContext
|
||||
* @param gl {WebGLContext}
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.restoreLostContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
this.uvBuffer = gl.createBuffer();
|
||||
this.colorBuffer = gl.createBuffer();
|
||||
};
|
||||
|
||||
/**
|
||||
* inits the batch's texture and blend mode based if the supplied sprite
|
||||
*
|
||||
* @method init
|
||||
* @param sprite {Sprite} the first sprite to be added to the batch. Only sprites with
|
||||
* the same base texture and blend mode will be allowed to be added to this batch
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.init = function(sprite)
|
||||
{
|
||||
sprite.batch = this;
|
||||
this.dirty = true;
|
||||
this.blendMode = sprite.blendMode;
|
||||
this.texture = sprite.texture.baseTexture;
|
||||
this.head = sprite;
|
||||
this.tail = sprite;
|
||||
this.size = 1;
|
||||
|
||||
this.growBatch();
|
||||
};
|
||||
|
||||
/**
|
||||
* inserts a sprite before the specified sprite
|
||||
*
|
||||
* @method insertBefore
|
||||
* @param sprite {Sprite} the sprite to be added
|
||||
* @param nextSprite {nextSprite} the first sprite will be inserted before this sprite
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite)
|
||||
{
|
||||
this.size++;
|
||||
|
||||
sprite.batch = this;
|
||||
this.dirty = true;
|
||||
var tempPrev = nextSprite.__prev;
|
||||
nextSprite.__prev = sprite;
|
||||
sprite.__next = nextSprite;
|
||||
|
||||
if(tempPrev)
|
||||
{
|
||||
sprite.__prev = tempPrev;
|
||||
tempPrev.__next = sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.head = sprite;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* inserts a sprite after the specified sprite
|
||||
*
|
||||
* @method insertAfter
|
||||
* @param sprite {Sprite} the sprite to be added
|
||||
* @param previousSprite {Sprite} the first sprite will be inserted after this sprite
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.insertAfter = function(sprite, previousSprite)
|
||||
{
|
||||
this.size++;
|
||||
|
||||
sprite.batch = this;
|
||||
this.dirty = true;
|
||||
|
||||
var tempNext = previousSprite.__next;
|
||||
previousSprite.__next = sprite;
|
||||
sprite.__prev = previousSprite;
|
||||
|
||||
if(tempNext)
|
||||
{
|
||||
sprite.__next = tempNext;
|
||||
tempNext.__prev = sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tail = sprite;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* removes a sprite from the batch
|
||||
*
|
||||
* @method remove
|
||||
* @param sprite {Sprite} the sprite to be removed
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.remove = function(sprite)
|
||||
{
|
||||
this.size--;
|
||||
|
||||
if(this.size === 0)
|
||||
{
|
||||
sprite.batch = null;
|
||||
sprite.__prev = null;
|
||||
sprite.__next = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if(sprite.__prev)
|
||||
{
|
||||
sprite.__prev.__next = sprite.__next;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.head = sprite.__next;
|
||||
this.head.__prev = null;
|
||||
}
|
||||
|
||||
if(sprite.__next)
|
||||
{
|
||||
sprite.__next.__prev = sprite.__prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tail = sprite.__prev;
|
||||
this.tail.__next = null;
|
||||
}
|
||||
|
||||
sprite.batch = null;
|
||||
sprite.__next = null;
|
||||
sprite.__prev = null;
|
||||
this.dirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Splits the batch into two with the specified sprite being the start of the new batch.
|
||||
*
|
||||
* @method split
|
||||
* @param sprite {Sprite} the sprite that indicates where the batch should be split
|
||||
* @return {WebGLBatch} the new batch
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.split = function(sprite)
|
||||
{
|
||||
this.dirty = true;
|
||||
|
||||
var batch = new PIXI.WebGLBatch(this.gl);
|
||||
batch.init(sprite);
|
||||
batch.texture = this.texture;
|
||||
batch.tail = this.tail;
|
||||
|
||||
this.tail = sprite.__prev;
|
||||
this.tail.__next = null;
|
||||
|
||||
sprite.__prev = null;
|
||||
// return a splite batch!
|
||||
|
||||
// TODO this size is wrong!
|
||||
// need to recalculate :/ problem with a linked list!
|
||||
// unless it gets calculated in the "clean"?
|
||||
|
||||
// need to loop through items as there is no way to know the length on a linked list :/
|
||||
var tempSize = 0;
|
||||
while(sprite)
|
||||
{
|
||||
tempSize++;
|
||||
sprite.batch = batch;
|
||||
sprite = sprite.__next;
|
||||
}
|
||||
|
||||
batch.size = tempSize;
|
||||
this.size -= tempSize;
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges two batchs together
|
||||
*
|
||||
* @method merge
|
||||
* @param batch {WebGLBatch} the batch that will be merged
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.merge = function(batch)
|
||||
{
|
||||
this.dirty = true;
|
||||
|
||||
this.tail.__next = batch.head;
|
||||
batch.head.__prev = this.tail;
|
||||
|
||||
this.size += batch.size;
|
||||
|
||||
this.tail = batch.tail;
|
||||
|
||||
var sprite = batch.head;
|
||||
while(sprite)
|
||||
{
|
||||
sprite.batch = this;
|
||||
sprite = sprite.__next;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Grows the size of the batch. As the elements in the batch cannot have a dynamic size this
|
||||
* function is used to increase the size of the batch. It also creates a little extra room so
|
||||
* that the batch does not need to be resized every time a sprite is added
|
||||
*
|
||||
* @method growBatch
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.growBatch = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
if( this.size === 1)
|
||||
{
|
||||
this.dynamicSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dynamicSize = this.size * 1.5;
|
||||
}
|
||||
|
||||
// grow verts
|
||||
this.verticies = new Float32Array(this.dynamicSize * 8);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
|
||||
|
||||
this.uvs = new Float32Array( this.dynamicSize * 8 );
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW);
|
||||
|
||||
this.dirtyUVS = true;
|
||||
|
||||
this.colors = new Float32Array( this.dynamicSize * 4 );
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW);
|
||||
|
||||
this.dirtyColors = true;
|
||||
|
||||
this.indices = new Uint16Array(this.dynamicSize * 6);
|
||||
var length = this.indices.length/6;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var index2 = i * 6;
|
||||
var index3 = i * 4;
|
||||
this.indices[index2 + 0] = index3 + 0;
|
||||
this.indices[index2 + 1] = index3 + 1;
|
||||
this.indices[index2 + 2] = index3 + 2;
|
||||
this.indices[index2 + 3] = index3 + 0;
|
||||
this.indices[index2 + 4] = index3 + 2;
|
||||
this.indices[index2 + 5] = index3 + 3;
|
||||
}
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh's all the data in the batch and sync's it with the webGL buffers
|
||||
*
|
||||
* @method refresh
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.refresh = function()
|
||||
{
|
||||
if (this.dynamicSize < this.size)
|
||||
{
|
||||
this.growBatch();
|
||||
}
|
||||
|
||||
var indexRun = 0;
|
||||
var index, colorIndex;
|
||||
|
||||
var displayObject = this.head;
|
||||
|
||||
while(displayObject)
|
||||
{
|
||||
index = indexRun * 8;
|
||||
|
||||
var texture = displayObject.texture;
|
||||
|
||||
var frame = texture.frame;
|
||||
var tw = texture.baseTexture.width;
|
||||
var th = texture.baseTexture.height;
|
||||
|
||||
this.uvs[index + 0] = frame.x / tw;
|
||||
this.uvs[index +1] = frame.y / th;
|
||||
|
||||
this.uvs[index +2] = (frame.x + frame.width) / tw;
|
||||
this.uvs[index +3] = frame.y / th;
|
||||
|
||||
this.uvs[index +4] = (frame.x + frame.width) / tw;
|
||||
this.uvs[index +5] = (frame.y + frame.height) / th;
|
||||
|
||||
this.uvs[index +6] = frame.x / tw;
|
||||
this.uvs[index +7] = (frame.y + frame.height) / th;
|
||||
|
||||
displayObject.updateFrame = false;
|
||||
|
||||
colorIndex = indexRun * 4;
|
||||
this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
|
||||
|
||||
displayObject = displayObject.__next;
|
||||
|
||||
indexRun++;
|
||||
}
|
||||
|
||||
this.dirtyUVS = true;
|
||||
this.dirtyColors = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates all the relevant geometry and uploads the data to the GPU
|
||||
*
|
||||
* @method update
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.update = function()
|
||||
{
|
||||
var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index;
|
||||
|
||||
var a, b, c, d, tx, ty;
|
||||
|
||||
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)
|
||||
{
|
||||
width = displayObject.texture.frame.width;
|
||||
height = displayObject.texture.frame.height;
|
||||
|
||||
// TODO trim??
|
||||
aX = displayObject.anchor.x;// - displayObject.texture.trim.x
|
||||
aY = displayObject.anchor.y; //- displayObject.texture.trim.y
|
||||
w0 = width * (1-aX);
|
||||
w1 = width * -aX;
|
||||
|
||||
h0 = height * (1-aY);
|
||||
h1 = height * -aY;
|
||||
|
||||
index = indexRun * 8;
|
||||
|
||||
worldTransform = displayObject.worldTransform;
|
||||
|
||||
a = worldTransform[0];
|
||||
b = worldTransform[3];
|
||||
c = worldTransform[1];
|
||||
d = worldTransform[4];
|
||||
tx = worldTransform[2];
|
||||
ty = worldTransform[5];
|
||||
|
||||
verticies[index + 0 ] = a * w1 + c * h1 + tx;
|
||||
verticies[index + 1 ] = d * h1 + b * w1 + ty;
|
||||
|
||||
verticies[index + 2 ] = a * w0 + c * h1 + tx;
|
||||
verticies[index + 3 ] = d * h1 + b * w0 + ty;
|
||||
|
||||
verticies[index + 4 ] = a * w0 + c * h0 + tx;
|
||||
verticies[index + 5 ] = d * h0 + b * w0 + ty;
|
||||
|
||||
verticies[index + 6] = a * w1 + c * h0 + tx;
|
||||
verticies[index + 7] = d * h0 + b * w1 + ty;
|
||||
|
||||
if(displayObject.updateFrame || displayObject.texture.updateFrame)
|
||||
{
|
||||
this.dirtyUVS = true;
|
||||
|
||||
var texture = displayObject.texture;
|
||||
|
||||
var frame = texture.frame;
|
||||
var tw = texture.baseTexture.width;
|
||||
var th = texture.baseTexture.height;
|
||||
|
||||
uvs[index + 0] = frame.x / tw;
|
||||
uvs[index +1] = frame.y / th;
|
||||
|
||||
uvs[index +2] = (frame.x + frame.width) / tw;
|
||||
uvs[index +3] = frame.y / th;
|
||||
|
||||
uvs[index +4] = (frame.x + frame.width) / tw;
|
||||
uvs[index +5] = (frame.y + frame.height) / th;
|
||||
|
||||
uvs[index +6] = frame.x / tw;
|
||||
uvs[index +7] = (frame.y + frame.height) / th;
|
||||
|
||||
displayObject.updateFrame = false;
|
||||
}
|
||||
|
||||
// TODO this probably could do with some optimisation....
|
||||
if(displayObject.cacheAlpha !== displayObject.worldAlpha)
|
||||
{
|
||||
displayObject.cacheAlpha = displayObject.worldAlpha;
|
||||
|
||||
var colorIndex = indexRun * 4;
|
||||
colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
|
||||
this.dirtyColors = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index = indexRun * 8;
|
||||
|
||||
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++;
|
||||
displayObject = displayObject.__next;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws the batch to the frame buffer
|
||||
*
|
||||
* @method render
|
||||
*/
|
||||
PIXI.WebGLBatch.prototype.render = function(start, end)
|
||||
{
|
||||
start = start || 0;
|
||||
|
||||
if(end === undefined)
|
||||
end = this.size;
|
||||
|
||||
if(this.dirty)
|
||||
{
|
||||
this.refresh();
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
if (this.size === 0)return;
|
||||
|
||||
this.update();
|
||||
var gl = this.gl;
|
||||
|
||||
//TODO optimize this!
|
||||
|
||||
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.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)
|
||||
{
|
||||
this.dirtyUVS = false;
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
|
||||
}
|
||||
|
||||
gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
|
||||
|
||||
// update color!
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
|
||||
|
||||
if(this.dirtyColors)
|
||||
{
|
||||
this.dirtyColors = false;
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors);
|
||||
}
|
||||
|
||||
gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
|
||||
// dont need to upload!
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
|
||||
var len = end - start;
|
||||
|
||||
// DRAW THAT this!
|
||||
gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,15 +2,11 @@
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
|
||||
|
||||
// an instance of the gl context..
|
||||
// only one at the moment :/
|
||||
PIXI.gl = null;
|
||||
PIXI.glContexts = []; // this is where we store the webGL contexts for easy access.
|
||||
|
||||
/**
|
||||
* the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
|
||||
* should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
|
||||
* the WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer
|
||||
* should be used for browsers that support webGL. This Render works by automatically managing webGLBatch's.
|
||||
* So no need for Sprite Batch's or Sprite Cloud's
|
||||
* Dont forget to add the view to your DOM or you will not see anything :)
|
||||
*
|
||||
@@ -18,123 +14,150 @@ PIXI.gl = null;
|
||||
* @constructor
|
||||
* @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 view {HTMLCanvasElement} the canvas to use as a view, optional
|
||||
* @param transparent=false {Boolean} If the render view is transparent, default false
|
||||
* @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment)
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
|
||||
{
|
||||
// do a catch.. only 1 webGL renderer..
|
||||
if(!PIXI.defaultRenderer)PIXI.defaultRenderer = this;
|
||||
|
||||
this.type = PIXI.WEBGL_RENDERER;
|
||||
|
||||
// do a catch.. only 1 webGL renderer..
|
||||
/**
|
||||
* Whether the render view is transparent
|
||||
*
|
||||
* @property transparent
|
||||
* @type Boolean
|
||||
*/
|
||||
this.transparent = !!transparent;
|
||||
|
||||
/**
|
||||
* The width of the canvas view
|
||||
*
|
||||
* @property width
|
||||
* @type Number
|
||||
* @default 800
|
||||
*/
|
||||
this.width = width || 800;
|
||||
|
||||
/**
|
||||
* The height of the canvas view
|
||||
*
|
||||
* @property height
|
||||
* @type Number
|
||||
* @default 600
|
||||
*/
|
||||
this.height = height || 600;
|
||||
|
||||
/**
|
||||
* The canvas element that everything is drawn to
|
||||
*
|
||||
* @property view
|
||||
* @type HTMLCanvasElement
|
||||
*/
|
||||
this.view = view || document.createElement( 'canvas' );
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
|
||||
// deal with losing context..
|
||||
var scope = this;
|
||||
this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false);
|
||||
this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false);
|
||||
// TODO-Alvin
|
||||
this.contextLost = this.handleContextLost.bind(this);
|
||||
this.contextRestoredLost = this.handleContextRestored.bind(this);
|
||||
// console.log(this.handleContextRestored)
|
||||
this.view.addEventListener('webglcontextlost', this.contextLost, false);
|
||||
this.view.addEventListener('webglcontextrestored', this.contextRestoredLost, false);
|
||||
|
||||
this.batchs = [];
|
||||
|
||||
var options = {
|
||||
this.options = {
|
||||
alpha: this.transparent,
|
||||
antialias:!!antialias, // SPEED UP??
|
||||
premultipliedAlpha:false,
|
||||
premultipliedAlpha:!!transparent,
|
||||
stencil:true
|
||||
};
|
||||
|
||||
//try 'experimental-webgl'
|
||||
try {
|
||||
PIXI.gl = this.gl = this.view.getContext('experimental-webgl', options);
|
||||
this.gl = this.view.getContext('experimental-webgl', this.options);
|
||||
} catch (e) {
|
||||
//try 'webgl'
|
||||
try {
|
||||
PIXI.gl = this.gl = this.view.getContext('webgl', options);
|
||||
this.gl = this.view.getContext('webgl', this.options);
|
||||
} catch (e2) {
|
||||
// fail, not able to get a context
|
||||
throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this);
|
||||
}
|
||||
}
|
||||
|
||||
PIXI.initDefaultShaders();
|
||||
|
||||
|
||||
|
||||
|
||||
// PIXI.activateDefaultShader();
|
||||
|
||||
var gl = this.gl;
|
||||
this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++;
|
||||
|
||||
gl.useProgram(PIXI.defaultShader.program);
|
||||
PIXI.glContexts[this.glContextId] = gl;
|
||||
|
||||
if(!PIXI.blendModesWebGL)
|
||||
{
|
||||
PIXI.blendModesWebGL = [];
|
||||
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
}
|
||||
|
||||
|
||||
PIXI.WebGLRenderer.gl = gl;
|
||||
|
||||
this.batch = new PIXI.WebGLBatch(gl);
|
||||
|
||||
this.projection = new PIXI.Point();
|
||||
this.projection.x = this.width/2;
|
||||
this.projection.y = -this.height/2;
|
||||
|
||||
this.offset = new PIXI.Point(0, 0);
|
||||
|
||||
this.resize(this.width, this.height);
|
||||
this.contextLost = false;
|
||||
|
||||
// time to create the render managers! each one focuses on managine a state in webGL
|
||||
this.shaderManager = new PIXI.WebGLShaderManager(gl); // deals with managing the shader programs and their attribs
|
||||
this.spriteBatch = new PIXI.WebGLSpriteBatch(gl); // manages the rendering of sprites
|
||||
this.maskManager = new PIXI.WebGLMaskManager(gl); // manages the masks using the stencil buffer
|
||||
this.filterManager = new PIXI.WebGLFilterManager(gl, this.transparent); // manages the filters
|
||||
|
||||
//
|
||||
this.renderSession = {};
|
||||
this.renderSession.gl = this.gl;
|
||||
this.renderSession.drawCount = 0;
|
||||
this.renderSession.shaderManager = this.shaderManager;
|
||||
this.renderSession.maskManager = this.maskManager;
|
||||
this.renderSession.filterManager = this.filterManager;
|
||||
this.renderSession.spriteBatch = this.spriteBatch;
|
||||
|
||||
|
||||
gl.useProgram(this.shaderManager.defaultShader.program);
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.CULL_FACE);
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
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;
|
||||
|
||||
//PIXI.pushShader(PIXI.defaultShader);
|
||||
|
||||
this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent);
|
||||
// this.stageRenderGroup. = this.transparent
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
|
||||
|
||||
/**
|
||||
* Gets a new WebGLBatch from the pool
|
||||
*
|
||||
* @static
|
||||
* @method getBatch
|
||||
* @return {WebGLBatch}
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLRenderer.getBatch = function()
|
||||
{
|
||||
if(PIXI._batchs.length === 0)
|
||||
{
|
||||
return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PIXI._batchs.pop();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Puts a batch back into the pool
|
||||
*
|
||||
* @static
|
||||
* @method returnBatch
|
||||
* @param batch {WebGLBatch} The batch to return
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLRenderer.returnBatch = function(batch)
|
||||
{
|
||||
batch.clean();
|
||||
PIXI._batchs.push(batch);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the stage to its webGL view
|
||||
*
|
||||
@@ -146,44 +169,49 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
|
||||
if(this.contextLost)return;
|
||||
|
||||
|
||||
// if rendering a new stage clear the batchs..
|
||||
// if rendering a new stage clear the batches..
|
||||
if(this.__stage !== stage)
|
||||
{
|
||||
if(stage.interactive)stage.interactionManager.removeEvents();
|
||||
|
||||
// TODO make this work
|
||||
// dont think this is needed any more?
|
||||
this.__stage = stage;
|
||||
this.stageRenderGroup.setRenderable(stage);
|
||||
}
|
||||
|
||||
// update any textures
|
||||
// update any textures this includes uvs and uploading them to the gpu
|
||||
PIXI.WebGLRenderer.updateTextures();
|
||||
|
||||
// update the scene graph
|
||||
PIXI.visibleCount++;
|
||||
stage.updateTransform();
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
// -- Does this need to be set every frame? -- //
|
||||
gl.colorMask(true, true, true, this.transparent);
|
||||
//gl.colorMask(true, true, true, this.transparent);
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
// make sure we are bound to the main frame buffer
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
||||
gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent);
|
||||
if(this.transparent)
|
||||
{
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1);
|
||||
}
|
||||
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// HACK TO TEST
|
||||
// this.projection.x = this.width/2;
|
||||
//this.projection.y = -this.height/2;
|
||||
|
||||
this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit;
|
||||
|
||||
PIXI.projection.x = this.width/2;
|
||||
PIXI.projection.y = -this.height/2;
|
||||
|
||||
this.stageRenderGroup.render(PIXI.projection);
|
||||
this.renderDisplayObject( stage, this.projection );
|
||||
|
||||
// interaction
|
||||
// run interaction!
|
||||
if(stage.interactive)
|
||||
{
|
||||
//need to add some events!
|
||||
@@ -193,17 +221,65 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
|
||||
stage.interactionManager.setTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
// after rendering lets confirm all frames that have been uodated..
|
||||
if(PIXI.Texture.frameUpdates.length > 0)
|
||||
else
|
||||
{
|
||||
for (var i=0; i < PIXI.Texture.frameUpdates.length; i++)
|
||||
if(stage._interactiveEventsAdded)
|
||||
{
|
||||
PIXI.Texture.frameUpdates[i].updateFrame = false;
|
||||
stage._interactiveEventsAdded = false;
|
||||
stage.interactionManager.setTarget(this);
|
||||
}
|
||||
|
||||
PIXI.Texture.frameUpdates = [];
|
||||
}
|
||||
|
||||
/*
|
||||
//can simulate context loss in Chrome like so:
|
||||
this.view.onmousedown = function(ev) {
|
||||
console.dir(this.gl.getSupportedExtensions());
|
||||
var ext = (
|
||||
gl.getExtension("WEBGL_scompressed_texture_s3tc")
|
||||
// gl.getExtension("WEBGL_compressed_texture_s3tc") ||
|
||||
// gl.getExtension("MOZ_WEBGL_compressed_texture_s3tc") ||
|
||||
// gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc")
|
||||
);
|
||||
console.dir(ext);
|
||||
var loseCtx = this.gl.getExtension("WEBGL_lose_context");
|
||||
console.log("killing context");
|
||||
loseCtx.loseContext();
|
||||
setTimeout(function() {
|
||||
console.log("restoring context...");
|
||||
loseCtx.restoreContext();
|
||||
}.bind(this), 1000);
|
||||
}.bind(this);
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a display Object
|
||||
*
|
||||
* @method renderDIsplayObject
|
||||
* @param displayObject {DisplayObject} The DisplayObject to render
|
||||
* @param projection {Point}
|
||||
* @param buffer {Array} buffer TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, projection, buffer)
|
||||
{
|
||||
// reset the render session data..
|
||||
this.renderSession.drawCount = 0;
|
||||
this.renderSession.currentBlendMode = 9999;
|
||||
|
||||
this.renderSession.projection = projection;
|
||||
this.renderSession.offset = this.offset;
|
||||
|
||||
// start the sprite batch
|
||||
this.spriteBatch.begin(this.renderSession);
|
||||
|
||||
// start the filter manager
|
||||
this.filterManager.begin(this.renderSession, buffer);
|
||||
|
||||
// render the scene!
|
||||
displayObject._renderWebGL(this.renderSession);
|
||||
|
||||
// finish the sprite batch
|
||||
this.spriteBatch.end();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -218,58 +294,19 @@ PIXI.WebGLRenderer.updateTextures = function()
|
||||
var i = 0;
|
||||
|
||||
//TODO break this out into a texture manager...
|
||||
for (i = 0; i < PIXI.texturesToUpdate.length; i++)
|
||||
PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]);
|
||||
//for (i = 0; i < PIXI.texturesToUpdate.length; i++)
|
||||
// PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]);
|
||||
|
||||
|
||||
for (i=0; i < PIXI.Texture.frameUpdates.length; i++)
|
||||
PIXI.WebGLRenderer.updateTextureFrame(PIXI.Texture.frameUpdates[i]);
|
||||
|
||||
for (i = 0; i < PIXI.texturesToDestroy.length; i++)
|
||||
PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]);
|
||||
|
||||
PIXI.texturesToUpdate = [];
|
||||
PIXI.texturesToDestroy = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a loaded webgl texture
|
||||
*
|
||||
* @static
|
||||
* @method updateTexture
|
||||
* @param texture {Texture} The texture to update
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLRenderer.updateTexture = function(texture)
|
||||
{
|
||||
//TODO break this out into a texture manager...
|
||||
var gl = PIXI.gl;
|
||||
|
||||
if(!texture._glTexture)
|
||||
{
|
||||
texture._glTexture = gl.createTexture();
|
||||
}
|
||||
|
||||
if(texture.hasLoaded)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
|
||||
// reguler...
|
||||
|
||||
if(!texture._powerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
PIXI.texturesToUpdate.length = 0;
|
||||
PIXI.texturesToDestroy.length = 0;
|
||||
PIXI.Texture.frameUpdates.length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -282,13 +319,35 @@ PIXI.WebGLRenderer.updateTexture = function(texture)
|
||||
PIXI.WebGLRenderer.destroyTexture = function(texture)
|
||||
{
|
||||
//TODO break this out into a texture manager...
|
||||
var gl = PIXI.gl;
|
||||
|
||||
if(texture._glTexture)
|
||||
for (var i = texture._glTextures.length - 1; i >= 0; i--)
|
||||
{
|
||||
texture._glTexture = gl.createTexture();
|
||||
gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture);
|
||||
var glTexture = texture._glTextures[i];
|
||||
var gl = PIXI.glContexts[i];
|
||||
|
||||
if(gl && glTexture)
|
||||
{
|
||||
gl.deleteTexture(glTexture);
|
||||
}
|
||||
}
|
||||
|
||||
texture._glTextures.length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @method updateTextureFrame
|
||||
* @param texture {Texture} The texture to update the frame from
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLRenderer.updateTextureFrame = function(texture)
|
||||
{
|
||||
texture.updateFrame = false;
|
||||
|
||||
// now set the uvs. Figured that the uv data sits with a texture rather than a sprite.
|
||||
// so uv data is stored on the texture itself
|
||||
texture._updateWebGLuvs();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -308,18 +367,87 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height)
|
||||
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
//var projectionMatrix = this.projectionMatrix;
|
||||
this.projection.x = this.width/2;
|
||||
this.projection.y = -this.height/2;
|
||||
};
|
||||
|
||||
PIXI.projection.x = this.width/2;
|
||||
PIXI.projection.y = -this.height/2;
|
||||
/**
|
||||
* Creates a WebGL texture
|
||||
*
|
||||
* @method createWebGLTexture
|
||||
* @param texture {Texture} the texture to render
|
||||
* @param gl {webglContext} the WebGL context
|
||||
* @static
|
||||
*/
|
||||
PIXI.createWebGLTexture = function(texture, gl)
|
||||
{
|
||||
|
||||
//PIXI.size.x = this.width/2;
|
||||
//PIXI.size.y = -this.height/2;
|
||||
|
||||
// projectionMatrix[0] = 2/this.width;
|
||||
// projectionMatrix[5] = -2/this.height;
|
||||
// projectionMatrix[12] = -1;
|
||||
// projectionMatrix[13] = 1;
|
||||
if(texture.hasLoaded)
|
||||
{
|
||||
texture._glTextures[gl.id] = gl.createTexture();
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
|
||||
// reguler...
|
||||
|
||||
if(!texture._powerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
return texture._glTextures[gl.id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a WebGL texture
|
||||
*
|
||||
* @method updateWebGLTexture
|
||||
* @param texture {Texture} the texture to update
|
||||
* @param gl {webglContext} the WebGL context
|
||||
* @private
|
||||
*/
|
||||
PIXI.updateWebGLTexture = function(texture, gl)
|
||||
{
|
||||
if( texture._glTextures[gl.id] )
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
|
||||
// reguler...
|
||||
|
||||
if(!texture._powerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -344,26 +472,91 @@ PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
|
||||
*/
|
||||
PIXI.WebGLRenderer.prototype.handleContextRestored = function()
|
||||
{
|
||||
this.gl = this.view.getContext('experimental-webgl', {
|
||||
alpha: true
|
||||
});
|
||||
|
||||
this.initShaders();
|
||||
//try 'experimental-webgl'
|
||||
try {
|
||||
this.gl = this.view.getContext('experimental-webgl', this.options);
|
||||
} catch (e) {
|
||||
//try 'webgl'
|
||||
try {
|
||||
this.gl = this.view.getContext('webgl', this.options);
|
||||
} catch (e2) {
|
||||
// fail, not able to get a context
|
||||
throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this);
|
||||
}
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
gl.id = PIXI.WebGLRenderer.glContextId ++;
|
||||
|
||||
|
||||
|
||||
// need to set the context...
|
||||
this.shaderManager.setContext(gl);
|
||||
this.spriteBatch.setContext(gl);
|
||||
this.maskManager.setContext(gl);
|
||||
this.filterManager.setContext(gl);
|
||||
|
||||
|
||||
this.renderSession.gl = this.gl;
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.CULL_FACE);
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.colorMask(true, true, true, this.transparent);
|
||||
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
for(var key in PIXI.TextureCache)
|
||||
{
|
||||
var texture = PIXI.TextureCache[key].baseTexture;
|
||||
texture._glTexture = null;
|
||||
PIXI.WebGLRenderer.updateTexture(texture);
|
||||
texture._glTextures = [];
|
||||
}
|
||||
|
||||
for (var i=0; i < this.batchs.length; i++)
|
||||
{
|
||||
this.batchs[i].restoreLostContext(this.gl);
|
||||
this.batchs[i].dirty = true;
|
||||
}
|
||||
|
||||
PIXI._restoreBatchs(this.gl);
|
||||
|
||||
/**
|
||||
* Whether the context was lost
|
||||
* @property contextLost
|
||||
* @type Boolean
|
||||
*/
|
||||
this.contextLost = false;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy TODO-Alvin
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.WebGLRenderer.prototype.destroy = function()
|
||||
{
|
||||
|
||||
// deal with losing context..
|
||||
|
||||
// remove listeners
|
||||
this.view.removeEventListener('webglcontextlost', this.contextLost);
|
||||
this.view.removeEventListener('webglcontextrestored', this.contextRestoredLost);
|
||||
|
||||
PIXI.glContexts[this.glContextId] = null;
|
||||
|
||||
this.projection = null;
|
||||
this.offset = null;
|
||||
|
||||
// time to create the render managers! each one focuses on managine a state in webGL
|
||||
this.shaderManager.destroy();
|
||||
this.spriteBatch.destroy();
|
||||
this.maskManager.destroy();
|
||||
this.filterManager.destroy();
|
||||
|
||||
this.shaderManager = null;
|
||||
this.spriteBatch = null;
|
||||
this.maskManager = null;
|
||||
this.filterManager = null;
|
||||
|
||||
this.gl = null;
|
||||
//
|
||||
this.renderSession = null;
|
||||
};
|
||||
|
||||
|
||||
PIXI.WebGLRenderer.glContextId = 0;
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
PIXI.initDefaultShaders = function()
|
||||
{
|
||||
PIXI.primitiveShader = new PIXI.PrimitiveShader();
|
||||
PIXI.primitiveShader.init();
|
||||
|
||||
PIXI.stripShader = new PIXI.StripShader();
|
||||
PIXI.stripShader.init();
|
||||
|
||||
PIXI.defaultShader = new PIXI.PixiShader();
|
||||
PIXI.defaultShader.init();
|
||||
|
||||
var gl = PIXI.gl;
|
||||
var shaderProgram = PIXI.defaultShader.program;
|
||||
|
||||
gl.useProgram(shaderProgram);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
SHADER COMPILER HELPERS
|
||||
*/
|
||||
|
||||
PIXI.CompileVertexShader = function(gl, shaderSrc)
|
||||
{
|
||||
return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
|
||||
};
|
||||
|
||||
PIXI.CompileFragmentShader = function(gl, shaderSrc)
|
||||
{
|
||||
return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER);
|
||||
};
|
||||
|
||||
PIXI._CompileShader = function(gl, shaderSrc, shaderType)
|
||||
{
|
||||
var src = shaderSrc.join("\n");
|
||||
var shader = gl.createShader(shaderType);
|
||||
gl.shaderSource(shader, src);
|
||||
gl.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
window.console.log(gl.getShaderInfoLog(shader));
|
||||
return null;
|
||||
}
|
||||
|
||||
return shader;
|
||||
};
|
||||
|
||||
PIXI.compileProgram = function(vertexSrc, fragmentSrc)
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc);
|
||||
var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc);
|
||||
|
||||
var shaderProgram = gl.createProgram();
|
||||
|
||||
gl.attachShader(shaderProgram, vertexShader);
|
||||
gl.attachShader(shaderProgram, fragmentShader);
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
||||
window.console.log("Could not initialise shaders");
|
||||
}
|
||||
|
||||
return shaderProgram;
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
* @author Richard Davey http://www.photonstorm.com @photonstorm
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class PIXI.PixiFastShader
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.PixiFastShader = function(gl)
|
||||
{
|
||||
|
||||
/**
|
||||
* @property gl
|
||||
* @type WebGLContext
|
||||
*/
|
||||
this.gl = gl;
|
||||
|
||||
/**
|
||||
* @property {any} program - The WebGL program.
|
||||
*/
|
||||
this.program = null;
|
||||
|
||||
/**
|
||||
* @property {array} fragmentSrc - The fragment shader.
|
||||
*/
|
||||
this.fragmentSrc = [
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
|
||||
'}'
|
||||
];
|
||||
|
||||
/**
|
||||
* @property {array} vertexSrc - The vertex shader
|
||||
*/
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aPositionCoord;',
|
||||
'attribute vec2 aScale;',
|
||||
'attribute float aRotation;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute float aColor;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
'uniform mat3 uMatrix;',
|
||||
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
|
||||
'const vec2 center = vec2(-1.0, 1.0);',
|
||||
|
||||
'void main(void) {',
|
||||
' vec2 v;',
|
||||
' vec2 sv = aVertexPosition * aScale;',
|
||||
' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
|
||||
' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
|
||||
' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
|
||||
' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
// ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
|
||||
' vColor = aColor;',
|
||||
'}'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @property {number} textureCount - A local texture counter for multi-texture shaders.
|
||||
*/
|
||||
this.textureCount = 0;
|
||||
|
||||
|
||||
this.init();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialises the shader
|
||||
* @method init
|
||||
*
|
||||
*/
|
||||
PIXI.PixiFastShader.prototype.init = function()
|
||||
{
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
// get and store the uniforms for the shader
|
||||
this.uSampler = gl.getUniformLocation(program, 'uSampler');
|
||||
|
||||
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
|
||||
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
|
||||
this.dimensions = gl.getUniformLocation(program, 'dimensions');
|
||||
this.uMatrix = gl.getUniformLocation(program, 'uMatrix');
|
||||
|
||||
// get and store the attributes
|
||||
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
|
||||
this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord');
|
||||
|
||||
this.aScale = gl.getAttribLocation(program, 'aScale');
|
||||
this.aRotation = gl.getAttribLocation(program, 'aRotation');
|
||||
|
||||
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
|
||||
|
||||
|
||||
// Begin worst hack eva //
|
||||
|
||||
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
|
||||
// maybe its somthing to do with the current state of the gl context.
|
||||
// Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
|
||||
// If theres any webGL people that know why could happen please help :)
|
||||
if(this.colorAttribute === -1)
|
||||
{
|
||||
this.colorAttribute = 2;
|
||||
}
|
||||
|
||||
this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute];
|
||||
|
||||
// End worst hack eva //
|
||||
|
||||
|
||||
this.program = program;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the shader
|
||||
* @method destroy
|
||||
*
|
||||
*/
|
||||
PIXI.PixiFastShader.prototype.destroy = function()
|
||||
{
|
||||
this.gl.deleteProgram( this.program );
|
||||
this.uniforms = null;
|
||||
this.gl = null;
|
||||
|
||||
this.attributes = null;
|
||||
};
|
||||
+102
-45
@@ -7,8 +7,14 @@
|
||||
* @class PIXI.PixiShader
|
||||
* @constructor
|
||||
*/
|
||||
PIXI.PixiShader = function()
|
||||
PIXI.PixiShader = function(gl)
|
||||
{
|
||||
/**
|
||||
* @property gl
|
||||
* @type WebGLContext
|
||||
*/
|
||||
this.gl = gl;
|
||||
|
||||
/**
|
||||
* @property {any} program - The WebGL program.
|
||||
*/
|
||||
@@ -20,28 +26,36 @@ PIXI.PixiShader = function()
|
||||
this.fragmentSrc = [
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying float vColor;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
|
||||
'}'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @property {number} textureCount - A local texture counter for multi-texture shaders.
|
||||
*/
|
||||
this.textureCount = 0;
|
||||
|
||||
this.attributes = [];
|
||||
|
||||
this.init();
|
||||
};
|
||||
|
||||
/**
|
||||
* @method PIXI.PixiShader#init
|
||||
* Initialises the shader
|
||||
* @method init
|
||||
*
|
||||
*/
|
||||
PIXI.PixiShader.prototype.init = function()
|
||||
{
|
||||
var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc);
|
||||
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.gl;
|
||||
|
||||
var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc);
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
// get and store the uniforms for the shader
|
||||
@@ -52,8 +66,24 @@ PIXI.PixiShader.prototype.init = function()
|
||||
|
||||
// get and store the attributes
|
||||
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
|
||||
|
||||
// Begin worst hack eva //
|
||||
|
||||
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
|
||||
// maybe its something to do with the current state of the gl context.
|
||||
// Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
|
||||
// If theres any webGL people that know why could happen please help :)
|
||||
if(this.colorAttribute === -1)
|
||||
{
|
||||
this.colorAttribute = 2;
|
||||
}
|
||||
|
||||
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute];
|
||||
|
||||
// End worst hack eva //
|
||||
|
||||
// add those custom shaders!
|
||||
for (var key in this.uniforms)
|
||||
@@ -72,12 +102,12 @@ PIXI.PixiShader.prototype.init = function()
|
||||
* Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/
|
||||
* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
|
||||
*
|
||||
* @method PIXI.PixiShader#initUniforms
|
||||
* @method initUniforms
|
||||
*/
|
||||
PIXI.PixiShader.prototype.initUniforms = function()
|
||||
{
|
||||
this.textureCount = 1;
|
||||
|
||||
var gl = this.gl;
|
||||
var uniform;
|
||||
|
||||
for (var key in this.uniforms)
|
||||
@@ -103,21 +133,21 @@ PIXI.PixiShader.prototype.initUniforms = function()
|
||||
|
||||
if (type === 'mat2')
|
||||
{
|
||||
uniform.glFunc = PIXI.gl.uniformMatrix2fv;
|
||||
uniform.glFunc = gl.uniformMatrix2fv;
|
||||
}
|
||||
else if (type === 'mat3')
|
||||
{
|
||||
uniform.glFunc = PIXI.gl.uniformMatrix3fv;
|
||||
uniform.glFunc = gl.uniformMatrix3fv;
|
||||
}
|
||||
else if (type === 'mat4')
|
||||
{
|
||||
uniform.glFunc = PIXI.gl.uniformMatrix4fv;
|
||||
uniform.glFunc = gl.uniformMatrix4fv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// GL function reference
|
||||
uniform.glFunc = PIXI.gl['uniform' + type];
|
||||
uniform.glFunc = gl['uniform' + type];
|
||||
|
||||
if (type === '2f' || type === '2i')
|
||||
{
|
||||
@@ -141,9 +171,9 @@ PIXI.PixiShader.prototype.initUniforms = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture is has loaded)
|
||||
* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded)
|
||||
*
|
||||
* @method PIXI.PixiShader#initSampler2D
|
||||
* @method initSampler2D
|
||||
*/
|
||||
PIXI.PixiShader.prototype.initSampler2D = function(uniform)
|
||||
{
|
||||
@@ -152,8 +182,10 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
|
||||
return;
|
||||
}
|
||||
|
||||
PIXI.gl.activeTexture(PIXI.gl['TEXTURE' + this.textureCount]);
|
||||
PIXI.gl.bindTexture(PIXI.gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
|
||||
var gl = this.gl;
|
||||
|
||||
gl.activeTexture(gl['TEXTURE' + this.textureCount]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
|
||||
|
||||
// Extended texture data
|
||||
if (uniform.textureData)
|
||||
@@ -170,19 +202,19 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
|
||||
// magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST
|
||||
// wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT
|
||||
|
||||
var magFilter = (data.magFilter) ? data.magFilter : PIXI.gl.LINEAR;
|
||||
var minFilter = (data.minFilter) ? data.minFilter : PIXI.gl.LINEAR;
|
||||
var wrapS = (data.wrapS) ? data.wrapS : PIXI.gl.CLAMP_TO_EDGE;
|
||||
var wrapT = (data.wrapT) ? data.wrapT : PIXI.gl.CLAMP_TO_EDGE;
|
||||
var format = (data.luminance) ? PIXI.gl.LUMINANCE : PIXI.gl.RGBA;
|
||||
var magFilter = (data.magFilter) ? data.magFilter : gl.LINEAR;
|
||||
var minFilter = (data.minFilter) ? data.minFilter : gl.LINEAR;
|
||||
var wrapS = (data.wrapS) ? data.wrapS : gl.CLAMP_TO_EDGE;
|
||||
var wrapT = (data.wrapT) ? data.wrapT : gl.CLAMP_TO_EDGE;
|
||||
var format = (data.luminance) ? gl.LUMINANCE : gl.RGBA;
|
||||
|
||||
if (data.repeat)
|
||||
{
|
||||
wrapS = PIXI.gl.REPEAT;
|
||||
wrapT = PIXI.gl.REPEAT;
|
||||
wrapS = gl.REPEAT;
|
||||
wrapT = gl.REPEAT;
|
||||
}
|
||||
|
||||
PIXI.gl.pixelStorei(PIXI.gl.UNPACK_FLIP_Y_WEBGL, false);
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY);
|
||||
|
||||
if (data.width)
|
||||
{
|
||||
@@ -191,21 +223,21 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
|
||||
var border = (data.border) ? data.border : 0;
|
||||
|
||||
// void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
|
||||
PIXI.gl.texImage2D(PIXI.gl.TEXTURE_2D, 0, format, width, height, border, format, PIXI.gl.UNSIGNED_BYTE, null);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels);
|
||||
PIXI.gl.texImage2D(PIXI.gl.TEXTURE_2D, 0, format, PIXI.gl.RGBA, PIXI.gl.UNSIGNED_BYTE, uniform.value.baseTexture.source);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.value.baseTexture.source);
|
||||
}
|
||||
|
||||
PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_MAG_FILTER, magFilter);
|
||||
PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_MIN_FILTER, minFilter);
|
||||
PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_WRAP_S, wrapS);
|
||||
PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_WRAP_T, wrapT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
|
||||
}
|
||||
|
||||
PIXI.gl.uniform1i(uniform.uniformLocation, this.textureCount);
|
||||
gl.uniform1i(uniform.uniformLocation, this.textureCount);
|
||||
|
||||
uniform._init = true;
|
||||
|
||||
@@ -216,12 +248,13 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
|
||||
/**
|
||||
* Updates the shader uniform values.
|
||||
*
|
||||
* @method PIXI.PixiShader#syncUniforms
|
||||
* @method syncUniforms
|
||||
*/
|
||||
PIXI.PixiShader.prototype.syncUniforms = function()
|
||||
{
|
||||
this.textureCount = 1;
|
||||
var uniform;
|
||||
var gl = this.gl;
|
||||
|
||||
// This would probably be faster in an array and it would guarantee key order
|
||||
for (var key in this.uniforms)
|
||||
@@ -233,32 +266,32 @@ PIXI.PixiShader.prototype.syncUniforms = function()
|
||||
{
|
||||
if (uniform.glMatrix === true)
|
||||
{
|
||||
uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.transpose, uniform.value);
|
||||
uniform.glFunc.call(gl, uniform.uniformLocation, uniform.transpose, uniform.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value);
|
||||
uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value);
|
||||
}
|
||||
}
|
||||
else if (uniform.glValueLength === 2)
|
||||
{
|
||||
uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y);
|
||||
uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y);
|
||||
}
|
||||
else if (uniform.glValueLength === 3)
|
||||
{
|
||||
uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z);
|
||||
uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z);
|
||||
}
|
||||
else if (uniform.glValueLength === 4)
|
||||
{
|
||||
uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w);
|
||||
uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w);
|
||||
}
|
||||
else if (uniform.type === 'sampler2D')
|
||||
{
|
||||
if (uniform._init)
|
||||
{
|
||||
PIXI.gl.activeTexture(PIXI.gl['TEXTURE' + this.textureCount]);
|
||||
PIXI.gl.bindTexture(PIXI.gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
|
||||
PIXI.gl.uniform1i(uniform.uniformLocation, this.textureCount);
|
||||
gl.activeTexture(gl['TEXTURE' + this.textureCount]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl));
|
||||
gl.uniform1i(uniform.uniformLocation, this.textureCount);
|
||||
this.textureCount++;
|
||||
}
|
||||
else
|
||||
@@ -270,22 +303,46 @@ PIXI.PixiShader.prototype.syncUniforms = function()
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the shader
|
||||
* @method destroy
|
||||
*
|
||||
*/
|
||||
PIXI.PixiShader.prototype.destroy = function()
|
||||
{
|
||||
this.gl.deleteProgram( this.program );
|
||||
this.uniforms = null;
|
||||
this.gl = null;
|
||||
|
||||
this.attributes = null;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @property defaultVertexSrc
|
||||
* @type String
|
||||
*/
|
||||
PIXI.PixiShader.defaultVertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute float aColor;',
|
||||
'attribute vec2 aColor;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
|
||||
'varying float vColor;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 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;',
|
||||
' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
|
||||
' vColor = vec4(color * aColor.x, aColor.x);',
|
||||
'}'
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
+52
-6
@@ -2,12 +2,28 @@
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
|
||||
PIXI.PrimitiveShader = function()
|
||||
/**
|
||||
* @class PrimitiveShader
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.PrimitiveShader = function(gl)
|
||||
{
|
||||
// the webGL program..
|
||||
/**
|
||||
* @property gl
|
||||
* @type WebGLContext
|
||||
*/
|
||||
this.gl = gl;
|
||||
|
||||
/**
|
||||
* @property {any} program - The WebGL program.
|
||||
*/
|
||||
this.program = null;
|
||||
|
||||
/**
|
||||
* @property fragmentSrc
|
||||
* @type Array
|
||||
*/
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec4 vColor;',
|
||||
@@ -17,6 +33,10 @@ PIXI.PrimitiveShader = function()
|
||||
'}'
|
||||
];
|
||||
|
||||
/**
|
||||
* @property vertexSrc
|
||||
* @type Array
|
||||
*/
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec4 aColor;',
|
||||
@@ -24,35 +44,61 @@ PIXI.PrimitiveShader = function()
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
'uniform float alpha;',
|
||||
'uniform vec3 tint;',
|
||||
'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;',
|
||||
' vColor = aColor * vec4(tint * alpha, alpha);',
|
||||
'}'
|
||||
];
|
||||
|
||||
this.init();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialises the shader
|
||||
* @method init
|
||||
*
|
||||
*/
|
||||
PIXI.PrimitiveShader.prototype.init = function()
|
||||
{
|
||||
var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.gl;
|
||||
|
||||
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
|
||||
gl.useProgram(program);
|
||||
|
||||
// get and store the uniforms for the shader
|
||||
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
|
||||
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
|
||||
this.tintColor = gl.getUniformLocation(program, 'tint');
|
||||
|
||||
|
||||
// get and store the attributes
|
||||
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
|
||||
this.attributes = [this.aVertexPosition, this.colorAttribute];
|
||||
|
||||
this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix');
|
||||
this.alpha = gl.getUniformLocation(program, 'alpha');
|
||||
|
||||
this.program = program;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the shader
|
||||
* @method destroy
|
||||
*
|
||||
*/
|
||||
PIXI.PrimitiveShader.prototype.destroy = function()
|
||||
{
|
||||
this.gl.deleteProgram( this.program );
|
||||
this.uniforms = null;
|
||||
this.gl = null;
|
||||
|
||||
this.attribute = null;
|
||||
};
|
||||
+16
-3
@@ -5,9 +5,14 @@
|
||||
|
||||
PIXI.StripShader = function()
|
||||
{
|
||||
// the webGL program..
|
||||
/**
|
||||
* @property {any} program - The WebGL program.
|
||||
*/
|
||||
this.program = null;
|
||||
|
||||
/**
|
||||
* @property {array} fragmentSrc - The fragment shader.
|
||||
*/
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
@@ -21,14 +26,17 @@ PIXI.StripShader = function()
|
||||
'}'
|
||||
];
|
||||
|
||||
/**
|
||||
* @property {array} fragmentSrc - The fragment shader.
|
||||
*/
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute float aColor;',
|
||||
'uniform mat3 translationMatrix;',
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'uniform vec2 offsetVector;',
|
||||
'varying float vColor;',
|
||||
|
||||
'void main(void) {',
|
||||
@@ -41,12 +49,17 @@ PIXI.StripShader = function()
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialises the shader
|
||||
* @method init
|
||||
*
|
||||
*/
|
||||
PIXI.StripShader.prototype.init = function()
|
||||
{
|
||||
var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
var gl = PIXI.gl;
|
||||
|
||||
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
|
||||
gl.useProgram(program);
|
||||
|
||||
// get and store the uniforms for the shader
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class FilterTexture
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
* @param width {Number} the horizontal range of the filter
|
||||
* @param height {Number} the vertical range of the filter
|
||||
* @private
|
||||
*/
|
||||
PIXI.FilterTexture = function(gl, width, height)
|
||||
{
|
||||
/**
|
||||
* @property gl
|
||||
* @type WebGLContext
|
||||
*/
|
||||
this.gl = 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);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the filter texture
|
||||
* @method clear
|
||||
*/
|
||||
PIXI.FilterTexture.prototype.clear = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
gl.clearColor(0,0,0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resizes the texture to the specified width and height
|
||||
*
|
||||
* @method resize
|
||||
* @param width {Number} the new width of the texture
|
||||
* @param height {Number} the new height of the texture
|
||||
*/
|
||||
PIXI.FilterTexture.prototype.resize = function(width, height)
|
||||
{
|
||||
if(this.width === width && this.height === height) return;
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
var gl = this.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);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the filter texture
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.FilterTexture.prototype.destroy = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
gl.deleteFramebuffer( this.frameBuffer );
|
||||
gl.deleteTexture( this.texture );
|
||||
|
||||
this.frameBuffer = null;
|
||||
this.texture = null;
|
||||
};
|
||||
@@ -0,0 +1,351 @@
|
||||
/**
|
||||
* @author Mat Groves
|
||||
*
|
||||
* Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
|
||||
* for creating the original pixi version!
|
||||
*
|
||||
* Heavily inspired by LibGDX's WebGLSpriteBatch:
|
||||
* https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
|
||||
*/
|
||||
|
||||
PIXI.WebGLFastSpriteBatch = function(gl)
|
||||
{
|
||||
|
||||
|
||||
this.vertSize = 10;
|
||||
this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize;
|
||||
this.size = this.maxSize;
|
||||
|
||||
// console.log(this.size);
|
||||
//the total number of floats in our batch
|
||||
var numVerts = this.size * 4 * this.vertSize;
|
||||
//the total number of indices in our batch
|
||||
var numIndices = this.maxSize * 6;
|
||||
|
||||
//vertex data
|
||||
this.vertices = new Float32Array(numVerts);
|
||||
//index data
|
||||
this.indices = new Uint16Array(numIndices);
|
||||
|
||||
this.vertexBuffer = null;
|
||||
this.indexBuffer = null;
|
||||
|
||||
this.lastIndexCount = 0;
|
||||
|
||||
for (var i=0, j=0; i < numIndices; i += 6, j += 4)
|
||||
{
|
||||
this.indices[i + 0] = j + 0;
|
||||
this.indices[i + 1] = j + 1;
|
||||
this.indices[i + 2] = j + 2;
|
||||
this.indices[i + 3] = j + 0;
|
||||
this.indices[i + 4] = j + 2;
|
||||
this.indices[i + 5] = j + 3;
|
||||
}
|
||||
|
||||
this.drawing = false;
|
||||
this.currentBatchSize = 0;
|
||||
this.currentBaseTexture = null;
|
||||
|
||||
this.currentBlendMode = 0;
|
||||
this.renderSession = null;
|
||||
|
||||
|
||||
this.shader = null;
|
||||
|
||||
this.matrix = null;
|
||||
|
||||
this.setContext(gl);
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
|
||||
// create a couple of buffers
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
|
||||
// 65535 is max index, so 65535 / 6 = 10922.
|
||||
|
||||
|
||||
//upload the index data
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
|
||||
|
||||
this.currentBlendMode = 99999;
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession)
|
||||
{
|
||||
this.renderSession = renderSession;
|
||||
this.shader = this.renderSession.shaderManager.fastShader;
|
||||
|
||||
this.matrix = spriteBatch.worldTransform.toArray(true);
|
||||
|
||||
// console.log(this.tempMatrix)
|
||||
this.start();
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.end = function()
|
||||
{
|
||||
this.flush();
|
||||
};
|
||||
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch)
|
||||
{
|
||||
|
||||
var children = spriteBatch.children;
|
||||
var sprite = children[0];
|
||||
|
||||
// if the uvs have not updated then no point rendering just yet!
|
||||
|
||||
// check texture.
|
||||
if(!sprite.texture._uvs)return;
|
||||
|
||||
this.currentBaseTexture = sprite.texture.baseTexture;
|
||||
// check blend mode
|
||||
if(sprite.blendMode !== this.currentBlendMode)
|
||||
{
|
||||
this.setBlendMode(sprite.blendMode);
|
||||
}
|
||||
|
||||
for(var i=0,j= children.length; i<j; i++)
|
||||
{
|
||||
this.renderSprite(children[i]);
|
||||
}
|
||||
|
||||
this.flush();
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.renderSprite = function(sprite)
|
||||
{
|
||||
//sprite = children[i];
|
||||
|
||||
// TODO trim??
|
||||
if(sprite.texture.baseTexture !== this.currentBaseTexture)
|
||||
{
|
||||
this.currentBaseTexture = sprite.texture.baseTexture;
|
||||
this.flush();
|
||||
|
||||
if(!sprite.texture._uvs)return;
|
||||
}
|
||||
|
||||
var uvs, verticies = this.vertices, width, height, w0, w1, h0, h1, index;
|
||||
|
||||
uvs = sprite.texture._uvs;
|
||||
|
||||
|
||||
width = sprite.texture.frame.width;
|
||||
height = sprite.texture.frame.height;
|
||||
|
||||
if (sprite.texture.trimmed)
|
||||
{
|
||||
// if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..
|
||||
var trim = sprite.texture.trim;
|
||||
|
||||
w1 = trim.x - sprite.anchor.x * trim.realWidth;
|
||||
w0 = w1 + sprite.texture.frame.width;
|
||||
|
||||
h1 = trim.y - sprite.anchor.y * trim.realHeight;
|
||||
h0 = h1 + sprite.texture.frame.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
w0 = (sprite.texture.frame.width ) * (1-sprite.anchor.x);
|
||||
w1 = (sprite.texture.frame.width ) * -sprite.anchor.x;
|
||||
|
||||
h0 = sprite.texture.frame.height * (1-sprite.anchor.y);
|
||||
h1 = sprite.texture.frame.height * -sprite.anchor.y;
|
||||
}
|
||||
|
||||
index = this.currentBatchSize * 4 * this.vertSize;
|
||||
|
||||
// xy
|
||||
verticies[index++] = w1;
|
||||
verticies[index++] = h1;
|
||||
|
||||
verticies[index++] = sprite.position.x;
|
||||
verticies[index++] = sprite.position.y;
|
||||
|
||||
//scale
|
||||
verticies[index++] = sprite.scale.x;
|
||||
verticies[index++] = sprite.scale.y;
|
||||
|
||||
//rotation
|
||||
verticies[index++] = sprite.rotation;
|
||||
|
||||
// uv
|
||||
verticies[index++] = uvs.x0;
|
||||
verticies[index++] = uvs.y1;
|
||||
// color
|
||||
verticies[index++] = sprite.alpha;
|
||||
|
||||
|
||||
// xy
|
||||
verticies[index++] = w0;
|
||||
verticies[index++] = h1;
|
||||
|
||||
verticies[index++] = sprite.position.x;
|
||||
verticies[index++] = sprite.position.y;
|
||||
|
||||
//scale
|
||||
verticies[index++] = sprite.scale.x;
|
||||
verticies[index++] = sprite.scale.y;
|
||||
|
||||
//rotation
|
||||
verticies[index++] = sprite.rotation;
|
||||
|
||||
// uv
|
||||
verticies[index++] = uvs.x1;
|
||||
verticies[index++] = uvs.y1;
|
||||
// color
|
||||
verticies[index++] = sprite.alpha;
|
||||
|
||||
|
||||
// xy
|
||||
verticies[index++] = w0;
|
||||
verticies[index++] = h0;
|
||||
|
||||
verticies[index++] = sprite.position.x;
|
||||
verticies[index++] = sprite.position.y;
|
||||
|
||||
//scale
|
||||
verticies[index++] = sprite.scale.x;
|
||||
verticies[index++] = sprite.scale.y;
|
||||
|
||||
//rotation
|
||||
verticies[index++] = sprite.rotation;
|
||||
|
||||
// uv
|
||||
verticies[index++] = uvs.x2;
|
||||
verticies[index++] = uvs.y2;
|
||||
// color
|
||||
verticies[index++] = sprite.alpha;
|
||||
|
||||
|
||||
|
||||
|
||||
// xy
|
||||
verticies[index++] = w1;
|
||||
verticies[index++] = h0;
|
||||
|
||||
verticies[index++] = sprite.position.x;
|
||||
verticies[index++] = sprite.position.y;
|
||||
|
||||
//scale
|
||||
verticies[index++] = sprite.scale.x;
|
||||
verticies[index++] = sprite.scale.y;
|
||||
|
||||
//rotation
|
||||
verticies[index++] = sprite.rotation;
|
||||
|
||||
// uv
|
||||
verticies[index++] = uvs.x3;
|
||||
verticies[index++] = uvs.y3;
|
||||
// color
|
||||
verticies[index++] = sprite.alpha;
|
||||
|
||||
// increment the batchs
|
||||
this.currentBatchSize++;
|
||||
|
||||
if(this.currentBatchSize >= this.size)
|
||||
{
|
||||
this.flush();
|
||||
}
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.flush = function()
|
||||
{
|
||||
|
||||
// If the batch is length 0 then return as there is nothing to draw
|
||||
if (this.currentBatchSize===0)return;
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
// bind the current texture
|
||||
|
||||
if(!this.currentBaseTexture._glTextures[gl.id])PIXI.createWebGLTexture(this.currentBaseTexture, gl);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]);// || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
|
||||
|
||||
// upload the verts to the buffer
|
||||
|
||||
|
||||
if(this.currentBatchSize > ( this.size * 0.5 ) )
|
||||
{
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
|
||||
}
|
||||
else
|
||||
{
|
||||
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
|
||||
}
|
||||
|
||||
|
||||
// now draw those suckas!
|
||||
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// then reset the batch!
|
||||
this.currentBatchSize = 0;
|
||||
|
||||
// increment the draw count
|
||||
this.renderSession.drawCount++;
|
||||
};
|
||||
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.stop = function()
|
||||
{
|
||||
this.flush();
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.start = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
// bind the main texture
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
// bind the buffers
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
|
||||
// set the projection
|
||||
var projection = this.renderSession.projection;
|
||||
gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
|
||||
|
||||
// set the matrix
|
||||
gl.uniformMatrix3fv(this.shader.uMatrix, false, this.matrix);
|
||||
|
||||
// set the pointers
|
||||
var stride = this.vertSize * 4;
|
||||
|
||||
gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
|
||||
gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4);
|
||||
gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4);
|
||||
gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4);
|
||||
gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4);
|
||||
gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4);
|
||||
|
||||
// set the blend mode..
|
||||
if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
|
||||
{
|
||||
this.setBlendMode(PIXI.blendModes.NORMAL);
|
||||
}
|
||||
};
|
||||
|
||||
PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode)
|
||||
{
|
||||
this.flush();
|
||||
|
||||
this.currentBlendMode = blendMode;
|
||||
|
||||
var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
|
||||
this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
|
||||
};
|
||||
|
||||
|
||||
+144
-175
@@ -2,32 +2,69 @@
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
|
||||
PIXI.WebGLFilterManager = function(transparent)
|
||||
/**
|
||||
* @class WebGLFilterManager
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
* @param transparent {Boolean} Whether or not the drawing context should be transparent
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLFilterManager = function(gl, transparent)
|
||||
{
|
||||
this.transparent = transparent;
|
||||
|
||||
this.filterStack = [];
|
||||
this.texturePool = [];
|
||||
|
||||
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
|
||||
this.setContext(gl);
|
||||
};
|
||||
|
||||
// API
|
||||
/**
|
||||
* Initialises the context and the properties
|
||||
* @method setContext
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.setContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
this.texturePool = [];
|
||||
|
||||
this.initShaderBuffers();
|
||||
};
|
||||
|
||||
// API
|
||||
|
||||
PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer)
|
||||
/**
|
||||
*
|
||||
* @method begin
|
||||
* @param renderSession {RenderSession}
|
||||
* @param buffer {ArrayBuffer}
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.begin = function(renderSession, buffer)
|
||||
{
|
||||
this.renderSession = renderSession;
|
||||
this.defaultShader = renderSession.shaderManager.defaultShader;
|
||||
|
||||
var projection = this.renderSession.projection;
|
||||
|
||||
this.width = projection.x * 2;
|
||||
this.height = -projection.y * 2;
|
||||
this.buffer = buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the filter and adds it to the current filter stack
|
||||
* @method pushFilter
|
||||
* @param filterBlock {Object} TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.gl;
|
||||
|
||||
var projection = this.renderSession.projection;
|
||||
var offset = this.renderSession.offset;
|
||||
|
||||
|
||||
// filter program
|
||||
// OPTIMISATION - the first filter is free if its a simple color change?
|
||||
@@ -41,7 +78,7 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
|
||||
var texture = this.texturePool.pop();
|
||||
if(!texture)
|
||||
{
|
||||
texture = new PIXI.FilterTexture(this.width, this.height);
|
||||
texture = new PIXI.FilterTexture(this.gl, this.width, this.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -50,7 +87,13 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
|
||||
this.getBounds(filterBlock.target);
|
||||
// this.getBounds(filterBlock.target);
|
||||
|
||||
filterBlock.target.filterArea = filterBlock.target.getBounds();
|
||||
// console.log(filterBlock.target.filterArea)
|
||||
// console.log(filterBlock.target.filterArea);
|
||||
// addpadding?
|
||||
//displayObject.filterArea.x
|
||||
|
||||
var filterArea = filterBlock.target.filterArea;
|
||||
|
||||
@@ -69,34 +112,45 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
|
||||
//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;
|
||||
projection.x = filterArea.width/2;
|
||||
projection.y = -filterArea.height/2;
|
||||
|
||||
PIXI.offset.x = -filterArea.x;
|
||||
PIXI.offset.y = -filterArea.y;
|
||||
offset.x = -filterArea.x;
|
||||
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);
|
||||
gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2);
|
||||
gl.uniform2f(this.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")
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the last filter from the filter stack and doesn't return it
|
||||
* @method popFilter
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.gl;
|
||||
var filterBlock = this.filterStack.pop();
|
||||
var filterArea = filterBlock.target.filterArea;
|
||||
var texture = filterBlock._glFilterTexture;
|
||||
var projection = this.renderSession.projection;
|
||||
var offset = this.renderSession.offset;
|
||||
|
||||
if(filterBlock.filterPasses.length > 1)
|
||||
{
|
||||
@@ -119,7 +173,7 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
|
||||
// nnow set the uvs..
|
||||
// now set the uvs..
|
||||
this.uvArray[2] = filterArea.width/this.width;
|
||||
this.uvArray[5] = filterArea.height/this.height;
|
||||
this.uvArray[6] = filterArea.width/this.width;
|
||||
@@ -129,9 +183,9 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
|
||||
var inputTexture = texture;
|
||||
var outputTexture = this.texturePool.pop();
|
||||
if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height);
|
||||
if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height);
|
||||
|
||||
// need to clear this FBO as it may have some left over elements from a prvious filter.
|
||||
// need to clear this FBO as it may have some left over elements from a previous filter.
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
@@ -199,11 +253,11 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
|
||||
|
||||
// TODO need toremove thease global elements..
|
||||
PIXI.projection.x = sizeX/2;
|
||||
PIXI.projection.y = -sizeY/2;
|
||||
projection.x = sizeX/2;
|
||||
projection.y = -sizeY/2;
|
||||
|
||||
PIXI.offset.x = offsetX;
|
||||
PIXI.offset.y = offsetY;
|
||||
offset.x = offsetX;
|
||||
offset.y = offsetY;
|
||||
|
||||
filterArea = filterBlock.target.filterArea;
|
||||
|
||||
@@ -241,6 +295,9 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
// bind the buffer
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, buffer );
|
||||
|
||||
// set the blend mode!
|
||||
//gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
// set texture
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
@@ -250,30 +307,39 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
|
||||
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);
|
||||
gl.useProgram(this.defaultShader.program);
|
||||
gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2);
|
||||
gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY);
|
||||
|
||||
// return the texture to the pool
|
||||
this.texturePool.push(texture);
|
||||
filterBlock._glFilterTexture = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Applies the filter to the specified area
|
||||
* @method applyFilterPass
|
||||
* @param filter {AbstractFilter} the filter that needs to be applied
|
||||
* @param filterArea {texture} TODO - might need an update
|
||||
* @param width {Number} the horizontal range of the filter
|
||||
* @param height {Number} the vertical range of the filter
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height)
|
||||
{
|
||||
// use program
|
||||
var gl = PIXI.gl;
|
||||
var shader = filter.shader;
|
||||
var gl = this.gl;
|
||||
var shader = filter.shaders[gl.id];
|
||||
|
||||
if(!shader)
|
||||
{
|
||||
shader = new PIXI.PixiShader();
|
||||
shader = new PIXI.PixiShader(gl);
|
||||
|
||||
shader.fragmentSrc = filter.fragmentSrc;
|
||||
shader.uniforms = filter.uniforms;
|
||||
shader.init();
|
||||
|
||||
filter.shader = shader;
|
||||
filter.shaders[gl.id] = shader;
|
||||
}
|
||||
|
||||
// set the shader
|
||||
@@ -284,10 +350,12 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea,
|
||||
|
||||
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();
|
||||
@@ -298,23 +366,34 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea,
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
|
||||
gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
|
||||
gl.vertexAttribPointer(shader.colorAttribute, 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 );
|
||||
|
||||
this.renderSession.drawCount++;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialises the shader buffers
|
||||
* @method initShaderBuffers
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.gl;
|
||||
|
||||
// create some buffers
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.uvBuffer = gl.createBuffer();
|
||||
this.colorBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
|
||||
|
||||
// bind and upload the vertexs..
|
||||
// keep a refferance to the vertexFloatData..
|
||||
// keep a reference to the vertexFloatData..
|
||||
this.vertexArray = new Float32Array([0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
0.0, 1.0,
|
||||
@@ -339,6 +418,17 @@ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
|
||||
this.uvArray,
|
||||
gl.STATIC_DRAW);
|
||||
|
||||
this.colorArray = new Float32Array([1.0, 0xFFFFFF,
|
||||
1.0, 0xFFFFFF,
|
||||
1.0, 0xFFFFFF,
|
||||
1.0, 0xFFFFFF]);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
this.colorArray,
|
||||
gl.STATIC_DRAW);
|
||||
|
||||
// bind and upload the index
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
gl.bufferData(
|
||||
@@ -347,150 +437,29 @@ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
|
||||
gl.STATIC_DRAW);
|
||||
};
|
||||
|
||||
PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject)
|
||||
/**
|
||||
* TODO-Alvin
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.WebGLFilterManager.prototype.destroy = function()
|
||||
{
|
||||
// time to get the width and height of the object!
|
||||
var worldTransform, width, height, aX, aY, w0, w1, h0, h1, doTest;
|
||||
var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4;
|
||||
var gl = this.gl;
|
||||
|
||||
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;
|
||||
this.filterStack = null;
|
||||
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
|
||||
// destroy textures
|
||||
for (var i = 0; i < this.texturePool.length; i++) {
|
||||
this.texturePool.destroy();
|
||||
}
|
||||
while(tempObject !== testObject);
|
||||
|
||||
this.texturePool = null;
|
||||
|
||||
displayObject.filterArea.x = minX;
|
||||
displayObject.filterArea.y = minY;
|
||||
|
||||
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)
|
||||
{
|
||||
if(this.width === width && this.height === height) return;
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
//destroy buffers..
|
||||
gl.deleteBuffer(this.vertexBuffer);
|
||||
gl.deleteBuffer(this.uvBuffer);
|
||||
gl.deleteBuffer(this.colorBuffer);
|
||||
gl.deleteBuffer(this.indexBuffer);
|
||||
};
|
||||
+63
-46
@@ -5,7 +5,9 @@
|
||||
/**
|
||||
* A set of functions used by the webGL renderer to draw the primitive graphics data
|
||||
*
|
||||
* @class CanvasGraphics
|
||||
* @class WebGLGraphics
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
PIXI.WebGLGraphics = function()
|
||||
{
|
||||
@@ -19,16 +21,21 @@ PIXI.WebGLGraphics = function()
|
||||
* @private
|
||||
* @method renderGraphics
|
||||
* @param graphics {Graphics}
|
||||
* @param projection {Object}
|
||||
* @param renderSession {Object}
|
||||
*/
|
||||
PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
|
||||
PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projection, offset)
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var gl = renderSession.gl;
|
||||
var projection = renderSession.projection,
|
||||
offset = renderSession.offset,
|
||||
shader = renderSession.shaderManager.primitiveShader;
|
||||
|
||||
if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0,
|
||||
if(!graphics._webGL[gl.id])graphics._webGL[gl.id] = {points:[], indices:[], lastIndex:0,
|
||||
buffer:gl.createBuffer(),
|
||||
indexBuffer:gl.createBuffer()};
|
||||
|
||||
var webGL = graphics._webGL[gl.id];
|
||||
|
||||
if(graphics.dirty)
|
||||
{
|
||||
graphics.dirty = false;
|
||||
@@ -37,43 +44,41 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
|
||||
{
|
||||
graphics.clearDirty = false;
|
||||
|
||||
graphics._webGL.lastIndex = 0;
|
||||
graphics._webGL.points = [];
|
||||
graphics._webGL.indices = [];
|
||||
webGL.lastIndex = 0;
|
||||
webGL.points = [];
|
||||
webGL.indices = [];
|
||||
|
||||
}
|
||||
|
||||
PIXI.WebGLGraphics.updateGraphics(graphics);
|
||||
PIXI.WebGLGraphics.updateGraphics(graphics, gl);
|
||||
}
|
||||
|
||||
PIXI.activatePrimitiveShader();
|
||||
renderSession.shaderManager.activatePrimitiveShader();
|
||||
|
||||
// This could be speeded up fo sure!
|
||||
var m = PIXI.mat3.clone(graphics.worldTransform);
|
||||
// This could be speeded up for sure!
|
||||
|
||||
PIXI.mat3.transpose(m);
|
||||
|
||||
// set the matrix transform for the
|
||||
// set the matrix transform
|
||||
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m);
|
||||
gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true));
|
||||
|
||||
gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y);
|
||||
gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
|
||||
gl.uniform2f(shader.projectionVector, projection.x, -projection.y);
|
||||
gl.uniform2f(shader.offsetVector, -offset.x, -offset.y);
|
||||
|
||||
gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
|
||||
gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint));
|
||||
|
||||
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);
|
||||
gl.uniform1f(shader.alpha, graphics.worldAlpha);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer);
|
||||
|
||||
gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
|
||||
gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
|
||||
|
||||
// set the index buffer!
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer);
|
||||
|
||||
gl.drawElements(gl.TRIANGLE_STRIP, webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
|
||||
|
||||
gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
|
||||
|
||||
PIXI.deactivatePrimitiveShader();
|
||||
renderSession.shaderManager.deactivatePrimitiveShader();
|
||||
|
||||
// return to default shader...
|
||||
// PIXI.activateShader(PIXI.defaultShader);
|
||||
@@ -85,11 +90,14 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
|
||||
* @static
|
||||
* @private
|
||||
* @method updateGraphics
|
||||
* @param graphics {Graphics}
|
||||
* @param graphicsData {Graphics} The graphics object to update
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.WebGLGraphics.updateGraphics = function(graphics)
|
||||
PIXI.WebGLGraphics.updateGraphics = function(graphics, gl)
|
||||
{
|
||||
for (var i = graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++)
|
||||
var webGL = graphics._webGL[gl.id];
|
||||
|
||||
for (var i = webGL.lastIndex; i < graphics.graphicsData.length; i++)
|
||||
{
|
||||
var data = graphics.graphicsData[i];
|
||||
|
||||
@@ -98,37 +106,37 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics)
|
||||
if(data.fill)
|
||||
{
|
||||
if(data.points.length>3)
|
||||
PIXI.WebGLGraphics.buildPoly(data, graphics._webGL);
|
||||
PIXI.WebGLGraphics.buildPoly(data, webGL);
|
||||
}
|
||||
|
||||
if(data.lineWidth > 0)
|
||||
{
|
||||
PIXI.WebGLGraphics.buildLine(data, graphics._webGL);
|
||||
PIXI.WebGLGraphics.buildLine(data, webGL);
|
||||
}
|
||||
}
|
||||
else if(data.type === PIXI.Graphics.RECT)
|
||||
{
|
||||
PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL);
|
||||
PIXI.WebGLGraphics.buildRectangle(data, webGL);
|
||||
}
|
||||
else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP)
|
||||
{
|
||||
PIXI.WebGLGraphics.buildCircle(data, graphics._webGL);
|
||||
PIXI.WebGLGraphics.buildCircle(data, webGL);
|
||||
}
|
||||
}
|
||||
|
||||
graphics._webGL.lastIndex = graphics.graphicsData.length;
|
||||
webGL.lastIndex = graphics.graphicsData.length;
|
||||
|
||||
var gl = PIXI.gl;
|
||||
|
||||
|
||||
graphics._webGL.glPoints = new Float32Array(graphics._webGL.points);
|
||||
webGL.glPoints = new Float32Array(webGL.points);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, webGL.glPoints, gl.STATIC_DRAW);
|
||||
|
||||
graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices);
|
||||
webGL.glIndicies = new Uint16Array(webGL.indices);
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.glIndicies, gl.STATIC_DRAW);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, webGL.glIndicies, gl.STATIC_DRAW);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -137,7 +145,7 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics)
|
||||
* @static
|
||||
* @private
|
||||
* @method buildRectangle
|
||||
* @param graphics {Graphics}
|
||||
* @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
|
||||
* @param webGLData {Object}
|
||||
*/
|
||||
PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
|
||||
@@ -185,13 +193,18 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
|
||||
|
||||
if(graphicsData.lineWidth)
|
||||
{
|
||||
var tempPoints = graphicsData.points;
|
||||
|
||||
graphicsData.points = [x, y,
|
||||
x + width, y,
|
||||
x + width, y + height,
|
||||
x, y + height,
|
||||
x, y];
|
||||
|
||||
|
||||
PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
|
||||
|
||||
graphicsData.points = tempPoints;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,7 +214,7 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
|
||||
* @static
|
||||
* @private
|
||||
* @method buildCircle
|
||||
* @param graphics {Graphics}
|
||||
* @param graphicsData {Graphics} The graphics object to draw
|
||||
* @param webGLData {Object}
|
||||
*/
|
||||
PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
|
||||
@@ -252,6 +265,8 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
|
||||
|
||||
if(graphicsData.lineWidth)
|
||||
{
|
||||
var tempPoints = graphicsData.points;
|
||||
|
||||
graphicsData.points = [];
|
||||
|
||||
for (i = 0; i < totalSegs + 1; i++)
|
||||
@@ -261,6 +276,8 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
|
||||
}
|
||||
|
||||
PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
|
||||
|
||||
graphicsData.points = tempPoints;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -270,7 +287,7 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
|
||||
* @static
|
||||
* @private
|
||||
* @method buildLine
|
||||
* @param graphics {Graphics}
|
||||
* @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
|
||||
* @param webGLData {Object}
|
||||
*/
|
||||
PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
|
||||
@@ -293,7 +310,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
|
||||
var firstPoint = new PIXI.Point( points[0], points[1] );
|
||||
var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] );
|
||||
|
||||
// if the first point is the last point - goona have issues :)
|
||||
// if the first point is the last point - gonna have issues :)
|
||||
if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y)
|
||||
{
|
||||
points.pop();
|
||||
@@ -480,7 +497,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
|
||||
* @static
|
||||
* @private
|
||||
* @method buildPoly
|
||||
* @param graphics {Graphics}
|
||||
* @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
|
||||
* @param webGLData {Object}
|
||||
*/
|
||||
PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData)
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @class WebGLMaskManager
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLMaskManager = function(gl)
|
||||
{
|
||||
this.maskStack = [];
|
||||
this.maskPosition = 0;
|
||||
|
||||
this.setContext(gl);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the drawing context to the one given in parameter
|
||||
* @method setContext
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.WebGLMaskManager.prototype.setContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the Mask and adds it to the current filter stack
|
||||
* @method pushMask
|
||||
* @param maskData {Array}
|
||||
* @param renderSession {RenderSession}
|
||||
*/
|
||||
PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if(this.maskStack.length === 0)
|
||||
{
|
||||
gl.enable(gl.STENCIL_TEST);
|
||||
gl.stencilFunc(gl.ALWAYS,1,1);
|
||||
}
|
||||
|
||||
// maskData.visible = false;
|
||||
|
||||
this.maskStack.push(maskData);
|
||||
|
||||
gl.colorMask(false, false, false, true);
|
||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
|
||||
|
||||
PIXI.WebGLGraphics.renderGraphics(maskData, renderSession);
|
||||
|
||||
gl.colorMask(true, true, true, true);
|
||||
gl.stencilFunc(gl.NOTEQUAL,0, this.maskStack.length);
|
||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the last filter from the filter stack and doesn't return it
|
||||
* @method popMask
|
||||
*
|
||||
* @param renderSession {RenderSession} TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLMaskManager.prototype.popMask = function(renderSession)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
var maskData = this.maskStack.pop();
|
||||
|
||||
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, renderSession);
|
||||
|
||||
gl.colorMask(true, true, true, true);
|
||||
gl.stencilFunc(gl.NOTEQUAL,0,this.maskStack.length);
|
||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||
}
|
||||
|
||||
if(this.maskStack.length === 0)gl.disable(gl.STENCIL_TEST);
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.WebGLMaskManager.prototype.destroy = function()
|
||||
{
|
||||
this.maskStack = null;
|
||||
this.gl = null;
|
||||
};
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class WebGLShaderManager
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
* @private
|
||||
*/
|
||||
PIXI.WebGLShaderManager = function(gl)
|
||||
{
|
||||
|
||||
this.maxAttibs = 10;
|
||||
this.attribState = [];
|
||||
this.tempAttribState = [];
|
||||
|
||||
for (var i = 0; i < this.maxAttibs; i++) {
|
||||
this.attribState[i] = false;
|
||||
}
|
||||
|
||||
this.setContext(gl);
|
||||
// the final one is used for the rendering strips
|
||||
//this.stripShader = new PIXI.StripShader(gl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the context and the properties
|
||||
* @method setContext
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
* @param transparent {Boolean} Whether or not the drawing context should be transparent
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.setContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
|
||||
// the next one is used for rendering primatives
|
||||
this.primitiveShader = new PIXI.PrimitiveShader(gl);
|
||||
|
||||
// this shader is used for the default sprite rendering
|
||||
this.defaultShader = new PIXI.PixiShader(gl);
|
||||
|
||||
// this shader is used for the fast sprite rendering
|
||||
this.fastShader = new PIXI.PixiFastShader(gl);
|
||||
|
||||
|
||||
this.activateShader(this.defaultShader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the context and the properties
|
||||
* @method setAttribs
|
||||
* @param attribs {Array} TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs)
|
||||
{
|
||||
// reset temp state
|
||||
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.tempAttribState.length; i++)
|
||||
{
|
||||
this.tempAttribState[i] = false;
|
||||
}
|
||||
|
||||
// set the new attribs
|
||||
for (i = 0; i < attribs.length; i++)
|
||||
{
|
||||
var attribId = attribs[i];
|
||||
this.tempAttribState[attribId] = true;
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
for (i = 0; i < this.attribState.length; i++)
|
||||
{
|
||||
|
||||
if(this.attribState[i] !== this.tempAttribState[i])
|
||||
{
|
||||
this.attribState[i] = this.tempAttribState[i];
|
||||
|
||||
if(this.tempAttribState[i])
|
||||
{
|
||||
gl.enableVertexAttribArray(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.disableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(this.tempAttribState)
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
* @method activateShader
|
||||
* @param shader {Object} the shader that is going to be activated
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.activateShader = function(shader)
|
||||
{
|
||||
//if(this.currentShader == shader)return;
|
||||
|
||||
this.currentShader = shader;
|
||||
// console.log(shader.program)
|
||||
this.gl.useProgram(shader.program);
|
||||
this.setAttribs(shader.attributes);
|
||||
|
||||
// console.log(shader.attributes)
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggers the primitive shader
|
||||
* @method activatePrimitiveShader
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
gl.useProgram(this.primitiveShader.program);
|
||||
|
||||
this.setAttribs(this.primitiveShader.attributes);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the primitive shader
|
||||
* @method deactivatePrimitiveShader
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
gl.useProgram(this.defaultShader.program);
|
||||
|
||||
this.setAttribs(this.defaultShader.attributes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.WebGLShaderManager.prototype.destroy = function()
|
||||
{
|
||||
this.attribState = null;
|
||||
|
||||
this.tempAttribState = null;
|
||||
|
||||
this.primitiveShader.destroy();
|
||||
|
||||
this.defaultShader.destroy();
|
||||
|
||||
this.fastShader.destroy();
|
||||
|
||||
this.gl = null;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
PIXI.initDefaultShaders = function()
|
||||
{
|
||||
|
||||
// PIXI.stripShader = new PIXI.StripShader();
|
||||
// PIXI.stripShader.init();
|
||||
|
||||
};
|
||||
|
||||
PIXI.CompileVertexShader = function(gl, shaderSrc)
|
||||
{
|
||||
return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
|
||||
};
|
||||
|
||||
PIXI.CompileFragmentShader = function(gl, shaderSrc)
|
||||
{
|
||||
return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER);
|
||||
};
|
||||
|
||||
PIXI._CompileShader = function(gl, shaderSrc, shaderType)
|
||||
{
|
||||
var src = shaderSrc.join("\n");
|
||||
var shader = gl.createShader(shaderType);
|
||||
gl.shaderSource(shader, src);
|
||||
gl.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
window.console.log(gl.getShaderInfoLog(shader));
|
||||
return null;
|
||||
}
|
||||
|
||||
return shader;
|
||||
};
|
||||
|
||||
PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc)
|
||||
{
|
||||
//var gl = PIXI.gl;
|
||||
var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc);
|
||||
var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc);
|
||||
|
||||
var shaderProgram = gl.createProgram();
|
||||
|
||||
gl.attachShader(shaderProgram, vertexShader);
|
||||
gl.attachShader(shaderProgram, fragmentShader);
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
||||
window.console.log("Could not initialise shaders");
|
||||
}
|
||||
|
||||
return shaderProgram;
|
||||
};
|
||||
@@ -0,0 +1,496 @@
|
||||
/**
|
||||
* @author Mat Groves
|
||||
*
|
||||
* Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
|
||||
* for creating the original pixi version!
|
||||
*
|
||||
* Heavily inspired by LibGDX's WebGLSpriteBatch:
|
||||
* https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @class WebGLSpriteBatch
|
||||
* @private
|
||||
* @constructor
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch = function(gl)
|
||||
{
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
*
|
||||
* @property vertSize
|
||||
* @type Number
|
||||
*/
|
||||
this.vertSize = 6;
|
||||
|
||||
/**
|
||||
* TODO-Alvin
|
||||
* @property size
|
||||
* @type Number
|
||||
*/
|
||||
this.size = 10000;//Math.pow(2, 16) / this.vertSize;
|
||||
|
||||
// console.log(this.size);
|
||||
//the total number of floats in our batch
|
||||
var numVerts = this.size * 4 * this.vertSize;
|
||||
//the total number of indices in our batch
|
||||
var numIndices = this.size * 6;
|
||||
|
||||
//vertex data
|
||||
|
||||
/**
|
||||
* Holds the vertices
|
||||
*
|
||||
* @property vertices
|
||||
* @type Float32Array
|
||||
*/
|
||||
this.vertices = new Float32Array(numVerts);
|
||||
|
||||
//index data
|
||||
/**
|
||||
* Holds the indices
|
||||
*
|
||||
* @property indices
|
||||
* @type Uint16Array
|
||||
*/
|
||||
this.indices = new Uint16Array(numIndices);
|
||||
|
||||
this.lastIndexCount = 0;
|
||||
|
||||
for (var i=0, j=0; i < numIndices; i += 6, j += 4)
|
||||
{
|
||||
this.indices[i + 0] = j + 0;
|
||||
this.indices[i + 1] = j + 1;
|
||||
this.indices[i + 2] = j + 2;
|
||||
this.indices[i + 3] = j + 0;
|
||||
this.indices[i + 4] = j + 2;
|
||||
this.indices[i + 5] = j + 3;
|
||||
}
|
||||
|
||||
|
||||
this.drawing = false;
|
||||
this.currentBatchSize = 0;
|
||||
this.currentBaseTexture = null;
|
||||
|
||||
this.setContext(gl);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method setContext
|
||||
*
|
||||
* @param gl {WebGLContext} the current WebGL drawing context
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.setContext = function(gl)
|
||||
{
|
||||
this.gl = gl;
|
||||
|
||||
// create a couple of buffers
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
|
||||
// 65535 is max index, so 65535 / 6 = 10922.
|
||||
|
||||
|
||||
//upload the index data
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
|
||||
|
||||
this.currentBlendMode = 99999;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method begin
|
||||
*
|
||||
* @param renderSession {RenderSession} the RenderSession
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession)
|
||||
{
|
||||
this.renderSession = renderSession;
|
||||
this.shader = this.renderSession.shaderManager.defaultShader;
|
||||
|
||||
this.start();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method end
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.end = function()
|
||||
{
|
||||
this.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method render
|
||||
*
|
||||
* @param sprite {Sprite} the sprite to render TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.render = function(sprite)
|
||||
{
|
||||
// check texture..
|
||||
if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size)
|
||||
{
|
||||
this.flush();
|
||||
this.currentBaseTexture = sprite.texture.baseTexture;
|
||||
}
|
||||
|
||||
|
||||
// check blend mode
|
||||
if(sprite.blendMode !== this.currentBlendMode)
|
||||
{
|
||||
this.setBlendMode(sprite.blendMode);
|
||||
}
|
||||
|
||||
// get the uvs for the texture
|
||||
var uvs = sprite._uvs || sprite.texture._uvs;
|
||||
// if the uvs have not updated then no point rendering just yet!
|
||||
if(!uvs)return;
|
||||
|
||||
// get the sprites current alpha
|
||||
var alpha = sprite.worldAlpha;
|
||||
var tint = sprite.tint;
|
||||
|
||||
var verticies = this.vertices;
|
||||
|
||||
var width = sprite.texture.frame.width;
|
||||
var height = sprite.texture.frame.height;
|
||||
|
||||
// TODO trim??
|
||||
var aX = sprite.anchor.x;
|
||||
var aY = sprite.anchor.y;
|
||||
|
||||
var w0, w1, h0, h1;
|
||||
|
||||
if (sprite.texture.trimmed)
|
||||
{
|
||||
// if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..
|
||||
var trim = sprite.texture.trim;
|
||||
|
||||
w1 = trim.x - aX * trim.realWidth;
|
||||
w0 = w1 + width;
|
||||
|
||||
h1 = trim.y - aY * trim.realHeight;
|
||||
h0 = h1 + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
w0 = (width ) * (1-aX);
|
||||
w1 = (width ) * -aX;
|
||||
|
||||
h0 = height * (1-aY);
|
||||
h1 = height * -aY;
|
||||
}
|
||||
|
||||
var index = this.currentBatchSize * 4 * this.vertSize;
|
||||
|
||||
var worldTransform = sprite.worldTransform;//.toArray();
|
||||
|
||||
var a = worldTransform.a;//[0];
|
||||
var b = worldTransform.c;//[3];
|
||||
var c = worldTransform.b;//[1];
|
||||
var d = worldTransform.d;//[4];
|
||||
var tx = worldTransform.tx;//[2];
|
||||
var ty = worldTransform.ty;///[5];
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w1 + c * h1 + tx;
|
||||
verticies[index++] = d * h1 + b * w1 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x0;
|
||||
verticies[index++] = uvs.y0;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w0 + c * h1 + tx;
|
||||
verticies[index++] = d * h1 + b * w0 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x1;
|
||||
verticies[index++] = uvs.y1;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w0 + c * h0 + tx;
|
||||
verticies[index++] = d * h0 + b * w0 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x2;
|
||||
verticies[index++] = uvs.y2;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w1 + c * h0 + tx;
|
||||
verticies[index++] = d * h0 + b * w1 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x3;
|
||||
verticies[index++] = uvs.y3;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// increment the batchsize
|
||||
this.currentBatchSize++;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method renderTilingSprite
|
||||
*
|
||||
* @param sprite {TilingSprite} the sprite to render TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite)
|
||||
{
|
||||
var texture = tilingSprite.tilingTexture;
|
||||
|
||||
if(texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size)
|
||||
{
|
||||
this.flush();
|
||||
this.currentBaseTexture = texture.baseTexture;
|
||||
}
|
||||
|
||||
// check blend mode
|
||||
if(tilingSprite.blendMode !== this.currentBlendMode)
|
||||
{
|
||||
this.setBlendMode(tilingSprite.blendMode);
|
||||
}
|
||||
|
||||
// set the textures uvs temporarily
|
||||
// TODO create a separate texture so that we can tile part of a texture
|
||||
|
||||
if(!tilingSprite._uvs)tilingSprite._uvs = new Float32Array(8);
|
||||
|
||||
var uvs = tilingSprite._uvs;
|
||||
|
||||
tilingSprite.tilePosition.x %= texture.baseTexture.width;
|
||||
tilingSprite.tilePosition.y %= texture.baseTexture.height;
|
||||
|
||||
var offsetX = tilingSprite.tilePosition.x/texture.baseTexture.width;
|
||||
var offsetY = tilingSprite.tilePosition.y/texture.baseTexture.height;
|
||||
|
||||
var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x);
|
||||
var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y);
|
||||
|
||||
uvs.x0 = 0 - offsetX;
|
||||
uvs.y0 = 0 - offsetY;
|
||||
|
||||
uvs.x1 = (1 * scaleX) - offsetX;
|
||||
uvs.y1 = 0 - offsetY;
|
||||
|
||||
uvs.x2 = (1 * scaleX) - offsetX;
|
||||
uvs.y2 = (1 * scaleY) - offsetY;
|
||||
|
||||
uvs.x3 = 0 - offsetX;
|
||||
uvs.y3 = (1 *scaleY) - offsetY;
|
||||
|
||||
|
||||
// get the tilingSprites current alpha
|
||||
var alpha = tilingSprite.worldAlpha;
|
||||
var tint = tilingSprite.tint;
|
||||
|
||||
var verticies = this.vertices;
|
||||
|
||||
var width = tilingSprite.width;
|
||||
var height = tilingSprite.height;
|
||||
|
||||
// TODO trim??
|
||||
var aX = tilingSprite.anchor.x; // - tilingSprite.texture.trim.x
|
||||
var aY = tilingSprite.anchor.y; //- tilingSprite.texture.trim.y
|
||||
var w0 = width * (1-aX);
|
||||
var w1 = width * -aX;
|
||||
|
||||
var h0 = height * (1-aY);
|
||||
var h1 = height * -aY;
|
||||
|
||||
var index = this.currentBatchSize * 4 * this.vertSize;
|
||||
|
||||
var worldTransform = tilingSprite.worldTransform;
|
||||
|
||||
var a = worldTransform.a;//[0];
|
||||
var b = worldTransform.c;//[3];
|
||||
var c = worldTransform.b;//[1];
|
||||
var d = worldTransform.d;//[4];
|
||||
var tx = worldTransform.tx;//[2];
|
||||
var ty = worldTransform.ty;///[5];
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w1 + c * h1 + tx;
|
||||
verticies[index++] = d * h1 + b * w1 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x0;
|
||||
verticies[index++] = uvs.y0;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w0 + c * h1 + tx;
|
||||
verticies[index++] = d * h1 + b * w0 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x1;
|
||||
verticies[index++] = uvs.y1;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w0 + c * h0 + tx;
|
||||
verticies[index++] = d * h0 + b * w0 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x2;
|
||||
verticies[index++] = uvs.y2;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// xy
|
||||
verticies[index++] = a * w1 + c * h0 + tx;
|
||||
verticies[index++] = d * h0 + b * w1 + ty;
|
||||
// uv
|
||||
verticies[index++] = uvs.x3;
|
||||
verticies[index++] = uvs.y3;
|
||||
// color
|
||||
verticies[index++] = alpha;
|
||||
verticies[index++] = tint;
|
||||
|
||||
// increment the batchs
|
||||
this.currentBatchSize++;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @method flush TODO-Alvin
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.flush = function()
|
||||
{
|
||||
// If the batch is length 0 then return as there is nothing to draw
|
||||
if (this.currentBatchSize===0)return;
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
// bind the current texture
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
|
||||
|
||||
// upload the verts to the buffer
|
||||
|
||||
if(this.currentBatchSize > ( this.size * 0.5 ) )
|
||||
{
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
|
||||
}
|
||||
else
|
||||
{
|
||||
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
|
||||
}
|
||||
|
||||
// var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
|
||||
//gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
|
||||
|
||||
// now draw those suckas!
|
||||
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// then reset the batch!
|
||||
this.currentBatchSize = 0;
|
||||
|
||||
// increment the draw count
|
||||
this.renderSession.drawCount++;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method stop
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.stop = function()
|
||||
{
|
||||
this.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method start
|
||||
*
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.start = function()
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
// bind the main texture
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
// bind the buffers
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
|
||||
// set the projection
|
||||
var projection = this.renderSession.projection;
|
||||
gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
|
||||
|
||||
// set the pointers
|
||||
var stride = this.vertSize * 4;
|
||||
gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
|
||||
gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4);
|
||||
gl.vertexAttribPointer(this.shader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4);
|
||||
|
||||
// set the blend mode..
|
||||
if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
|
||||
{
|
||||
this.setBlendMode(PIXI.blendModes.NORMAL);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @method setBlendMode
|
||||
*
|
||||
* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD
|
||||
* TODO-Alvin
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode)
|
||||
{
|
||||
this.flush();
|
||||
|
||||
this.currentBlendMode = blendMode;
|
||||
|
||||
var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
|
||||
this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the SpriteBatch
|
||||
* @method destroy
|
||||
*/
|
||||
PIXI.WebGLSpriteBatch.prototype.destroy = function()
|
||||
{
|
||||
|
||||
this.vertices = null;
|
||||
this.indices = null;
|
||||
|
||||
this.gl.deleteBuffer( this.vertexBuffer );
|
||||
this.gl.deleteBuffer( this.indexBuffer );
|
||||
|
||||
this.currentBaseTexture = null;
|
||||
|
||||
this.gl = null;
|
||||
};
|
||||
|
||||
+34
-17
@@ -9,16 +9,18 @@
|
||||
* http://www.bmglyph.com/ for mac.
|
||||
*
|
||||
* @class BitmapText
|
||||
* @extends DisplayObjectContainer
|
||||
* @extends SpriteBatch
|
||||
* @constructor
|
||||
* @param text {String} The copy that you would like the text to display
|
||||
* @param style {Object} The style parameters
|
||||
* @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously)
|
||||
* @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right')
|
||||
* @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
|
||||
*/
|
||||
PIXI.BitmapText = function(text, style)
|
||||
{
|
||||
PIXI.DisplayObjectContainer.call(this);
|
||||
PIXI.SpriteBatch.call(this);
|
||||
|
||||
this._pool = [];
|
||||
|
||||
this.setText(text);
|
||||
this.setStyle(style);
|
||||
@@ -27,7 +29,7 @@ PIXI.BitmapText = function(text, style)
|
||||
};
|
||||
|
||||
// constructor
|
||||
PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
|
||||
PIXI.BitmapText.prototype = Object.create(PIXI.SpriteBatch.prototype);
|
||||
PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
|
||||
|
||||
/**
|
||||
@@ -44,11 +46,11 @@ PIXI.BitmapText.prototype.setText = function(text)
|
||||
|
||||
/**
|
||||
* Set the style of the text
|
||||
* style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously)
|
||||
* [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
|
||||
*
|
||||
* @method setStyle
|
||||
* @param style {Object} The style parameters
|
||||
* @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously)
|
||||
* @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right')
|
||||
* @param style {Object} The style parameters, contained as properties of an object
|
||||
*/
|
||||
PIXI.BitmapText.prototype.setStyle = function(style)
|
||||
{
|
||||
@@ -61,6 +63,7 @@ PIXI.BitmapText.prototype.setStyle = function(style)
|
||||
this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size;
|
||||
|
||||
this.dirty = true;
|
||||
this.tint = style.tint;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,6 +82,8 @@ PIXI.BitmapText.prototype.updateText = function()
|
||||
var lineWidths = [];
|
||||
var line = 0;
|
||||
var scale = this.fontSize / data.size;
|
||||
|
||||
|
||||
for(var i = 0; i < this.text.length; i++)
|
||||
{
|
||||
var charCode = this.text.charCodeAt(i);
|
||||
@@ -125,13 +130,30 @@ PIXI.BitmapText.prototype.updateText = function()
|
||||
lineAlignOffsets.push(alignOffset);
|
||||
}
|
||||
|
||||
for(i = 0; i < chars.length; i++)
|
||||
var lenChildren = this.children.length;
|
||||
var lenChars = chars.length;
|
||||
var tint = this.tint || 0xFFFFFF;
|
||||
for(i = 0; i < lenChars; i++)
|
||||
{
|
||||
var c = new PIXI.Sprite(chars[i].texture); //PIXI.Sprite.fromFrame(chars[i].charCode);
|
||||
var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool.
|
||||
|
||||
if (c) c.setTexture(chars[i].texture); // check if got one before.
|
||||
else c = new PIXI.Sprite(chars[i].texture); // if no create new one.
|
||||
|
||||
c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale;
|
||||
c.position.y = chars[i].position.y * scale;
|
||||
c.scale.x = c.scale.y = scale;
|
||||
this.addChild(c);
|
||||
c.tint = tint;
|
||||
if (!c.parent) this.addChild(c);
|
||||
}
|
||||
|
||||
// remove unnecessary children.
|
||||
// and put their into the pool.
|
||||
while(this.children.length > lenChars)
|
||||
{
|
||||
var child = this.getChildAt(this.children.length - 1);
|
||||
this._pool.push(child);
|
||||
this.removeChild(child);
|
||||
}
|
||||
|
||||
this.width = maxLineWidth * scale;
|
||||
@@ -139,7 +161,7 @@ PIXI.BitmapText.prototype.updateText = function()
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the transfor of this object
|
||||
* Updates the transform of this object
|
||||
*
|
||||
* @method updateTransform
|
||||
* @private
|
||||
@@ -148,16 +170,11 @@ PIXI.BitmapText.prototype.updateTransform = function()
|
||||
{
|
||||
if(this.dirty)
|
||||
{
|
||||
while(this.children.length > 0)
|
||||
{
|
||||
this.removeChild(this.getChildAt(0));
|
||||
}
|
||||
this.updateText();
|
||||
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
|
||||
PIXI.SpriteBatch.prototype.updateTransform.call(this);
|
||||
};
|
||||
|
||||
PIXI.BitmapText.fonts = {};
|
||||
|
||||
+40
-5
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Text Object will create a line(s) of text to split a line you can use '\n'
|
||||
* A Text Object will create a line(s) of text. To split a line you can use '\n'
|
||||
*
|
||||
* @class Text
|
||||
* @extends Sprite
|
||||
@@ -12,7 +12,7 @@
|
||||
* @param [style] {Object} The style parameters
|
||||
* @param [style.font] {String} default 'bold 20pt Arial' The style and size of the font
|
||||
* @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.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
|
||||
* @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.wordWrap=false] {Boolean} Indicates if word wrap should be used
|
||||
@@ -20,8 +20,21 @@
|
||||
*/
|
||||
PIXI.Text = function(text, style)
|
||||
{
|
||||
/**
|
||||
* The canvas element that everything is drawn to
|
||||
*
|
||||
* @property canvas
|
||||
* @type HTMLCanvasElement
|
||||
*/
|
||||
this.canvas = document.createElement('canvas');
|
||||
|
||||
/**
|
||||
* The canvas 2d context that everything is drawn with
|
||||
* @property context
|
||||
* @type HTMLCanvasElement 2d Context
|
||||
*/
|
||||
this.context = this.canvas.getContext('2d');
|
||||
|
||||
PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
|
||||
|
||||
this.setText(text);
|
||||
@@ -42,7 +55,7 @@ PIXI.Text.prototype.constructor = PIXI.Text;
|
||||
* @param [style] {Object} The style parameters
|
||||
* @param [style.font='bold 20pt Arial'] {String} The style and size of the font
|
||||
* @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.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
|
||||
* @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.wordWrap=false] {Boolean} Indicates if word wrap should be used
|
||||
@@ -72,6 +85,7 @@ PIXI.Text.prototype.setText = function(text)
|
||||
{
|
||||
this.text = text.toString() || ' ';
|
||||
this.dirty = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,6 +122,8 @@ PIXI.Text.prototype.updateText = function()
|
||||
var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness;
|
||||
this.canvas.height = lineHeight * lines.length;
|
||||
|
||||
if(navigator.isCocoonJS) this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
|
||||
|
||||
//set canvas text styles
|
||||
this.context.fillStyle = this.style.fill;
|
||||
this.context.font = this.style.font;
|
||||
@@ -161,11 +177,29 @@ PIXI.Text.prototype.updateTexture = function()
|
||||
this._width = this.canvas.width;
|
||||
this._height = this.canvas.height;
|
||||
|
||||
PIXI.texturesToUpdate.push(this.texture.baseTexture);
|
||||
this.requiresUpdate = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the transfor of this object
|
||||
* Renders the object using the WebGL renderer
|
||||
*
|
||||
* @method _renderWebGL
|
||||
* @param renderSession {RenderSession}
|
||||
* @private
|
||||
*/
|
||||
PIXI.Text.prototype._renderWebGL = function(renderSession)
|
||||
{
|
||||
if(this.requiresUpdate)
|
||||
{
|
||||
this.requiresUpdate = false;
|
||||
PIXI.updateWebGLTexture(this.texture.baseTexture, renderSession.gl);
|
||||
}
|
||||
|
||||
PIXI.Sprite.prototype._renderWebGL.call(this, renderSession);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the transform of this object
|
||||
*
|
||||
* @method updateTransform
|
||||
* @private
|
||||
@@ -184,6 +218,7 @@ PIXI.Text.prototype.updateTransform = function()
|
||||
/*
|
||||
* http://stackoverflow.com/users/34441/ellisbben
|
||||
* great solution to the problem!
|
||||
* returns the height of the given font
|
||||
*
|
||||
* @method determineFontHeight
|
||||
* @param fontStyle {Object}
|
||||
|
||||
@@ -6,6 +6,8 @@ PIXI.BaseTextureCache = {};
|
||||
PIXI.texturesToUpdate = [];
|
||||
PIXI.texturesToDestroy = [];
|
||||
|
||||
PIXI.BaseTextureCacheIdGenerator = 0;
|
||||
|
||||
/**
|
||||
* A texture stores the information that represents an image. All textures have a base texture
|
||||
*
|
||||
@@ -13,6 +15,7 @@ PIXI.texturesToDestroy = [];
|
||||
* @uses EventTarget
|
||||
* @constructor
|
||||
* @param source {String} the source object (image or canvas)
|
||||
* @param scaleMode {Number} Should be one of the PIXI.scaleMode consts
|
||||
*/
|
||||
PIXI.BaseTexture = function(source, scaleMode)
|
||||
{
|
||||
@@ -39,10 +42,10 @@ PIXI.BaseTexture = function(source, scaleMode)
|
||||
/**
|
||||
* The scale mode to apply when scaling this texture
|
||||
* @property scaleMode
|
||||
* @type PIXI.BaseTexture.SCALE_MODE
|
||||
* @default PIXI.BaseTexture.SCALE_MODE.LINEAR
|
||||
* @type PIXI.scaleModes
|
||||
* @default PIXI.scaleModes.LINEAR
|
||||
*/
|
||||
this.scaleMode = scaleMode || PIXI.BaseTexture.SCALE_MODE.DEFAULT;
|
||||
this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT;
|
||||
|
||||
/**
|
||||
* [read-only] Describes if the base texture has loaded or not
|
||||
@@ -63,34 +66,7 @@ PIXI.BaseTexture = function(source, scaleMode)
|
||||
|
||||
if(!source)return;
|
||||
|
||||
if(this.source instanceof Image || this.source instanceof HTMLImageElement)
|
||||
{
|
||||
if(this.source.complete)
|
||||
{
|
||||
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 } );
|
||||
};
|
||||
//this.image.src = imageUrl;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(this.source.complete || this.source.getContext)
|
||||
{
|
||||
this.hasLoaded = true;
|
||||
this.width = this.source.width;
|
||||
@@ -98,9 +74,32 @@ PIXI.BaseTexture = function(source, scaleMode)
|
||||
|
||||
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 } );
|
||||
};
|
||||
//this.image.src = imageUrl;
|
||||
}
|
||||
|
||||
this.imageUrl = null;
|
||||
this._powerOf2 = false;
|
||||
|
||||
//TODO will be used for futer pixi 1.5...
|
||||
this.id = PIXI.BaseTextureCacheIdGenerator++;
|
||||
|
||||
// used for webGL
|
||||
this._glTextures = [];
|
||||
|
||||
};
|
||||
|
||||
PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
|
||||
@@ -112,10 +111,9 @@ PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
|
||||
*/
|
||||
PIXI.BaseTexture.prototype.destroy = function()
|
||||
{
|
||||
if(this.source instanceof Image)
|
||||
if(this.imageUrl)
|
||||
{
|
||||
if (this.imageUrl in PIXI.BaseTextureCache)
|
||||
delete PIXI.BaseTextureCache[this.imageUrl];
|
||||
delete PIXI.BaseTextureCache[this.imageUrl];
|
||||
this.imageUrl = null;
|
||||
this.source.src = null;
|
||||
}
|
||||
@@ -138,7 +136,7 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc)
|
||||
|
||||
/**
|
||||
* Helper function that returns a base texture based on an image url
|
||||
* If the image is not in the base texture cache it will be created and loaded
|
||||
* If the image is not in the base texture cache it will be created and loaded
|
||||
*
|
||||
* @static
|
||||
* @method fromImage
|
||||
@@ -148,6 +146,8 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc)
|
||||
PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
|
||||
{
|
||||
var baseTexture = PIXI.BaseTextureCache[imageUrl];
|
||||
crossorigin = !crossorigin;
|
||||
|
||||
if(!baseTexture)
|
||||
{
|
||||
// new Image() breaks tex loading in some versions of Chrome.
|
||||
@@ -166,8 +166,22 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
|
||||
return baseTexture;
|
||||
};
|
||||
|
||||
PIXI.BaseTexture.SCALE_MODE = {
|
||||
DEFAULT: 0, //default to LINEAR
|
||||
LINEAR: 0,
|
||||
NEAREST: 1
|
||||
};
|
||||
PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode)
|
||||
{
|
||||
if(!canvas._pixiId)
|
||||
{
|
||||
canvas._pixiId = 'canvas_' + PIXI.TextureCacheIdGenerator++;
|
||||
}
|
||||
|
||||
var baseTexture = PIXI.BaseTextureCache[canvas._pixiId];
|
||||
|
||||
if(!baseTexture)
|
||||
{
|
||||
baseTexture = new PIXI.BaseTexture(canvas, scaleMode);
|
||||
PIXI.BaseTextureCache[canvas._pixiId] = baseTexture;
|
||||
}
|
||||
|
||||
return baseTexture;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/**
|
||||
A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it.
|
||||
|
||||
__Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded.
|
||||
__Hint__: All DisplayObjects (exmpl. Sprites) that render on RenderTexture should be preloaded.
|
||||
Otherwise black rectangles will be drawn instead.
|
||||
|
||||
RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example:
|
||||
@@ -30,112 +30,73 @@
|
||||
@param width {Number} The width of the render texture
|
||||
@param height {Number} The height of the render texture
|
||||
*/
|
||||
PIXI.RenderTexture = function(width, height)
|
||||
PIXI.RenderTexture = function(width, height, renderer)
|
||||
{
|
||||
PIXI.EventTarget.call( this );
|
||||
|
||||
this.width = width || 100;
|
||||
this.height = height || 100;
|
||||
|
||||
this.indetityMatrix = PIXI.mat3.create();
|
||||
|
||||
this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
|
||||
|
||||
if(PIXI.gl)
|
||||
this.baseTexture = new PIXI.BaseTexture();
|
||||
this.baseTexture.width = this.width;
|
||||
this.baseTexture.height = this.height;
|
||||
this.baseTexture._glTextures = [];
|
||||
|
||||
this.baseTexture.hasLoaded = true;
|
||||
|
||||
// each render texture can only belong to one renderer at the moment if its webGL
|
||||
this.renderer = renderer || PIXI.defaultRenderer;
|
||||
|
||||
if(this.renderer.type === PIXI.WEBGL_RENDERER)
|
||||
{
|
||||
this.initWebGL();
|
||||
var gl = this.renderer.gl;
|
||||
|
||||
this.textureBuffer = new PIXI.FilterTexture(gl, this.width, this.height);
|
||||
this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture;
|
||||
|
||||
this.render = this.renderWebGL;
|
||||
this.projection = new PIXI.Point(this.width/2 , -this.height/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.initCanvas();
|
||||
this.render = this.renderCanvas;
|
||||
this.textureBuffer = new PIXI.CanvasBuffer(this.width, this.height);
|
||||
this.baseTexture.source = this.textureBuffer.canvas;
|
||||
}
|
||||
|
||||
PIXI.Texture.frameUpdates.push(this);
|
||||
|
||||
|
||||
};
|
||||
|
||||
PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
|
||||
PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
|
||||
|
||||
/**
|
||||
* Initializes the webgl data for this texture
|
||||
*
|
||||
* @method initWebGL
|
||||
* @private
|
||||
*/
|
||||
PIXI.RenderTexture.prototype.initWebGL = function()
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
this.glFramebuffer = gl.createFramebuffer();
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
|
||||
|
||||
this.glFramebuffer.width = this.width;
|
||||
this.glFramebuffer.height = this.height;
|
||||
|
||||
this.baseTexture = new PIXI.BaseTexture();
|
||||
|
||||
this.baseTexture.width = this.width;
|
||||
this.baseTexture.height = this.height;
|
||||
|
||||
this.baseTexture._glTexture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
|
||||
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);
|
||||
|
||||
this.baseTexture.isRender = true;
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
|
||||
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);
|
||||
|
||||
// set the correct render function..
|
||||
this.render = this.renderWebGL;
|
||||
};
|
||||
|
||||
|
||||
PIXI.RenderTexture.prototype.resize = function(width, height)
|
||||
{
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
if(PIXI.gl)
|
||||
this.frame.width = this.width;
|
||||
this.frame.height = this.height;
|
||||
|
||||
if(this.renderer.type === PIXI.WEBGL_RENDERER)
|
||||
{
|
||||
this.projection.x = this.width / 2;
|
||||
this.projection.y = -this.height / 2;
|
||||
|
||||
var gl = PIXI.gl;
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
|
||||
var gl = this.gl;
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTextures[gl.id]);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.frame.width = this.width;
|
||||
this.frame.height = this.height;
|
||||
this.renderer.resize(this.width, this.height);
|
||||
this.textureBuffer.resize(this.width, this.height);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the canvas data for this texture
|
||||
*
|
||||
* @method initCanvas
|
||||
* @private
|
||||
*/
|
||||
PIXI.RenderTexture.prototype.initCanvas = function()
|
||||
{
|
||||
this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0);
|
||||
|
||||
this.baseTexture = new PIXI.BaseTexture(this.renderer.view);
|
||||
this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
|
||||
|
||||
this.render = this.renderCanvas;
|
||||
PIXI.Texture.frameUpdates.push(this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -148,64 +109,42 @@ PIXI.RenderTexture.prototype.initCanvas = function()
|
||||
*/
|
||||
PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
|
||||
{
|
||||
var gl = PIXI.gl;
|
||||
var gl = this.renderer.gl;
|
||||
|
||||
// enable the alpha color mask..
|
||||
gl.colorMask(true, true, true, true);
|
||||
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer );
|
||||
|
||||
if(clear)
|
||||
{
|
||||
gl.clearColor(0,0,0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
if(clear)this.textureBuffer.clear();
|
||||
|
||||
// THIS WILL MESS WITH HIT TESTING!
|
||||
var children = displayObject.children;
|
||||
|
||||
//TODO -? create a new one??? dont think so!
|
||||
var originalWorldTransform = displayObject.worldTransform;
|
||||
displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix;
|
||||
displayObject.worldTransform = PIXI.RenderTexture.tempMatrix;
|
||||
// modify to flip...
|
||||
displayObject.worldTransform[4] = -1;
|
||||
displayObject.worldTransform[5] = this.projection.y * -2;
|
||||
displayObject.worldTransform.d = -1;
|
||||
displayObject.worldTransform.ty = this.projection.y * -2;
|
||||
|
||||
if(position)
|
||||
{
|
||||
displayObject.worldTransform[2] = position.x;
|
||||
displayObject.worldTransform[5] -= position.y;
|
||||
displayObject.worldTransform.tx = position.x;
|
||||
displayObject.worldTransform.ty -= position.y;
|
||||
}
|
||||
|
||||
PIXI.visibleCount++;
|
||||
displayObject.vcount = PIXI.visibleCount;
|
||||
|
||||
for(var i=0,j=children.length; i<j; i++)
|
||||
{
|
||||
children[i].updateTransform();
|
||||
}
|
||||
|
||||
var renderGroup = displayObject.__renderGroup;
|
||||
// update the textures!
|
||||
PIXI.WebGLRenderer.updateTextures();
|
||||
|
||||
if(renderGroup)
|
||||
{
|
||||
if(displayObject === renderGroup.root)
|
||||
{
|
||||
renderGroup.render(this.projection, this.glFramebuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
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.glFramebuffer);
|
||||
}
|
||||
//
|
||||
this.renderer.renderDisplayObject(displayObject, this.projection, this.textureBuffer.frameBuffer);
|
||||
|
||||
displayObject.worldTransform = originalWorldTransform;
|
||||
};
|
||||
@@ -221,27 +160,30 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
|
||||
*/
|
||||
PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear)
|
||||
{
|
||||
//console.log("!!")
|
||||
var children = displayObject.children;
|
||||
|
||||
displayObject.worldTransform = PIXI.mat3.create();
|
||||
displayObject.worldTransform = PIXI.RenderTexture.tempMatrix;
|
||||
|
||||
if(position)
|
||||
{
|
||||
displayObject.worldTransform[2] = position.x;
|
||||
displayObject.worldTransform[5] = position.y;
|
||||
displayObject.worldTransform.tx = position.x;
|
||||
displayObject.worldTransform.ty = position.y;
|
||||
}
|
||||
|
||||
|
||||
for(var i = 0, j = children.length; i < j; i++)
|
||||
{
|
||||
children[i].updateTransform();
|
||||
}
|
||||
|
||||
if(clear) this.renderer.context.clearRect(0,0, this.width, this.height);
|
||||
if(clear)this.textureBuffer.clear();
|
||||
|
||||
this.renderer.renderDisplayObject(displayObject);
|
||||
var context = this.textureBuffer.context;
|
||||
|
||||
this.renderer.context.setTransform(1,0,0,1,0,0);
|
||||
this.renderer.renderDisplayObject(displayObject, context);
|
||||
|
||||
//PIXI.texturesToUpdate.push(this.baseTexture);
|
||||
context.setTransform(1,0,0,1,0,0);
|
||||
};
|
||||
|
||||
PIXI.RenderTexture.tempMatrix = new PIXI.Matrix();
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
PIXI.TextureCache = {};
|
||||
PIXI.FrameCache = {};
|
||||
|
||||
PIXI.TextureCacheIdGenerator = 0;
|
||||
|
||||
/**
|
||||
* A texture stores the information that represents an image or part of an image. It cannot be added
|
||||
* to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
|
||||
@@ -57,8 +59,7 @@ PIXI.Texture = function(baseTexture, frame)
|
||||
if(baseTexture.hasLoaded)
|
||||
{
|
||||
if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
|
||||
//console.log(frame)
|
||||
|
||||
|
||||
this.setFrame(frame);
|
||||
}
|
||||
else
|
||||
@@ -83,9 +84,8 @@ PIXI.Texture.prototype.onBaseTextureLoaded = function()
|
||||
baseTexture.removeEventListener( 'loaded', this.onLoaded );
|
||||
|
||||
if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
|
||||
this.noFrame = false;
|
||||
this.width = this.frame.width;
|
||||
this.height = this.frame.height;
|
||||
|
||||
this.setFrame(this.frame);
|
||||
|
||||
this.scope.dispatchEvent( { type: 'update', content: this } );
|
||||
};
|
||||
@@ -121,9 +121,32 @@ PIXI.Texture.prototype.setFrame = function(frame)
|
||||
this.updateFrame = true;
|
||||
|
||||
PIXI.Texture.frameUpdates.push(this);
|
||||
|
||||
|
||||
//this.dispatchEvent( { type: 'update', content: this } );
|
||||
};
|
||||
|
||||
PIXI.Texture.prototype._updateWebGLuvs = function()
|
||||
{
|
||||
if(!this._uvs)this._uvs = new PIXI.TextureUvs();
|
||||
|
||||
var frame = this.frame;
|
||||
var tw = this.baseTexture.width;
|
||||
var th = this.baseTexture.height;
|
||||
|
||||
this._uvs.x0 = frame.x / tw;
|
||||
this._uvs.y0 = frame.y / th;
|
||||
|
||||
this._uvs.x1 = (frame.x + frame.width) / tw;
|
||||
this._uvs.y1 = frame.y / th;
|
||||
|
||||
this._uvs.x2 = (frame.x + frame.width) / tw;
|
||||
this._uvs.y2 = (frame.y + frame.height) / th;
|
||||
|
||||
this._uvs.x3 = frame.x / tw;
|
||||
this._uvs.y3 = (frame.y + frame.height) / th;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function that returns a texture based on an image url
|
||||
* If the image is not in the texture cache it will be created and loaded
|
||||
@@ -159,7 +182,7 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
|
||||
PIXI.Texture.fromFrame = function(frameId)
|
||||
{
|
||||
var texture = PIXI.TextureCache[frameId];
|
||||
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
|
||||
if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ');
|
||||
return texture;
|
||||
};
|
||||
|
||||
@@ -174,8 +197,10 @@ PIXI.Texture.fromFrame = function(frameId)
|
||||
*/
|
||||
PIXI.Texture.fromCanvas = function(canvas, scaleMode)
|
||||
{
|
||||
var baseTexture = new PIXI.BaseTexture(canvas, scaleMode);
|
||||
return new PIXI.Texture(baseTexture);
|
||||
var baseTexture = PIXI.BaseTexture.fromCanvas(canvas, scaleMode);
|
||||
|
||||
return new PIXI.Texture( baseTexture );
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -210,4 +235,24 @@ PIXI.Texture.removeTextureFromCache = function(id)
|
||||
// this is more for webGL.. it contains updated frames..
|
||||
PIXI.Texture.frameUpdates = [];
|
||||
|
||||
PIXI.Texture.SCALE_MODE = PIXI.BaseTexture.SCALE_MODE;
|
||||
PIXI.TextureUvs = function()
|
||||
{
|
||||
this.x0 = 0;
|
||||
this.y0 = 0;
|
||||
|
||||
this.x1 = 0;
|
||||
this.y1 = 0;
|
||||
|
||||
this.x2 = 0;
|
||||
this.y2 = 0;
|
||||
|
||||
this.x3 = 0;
|
||||
this.y4 = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+11
-10
@@ -4,16 +4,15 @@
|
||||
|
||||
/**
|
||||
* This helper function will automatically detect which renderer you should be using.
|
||||
* WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
|
||||
* WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by
|
||||
* the browser then this function will return a canvas renderer
|
||||
*
|
||||
* @method autoDetectRenderer
|
||||
* @class autoDetectRenderer
|
||||
* @static
|
||||
* @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)
|
||||
* @param width=800 {Number} the width of the renderers view
|
||||
* @param height=600 {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
|
||||
*/
|
||||
@@ -31,13 +30,15 @@ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
|
||||
}
|
||||
} )();
|
||||
|
||||
if(webgl)
|
||||
// used to detect ie 11 - no longer required
|
||||
/* if(webgl)
|
||||
{
|
||||
var ie = (navigator.userAgent.toLowerCase().indexOf('trident') !== -1);
|
||||
webgl = !ie;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//console.log(webgl);
|
||||
if( webgl )
|
||||
{
|
||||
return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
/**
|
||||
* https://github.com/mrdoob/eventtarget.js/
|
||||
* THankS mr DOob!
|
||||
@@ -7,7 +11,7 @@
|
||||
* Adds event emitter functionality to a class
|
||||
*
|
||||
* @class EventTarget
|
||||
* @example
|
||||
*
|
||||
* function MyEmitter() {
|
||||
* PIXI.EventTarget.call(this); //mixes in event target stuff
|
||||
* }
|
||||
@@ -17,8 +21,21 @@
|
||||
*/
|
||||
PIXI.EventTarget = function () {
|
||||
|
||||
/**
|
||||
* Holds all the listeners
|
||||
*
|
||||
* @property listeneners
|
||||
* @type Object
|
||||
*/
|
||||
var listeners = {};
|
||||
|
||||
/**
|
||||
* Adds a listener for a specific event
|
||||
*
|
||||
* @method addEventListener
|
||||
* @param type {string} A string representing the event type to listen for.
|
||||
* @param listener {function} The callback function that will be fired when the event occurs
|
||||
*/
|
||||
this.addEventListener = this.on = function ( type, listener ) {
|
||||
|
||||
|
||||
@@ -35,6 +52,12 @@ PIXI.EventTarget = function () {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Fires the event, ie pretends that the event has happened
|
||||
*
|
||||
* @method dispatchEvent
|
||||
* @param event {Event} the event object
|
||||
*/
|
||||
this.dispatchEvent = this.emit = function ( event ) {
|
||||
|
||||
if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
|
||||
@@ -51,6 +74,13 @@ PIXI.EventTarget = function () {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the specified listener that was assigned to the specified event type
|
||||
*
|
||||
* @method removeEventListener
|
||||
* @param type {string} A string representing the event type which will have its listener removed
|
||||
* @param listener {function} The callback function that was be fired when the event occured
|
||||
*/
|
||||
this.removeEventListener = this.off = function ( type, listener ) {
|
||||
|
||||
var index = listeners[ type ].indexOf( listener );
|
||||
@@ -63,6 +93,12 @@ PIXI.EventTarget = function () {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all the listeners that were active for the specified event type
|
||||
*
|
||||
* @method removeAllEventListeners
|
||||
* @param type {string} A string representing the event type which will have all its listeners removed
|
||||
*/
|
||||
this.removeAllEventListeners = function( type ) {
|
||||
var a = listeners[type];
|
||||
if (a)
|
||||
|
||||
+22
-9
@@ -28,17 +28,23 @@
|
||||
|
||||
This is an amazing lib!
|
||||
|
||||
slightly modified by mat groves (matgroves.com);
|
||||
slightly modified by Mat Groves (matgroves.com);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on the Polyk library http://polyk.ivank.net released under MIT licence.
|
||||
* This is an amazing lib!
|
||||
* slightly modified by Mat Groves (matgroves.com);
|
||||
* @class PolyK
|
||||
*
|
||||
*/
|
||||
PIXI.PolyK = {};
|
||||
|
||||
/**
|
||||
* Triangulates shapes for webGL graphic fills
|
||||
*
|
||||
* @method Triangulate
|
||||
* @namespace PolyK
|
||||
* @constructor
|
||||
*
|
||||
*/
|
||||
PIXI.PolyK.Triangulate = function(p)
|
||||
{
|
||||
@@ -114,10 +120,17 @@ PIXI.PolyK.Triangulate = function(p)
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a point is within a triangle
|
||||
* Checks whether a point is within a triangle
|
||||
*
|
||||
* @class _PointInTriangle
|
||||
* @namespace PolyK
|
||||
* @method _PointInTriangle
|
||||
* @param px {Number} x coordinate of the point to test
|
||||
* @param py {Number} y coordinate of the point to test
|
||||
* @param ax {Number} x coordinate of the a point of the triangle
|
||||
* @param ay {Number} y coordinate of the a point of the triangle
|
||||
* @param bx {Number} x coordinate of the b point of the triangle
|
||||
* @param by {Number} y coordinate of the b point of the triangle
|
||||
* @param cx {Number} x coordinate of the c point of the triangle
|
||||
* @param cy {Number} y coordinate of the c point of the triangle
|
||||
* @private
|
||||
*/
|
||||
PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy)
|
||||
@@ -144,10 +157,10 @@ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy)
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a shape is convex
|
||||
* Checks whether a shape is convex
|
||||
*
|
||||
* @class _convex
|
||||
* @namespace PolyK
|
||||
* @method _convex
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
|
||||
|
||||
+79
-26
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @author Mat Groves http://matgroves.com/ @Doormat23
|
||||
*/
|
||||
|
||||
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||||
|
||||
@@ -7,6 +11,8 @@
|
||||
|
||||
/**
|
||||
* A polyfill for requestAnimationFrame
|
||||
* You can actually use both requestAnimationFrame and requestAnimFrame,
|
||||
* you will still benefit from the polyfill
|
||||
*
|
||||
* @method requestAnimationFrame
|
||||
*/
|
||||
@@ -48,10 +54,20 @@ window.requestAnimFrame = window.requestAnimationFrame;
|
||||
* @method hex2rgb
|
||||
* @param hex {Number}
|
||||
*/
|
||||
PIXI.hex2rgb = function hex2rgb(hex) {
|
||||
PIXI.hex2rgb = function(hex) {
|
||||
return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a color as an [R, G, B] array to a hex number
|
||||
*
|
||||
* @method rgb2hex
|
||||
* @param rgb {Array}
|
||||
*/
|
||||
PIXI.rgb2hex = function(rgb) {
|
||||
return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
|
||||
};
|
||||
|
||||
/**
|
||||
* A polyfill for Function.prototype.bind
|
||||
*
|
||||
@@ -86,7 +102,7 @@ if (typeof Function.prototype.bind !== 'function') {
|
||||
* @class AjaxRequest
|
||||
* @constructor
|
||||
*/
|
||||
PIXI.AjaxRequest = function AjaxRequest()
|
||||
PIXI.AjaxRequest = function()
|
||||
{
|
||||
var activexmodes = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; //activeX versions to check for in IE
|
||||
|
||||
@@ -111,34 +127,71 @@ PIXI.AjaxRequest = function AjaxRequest()
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* DEBUGGING ONLY
|
||||
*/
|
||||
PIXI.runList = function(item)
|
||||
PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a)
|
||||
{
|
||||
window.console.log('>>>>>>>>>');
|
||||
window.console.log('_');
|
||||
var safe = 0;
|
||||
var tmp = item.first;
|
||||
window.console.log(tmp);
|
||||
// console.log(r, b, c, d)
|
||||
return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6);// | (Math.floor((a)*63))
|
||||
// i = i | (Math.floor((a)*63));
|
||||
// return i;
|
||||
// var r = (i / 262144.0 ) / 64;
|
||||
// var g = (i / 4096.0)%64 / 64;
|
||||
// var b = (i / 64.0)%64 / 64;
|
||||
// var a = (i)%64 / 64;
|
||||
|
||||
// console.log(r, g, b, a);
|
||||
// return i;
|
||||
|
||||
while(tmp._iNext)
|
||||
{
|
||||
safe++;
|
||||
tmp = tmp._iNext;
|
||||
window.console.log(tmp);
|
||||
// console.log(tmp);
|
||||
|
||||
if(safe > 100)
|
||||
{
|
||||
window.console.log('BREAK');
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
*/
|
||||
/*
|
||||
PIXI.packColorRGB = function(r, g, b)//r, g, b, a)
|
||||
{
|
||||
return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255));
|
||||
};
|
||||
|
||||
PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a)
|
||||
{
|
||||
return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255));
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks whether the Canvas BlendModes are supported by the current browser
|
||||
*
|
||||
* @method canUseNewCanvasBlendModes
|
||||
* @return {Boolean} whether they are supported
|
||||
*/
|
||||
PIXI.canUseNewCanvasBlendModes = function()
|
||||
{
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 1;
|
||||
canvas.height = 1;
|
||||
var context = canvas.getContext('2d');
|
||||
context.fillStyle = '#000';
|
||||
context.fillRect(0,0,1,1);
|
||||
context.globalCompositeOperation = 'multiply';
|
||||
context.fillStyle = '#fff';
|
||||
context.fillRect(0,0,1,1);
|
||||
return context.getImageData(0,0,1,1).data[0] === 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Given a number, this function returns the closest number that is a power of two
|
||||
* this function is taken from Starling Framework as its pretty neat ;)
|
||||
*
|
||||
* @method getNextPowerOfTwo
|
||||
* @param number {Number}
|
||||
* @return {Number} the closest number that is a power of two
|
||||
*/
|
||||
PIXI.getNextPowerOfTwo = function(number)
|
||||
{
|
||||
if (number > 0 && (number & (number - 1)) === 0) // see: http://goo.gl/D9kPj
|
||||
return number;
|
||||
else
|
||||
{
|
||||
var result = 1;
|
||||
while (result < number) result <<= 1;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user