diff --git a/CCBoot.js b/CCBoot.js
index a048a028b3..22c50494b6 100644
--- a/CCBoot.js
+++ b/CCBoot.js
@@ -82,6 +82,8 @@ cc._canvas = null;
cc.container = null;
cc._gameDiv = null;
+window.ENABLE_IMAEG_POOL = true;
+
/**
* Iterate over an object or an array, executing a function for each matched element.
* @param {object|array} obj
@@ -583,6 +585,33 @@ cc.path = /** @lends cc.path# */{
* @see cc.loader
*/
+var imagePool = {
+ _pool: new Array(10),
+ _MAX: 10,
+ _smallImg: "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=",
+
+ count: 0,
+ get: function () {
+ if (this.count > 0) {
+ this.count--;
+ var result = this._pool[this.count];
+ this._pool[this.count] = null;
+ return result;
+ }
+ else {
+ return new Image();
+ }
+ },
+ put: function (img) {
+ var pool = this._pool;
+ if (img instanceof HTMLImageElement && this.count < this._MAX) {
+ img.src = this._smallImg;
+ pool[this.count] = img;
+ this.count++;
+ }
+ }
+};
+
/**
* Singleton instance of cc.Loader.
* @name cc.loader
@@ -768,29 +797,55 @@ cc.loader = (function () {
xhr.setRequestHeader("Accept-Charset", "utf-8");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4)
- xhr.status === 200 ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
};
} else {
if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
- xhr.onload = function () {
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
if (xhr._timeoutId >= 0) {
clearTimeout(xhr._timeoutId);
}
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
if (xhr.readyState === 4) {
- xhr.status === 200 ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
}
};
- xhr.onerror = function () {
+ var errorCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
cb({status: xhr.status, errorMessage: errInfo}, null);
};
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
if (xhr.ontimeout === undefined) {
xhr._timeoutId = setTimeout(function () {
- xhr.ontimeout();
+ timeoutCallback();
}, xhr.timeout);
}
- xhr.ontimeout = function () {
- cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
- };
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
}
xhr.send(null);
} else {
@@ -807,29 +862,55 @@ cc.loader = (function () {
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
- xhr.onload = function () {
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
if (xhr._timeoutId >= 0) {
clearTimeout(xhr._timeoutId);
}
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
var arrayBuffer = xhr.response; // Note: not oReq.responseText
if (arrayBuffer) {
window.msg = arrayBuffer;
}
if (xhr.readyState === 4) {
- xhr.status === 200 ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
}
};
- xhr.onerror = function(){
+ var errorCallback = function(){
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
cb({status:xhr.status, errorMessage:errInfo}, null);
};
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
if (xhr.ontimeout === undefined) {
xhr._timeoutId = setTimeout(function () {
- xhr.ontimeout();
+ timeoutCallback();
}, xhr.timeout);
}
- xhr.ontimeout = function () {
- cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
- };
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
xhr.send(null);
},
@@ -867,7 +948,7 @@ cc.loader = (function () {
* @param {function} callback
* @returns {Image}
*/
- loadImg: function (url, option, callback) {
+ loadImg: function (url, option, callback, img) {
var opt = {
isCrossOrigin: true
};
@@ -876,10 +957,10 @@ cc.loader = (function () {
else if (option !== undefined)
callback = option;
- var img = this.getRes(url);
- if (img) {
- callback && callback(null, img);
- return img;
+ var texture = this.getRes(url);
+ if (texture) {
+ callback && callback(null, texture);
+ return null;
}
var queue = _queue[url];
@@ -888,18 +969,16 @@ cc.loader = (function () {
return queue.img;
}
- img = new Image();
+ img = img || imagePool.get();
if (opt.isCrossOrigin && location.origin !== "file://")
img.crossOrigin = "Anonymous";
+ else
+ img.crossOrigin = null;
var loadCallback = function () {
this.removeEventListener('load', loadCallback, false);
this.removeEventListener('error', errorCallback, false);
- if (!_urlRegExp.test(url)) {
- cc.loader.cache[url] = img;
- }
-
var queue = _queue[url];
if (queue) {
var callbacks = queue.callbacks;
@@ -912,16 +991,21 @@ cc.loader = (function () {
queue.img = null;
delete _queue[url];
}
+
+ if (window.ENABLE_IMAEG_POOL && cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
};
var self = this;
var errorCallback = function () {
+ this.removeEventListener('load', loadCallback, false);
this.removeEventListener('error', errorCallback, false);
- if (img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
+ if (window.location.protocol !== 'https:' && img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
opt.isCrossOrigin = false;
self.release(url);
- cc.loader.loadImg(url, opt, callback);
+ cc.loader.loadImg(url, opt, callback, img);
} else {
var queue = _queue[url];
if (queue) {
@@ -935,6 +1019,10 @@ cc.loader = (function () {
queue.img = null;
delete _queue[url];
}
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
}
};
@@ -976,7 +1064,7 @@ cc.loader = (function () {
loader = _register[type.toLowerCase()];
}
if (!loader) {
- cc.error("loader for [" + type + "] not exists!");
+ cc.error("loader for [" + type + "] doesn't exist!");
return cb();
}
var realUrl = url;
@@ -1757,8 +1845,8 @@ var _initSys = function () {
sys.browserVersion = "";
/* Determine the browser version number */
(function(){
- var versionReg1 = /(micromessenger|qq|mx|maxthon|baidu|sogou)(mobile)?(browser)?\/?([\d.]+)/i;
- var versionReg2 = /(msie |rv:|firefox|chrome|ucbrowser|oupeng|opera|opr|safari|miui)(mobile)?(browser)?\/?([\d.]+)/i;
+ var versionReg1 = /(mqqbrowser|micromessenger|sogou|qzone|liebao|maxthon|mxbrowser|baidu)(mobile)?(browser)?\/?([\d.]+)/i;
+ var versionReg2 = /(msie |rv:|firefox|chrome|ucbrowser|qq|oupeng|opera|opr|safari|miui)(mobile)?(browser)?\/?([\d.]+)/i;
var tmp = ua.match(versionReg1);
if(!tmp) tmp = ua.match(versionReg2);
sys.browserVersion = tmp ? tmp[4] : "";
@@ -1844,7 +1932,7 @@ var _initSys = function () {
var tmpCanvas = document.createElement("CANVAS");
try{
var context = cc.create3DContext(tmpCanvas);
- if (context && context.getShaderPrecisionFormat) {
+ if (context) {
_supportWebGL = true;
}
@@ -2330,6 +2418,7 @@ cc.game = /** @lends cc.game# */{
config[CONFIG_KEY.frameRate] = frameRate;
if (self._intervalId)
window.cancelAnimationFrame(self._intervalId);
+ self._intervalId = 0;
self._paused = true;
self._setAnimFrame();
self._runMainLoop();
@@ -2512,8 +2601,9 @@ cc.game = /** @lends cc.game# */{
// @Time ticker section
_setAnimFrame: function () {
this._lastTime = new Date();
- this._frameTime = 1000 / cc.game.config[cc.game.CONFIG_KEY.frameRate];
- if ((cc.sys.os === cc.sys.OS_IOS && cc.sys.browserType === cc.sys.BROWSER_TYPE_WECHAT) || cc.game.config[cc.game.CONFIG_KEY.frameRate] !== 60) {
+ var frameRate = cc.game.config[cc.game.CONFIG_KEY.frameRate];
+ this._frameTime = 1000 / frameRate;
+ if (frameRate !== 60 && frameRate !== 30) {
window.requestAnimFrame = this._stTime;
window.cancelAnimationFrame = this._ctTime;
}
@@ -2551,20 +2641,26 @@ cc.game = /** @lends cc.game# */{
//Run game.
_runMainLoop: function () {
var self = this, callback, config = self.config, CONFIG_KEY = self.CONFIG_KEY,
- director = cc.director;
+ director = cc.director,
+ skip = true, frameRate = config[CONFIG_KEY.frameRate];
director.setDisplayStats(config[CONFIG_KEY.showFPS]);
callback = function () {
if (!self._paused) {
+ if (frameRate === 30) {
+ if (skip = !skip) {
+ self._intervalId = window.requestAnimFrame(callback);
+ return;
+ }
+ }
+
director.mainLoop();
- if (self._intervalId)
- window.cancelAnimationFrame(self._intervalId);
self._intervalId = window.requestAnimFrame(callback);
}
};
- window.requestAnimFrame(callback);
+ self._intervalId = window.requestAnimFrame(callback);
self._paused = false;
},
@@ -2660,7 +2756,7 @@ cc.game = /** @lends cc.game# */{
}
width = width || element.clientWidth;
height = height || element.clientHeight;
- this.canvas = cc._canvas = localCanvas = document.createElement("CANVAS");
+ this.canvas = cc._canvas = localCanvas = cc.$(document.createElement("CANVAS"));
this.container = cc.container = localContainer = document.createElement("DIV");
element.appendChild(localContainer);
}
diff --git a/README.mdown b/README.mdown
index c41b79bc2c..3b13c27fac 100644
--- a/README.mdown
+++ b/README.mdown
@@ -1,40 +1,26 @@
Cocos2d-html5
==================
-[Cocos2d-html5][1] is a cross-platform 2D game engine written in Javascript, based on [Cocos2d-X][2] and licensed under MIT.
+[Cocos2d-html5][1] is a cross-platform 2D game engine written in JavaScript, based on [Cocos2d-X][2] and licensed under MIT.
It incorporates the same high level api as “Cocos2d JS-binding engine” and compatible with Cocos2d-X.
It currently supports canvas and WebGL renderer.
+-------------
+
+#### Cocos2d-html5 has evolved to [Cocos Creator][11], new generation of Cocos game engine with a full featured editor and content creation friendly workflow. It supports all major platforms allowing games to be quickly released for the web, iOS, Android, Windows, Mac, and various mini-game platforms. A pure JavaScript-developed engine runtime is available on the web and mini-game platforms for better performance and smaller packages. On other native platforms, C++ is used to implement the underlying framework, providing greater operational efficiency. The latest repository is maintained in here [Engine of Cocos Creator][9].
+
+-------------
+
Cross Platform
-------------
* Popular browsers: Chrome 14+, Safari 5.0+, IE9+, Firefox 3.5+.
- * Mobile platforms: coming soon.
+ * Mobile platforms: Mobile browsers,Facebook Instant Games and Mini Games.
* Native App: Same piece of code can run on "Cocos2d JS-Binding Engine" without or with little modification.
Documentation
------------------
* Website: [www.cocos2d-x.org][3]
- * API References: [http://www.cocos2d-x.org/wiki/Reference] [4]
-
-
-Installing from [bower][8] (version >=3.4)
-------------------
-
-```shell
-$ bower install cocos2d-html5
-```
-
-Running the tests (version <3)
-------------------
-
-```shell
-$ git clone git://github.com/cocos2d/cocos2d-html5.git
-$ cd cocos2d-html5
-$ git submodule update --init
-$ python -m SimpleHTTPServer
-```
-... and then open a browser and go to `http://localhost:8000/tests`
-
+ * Cocos Creator download: [Cocos Creator][10]
Contact us
------------------
@@ -49,4 +35,7 @@ Contact us
[5]: http://forum.cocos2d-x.org "http://forum.cocos2d-x.org"
[6]: http://www.twitter.com/cocos2dhtml5 "http://www.twitter.com/cocos2dhtml5"
[7]: http://t.sina.com.cn/cocos2dhtml5 "http://t.sina.com.cn/cocos2dhtml5"
-[8]: http://bower.io "http://bower.io"
\ No newline at end of file
+[8]: http://bower.io "http://bower.io"
+[9]: https://github.com/cocos-creator/engine
+[10]: http://cocos2d-x.org/download
+[11]: https://www.cocos.com/en/products#CocosCreator "https://www.cocos.com"
diff --git a/cocos2d/actions/CCActionInterval.js b/cocos2d/actions/CCActionInterval.js
index 74a855748e..905d72b0a2 100644
--- a/cocos2d/actions/CCActionInterval.js
+++ b/cocos2d/actions/CCActionInterval.js
@@ -137,7 +137,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
*
* @example
* //example
- * action.easeing(cc.easeIn(3.0));
+ * action.easing(cc.easeIn(3.0));
* @param {Object} easeObj
* @returns {cc.ActionInterval}
*/
@@ -997,7 +997,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Create a spawn action which runs several actions in parallel.
* @function
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
* @example
* // example
* var action = cc.spawn(cc.jumpBy(2, cc.p(300, 0), 50, 4), cc.rotateBy(2, 720));
@@ -1022,7 +1022,7 @@ cc.spawn = function (/*Multiple Arguments*/tempArray) {
* @static
* @deprecated since v3.0
Please use cc.spawn instead.
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
*/
cc.Spawn.create = cc.spawn;
@@ -1083,7 +1083,7 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._dstAngleX = deltaAngleX || 0;
- this._dstAngleY = deltaAngleY || this._dstAngleX;
+ this._dstAngleY = deltaAngleY !== undefined ? deltaAngleY : this._dstAngleX;
return true;
}
return false;
@@ -1311,7 +1311,7 @@ cc.RotateBy.create = cc.rotateBy;
* @param {cc.Point|Number} deltaPos
* @param {Number} [deltaY]
* @example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
_positionDelta: null,
@@ -1430,7 +1430,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* @return {cc.MoveBy}
* @example
* // example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.moveBy = function (duration, deltaPos, deltaY) {
return new cc.MoveBy(duration, deltaPos, deltaY);
@@ -1458,7 +1458,7 @@ cc.MoveBy.create = cc.moveBy;
* @param {cc.Point|Number} position
* @param {Number} y
* @example
- * var actionBy = new cc.MoveTo(2, cc.p(80, 80));
+ * var actionTo = new cc.MoveTo(2, cc.p(80, 80));
*/
cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
_endPosition: null,
@@ -1524,12 +1524,12 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* Moving to the specified coordinates.
* @function
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
* @example
* // example
- * var actionBy = cc.moveTo(2, cc.p(80, 80));
+ * var actionTo = cc.moveTo(2, cc.p(80, 80));
*/
cc.moveTo = function (duration, position, y) {
return new cc.MoveTo(duration, position, y);
@@ -1540,9 +1540,9 @@ cc.moveTo = function (duration, position, y) {
* @static
* @deprecated since v3.0
Please use cc.moveTo instead.
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
*/
cc.MoveTo.create = cc.moveTo;
diff --git a/cocos2d/clipping-nodes/CCClippingNode.js b/cocos2d/clipping-nodes/CCClippingNode.js
index c7a1921b27..7214ea13e7 100644
--- a/cocos2d/clipping-nodes/CCClippingNode.js
+++ b/cocos2d/clipping-nodes/CCClippingNode.js
@@ -128,9 +128,6 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
},
visit: function (parent) {
- if (!this._visible)
- return;
-
this._renderCmd.clippingVisit(parent && parent._renderCmd);
},
diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
index d563fb711c..6d8956a32b 100644
--- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
+++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
@@ -22,6 +22,17 @@
THE SOFTWARE.
****************************************************************************/
+function setProgram (node, program) {
+ node.shaderProgram = program;
+
+ var children = node.children;
+ if (!children)
+ return;
+
+ for (var i = 0; i < children.length; i++)
+ setProgram(children[i], program);
+}
+
// ------------------------------- ClippingNode's WebGL render cmd ------------------------------
(function () {
cc.ClippingNode.WebGLRenderCmd = function (renderable) {
@@ -128,7 +139,7 @@
var node = this._node;
if (node._stencil) {
var program = node._originStencilProgram;
- cc.setProgram(node._stencil, program);
+ setProgram(node._stencil, program);
}
};
diff --git a/cocos2d/core/CCActionManager.js b/cocos2d/core/CCActionManager.js
index f3c90b46ab..980be114b4 100644
--- a/cocos2d/core/CCActionManager.js
+++ b/cocos2d/core/CCActionManager.js
@@ -30,25 +30,14 @@
* @example
* var element = new cc.HashElement();
*/
-cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
- actions:null,
- target:null, //ccobject
- actionIndex:0,
- currentAction:null, //CCAction
- currentActionSalvaged:false,
- paused:false,
- /**
- * Constructor
- */
- ctor:function () {
- this.actions = [];
- this.target = null;
- this.actionIndex = 0;
- this.currentAction = null; //CCAction
- this.currentActionSalvaged = false;
- this.paused = false;
- }
-});
+cc.HashElement = function () {
+ this.actions = [];
+ this.target = null;
+ this.actionIndex = 0;
+ this.currentAction = null; //CCAction
+ this.paused = false;
+ this.lock = false;
+};
/**
* cc.ActionManager is a class that can manage actions.
@@ -64,10 +53,6 @@ cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
* var mng = new cc.ActionManager();
*/
cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
- _hashTargets:null,
- _arrayTargets:null,
- _currentTarget:null,
- _currentTargetSalvaged:false,
_elementPool: [],
_searchElementByTarget:function (arr, target) {
@@ -82,7 +67,6 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
this._hashTargets = {};
this._arrayTargets = [];
this._currentTarget = null;
- this._currentTargetSalvaged = false;
},
_getElement: function (target, paused) {
@@ -99,8 +83,9 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
element.actions.length = 0;
element.actionIndex = 0;
element.currentAction = null;
- element.currentActionSalvaged = false;
element.paused = false;
+ element.target = null;
+ element.lock = false;
this._elementPool.push(element);
},
@@ -116,7 +101,7 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
if(!action)
throw new Error("cc.ActionManager.addAction(): action must be non-null");
if(!target)
- throw new Error("cc.ActionManager.addAction(): action must be non-null");
+ throw new Error("cc.ActionManager.addAction(): target must be non-null");
//check if the action target already exists
var element = this._hashTargets[target.__instanceId];
@@ -156,15 +141,8 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
return;
var element = this._hashTargets[target.__instanceId];
if (element) {
- if (element.actions.indexOf(element.currentAction) !== -1 && !(element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.length = 0;
- if (this._currentTarget === element && !forceDelete) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
/** Removes an action given an action reference.
@@ -181,6 +159,9 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var i = 0; i < element.actions.length; i++) {
if (element.actions[i] === action) {
element.actions.splice(i, 1);
+ // update actionIndex in case we are in tick. looping over the actions
+ if (element.actionIndex >= i)
+ element.actionIndex--;
break;
}
}
@@ -291,10 +272,10 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
* @param {Array} targetsToResume
*/
resumeTargets:function(targetsToResume){
- if(!targetsToResume)
+ if (!targetsToResume)
return;
- for(var i = 0 ; i< targetsToResume.length; i++){
+ for (var i = 0; i< targetsToResume.length; i++) {
if(targetsToResume[i])
this.resumeTarget(targetsToResume[i]);
}
@@ -311,9 +292,6 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
_removeActionAtIndex:function (index, element) {
var action = element.actions[index];
- if ((action === element.currentAction) && (!element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.splice(index, 1);
// update actionIndex in case we are in tick. looping over the actions
@@ -321,17 +299,13 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
element.actionIndex--;
if (element.actions.length === 0) {
- if (this._currentTarget === element) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
_deleteHashElement:function (element) {
var ret = false;
- if (element) {
+ if (element && !element.lock) {
if (this._hashTargets[element.target.__instanceId]) {
delete this._hashTargets[element.target.__instanceId];
var targets = this._arrayTargets;
@@ -356,41 +330,30 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var elt = 0; elt < locTargets.length; elt++) {
this._currentTarget = locTargets[elt];
locCurrTarget = this._currentTarget;
- //this._currentTargetSalvaged = false;
- if (!locCurrTarget.paused) {
+ if (!locCurrTarget.paused && locCurrTarget.actions) {
+ locCurrTarget.lock = true;
// The 'actions' CCMutableArray may change while inside this loop.
- for (locCurrTarget.actionIndex = 0;
- locCurrTarget.actionIndex < (locCurrTarget.actions ? locCurrTarget.actions.length : 0);
- locCurrTarget.actionIndex++) {
+ for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
if (!locCurrTarget.currentAction)
continue;
- locCurrTarget.currentActionSalvaged = false;
//use for speed
locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
- if (locCurrTarget.currentActionSalvaged) {
- // The currentAction told the node to remove it. To prevent the action from
- // accidentally deallocating itself before finishing its step, we retained
- // it. Now that step is done, it's safe to release it.
- locCurrTarget.currentAction = null;//release
- } else if (locCurrTarget.currentAction.isDone()) {
+
+ if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
locCurrTarget.currentAction.stop();
var action = locCurrTarget.currentAction;
- // Make currentAction nil to prevent removeAction from salvaging it.
locCurrTarget.currentAction = null;
this.removeAction(action);
}
locCurrTarget.currentAction = null;
}
+ locCurrTarget.lock = false;
}
-
- // elt, at this moment, is still valid
- // so it is safe to ask this here (issue #490)
-
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
- if (this._currentTargetSalvaged && locCurrTarget.actions.length === 0) {
+ if (locCurrTarget.actions.length === 0) {
this._deleteHashElement(locCurrTarget) && elt--;
}
}
diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js
index b906a7fbd7..b8a021f43c 100644
--- a/cocos2d/core/CCDirector.js
+++ b/cocos2d/core/CCDirector.js
@@ -136,6 +136,7 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
//action manager
if (cc.ActionManager) {
this._actionManager = new cc.ActionManager();
+ this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
} else {
this._actionManager = null;
}
@@ -183,7 +184,7 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
convertToGL: function (uiPoint) {
var docElem = document.documentElement;
var view = cc.view;
- var box = element.getBoundingClientRect();
+ var box = docElem.getBoundingClientRect();
box.left += window.pageXOffset - docElem.clientLeft;
box.top += window.pageYOffset - docElem.clientTop;
var x = view._devicePixelRatio * (uiPoint.x - box.left);
@@ -202,7 +203,7 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
convertToUI: function (glPoint) {
var docElem = document.documentElement;
var view = cc.view;
- var box = element.getBoundingClientRect();
+ var box = docElem.getBoundingClientRect();
box.left += window.pageXOffset - docElem.clientLeft;
box.top += window.pageYOffset - docElem.clientTop;
var uiPoint = {x: 0, y: 0};
@@ -228,7 +229,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
//tick before glClear: issue #533
if (!this._paused) {
- this._actionManager.update(this._deltaTime);
this._scheduler.update(this._deltaTime);
cc.eventManager.dispatchEvent(this._eventAfterUpdate);
}
@@ -943,4 +943,4 @@ cc.Director.PROJECTION_CUSTOM = 3;
* @constant
* @type {Number}
*/
-cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_2D;
+cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D;
diff --git a/cocos2d/core/CCDrawingPrimitivesCanvas.js b/cocos2d/core/CCDrawingPrimitivesCanvas.js
index ce4c914a85..f94b4ca297 100644
--- a/cocos2d/core/CCDrawingPrimitivesCanvas.js
+++ b/cocos2d/core/CCDrawingPrimitivesCanvas.js
@@ -56,11 +56,9 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
if (!size) {
size = 1;
}
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
- var newPoint = cc.p(point.x * locScaleX, point.y * locScaleY);
var ctx = this._renderContext.getContext();
ctx.beginPath();
- ctx.arc(newPoint.x, -newPoint.y, size * locScaleX, 0, Math.PI * 2, false);
+ ctx.arc(point.x, -point.y, size, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
},
@@ -79,11 +77,11 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
if (!size) {
size = 1;
}
- var locContext = this._renderContext.getContext(),locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
+ var locContext = this._renderContext.getContext();
locContext.beginPath();
for (var i = 0, len = points.length; i < len; i++)
- locContext.arc(points[i].x * locScaleX, -points[i].y * locScaleY, size * locScaleX, 0, Math.PI * 2, false);
+ locContext.arc(points[i].x, -points[i].y, size, 0, Math.PI * 2, false);
locContext.closePath();
locContext.fill();
},
@@ -95,7 +93,7 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
* @param {cc.Point} destination
*/
drawLine:function (origin, destination) {
- var locContext = this._renderContext.getContext(), locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
+ var locContext = this._renderContext.getContext();
locContext.beginPath();
locContext.moveTo(origin.x , -origin.y );
locContext.lineTo(destination.x, -destination.y );
@@ -151,7 +149,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
throw new Error("Polygon's point must greater than 2");
var firstPoint = vertices[0], locContext = this._renderContext.getContext();
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
locContext.beginPath();
locContext.moveTo(firstPoint.x , -firstPoint.y );
for (var i = 1, len = vertices.length; i < len; i++)
@@ -189,7 +186,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
drawCircle: function (center, radius, angle, segments, drawLineToCenter) {
drawLineToCenter = drawLineToCenter || false;
var locContext = this._renderContext.getContext();
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
locContext.beginPath();
var endAngle = angle - Math.PI * 2;
locContext.arc(0 | (center.x ), 0 | -(center.y ), radius , -angle, -endAngle, false);
@@ -379,7 +375,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
drawColorBall:function (ctx, radius, color) {
var wrapper = ctx || this._renderContext;
var context = wrapper.getContext();
- radius *= cc.view.getScaleX();
var colorStr = "rgba(" +(0|color.r) + "," + (0|color.g) + "," + (0|color.b);
var subRadius = radius / 10;
@@ -432,6 +427,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
* @param {Number} width
*/
setLineWidth:function (width) {
- this._renderContext.getContext().lineWidth = width * cc.view.getScaleX();
+ this._renderContext.getContext().lineWidth = width;
}
});
\ No newline at end of file
diff --git a/cocos2d/core/CCDrawingPrimitivesWebGL.js b/cocos2d/core/CCDrawingPrimitivesWebGL.js
index f8c9b46d0d..6daa60cb01 100644
--- a/cocos2d/core/CCDrawingPrimitivesWebGL.js
+++ b/cocos2d/core/CCDrawingPrimitivesWebGL.js
@@ -61,6 +61,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
_t._shader = cc.shaderCache.programForKey(cc.SHADER_POSITION_UCOLOR);
_t._shader._addUniformLocation(this._colorLocation);
_t._shader._addUniformLocation(this._pointSizeLocation);
+ _t._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(_t._shader);
_t._initialized = true;
}
@@ -81,7 +82,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -110,7 +111,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -145,7 +146,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -200,7 +201,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -231,7 +232,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.setDrawColor(color.r, color.g, color.b, color.a);
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -279,7 +280,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[(segments + 1) * 2 + 1] = center.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -317,7 +318,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[segments * 2 + 1] = destination.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -356,7 +357,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[segments * 2 + 1] = destination.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -416,7 +417,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
}
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
diff --git a/cocos2d/core/CCScheduler.js b/cocos2d/core/CCScheduler.js
index 0c75dc15af..1504bd70c0 100644
--- a/cocos2d/core/CCScheduler.js
+++ b/cocos2d/core/CCScheduler.js
@@ -385,7 +385,7 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
_removeUpdateFromHash:function (entry) {
var self = this;
- element = self._hashForUpdates[entry.target.__instanceId];
+ var element = self._hashForUpdates[entry.target.__instanceId];
if (element) {
// Remove list entry from list
var list = element.list, listEntry = element.entry;
diff --git a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
index 8fce00f8da..5810d00794 100644
--- a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
@@ -68,8 +68,7 @@
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
if (this._uniformColor && this._colorF32Array) {
diff --git a/cocos2d/core/base-nodes/CCNode.js b/cocos2d/core/base-nodes/CCNode.js
index 2b62bc06c4..9d3e6f15e5 100644
--- a/cocos2d/core/base-nodes/CCNode.js
+++ b/cocos2d/core/base-nodes/CCNode.js
@@ -306,6 +306,8 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {Number} localZOrder
*/
setLocalZOrder: function (localZOrder) {
+ if (localZOrder === this._localZOrder)
+ return;
if (this._parent)
this._parent.reorderChild(this, localZOrder);
else
@@ -1365,9 +1367,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
cc.log(cc._LogInfos.Node_reorderChild_2);
return;
}
- if (zOrder === child.zIndex) {
- return;
- }
cc.renderer.childrenOrderDirty = this._reorderChildDirty = true;
child.arrivalOrder = cc.s_globalOrderOfArrival;
cc.s_globalOrderOfArrival++;
@@ -2015,7 +2014,7 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
updateTransform: function () {
var children = this._children, node;
for (var i = 0; i < children.length; i++) {
- varnode = children[i];
+ node = children[i];
if (node)
node.updateTransform();
}
@@ -2102,12 +2101,16 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {cc.Node} parent
*/
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var renderer = cc.renderer, cmd = this._renderCmd;
- cmd.visit(parent && parent._renderCmd);
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
var i, children = this._children, len = children.length, child;
if (len > 0) {
@@ -2236,6 +2239,14 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
this._renderCmd.setShaderProgram(newShaderProgram);
},
+ setGLProgramState: function (glProgramState) {
+ this._renderCmd.setGLProgramState(glProgramState);
+ },
+
+ getGLProgramState: function () {
+ return this._renderCmd.getGLProgramState();
+ },
+
/**
* Returns the state of OpenGL server side.
* @function
diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
index 1cc0bef5f6..43c46d0f7f 100644
--- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
@@ -442,6 +442,22 @@ cc.Node.RenderCmd.prototype = {
_updateColor: function () {
},
+ _propagateFlagsDown: function (parentCmd) {
+ var locFlag = this._dirtyFlag;
+ var parentNode = parentCmd ? parentCmd._node : null;
+
+ if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & dirtyFlags.colorDirty))
+ locFlag |= dirtyFlags.colorDirty;
+
+ if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & dirtyFlags.opacityDirty))
+ locFlag |= dirtyFlags.opacityDirty;
+
+ if(parentCmd && (parentCmd._dirtyFlag & dirtyFlags.transformDirty))
+ locFlag |= dirtyFlags.transformDirty;
+
+ this._dirtyFlag = locFlag;
+ },
+
updateStatus: function () {
var locFlag = this._dirtyFlag;
var colorDirty = locFlag & dirtyFlags.colorDirty,
@@ -513,7 +529,23 @@ cc.Node.RenderCmd.prototype = {
if (locFlag & dirtyFlags.orderDirty)
this._dirtyFlag &= ~dirtyFlags.orderDirty;
- }
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //do nothing.
+ },
+
+ getShaderProgram: function () {
+ return null;
+ },
+
+ getGLProgramState: function () {
+ return null;
+ },
+
+ setGLProgramState: function (glProgramState) {
+ // do nothing
+ },
};
cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform;
@@ -607,14 +639,6 @@ cc.Node.RenderCmd.prototype._originSyncStatus = cc.Node.RenderCmd.prototype._syn
}
};
- proto.setShaderProgram = function (shaderProgram) {
- //do nothing.
- };
-
- proto.getShaderProgram = function () {
- return null;
- };
-
//util functions
cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc = function (blendFunc) {
if (!blendFunc)
diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
index 62e469800e..7680017273 100644
--- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
@@ -27,7 +27,7 @@
this._node = renderable;
this._anchorPointInPoints = {x: 0, y: 0};
this._displayedColor = cc.color(255, 255, 255, 255);
- this._shaderProgram = null;
+ this._glProgramState = null;
};
var proto = cc.Node.WebGLRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
@@ -38,10 +38,28 @@
};
proto.setShaderProgram = function (shaderProgram) {
- this._shaderProgram = shaderProgram;
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
};
proto.getShaderProgram = function () {
- return this._shaderProgram;
+ return this._glProgramState ? this._glProgramState.getGLProgram() : null;
};
+
+ proto.getGLProgramState = function () {
+ return this._glProgramState;
+ };
+
+ proto.setGLProgramState = function (glProgramState) {
+ this._glProgramState = glProgramState;
+ };
+
+ // Use a property getter/setter for backwards compatability, and
+ // to ease the transition from using glPrograms directly, to
+ // using glProgramStates.
+ Object.defineProperty(proto, '_shaderProgram', {
+ set: function (value) { this.setShaderProgram(value); },
+ get: function () { return this.getShaderProgram(); }
+ });
+ /** @expose */
+ proto._shaderProgram;
})();
diff --git a/cocos2d/core/event-manager/CCEventListener.js b/cocos2d/core/event-manager/CCEventListener.js
index 06e5bd4eee..c970c43fdf 100644
--- a/cocos2d/core/event-manager/CCEventListener.js
+++ b/cocos2d/core/event-manager/CCEventListener.js
@@ -277,15 +277,16 @@ cc.EventListener.CUSTOM = 8;
cc._EventListenerCustom = cc.EventListener.extend({
_onCustomEvent: null,
- ctor: function (listenerId, callback) {
+ ctor: function (listenerId, callback, target) {
this._onCustomEvent = callback;
- var selfPointer = this;
- var listener = function (event) {
- if (selfPointer._onCustomEvent !== null)
- selfPointer._onCustomEvent(event);
- };
+ this._target = target;
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, this._callback);
+ },
+
+ _callback: function (event) {
+ if (this._onCustomEvent !== null)
+ this._onCustomEvent.call(this._target, event);
},
checkAvailable: function () {
@@ -308,31 +309,31 @@ cc._EventListenerMouse = cc.EventListener.extend({
onMouseScroll: null,
ctor: function () {
- var selfPointer = this;
- var listener = function (event) {
- var eventType = cc.EventMouse;
- switch (event._eventType) {
- case eventType.DOWN:
- if (selfPointer.onMouseDown)
- selfPointer.onMouseDown(event);
- break;
- case eventType.UP:
- if (selfPointer.onMouseUp)
- selfPointer.onMouseUp(event);
- break;
- case eventType.MOVE:
- if (selfPointer.onMouseMove)
- selfPointer.onMouseMove(event);
- break;
- case eventType.SCROLL:
- if (selfPointer.onMouseScroll)
- selfPointer.onMouseScroll(event);
- break;
- default:
- break;
- }
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, this._callback);
+ },
+
+ _callback: function (event) {
+ var eventType = cc.EventMouse;
+ switch (event._eventType) {
+ case eventType.DOWN:
+ if (this.onMouseDown)
+ this.onMouseDown(event);
+ break;
+ case eventType.UP:
+ if (this.onMouseUp)
+ this.onMouseUp(event);
+ break;
+ case eventType.MOVE:
+ if (this.onMouseMove)
+ this.onMouseMove(event);
+ break;
+ case eventType.SCROLL:
+ if (this.onMouseScroll)
+ this.onMouseScroll(event);
+ break;
+ default:
+ break;
+ }
},
clone: function () {
@@ -501,11 +502,12 @@ cc._EventListenerFocus = cc.EventListener.extend({
},
onFocusChanged: null,
ctor: function(){
- var listener = function(event){
- if(this.onFocusChanged)
- this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, this._callback);
+ },
+ _callback: function (event) {
+ if (this.onFocusChanged) {
+ this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
+ }
}
});
diff --git a/cocos2d/core/event-manager/CCEventManager.js b/cocos2d/core/event-manager/CCEventManager.js
index 890ba5bf7c..7f54f03939 100644
--- a/cocos2d/core/event-manager/CCEventManager.js
+++ b/cocos2d/core/event-manager/CCEventManager.js
@@ -258,8 +258,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (!this._inDispatch) {
listeners.clear();
- delete this._listenersMap[listenerID];
}
+ delete this._listenersMap[listenerID];
}
var locToAddedListeners = this._toAddedListeners, listener;
@@ -751,8 +751,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
* @param {function} callback
* @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
*/
- addCustomListener: function (eventName, callback) {
- var listener = new cc._EventListenerCustom(eventName, callback);
+ addCustomListener: function (eventName, callback, target) {
+ var listener = new cc._EventListenerCustom(eventName, callback, target);
this.addListener(listener, 1);
return listener;
},
diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js
index 2342fc555c..ac988109b9 100644
--- a/cocos2d/core/labelttf/CCLabelTTF.js
+++ b/cocos2d/core/labelttf/CCLabelTTF.js
@@ -826,7 +826,11 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
_t._rectRotated = rotated || false;
_t.setContentSize(untrimmedSize || rect);
- _t.setVertexRect(rect);
+ var locRect = _t._rect;
+ locRect.x = rect.x;
+ locRect.y = rect.y;
+ locRect.width = rect.width;
+ locRect.height = rect.height;
_t._renderCmd._setTextureCoords(rect, false);
var relativeOffsetX = _t._unflippedOffsetPositionFromCenter.x, relativeOffsetY = _t._unflippedOffsetPositionFromCenter.y;
@@ -834,7 +838,6 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
relativeOffsetX = -relativeOffsetX;
if (_t._flippedY)
relativeOffsetY = -relativeOffsetY;
- var locRect = _t._rect;
_t._offsetPosition.x = relativeOffsetX + (rect.width - locRect.width) / 2;
_t._offsetPosition.y = relativeOffsetY + (rect.height - locRect.height) / 2;
},
diff --git a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
index 51fb3888b4..44c8f1866f 100644
--- a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
+++ b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
@@ -24,13 +24,25 @@ cc.LabelTTF._textBaseline = ["top", "middle", "bottom"];
//check the first character
cc.LabelTTF.wrapInspection = true;
-//Support: English French German
-//Other as Oriental Language
-cc.LabelTTF._wordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)/;
-cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》?。,!]/;
-cc.LabelTTF._lastWordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)$/;
-cc.LabelTTF._lastEnglish = /[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+$/;
-cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
+// These regular expressions consider a word any sequence of characters
+// from these Unicode (sub)blocks:
+// - Basic Latin (letters and numbers, plus the hypen-minus '-')
+// - Latin-1 Supplement (accentuated letters and ¿¡ only)
+// - Latin Extended-A (complete)
+// - Latin Extended-B (complete)
+// - IPA Extensions (complete)
+// - Spacing Modifier Letters (complete)
+// - Combining Diacritical Marks (Combining Grapheme Joiner excluded)
+// - Greek and Coptic (complete, including reserved code points)
+// - Cyrillic (complete)
+// - Cyrillic Supplement (complete)
+// - General Punctuation (Non-Breaking Hyphen* [U+2011] and quotation marks)
+// * Note that Hyphen [U+2010] is considered a word boundary.
+cc.LabelTTF._wordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)/;
+cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》»?。,!\u2010′-‴›‼⁆⁇-⁉]/;
+cc.LabelTTF._lastWordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)$/;
+cc.LabelTTF._lastEnglish = /[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+$/;
+cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]/;
(function () {
cc.LabelTTF.RenderCmd = function () {
@@ -375,8 +387,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
var locStrLen = this._strings.length;
for (var i = 0; i < locStrLen; i++) {
var line = this._strings[i];
- if (locStrokeEnabled)
+ if (locStrokeEnabled) {
+ context.lineJoin = 'round';
context.strokeText(line, xOffset, yOffsetArray[i]);
+ }
context.fillText(line, xOffset, yOffsetArray[i]);
}
cc.g_NumberOfDraws++;
@@ -418,7 +432,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
if (node._string.length === 0) {
locLabelCanvas.width = 1;
locLabelCanvas.height = locContentSize.height || 1;
- node._texture && node._texture.handleLoadedTexture();
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
return true;
}
@@ -432,7 +449,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
if (flag) locContext.clearRect(0, 0, width, height);
this._saveStatus();
this._drawTTFInCanvas(locContext);
- node._texture && node._texture.handleLoadedTexture();
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
node.setTextureRect(cc.rect(0, 0, width, height));
return true;
};
diff --git a/cocos2d/core/layers/CCLayer.js b/cocos2d/core/layers/CCLayer.js
index db1e783a2e..c752ad814f 100644
--- a/cocos2d/core/layers/CCLayer.js
+++ b/cocos2d/core/layers/CCLayer.js
@@ -75,12 +75,16 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
},
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var renderer = cc.renderer, cmd = this._renderCmd;
- cmd.visit(parent && parent._renderCmd);
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
if (cmd._isBaked) {
renderer.pushRenderCommand(cmd);
@@ -247,13 +251,17 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
return true;
},
- visit: function () {
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var renderer = cc.renderer, cmd = this._renderCmd;
- cmd.visit(parent && parent._renderCmd);
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
if (cmd._isBaked) {
renderer.pushRenderCommand(cmd._bakeRenderCmd);
diff --git a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
index 544428278b..4acf7f22d6 100644
--- a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
+++ b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
@@ -136,8 +136,7 @@
this._dataDirty = false;
}
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
@@ -302,8 +301,7 @@
}
//draw gradient layer
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
diff --git a/cocos2d/core/platform/CCClass.js b/cocos2d/core/platform/CCClass.js
index 6b7a2e8043..be34ad92eb 100644
--- a/cocos2d/core/platform/CCClass.js
+++ b/cocos2d/core/platform/CCClass.js
@@ -140,19 +140,19 @@ cc.inject = function (srcPrototype, destPrototype) {
* @namespace
* @name ClassManager
*/
-var ClassManager = {
- id : (0|(Math.random()*998)),
+var ClassManager = function () {
+ var id = (0|(Math.random()*998));
+ var instanceId = (0|(Math.random()*998));
- instanceId : (0|(Math.random()*998)),
-
- getNewID : function(){
- return this.id++;
- },
+ this.getNewID = function () {
+ return id++;
+ };
- getNewInstanceId : function(){
- return this.instanceId++;
- }
+ this.getNewInstanceId = function () {
+ return instanceId++;
+ };
};
+var classManager = new ClassManager();
/* Managed JavaScript Inheritance
* Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/
@@ -192,7 +192,7 @@ var ClassManager = {
var Class;
if (cc.game.config && cc.game.config[cc.game.CONFIG_KEY.exposeClassName]) {
var constructor = "(function " + (props._className || "Class") + " (arg0, arg1, arg2, arg3, arg4, arg5) {\n";
- constructor += " this.__instanceId = ClassManager.getNewInstanceId();\n";
+ constructor += " this.__instanceId = classManager.getNewInstanceId();\n";
constructor += " if (this.ctor) {\n";
constructor += " switch (arguments.length) {\n";
constructor += " case 0: this.ctor(); break;\n";
@@ -208,7 +208,7 @@ var ClassManager = {
}
else {
Class = function (arg0, arg1, arg2, arg3, arg4) {
- this.__instanceId = ClassManager.getNewInstanceId();
+ this.__instanceId = classManager.getNewInstanceId();
if (this.ctor) {
switch (arguments.length) {
case 0: this.ctor(); break;
@@ -223,7 +223,7 @@ var ClassManager = {
};
}
- desc.value = ClassManager.getNewID();
+ desc.value = classManager.getNewID();
Object.defineProperty(prototype, '__pid', desc);
// Populate our constructed prototype object
diff --git a/cocos2d/core/platform/CCConfig.js b/cocos2d/core/platform/CCConfig.js
index 027bede099..b4795155ed 100644
--- a/cocos2d/core/platform/CCConfig.js
+++ b/cocos2d/core/platform/CCConfig.js
@@ -31,7 +31,7 @@
* @type {String}
* @name cc.ENGINE_VERSION
*/
-window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.14";
+window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.17";
/**
*
@@ -165,23 +165,6 @@ cc.TEXTURE_ATLAS_USE_VAO = 0; */ cc.TEXTURE_NPOT_SUPPORT = 0; -/** - *
- * If enabled, cocos2d supports retina display.
- * For performance reasons, it's recommended disable it in games without retina display support, like iPad only games.
- *
- * To enable set it to 1. Use 0 to disable it. Enabled by default.
- *
- * This value governs only the PNG, GIF, BMP, images.
- * This value DOES NOT govern the PVR (PVR.GZ, PVR.CCZ) files. If NPOT PVR is loaded, then it will create an NPOT texture ignoring this value.
- * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
- *
* It's the suffix that will be appended to the files in order to load "retina display" images.
@@ -262,13 +245,6 @@ cc.LABELATLAS_DEBUG_DRAW = 0;
cc.DRAWNODE_TOTAL_VERTICES = 20000;
-/**
- * Whether or not support retina display
- * @constant
- * @type {Number}
- */
-cc.IS_RETINA_DISPLAY_SUPPORTED = 0;
-
/**
* Default engine
* @constant
diff --git a/cocos2d/core/platform/CCEGLView.js b/cocos2d/core/platform/CCEGLView.js
index 37c89fd688..f91e54b8b8 100755
--- a/cocos2d/core/platform/CCEGLView.js
+++ b/cocos2d/core/platform/CCEGLView.js
@@ -37,7 +37,7 @@ cc.DENSITYDPI_LOW = "low-dpi";
var __BrowserGetter = {
init: function () {
- this.html = document.getElementsByTagName("html")[0];
+ this.html = document.documentElement;
},
availWidth: function (frame) {
if (!frame || frame === this.html)
@@ -66,25 +66,11 @@ if (cc.sys.os === cc.sys.OS_IOS) // All browsers are WebView
switch (__BrowserGetter.adaptationType) {
case cc.sys.BROWSER_TYPE_SAFARI:
__BrowserGetter.meta["minimal-ui"] = "true";
- __BrowserGetter.availWidth = function (frame) {
- return frame.clientWidth;
- };
- __BrowserGetter.availHeight = function (frame) {
- return frame.clientHeight;
- };
break;
case cc.sys.BROWSER_TYPE_CHROME:
__BrowserGetter.__defineGetter__("target-densitydpi", function () {
return cc.view._targetDensityDPI;
});
- case cc.sys.BROWSER_TYPE_SOUGOU:
- case cc.sys.BROWSER_TYPE_UC:
- __BrowserGetter.availWidth = function (frame) {
- return frame.clientWidth;
- };
- __BrowserGetter.availHeight = function (frame) {
- return frame.clientHeight;
- };
break;
case cc.sys.BROWSER_TYPE_MIUI:
__BrowserGetter.init = function (view) {
@@ -140,6 +126,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
_resizeCallback: null,
_orientationChanging: true,
+ _resizing: false,
_scaleX: 1,
_originalScaleX: 1,
@@ -187,8 +174,6 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
_t._viewName = "Cocos2dHTML5";
var sys = cc.sys;
- _t.enableRetina(sys.os === sys.OS_IOS || sys.os === sys.OS_OSX);
- _t.enableAutoFullScreen(sys.isMobile && sys.browserType !== sys.BROWSER_TYPE_BAIDU);
cc.visibleRect && cc.visibleRect.init(_t._visibleRect);
// Setup system default resolution policies
@@ -199,6 +184,12 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
_t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH);
_t._targetDensityDPI = cc.DENSITYDPI_HIGH;
+
+ if (sys.isMobile) {
+ window.addEventListener('orientationchange', this._orientationChange);
+ } else {
+ this._orientationChanging = false;
+ }
},
// Resize helper functions
@@ -209,18 +200,35 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
} else {
view = cc.view;
}
+ if (view._orientationChanging) {
+ return;
+ }
// Check frame size changed or not
var prevFrameW = view._frameSize.width, prevFrameH = view._frameSize.height, prevRotated = view._isRotated;
- view._initFrameSize();
+ if (cc.sys.isMobile) {
+ var containerStyle = cc.game.container.style,
+ margin = containerStyle.margin;
+ containerStyle.margin = '0';
+ containerStyle.display = 'none';
+ view._initFrameSize();
+ containerStyle.margin = margin;
+ containerStyle.display = 'block';
+ }
+ else {
+ view._initFrameSize();
+ }
if (view._isRotated === prevRotated && view._frameSize.width === prevFrameW && view._frameSize.height === prevFrameH)
return;
// Frame size changed, do resize works
var width = view._originalDesignResolutionSize.width;
var height = view._originalDesignResolutionSize.height;
- if (width > 0)
+ view._resizing = true;
+ if (width > 0) {
view.setDesignResolutionSize(width, height, view._resolutionPolicy);
+ }
+ view._resizing = false;
cc.eventManager.dispatchCustomEvent('canvas-resize');
if (view._resizeCallback) {
@@ -230,7 +238,13 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
_orientationChange: function () {
cc.view._orientationChanging = true;
- cc.view._resizeEvent();
+ if (cc.sys.isMobile) {
+ cc.game.container.style.display = "none";
+ }
+ setTimeout(function () {
+ cc.view._orientationChanging = false;
+ cc.view._resizeEvent();
+ }, 300);
},
/**
@@ -268,14 +282,12 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
if (!this.__resizeWithBrowserSize) {
this.__resizeWithBrowserSize = true;
window.addEventListener('resize', this._resizeEvent);
- window.addEventListener('orientationchange', this._orientationChange);
}
} else {
//disable
if (this.__resizeWithBrowserSize) {
this.__resizeWithBrowserSize = false;
window.removeEventListener('resize', this._resizeEvent);
- window.removeEventListener('orientationchange', this._orientationChange);
}
}
},
@@ -305,9 +317,11 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
orientation = orientation & cc.ORIENTATION_AUTO;
if (orientation && this._orientation !== orientation) {
this._orientation = orientation;
- var designWidth = this._originalDesignResolutionSize.width;
- var designHeight = this._originalDesignResolutionSize.height;
- this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
+ if (this._resolutionPolicy) {
+ var designWidth = this._originalDesignResolutionSize.width;
+ var designHeight = this._originalDesignResolutionSize.height;
+ this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
+ }
}
},
@@ -329,7 +343,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
var h = __BrowserGetter.availHeight(this._frame);
var isLandscape = w >= h;
- if (!this._orientationChanging || !cc.sys.isMobile ||
+ if (!cc.sys.isMobile ||
(isLandscape && this._orientation & cc.ORIENTATION_LANDSCAPE) ||
(!isLandscape && this._orientation & cc.ORIENTATION_PORTRAIT)) {
locFrameSize.width = w;
@@ -347,9 +361,6 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
cc.container.style.transformOrigin = '0px 0px 0px';
this._isRotated = true;
}
- setTimeout(function () {
- cc.view._orientationChanging = false;
- }, 1000);
},
// hack
@@ -482,12 +493,6 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
return this._autoFullScreen;
},
- /**
- * Force destroying EGL view, subclass must implement this method.
- */
- end: function () {
- },
-
/**
* Get whether render system is ready(no matter opengl or canvas),
* this name is for the compatibility with cocos2d-x, subclass must implement this method.
@@ -568,17 +573,10 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
this._frameSize.height = height;
this._frame.style.width = width + "px";
this._frame.style.height = height + "px";
- //this.centerWindow();
this._resizeEvent();
cc.director.setProjection(cc.director.getProjection());
},
- /**
- * Empty function
- */
- centerWindow: function () {
- },
-
/**
* Returns the visible area size of the view port.
* @return {cc.Size}
@@ -686,9 +684,9 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
if (cc.sys.isMobile)
this._adjustViewportMeta();
- // Permit to re-detect the orientation of device.
- this._orientationChanging = true;
- this._initFrameSize();
+ // If resizing, then frame size is already initialized, this logic should be improved
+ if (!this._resizing)
+ this._initFrameSize();
if (!policy) {
cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2);
@@ -771,8 +769,10 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
this._setViewportMeta({"width": width}, true);
// Set body width to the exact pixel resolution
- document.documentElement.style.width = width + 'px';
- document.body.style.width = "100%";
+ document.documentElement.style.width = width + "px";
+ document.body.style.width = width + "px";
+ document.body.style.left = "0px";
+ document.body.style.top = "0px";
// Reset the resolution size and policy
this.setDesignResolutionSize(width, height, resolutionPolicy);
@@ -838,13 +838,13 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
var boxArr = gl.getParameter(gl.SCISSOR_BOX);
_scissorRect = cc.rect(boxArr[0], boxArr[1], boxArr[2], boxArr[3]);
}
- var scaleX = this._scaleX;
- var scaleY = this._scaleY;
+ var scaleXFactor = 1 / this._scaleX;
+ var scaleYFactor = 1 / this._scaleY;
return cc.rect(
- (_scissorRect.x - this._viewPortRect.x) / scaleX,
- (_scissorRect.y - this._viewPortRect.y) / scaleY,
- _scissorRect.width / scaleX,
- _scissorRect.height / scaleY
+ (_scissorRect.x - this._viewPortRect.x) * scaleXFactor,
+ (_scissorRect.y - this._viewPortRect.y) * scaleYFactor,
+ _scissorRect.width * scaleXFactor,
+ _scissorRect.height * scaleYFactor
);
},
@@ -985,7 +985,7 @@ cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{
_setupContainer: function (view, w, h) {
var locCanvas = cc.game.canvas, locContainer = cc.game.container;
- if (cc.sys.isMobile) {
+ if (cc.sys.os === cc.sys.OS_ANDROID) {
document.body.style.width = (view._isRotated ? h : w) + 'px';
document.body.style.height = (view._isRotated ? w : h) + 'px';
}
@@ -1094,7 +1094,7 @@ cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{
this._setupContainer(view, view._frameSize.width, view._frameSize.height);
// Setup container's margin and padding
if (view._isRotated) {
- containerStyle.marginLeft = frameH + 'px';
+ containerStyle.margin = '0 0 0 ' + frameH + 'px';
}
else {
containerStyle.margin = '0px';
@@ -1124,7 +1124,7 @@ cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{
this._setupContainer(view, containerW, containerH);
// Setup container's margin and padding
if (view._isRotated) {
- containerStyle.marginLeft = frameH + 'px';
+ containerStyle.margin = '0 0 0 ' + frameH + 'px';
}
else {
containerStyle.margin = '0px';
diff --git a/cocos2d/core/platform/CCInputExtension.js b/cocos2d/core/platform/CCInputExtension.js
index 6f780104b1..e61f58459a 100644
--- a/cocos2d/core/platform/CCInputExtension.js
+++ b/cocos2d/core/platform/CCInputExtension.js
@@ -39,10 +39,12 @@ _p.setAccelerometerEnabled = function(isEnable){
var scheduler = cc.director.getScheduler();
if(_t._accelEnabled){
_t._accelCurTime = 0;
+ _t._registerAccelerometerEvent();
scheduler.scheduleUpdate(_t);
} else {
_t._accelCurTime = 0;
- scheduler.scheduleUpdate(_t);
+ _t._unregisterAccelerometerEvent();
+ scheduler.unscheduleUpdate(_t);
}
};
@@ -85,7 +87,14 @@ _p._registerAccelerometerEvent = function(){
_t._minus = -1;
}
- w.addEventListener(_deviceEventType, _t.didAccelerate.bind(_t), false);
+ _t.didAccelerateCallback = _t.didAccelerate.bind(_t);
+ w.addEventListener(_deviceEventType, _t.didAccelerateCallback, false);
+};
+
+_p._unregisterAccelerometerEvent = function () {
+ this._acceleration = null;
+ var _deviceEventType = (this._accelDeviceEvent === window.DeviceMotionEvent) ? "devicemotion" : "deviceorientation";
+ window.removeEventListener(_deviceEventType, this.didAccelerateCallback, false);
};
_p.didAccelerate = function (eventData) {
diff --git a/cocos2d/core/platform/CCInputManager.js b/cocos2d/core/platform/CCInputManager.js
index 382b1f86ed..270c535c7d 100644
--- a/cocos2d/core/platform/CCInputManager.js
+++ b/cocos2d/core/platform/CCInputManager.js
@@ -601,7 +601,7 @@ cc.inputManager = /** @lends cc.inputManager# */{
this._registerKeyboardEvent();
//register Accelerometer event
- this._registerAccelerometerEvent();
+ // this._registerAccelerometerEvent();
this._isRegisterEvent = true;
},
@@ -609,6 +609,10 @@ cc.inputManager = /** @lends cc.inputManager# */{
_registerKeyboardEvent: function () {
},
+ /**
+ * Register Accelerometer event
+ * @function
+ */
_registerAccelerometerEvent: function () {
},
diff --git a/cocos2d/core/platform/CCLoaders.js b/cocos2d/core/platform/CCLoaders.js
index 69c8e9430f..16749a0949 100644
--- a/cocos2d/core/platform/CCLoaders.js
+++ b/cocos2d/core/platform/CCLoaders.js
@@ -48,15 +48,19 @@ cc._imgLoader = {
load: function (realUrl, url, res, cb) {
var callback;
if (cc.loader.isLoading(realUrl)) {
- callback = cb;
+ callback = function (err, img) {
+ if (err)
+ return cb(err);
+ var tex = cc.textureCache.getTextureForKey(url) || cc.textureCache.handleLoadedTexture(url, img);
+ cb(null, tex);
+ };
}
else {
callback = function (err, img) {
if (err)
return cb(err);
- cc.loader.cache[url] = img;
- cc.textureCache.handleLoadedTexture(url);
- cb(null, img);
+ var tex = cc.textureCache.handleLoadedTexture(url, img);
+ cb(null, tex);
};
}
cc.loader.loadImg(realUrl, callback);
diff --git a/cocos2d/core/platform/CCMacro.js b/cocos2d/core/platform/CCMacro.js
index 8ee902585b..a52958c3dc 100644
--- a/cocos2d/core/platform/CCMacro.js
+++ b/cocos2d/core/platform/CCMacro.js
@@ -175,7 +175,7 @@ cc.nodeDrawSetup = function (node) {
//cc.glEnable(node._glServerState);
if (node._shaderProgram) {
//cc._renderContext.useProgram(node._shaderProgram._programObj);
- node._shaderProgram.use();
+ node._glProgramState.apply();
node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
}
};
@@ -244,10 +244,8 @@ cc.FLT_EPSILON = 0.0000001192092896;
* @return {Number}
* @function
*/
-cc.contentScaleFactor = cc.IS_RETINA_DISPLAY_SUPPORTED ? function () {
+cc.contentScaleFactor = function () {
return cc.director._contentScaleFactor;
-} : function () {
- return 1;
};
/**
@@ -312,12 +310,10 @@ cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) {
* @return {cc.Rect}
* @function
*/
-cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) {
+cc.rectPixelsToPoints = function (pixel) {
var scale = cc.contentScaleFactor();
return cc.rect(pixel.x / scale, pixel.y / scale,
pixel.width / scale, pixel.height / scale);
-} : function (p) {
- return p;
};
/**
@@ -326,12 +322,10 @@ cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) {
* @return {cc.Rect}
* @function
*/
-cc.rectPointsToPixels = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (point) {
+cc.rectPointsToPixels = function (point) {
var scale = cc.contentScaleFactor();
return cc.rect(point.x * scale, point.y * scale,
point.width * scale, point.height * scale);
-} : function (p) {
- return p;
};
//some gl constant variable
@@ -505,6 +499,13 @@ cc.ORIENTATION_AUTO = 3;
*/
cc.CONCURRENCY_HTTP_REQUEST_COUNT = cc.sys.isMobile ? 20 : 0;
+/**
+ * The maximum vertex count for a single batched draw call.
+ * @constant
+ * @type Number
+ */
+cc.BATCH_VERTEX_COUNT = 2000;
+
// ------------------- vertex attrib flags -----------------------------
/**
diff --git a/cocos2d/core/platform/CCTypes.js b/cocos2d/core/platform/CCTypes.js
index 252061782d..e076fe2ae4 100644
--- a/cocos2d/core/platform/CCTypes.js
+++ b/cocos2d/core/platform/CCTypes.js
@@ -37,7 +37,7 @@ cc.Color = function (r, g, b, a) {
r = r || 0;
g = g || 0;
b = b || 0;
- a = a || 0;
+ a = typeof a === 'number' ? a : 255;
this._val = ((r << 24) >>> 0) + (g << 16) + (b << 8) + a;
};
diff --git a/cocos2d/core/renderer/RendererCanvas.js b/cocos2d/core/renderer/RendererCanvas.js
index 65d2a8835c..57e569cd81 100644
--- a/cocos2d/core/renderer/RendererCanvas.js
+++ b/cocos2d/core/renderer/RendererCanvas.js
@@ -163,9 +163,9 @@ cc.rendererCanvas = {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, viewport.width, viewport.height);
- if (this._clearColor.r !== 0 ||
- this._clearColor.g !== 0 ||
- this._clearColor.b !== 0) {
+ if (this._clearColor.r !== 255 ||
+ this._clearColor.g !== 255 ||
+ this._clearColor.b !== 255) {
wrapper.setFillStyle(this._clearFillStyle);
wrapper.setGlobalAlpha(this._clearColor.a);
ctx.fillRect(0, 0, viewport.width, viewport.height);
diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js
index f7616a5a36..d0655f6f28 100644
--- a/cocos2d/core/renderer/RendererWebGL.js
+++ b/cocos2d/core/renderer/RendererWebGL.js
@@ -33,8 +33,8 @@ var _batchedInfo = {
blendSrc: null,
// The batched blend destination, all batching element should have the same blend destination
blendDst: null,
- // The batched shader, all batching element should have the same shader
- shader: null
+ // The batched gl program state, all batching element should have the same state
+ glProgramState: null
},
_batchBroken = false,
@@ -129,7 +129,7 @@ return {
_cacheToBufferCmds: {}, // an array saves the renderer commands need for cache to other canvas
_cacheInstanceIds: [],
_currentID: 0,
- _clearColor: cc.color(), //background color,default BLACK
+ _clearColor: cc.color(0, 0, 0, 255), //background color,default BLACK
init: function () {
var gl = cc._renderContext;
@@ -138,7 +138,7 @@ return {
this.mat4Identity = new cc.math.Matrix4();
this.mat4Identity.identity();
- initQuadBuffer(2000);
+ initQuadBuffer(cc.BATCH_VERTEX_COUNT);
if (cc.sys.os === cc.sys.OS_IOS) {
_IS_IOS = true;
}
@@ -313,18 +313,23 @@ return {
_batchingSize += increment;
},
- _updateBatchedInfo: function (texture, blendFunc, shaderProgram) {
- if (texture) {
+ _updateBatchedInfo: function (texture, blendFunc, glProgramState) {
+ if (texture !== _batchedInfo.texture ||
+ blendFunc.src !== _batchedInfo.blendSrc ||
+ blendFunc.dst !== _batchedInfo.blendDst ||
+ glProgramState !== _batchedInfo.glProgramState) {
+ // Draw batched elements
+ this._batchRendering();
+ // Update _batchedInfo
_batchedInfo.texture = texture;
- }
-
- if (blendFunc) {
_batchedInfo.blendSrc = blendFunc.src;
_batchedInfo.blendDst = blendFunc.dst;
- }
+ _batchedInfo.glProgramState = glProgramState;
- if (shaderProgram) {
- _batchedInfo.shader = shaderProgram;
+ return true;
+ }
+ else {
+ return false;
}
},
@@ -339,60 +344,29 @@ return {
// Check batching
var node = cmd._node;
- var texture = node._texture || (node._spriteFrame ? node._spriteFrame._texture : null);
+ var texture = node._texture || (node._spriteFrame && node._spriteFrame._texture);
var blendSrc = node._blendFunc.src;
var blendDst = node._blendFunc.dst;
- var shader = cmd._shaderProgram;
+ var glProgramState = cmd._glProgramState;
if (_batchBroken ||
_batchedInfo.texture !== texture ||
_batchedInfo.blendSrc !== blendSrc ||
_batchedInfo.blendDst !== blendDst ||
- _batchedInfo.shader !== shader) {
+ _batchedInfo.glProgramState !== glProgramState) {
// Draw batched elements
this._batchRendering();
// Update _batchedInfo
_batchedInfo.texture = texture;
_batchedInfo.blendSrc = blendSrc;
_batchedInfo.blendDst = blendDst;
- _batchedInfo.shader = shader;
+ _batchedInfo.glProgramState = glProgramState;
_batchBroken = false;
}
// Upload vertex data
var len = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex);
if (len > 0) {
- var i, curr, type = cmd.vertexType || VertexType.QUAD;
- switch (type) {
- case VertexType.QUAD:
- for (i = 0; i < len; i += 4) {
- curr = _batchingSize + i;
- _indexData[_indexSize++] = curr + 0;
- _indexData[_indexSize++] = curr + 1;
- _indexData[_indexSize++] = curr + 2;
- _indexData[_indexSize++] = curr + 1;
- _indexData[_indexSize++] = curr + 2;
- _indexData[_indexSize++] = curr + 3;
- }
- break;
- case VertexType.TRIANGLE:
- _pureQuad = false;
- for (i = 0; i < len; i += 3) {
- curr = _batchingSize + i;
- _indexData[_indexSize++] = curr + 0;
- _indexData[_indexSize++] = curr + 1;
- _indexData[_indexSize++] = curr + 2;
- }
- break;
- case VertexType.CUSTOM:
- _pureQuad = false;
- if (cmd.uploadIndexData) {
- _indexSize += cmd.uploadIndexData(_indexData, _indexSize, _batchingSize);
- }
- break;
- default:
- return;
- }
- _batchingSize += len;
+ this._increaseBatchingSize(len, cmd.vertexType);
}
},
@@ -403,12 +377,12 @@ return {
var gl = cc._renderContext;
var texture = _batchedInfo.texture;
- var shader = _batchedInfo.shader;
+ var glProgramState = _batchedInfo.glProgramState;
var uploadAll = _batchingSize > _maxVertexSize * 0.5;
- if (shader) {
- shader.use();
- shader._updateProjectionUniform();
+ if (glProgramState) {
+ glProgramState.apply();
+ glProgramState.getGLProgram()._updateProjectionUniform();
}
cc.glBlendFunc(_batchedInfo.blendSrc, _batchedInfo.blendDst);
diff --git a/cocos2d/core/scenes/CCLoaderScene.js b/cocos2d/core/scenes/CCLoaderScene.js
index 12c482c476..2f051811b1 100644
--- a/cocos2d/core/scenes/CCLoaderScene.js
+++ b/cocos2d/core/scenes/CCLoaderScene.js
@@ -33,6 +33,7 @@
cc.LoaderScene = cc.Scene.extend({
_interval : null,
_label : null,
+ _logo : null,
_className:"LoaderScene",
cb: null,
target: null,
@@ -132,7 +133,7 @@ cc.LoaderScene = cc.Scene.extend({
this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
this._bgLayer._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
this._label._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
- this._logo._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ this._logo && this._logo._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
}
});
/**
diff --git a/cocos2d/core/sprites/CCSpriteFrameCache.js b/cocos2d/core/sprites/CCSpriteFrameCache.js
index d8df34823b..7d38e89a5b 100644
--- a/cocos2d/core/sprites/CCSpriteFrameCache.js
+++ b/cocos2d/core/sprites/CCSpriteFrameCache.js
@@ -169,7 +169,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
var frame = frames[key];
var spriteFrame = spriteFrames[key];
if (!spriteFrame) {
- spriteFrame = new cc.SpriteFrame(texture, frame.rect, frame.rotated, frame.offset, frame.size);
+ spriteFrame = new cc.SpriteFrame(texture, cc.rect(frame.rect), frame.rotated, frame.offset, frame.size);
var aliases = frame.aliases;
if (aliases) {//set aliases
for (var i = 0, li = aliases.length; i < li; i++) {
diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
index 79e0c4b58f..51ea5024cb 100644
--- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
+++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
@@ -235,10 +235,12 @@
node._texture = texture;
// Update texture rect and blend func
- var texSize = texture._contentSize;
- var rect = cc.rect(0, 0, texSize.width, texSize.height);
- node.setTextureRect(rect);
- this._updateBlendFunc();
+ if (texture) {
+ var texSize = texture._contentSize;
+ var rect = cc.rect(0, 0, texSize.width, texSize.height);
+ node.setTextureRect(rect);
+ this._updateBlendFunc();
+ }
if (node._textureLoaded) {
// Force refresh the render command list
@@ -296,7 +298,7 @@
proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
var node = this._node, locTexture = node._texture;
if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity)
- return false;
+ return 0;
// Fill in vertex data with quad information (4 vertices for sprite)
var opacity = this._displayedOpacity;
diff --git a/cocos2d/core/support/CCPointExtension.js b/cocos2d/core/support/CCPointExtension.js
index d2ea212435..3171a5f7ea 100644
--- a/cocos2d/core/support/CCPointExtension.js
+++ b/cocos2d/core/support/CCPointExtension.js
@@ -510,5 +510,7 @@ cc.pAddIn = function(v1, v2) {
* @param {cc.Point} v
*/
cc.pNormalizeIn = function(v) {
- cc.pMultIn(v, 1.0 / Math.sqrt(v.x * v.x + v.y * v.y));
+ var n = Math.sqrt(v.x * v.x + v.y * v.y);
+ if (n !== 0)
+ cc.pMultIn(v, 1.0 / n);
};
diff --git a/cocos2d/core/textures/CCTexture2D.js b/cocos2d/core/textures/CCTexture2D.js
index cd0a9ff153..b69d83cfd9 100644
--- a/cocos2d/core/textures/CCTexture2D.js
+++ b/cocos2d/core/textures/CCTexture2D.js
@@ -190,11 +190,8 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
*/
handleLoadedTexture: function () {
var self = this;
- if (self._textureLoaded) return;
if (!self._htmlElementObj) {
- var img = cc.loader.getRes(self.url);
- if (!img) return;
- self.initWithElement(img);
+ return;
}
var locElement = self._htmlElementObj;
@@ -229,6 +226,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
},
releaseTexture: function () {
+ this._htmlElementObj = null;
cc.loader.release(this.url);
},
diff --git a/cocos2d/core/textures/CCTextureCache.js b/cocos2d/core/textures/CCTextureCache.js
index 2099565eb3..5e59c2f83c 100644
--- a/cocos2d/core/textures/CCTextureCache.js
+++ b/cocos2d/core/textures/CCTextureCache.js
@@ -279,11 +279,11 @@ cc.textureCache = /** @lends cc.textureCache# */{
var selTexture = locTextures[key];
count++;
if (selTexture.getHtmlElementObj() instanceof HTMLImageElement)
- cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo, key, selTexture.getHtmlElementObj().src, selTexture.pixelsWidth, selTexture.pixelsHeight);
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo, key, selTexture.getHtmlElementObj().src, selTexture.getPixelsWide(), selTexture.getPixelsHigh());
else {
- cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selTexture.pixelsWidth, selTexture.pixelsHeight);
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selTexture.getPixelsWide(), selTexture.getPixelsHigh());
}
- totalBytes += selTexture.pixelsWidth * selTexture.pixelsHeight * 4;
+ totalBytes += selTexture.getPixelsWide() * selTexture.getPixelsHigh() * 4;
}
var locTextureColorsCache = this._textureColorsCache;
@@ -313,7 +313,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
var _p = cc.textureCache;
- _p.handleLoadedTexture = function (url) {
+ _p.handleLoadedTexture = function (url, img) {
var locTexs = this._textures;
//remove judge
var tex = locTexs[url];
@@ -321,7 +321,9 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
tex = locTexs[url] = new cc.Texture2D();
tex.url = url;
}
+ tex.initWithElement(img);
tex.handleLoadedTexture();
+ return tex;
};
/**
@@ -365,12 +367,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
if (err)
return cb && cb.call(target, err);
- if (!cc.loader.cache[url]) {
- cc.loader.cache[url] = img;
- }
- cc.textureCache.handleLoadedTexture(url);
-
- var texResult = locTexs[url];
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
cb && cb.call(target, texResult);
});
diff --git a/cocos2d/core/textures/TexturesWebGL.js b/cocos2d/core/textures/TexturesWebGL.js
index bcec5bfb53..2dfe145e56 100644
--- a/cocos2d/core/textures/TexturesWebGL.js
+++ b/cocos2d/core/textures/TexturesWebGL.js
@@ -83,6 +83,7 @@ cc._tmp.WebGLTexture2D = function () {
releaseTexture: function () {
if (this._webTextureObj)
cc._renderContext.deleteTexture(this._webTextureObj);
+ this._htmlElementObj = null;
cc.loader.release(this.url);
},
@@ -339,8 +340,8 @@ cc._tmp.WebGLTexture2D = function () {
point.x, height + point.y, 0.0,
width + point.x, height + point.y, 0.0];
- self._shaderProgram.use();
- self._shaderProgram.setUniformsForBuiltins();
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
cc.glBindTexture2D(self);
@@ -369,8 +370,8 @@ cc._tmp.WebGLTexture2D = function () {
rect.x, rect.y + rect.height, /*0.0,*/
rect.x + rect.width, rect.y + rect.height /*0.0*/];
- self._shaderProgram.use();
- self._shaderProgram.setUniformsForBuiltins();
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
cc.glBindTexture2D(self);
@@ -457,11 +458,8 @@ cc._tmp.WebGLTexture2D = function () {
// Not sure about this ! Some texture need to be updated even after loaded
if (!cc.game._rendererInitialized)
return;
- if (!self._htmlElementObj) {
- var img = cc.loader.getRes(self.url);
- if (!img) return;
- self.initWithElement(img);
- }
+ if (!self._htmlElementObj)
+ return;
if (!self._htmlElementObj.width || !self._htmlElementObj.height)
return;
@@ -498,6 +496,9 @@ cc._tmp.WebGLTexture2D = function () {
self._hasPremultipliedAlpha = premultiplied;
self._hasMipmaps = false;
+ if (window.ENABLE_IMAEG_POOL) {
+ self._htmlElementObj = null;
+ }
//dispatch load event to listener.
self.dispatchEvent("load");
@@ -854,7 +855,7 @@ cc._tmp.WebGLTextureAtlas = function () {
cc._tmp.WebGLTextureCache = function () {
var _p = cc.textureCache;
- _p.handleLoadedTexture = function (url) {
+ _p.handleLoadedTexture = function (url, img) {
var locTexs = this._textures, tex, ext;
//remove judge(webgl)
if (!cc.game._rendererInitialized) {
@@ -865,6 +866,7 @@ cc._tmp.WebGLTextureCache = function () {
tex = locTexs[url] = new cc.Texture2D();
tex.url = url;
}
+ tex.initWithElement(img);
ext = cc.path.extname(url);
if (ext === ".png") {
tex.handleLoadedTexture(true);
@@ -872,6 +874,7 @@ cc._tmp.WebGLTextureCache = function () {
else {
tex.handleLoadedTexture();
}
+ return tex;
};
/**
@@ -917,12 +920,7 @@ cc._tmp.WebGLTextureCache = function () {
if (err)
return cb && cb.call(target, err);
- if (!cc.loader.cache[url]) {
- cc.loader.cache[url] = img;
- }
- cc.textureCache.handleLoadedTexture(url);
-
- var texResult = locTexs[url];
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
cb && cb.call(target, texResult);
});
diff --git a/cocos2d/core/utils/BinaryLoader.js b/cocos2d/core/utils/BinaryLoader.js
index 7127b1279c..46b82b65cf 100644
--- a/cocos2d/core/utils/BinaryLoader.js
+++ b/cocos2d/core/utils/BinaryLoader.js
@@ -37,6 +37,7 @@ cc.loader.loadBinary = function (url, cb) {
var xhr = this.getXMLHttpRequest(),
errInfo = "load " + url + " failed!";
xhr.open("GET", url, true);
+ xhr.responseType = 'arraybuffer';
if (cc.loader.loadBinary._IEFilter) {
// IE-specific logic here
xhr.setRequestHeader("Accept-Charset", "x-user-defined");
@@ -49,7 +50,7 @@ cc.loader.loadBinary = function (url, cb) {
} else {
if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=x-user-defined");
xhr.onload = function () {
- xhr.readyState === 4 && xhr.status === 200 ? cb(null, self._str2Uint8Array(xhr.responseText)) : cb(errInfo);
+ xhr.readyState === 4 && xhr.status === 200 ? cb(null, new Uint8Array(xhr.response)) : cb(errInfo);
};
}
xhr.send(null);
@@ -102,7 +103,7 @@ cc.loader.loadBinarySync = function (url) {
return null;
}
- arrayInfo = this._str2Uint8Array(req.responseText);
+ arrayInfo = self._str2Uint8Array(req.responseText);
}
return arrayInfo;
};
@@ -151,4 +152,4 @@ if (cc.loader.loadBinary._IEFilter) {
return byteMapping[match];
}) + lastChr;
};
-}
\ No newline at end of file
+}
diff --git a/cocos2d/effects/CCGrid.js b/cocos2d/effects/CCGrid.js
index f6459a2269..361cba84b3 100644
--- a/cocos2d/effects/CCGrid.js
+++ b/cocos2d/effects/CCGrid.js
@@ -39,7 +39,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
_step: null,
_grabber: null,
_isTextureFlipped: false,
- _shaderProgram: null,
+ _glProgramState: null,
_directorProjection: 0,
_dirty: false,
@@ -62,7 +62,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
this._step = cc.p(0, 0);
this._grabber = null;
this._isTextureFlipped = false;
- this._shaderProgram = null;
+ this._glProgramState = null;
this._directorProjection = 0;
this._dirty = false;
@@ -227,7 +227,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
if (!this._grabber)
return false;
this._grabber.grab(this._texture);
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE));
this.calculateVertexPoints();
return true;
},
@@ -443,9 +443,7 @@ cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- //this._shaderProgram.setUniformsForBuiltins();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
var gl = cc._renderContext, locDirty = this._dirty;
@@ -714,9 +712,7 @@ cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
- //this._shaderProgram.setUniformsForBuiltins();
+ this._glProgramState.apply(this._matrix);
//
// Attributes
diff --git a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js
index e2d74f574a..a7d793a336 100644
--- a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js
+++ b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js
@@ -49,8 +49,7 @@ cc.MotionStreak.WebGLRenderCmd.prototype.rendering = function (ctx) {
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
cc.glBindTexture2D(node.texture);
diff --git a/cocos2d/particle/CCParticleBatchNode.js b/cocos2d/particle/CCParticleBatchNode.js
index 38959df638..53c381fc30 100644
--- a/cocos2d/particle/CCParticleBatchNode.js
+++ b/cocos2d/particle/CCParticleBatchNode.js
@@ -148,12 +148,15 @@ cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{
},
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var cmd = this._renderCmd;
- cmd.visit(parent && parent._renderCmd);
+ cmd.visit(parentCmd);
cc.renderer.pushRenderCommand(cmd);
cmd._dirtyFlag = 0;
},
@@ -275,9 +278,6 @@ cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{
return;
}
- if (zOrder === child.zIndex)
- return;
-
// no reordering if only 1 child
if (this._children.length > 1) {
var getIndexes = this._getCurrentIndex(child, zOrder);
diff --git a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js
index 3dda639728..765e7553ad 100644
--- a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js
+++ b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js
@@ -49,8 +49,7 @@
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFuncForParticle(_t._blendFunc.src, _t._blendFunc.dst);
_t.textureAtlas.drawQuads();
};
diff --git a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js
index 781baf7004..5f602e99f2 100644
--- a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js
+++ b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js
@@ -195,11 +195,12 @@
};
proto._updateDeltaColor = function (selParticle, dt) {
if (!this._node._dontTint) {
- selParticle.color.r += selParticle.deltaColor.r * dt;
- selParticle.color.g += selParticle.deltaColor.g * dt;
- selParticle.color.b += selParticle.deltaColor.b * dt;
- selParticle.color.a += selParticle.deltaColor.a * dt;
- selParticle.isChangeColor = true;
+ var deltaColor = selParticle.deltaColor;
+ selParticle.color.r += deltaColor.r * dt;
+ selParticle.color.g += deltaColor.g * dt;
+ selParticle.color.b += deltaColor.b * dt;
+ selParticle.color.a += deltaColor.a * dt;
+ selParticle.isChangeColor = deltaColor.r !== 0 || deltaColor.g !== 0 || deltaColor.b !== 0;
}
};
})();
diff --git a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js
index 892f8a2d21..54b1236119 100644
--- a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js
+++ b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js
@@ -204,8 +204,7 @@
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); //;
+ this._glProgramState.apply(this._matrix);
cc.glBindTexture2D(node._texture);
cc.glBlendFuncForParticle(node._blendFunc.src, node._blendFunc.dst);
diff --git a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js
index 1c2a9fb69a..0b8a18504c 100644
--- a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js
+++ b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js
@@ -54,8 +54,7 @@
//cc.DrawNode.prototype.draw.call(node);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
node._render();
node.clear();
diff --git a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js
index 8ee5a7da1a..8a89913eed 100644
--- a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js
+++ b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js
@@ -35,6 +35,7 @@
this._bl = cc.p();
this._tr = cc.p();
+ this._transformUpdating = false;
this.initCmd();
};
@@ -55,7 +56,9 @@
this._tr.x = rx * wt.a + ty * wt.c + wt.tx;
this._tr.y = rx * wt.b + ty * wt.d + wt.ty;
+ this._transformUpdating = true;
this._updateProgressData();
+ this._transformUpdating = false;
};
proto.rendering = function (ctx) {
@@ -64,7 +67,7 @@
if (this._vertexDataCount === 0 || !node._sprite)
return;
- this._shaderProgram.use();
+ this._glProgramState.apply();
this._shaderProgram._updateProjectionUniform();
var blendFunc = node._sprite._blendFunc;
@@ -449,7 +452,7 @@
this._updateColor();
var locVertexData = this._vertexData;
- if (!sameIndexCount) {
+ if (this._transformUpdating || !sameIndexCount) {
// First we populate the array with the m_tMidpoint, then all
// vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
this._textureCoordFromAlphaPoint(locVertexData[0].texCoords, locMidPoint.x, locMidPoint.y);
diff --git a/cocos2d/render-texture/CCRenderTexture.js b/cocos2d/render-texture/CCRenderTexture.js
index 97bd77700a..5cc00ae45a 100644
--- a/cocos2d/render-texture/CCRenderTexture.js
+++ b/cocos2d/render-texture/CCRenderTexture.js
@@ -133,13 +133,17 @@ cc.RenderTexture = cc.Node.extend(/** @lends cc.RenderTexture# */{
},
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var renderer = cc.renderer, cmd = this._renderCmd;
+ var renderer = cc.renderer;
- cmd.visit(parent && parent._renderCmd);
+ cmd.visit(parentCmd);
renderer.pushRenderCommand(cmd);
this.sprite.visit(this);
cmd._dirtyFlag = 0;
@@ -235,10 +239,10 @@ cc.RenderTexture = cc.Node.extend(/** @lends cc.RenderTexture# */{
/**
* clears the texture with a color
- * @param {Number|cc.Rect} r red 0-1
- * @param {Number} g green 0-1
- * @param {Number} b blue 0-1
- * @param {Number} a alpha 0-1
+ * @param {Number|cc.Rect} r red 0-255
+ * @param {Number} g green 0-255
+ * @param {Number} b blue 0-255
+ * @param {Number} a alpha 0-255
*/
clear: function (r, g, b, a) {
this.beginWithClear(r, g, b, a);
diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js
index d9e59b109d..0cf9f4702d 100644
--- a/cocos2d/shaders/CCGLProgram.js
+++ b/cocos2d/shaders/CCGLProgram.js
@@ -42,28 +42,30 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
_projectionUpdated: -1,
// Uniform cache
- _updateUniformLocation: function (location) {
- if (!location)
+ _updateUniform: function (name) {
+ if (!name)
return false;
- var updated;
- var element = this._hashForUniforms[location];
-
- if (!element) {
- element = [
- arguments[1],
- arguments[2],
- arguments[3],
- arguments[4]
- ];
- this._hashForUniforms[location] = element;
+ var updated = false;
+ var element = this._hashForUniforms[name];
+ var args;
+ if (Array.isArray(arguments[1])) {
+ args = arguments[1];
+ } else {
+ args = new Array(arguments.length - 1);
+ for (var i = 1; i < arguments.length; i += 1) {
+ args[i - 1] = arguments[i];
+ }
+ }
+
+ if (!element || element.length !== args.length) {
+ this._hashForUniforms[name] = [].concat(args);
updated = true;
} else {
- updated = false;
- var count = arguments.length - 1;
- for (var i = 0; i < count; ++i) {
- if (arguments[i + 1] !== element[i]) {
- element[i] = arguments[i + 1];
+ for (var i = 0; i < args.length; i += 1) {
+ // Array and Typed Array inner values could be changed, so we must update them
+ if (args[i] !== element[i] || typeof args[i] === 'object') {
+ element[i] = args[i];
updated = true;
}
}
@@ -169,9 +171,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
if (this._fragShader)
locGL.attachShader(this._programObj, this._fragShader);
- for (var key in this._hashForUniforms) {
- delete this._hashForUniforms[key];
- }
+ if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {};
cc.checkGLErrorDebug();
return true;
@@ -268,18 +268,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* cc.UNIFORM_SAMPLER
*/
updateUniforms: function () {
- this._uniforms[cc.UNIFORM_PMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_PMATRIX_S);
- this._uniforms[cc.UNIFORM_MVMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVMATRIX_S);
- this._uniforms[cc.UNIFORM_MVPMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVPMATRIX_S);
- this._uniforms[cc.UNIFORM_TIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_TIME_S);
- this._uniforms[cc.UNIFORM_SINTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SINTIME_S);
- this._uniforms[cc.UNIFORM_COSTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_COSTIME_S);
-
+ this._addUniformLocation(cc.UNIFORM_PMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_MVMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_MVPMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_TIME_S);
+ this._addUniformLocation(cc.UNIFORM_SINTIME_S);
+ this._addUniformLocation(cc.UNIFORM_COSTIME_S);
+ this._addUniformLocation(cc.UNIFORM_RANDOM01_S);
+ this._addUniformLocation(cc.UNIFORM_SAMPLER_S);
this._usesTime = (this._uniforms[cc.UNIFORM_TIME_S] != null || this._uniforms[cc.UNIFORM_SINTIME_S] != null || this._uniforms[cc.UNIFORM_COSTIME_S] != null);
- this._uniforms[cc.UNIFORM_RANDOM01_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_RANDOM01_S);
- this._uniforms[cc.UNIFORM_SAMPLER_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SAMPLER_S);
-
this.use();
// Since sample most probably won't change, set it to 0 now.
this.setUniformLocationWith1i(this._uniforms[cc.UNIFORM_SAMPLER_S], 0);
@@ -287,7 +285,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
_addUniformLocation: function (name) {
var location = this._glContext.getUniformLocation(this._programObj, name);
+ if (location) location._name = name;
this._uniforms[name] = location;
+ return location;
},
/**
@@ -301,7 +301,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
if (!this._programObj)
throw new Error("cc.GLProgram.getUniformLocationForName(): Invalid operation. Cannot get uniform location when program is not initialized");
- var location = this._uniforms[name] || this._glContext.getUniformLocation(this._programObj, name);
+ var location = this._uniforms[name] || this._addUniformLocation(name);
return location;
},
@@ -327,16 +327,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} i1
*/
setUniformLocationWith1i: function (location, i1) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, i1);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform1i(locObj, i1);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform1i(location, i1);
}
- }
- else {
- gl.uniform1i(location, i1);
+ } else {
+ this._glContext.uniform1i(location, i1);
}
},
@@ -347,16 +346,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} i2
*/
setUniformLocationWith2i: function (location, i1, i2) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, i1, i2);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform2i(locObj, i1, i2);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2i(location, i1, i2);
}
- }
- else {
- gl.uniform2i(location, i1, i2);
+ } else {
+ this._glContext.uniform2i(location, i1, i2);
}
},
@@ -368,16 +366,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} i3
*/
setUniformLocationWith3i: function (location, i1, i2, i3) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, i1, i2, i3);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform3i(locObj, i1, i2, i3);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2, i3)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3i(location, i1, i2, i3);
}
- }
- else {
- gl.uniform3i(location, i1, i2, i3);
+ } else {
+ this._glContext.uniform3i(location, i1, i2, i3);
}
},
@@ -390,16 +387,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} i4
*/
setUniformLocationWith4i: function (location, i1, i2, i3, i4) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, i1, i2, i3, i4);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform4i(locObj, i1, i2, i3, i4);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2, i3, i4)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4i(location, i1, i2, i3, i4);
}
- }
- else {
- gl.uniform4i(location, i1, i2, i3, i4);
+ } else {
+ this._glContext.uniform4i(location, i1, i2, i3, i4);
}
},
@@ -410,8 +406,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} numberOfArrays
*/
setUniformLocationWith2iv: function (location, intArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform2iv(locObj, intArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform2iv(location, intArray);
+ }
},
/**
@@ -420,8 +424,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Int32Array} intArray
*/
setUniformLocationWith3iv: function (location, intArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform3iv(locObj, intArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform3iv(location, intArray);
+ }
},
/**
@@ -430,8 +442,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Int32Array} intArray
*/
setUniformLocationWith4iv: function (location, intArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform4iv(locObj, intArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform4iv(location, intArray);
+ }
},
/**
@@ -449,16 +469,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} f1
*/
setUniformLocationWith1f: function (location, f1) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, f1);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform1f(locObj, f1);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform1f(location, f1);
}
- }
- else {
- gl.uniform1f(location, f1);
+ } else {
+ this._glContext.uniform1f(location, f1);
}
},
@@ -469,16 +488,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} f2
*/
setUniformLocationWith2f: function (location, f1, f2) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, f1, f2);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform2f(locObj, f1, f2);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2f(location, f1, f2);
}
- }
- else {
- gl.uniform2f(location, f1, f2);
+ } else {
+ this._glContext.uniform2f(location, f1, f2);
}
},
@@ -490,16 +508,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} f3
*/
setUniformLocationWith3f: function (location, f1, f2, f3) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, f1, f2, f3);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform3f(locObj, f1, f2, f3);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2, f3)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3f(location, f1, f2, f3);
}
- }
- else {
- gl.uniform3f(location, f1, f2, f3);
+ } else {
+ this._glContext.uniform3f(location, f1, f2, f3);
}
},
@@ -512,16 +529,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Number} f4
*/
setUniformLocationWith4f: function (location, f1, f2, f3, f4) {
- var gl = this._glContext;
- if (typeof location === 'string') {
- var updated = this._updateUniformLocation(location, f1, f2, f3, f4);
- if (updated) {
- var locObj = this.getUniformLocationForName(location);
- gl.uniform4f(locObj, f1, f2, f3, f4);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2, f3, f4)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4f(location, f1, f2, f3, f4);
}
- }
- else {
- gl.uniform4f(location, f1, f2, f3, f4);
+ } else {
+ this._glContext.uniform4f(location, f1, f2, f3, f4);
+ cc.log('uniform4f', f1, f2, f3, f4);
}
},
@@ -531,8 +548,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Float32Array} floatArray
*/
setUniformLocationWith2fv: function (location, floatArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform2fv(locObj, floatArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform2fv(location, floatArray);
+ }
},
/**
@@ -541,8 +566,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Float32Array} floatArray
*/
setUniformLocationWith3fv: function (location, floatArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform3fv(locObj, floatArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform3fv(location, floatArray);
+ }
},
/**
@@ -551,17 +584,53 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Float32Array} floatArray
*/
setUniformLocationWith4fv: function (location, floatArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniform4fv(locObj, floatArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform4fv(location, floatArray);
+ cc.log('uniform4fv', floatArray);
+ }
+ },
+
+ /**
+ * calls glUniformMatrix2fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} matrixArray
+ */
+ setUniformLocationWithMatrix2fv: function (location, matrixArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix2fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix2fv(location, false, matrixArray);
+ }
},
+
/**
* calls glUniformMatrix3fv
* @param {WebGLUniformLocation|String} location
* @param {Float32Array} matrixArray
*/
setUniformLocationWithMatrix3fv: function (location, matrixArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniformMatrix3fv(locObj, false, matrixArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix3fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix3fv(location, false, matrixArray);
+ }
},
/**
@@ -570,8 +639,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* @param {Float32Array} matrixArray
*/
setUniformLocationWithMatrix4fv: function (location, matrixArray) {
- var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location;
- this._glContext.uniformMatrix4fv(locObj, false, matrixArray);
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix4fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix4fv(location, false, matrixArray);
+ }
},
setUniformLocationF32: function () {
@@ -664,25 +741,25 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
* will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program.
*/
setUniformForModelViewProjectionMatrix: function () {
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false,
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S],
cc.getMat4MultiplyValue(cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top));
},
setUniformForModelViewProjectionMatrixWithMat4: function (swapMat4) {
cc.kmMat4Multiply(swapMat4, cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top);
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false, swapMat4.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], swapMat4.mat);
},
setUniformForModelViewAndProjectionMatrixWithMat4: function () {
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, cc.modelview_matrix_stack.top.mat);
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], cc.modelview_matrix_stack.top.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat);
},
_setUniformForMVPMatrixWithMat4: function (modelViewMatrix) {
if (!modelViewMatrix)
throw new Error("modelView matrix is undefined.");
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, modelViewMatrix.mat);
- this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], modelViewMatrix.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat);
},
_updateProjectionUniform: function () {
@@ -748,7 +825,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
reset: function () {
this._vertShader = null;
this._fragShader = null;
- this._uniforms.length = 0;
+ if (Object.keys(this._uniforms).length > 0) this._uniforms = {};
// it is already deallocated by android
//ccGLDeleteProgram(m_uProgram);
@@ -756,10 +833,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
this._programObj = null;
// Purge uniform hash
- for (var key in this._hashForUniforms) {
- this._hashForUniforms[key].length = 0;
- delete this._hashForUniforms[key];
- }
+ if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {};
},
/**
@@ -795,8 +869,8 @@ cc.GLProgram.create = function (vShaderFileName, fShaderFileName) {
cc.GLProgram._highpSupported = null;
cc.GLProgram._isHighpSupported = function () {
- if (cc.GLProgram._highpSupported == null) {
- var ctx = cc._renderContext;
+ var ctx = cc._renderContext;
+ if (ctx.getShaderPrecisionFormat && cc.GLProgram._highpSupported == null) {
var highp = ctx.getShaderPrecisionFormat(ctx.FRAGMENT_SHADER, ctx.HIGH_FLOAT);
cc.GLProgram._highpSupported = highp.precision !== 0;
}
diff --git a/cocos2d/shaders/CCGLProgramState.js b/cocos2d/shaders/CCGLProgramState.js
new file mode 100644
index 0000000000..c5bc2fd428
--- /dev/null
+++ b/cocos2d/shaders/CCGLProgramState.js
@@ -0,0 +1,303 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var types =
+ {
+ GL_FLOAT: 0,
+ GL_INT: 1,
+ GL_FLOAT_VEC2: 2,
+ GL_FLOAT_VEC3: 3,
+ GL_FLOAT_VEC4: 4,
+ GL_FLOAT_MAT4: 5,
+ GL_CALLBACK: 6,
+ GL_TEXTURE: 7
+ };
+
+
+
+cc.UniformValue = function (uniform, glprogram) {
+ this._uniform = uniform;
+ this._glprogram = glprogram;
+
+ this._value = null;
+ this._type = -1;
+};
+
+cc.UniformValue.prototype = {
+ setFloat: function setFloat(value) {
+ this._value = value;
+ this._type = types.GL_FLOAT;
+ },
+
+ setInt: function setInt(value) {
+ this._value = value;
+ this._type = types.GL_INT;
+ },
+
+ setVec2: function setVec2(v1, v2) {
+ this._value = [v1, v2];
+ this._type = types.GL_FLOAT_VEC2;
+ },
+
+ setVec2v: function setVec2v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC2;
+ },
+
+ setVec3: function setVec3(v1, v2, v3) {
+ this._value = [v1, v2, v3];
+ this._type = types.GL_FLOAT_VEC3;
+ },
+
+ setVec3v: function setVec3v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC3;
+ },
+
+ setVec4: function setVec4(v1, v2, v3, v4) {
+ this._value = [v1, v2, v3, v4];
+ this._type = types.GL_FLOAT_VEC4;
+ },
+
+ setVec4v: function setVec4v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC4;
+ },
+
+ setMat4: function setMat4(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_MAT4;
+ },
+
+ setCallback: function setCallback(fn) {
+ this._value = fn;
+ this._type = types.GL_CALLBACK;
+ },
+
+ setTexture: function setTexture(textureId, textureUnit) {
+ this._value = textureUnit;
+ this._textureId = textureId;
+ this._type = types.GL_TEXTURE;
+ },
+
+ apply: function apply() {
+ switch (this._type) {
+ case types.GL_INT:
+ this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT:
+ this._glprogram.setUniformLocationWith1f(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC2:
+ this._glprogram.setUniformLocationWith2fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC3:
+ this._glprogram.setUniformLocationWith3fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC4:
+ this._glprogram.setUniformLocationWith4fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_MAT4:
+ this._glprogram.setUniformLocationWithMatrix4fv(this._uniform._location, this._value);
+ break;
+ case types.GL_CALLBACK:
+ this._value(this._glprogram, this._uniform);
+ break;
+ case types.GL_TEXTURE:
+ this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value);
+ cc.glBindTexture2DN(this._value, this._textureId);
+ break;
+ default:
+ ;
+ }
+ },
+};
+
+cc.GLProgramState = function (glprogram) {
+ this._glprogram = glprogram;
+ this._uniforms = {};
+ this._boundTextureUnits = {};
+ this._textureUnitIndex = 1; // Start at 1, as CC_Texture0 is bound to 0
+
+ var activeUniforms = glprogram._glContext.getProgramParameter(glprogram._programObj,
+ glprogram._glContext.ACTIVE_UNIFORMS);
+
+ for (var i = 0; i < activeUniforms; i += 1) {
+ var uniform = glprogram._glContext.getActiveUniform(glprogram._programObj, i);
+ if (uniform.name.indexOf("CC_") !== 0) {
+ uniform._location = glprogram._glContext.getUniformLocation(glprogram._programObj, uniform.name);
+ uniform._location._name = uniform.name;
+ var uniformValue = new cc.UniformValue(uniform, glprogram);
+ this._uniforms[uniform.name] = uniformValue;
+ }
+ }
+};
+
+cc.GLProgramState.prototype = {
+ apply: function apply(modelView) {
+ this._glprogram.use();
+ if (modelView) {
+ this._glprogram._setUniformForMVPMatrixWithMat4(modelView);
+ }
+
+ for (var name in this._uniforms) {
+ this._uniforms[name].apply();
+ };
+ },
+
+ setGLProgram: function setGLProgram(glprogram) {
+ this._glprogram = glprogram;
+ },
+
+ getGLProgram: function getGLProgram() {
+ return this._glprogram;
+ },
+
+ getUniformCount: function getUniformCount() {
+ return this._uniforms.length;
+ },
+
+ getUniformValue: function getUniformValue(uniform) {
+ return this._uniforms[uniform];
+ },
+
+ setUniformInt: function setUniformInt(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setInt(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformFloat: function setUniformFloat(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setFloat(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec2: function setUniformVec2(uniform, v1, v2) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec2(v1, v2);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec2v: function setUniformVec2v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec2v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec3: function setUniformVec3(uniform, v1, v2, v3) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec3(v1, v2, v3);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec3v: function setUniformVec3v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec3v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec4: function setUniformVec4(uniform, v1, v2, v3, v4) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec4(v1, v2, v3, v4);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec4v: function setUniformVec4v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec4v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+
+ setUniformMat4: function setUniformMat4(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setMat4(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+
+ },
+
+ setUniformCallback: function setUniformCallback(uniform, callback) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setCallback(callback);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+
+ },
+
+ setUniformTexture: function setUniformTexture(uniform, texture) {
+ var uniformValue = this.getUniformValue(uniform);
+ if (uniformValue) {
+ var textureUnit = this._boundTextureUnits[uniform];
+ if (textureUnit) {
+ uniformValue.setTexture(texture, textureUnit);
+ } else {
+ uniformValue.setTexture(texture, this._textureUnitIndex);
+ this._boundTextureUnits[uniform] = this._textureUnitIndex++;
+ }
+ }
+ }
+};
+
+cc.GLProgramState._cache = {};
+cc.GLProgramState.getOrCreateWithGLProgram = function (glprogram) {
+ var programState = cc.GLProgramState._cache[glprogram.__instanceId];
+ if (!programState) {
+ programState = new cc.GLProgramState(glprogram);
+ cc.GLProgramState._cache[glprogram.__instanceId] = programState;
+ }
+
+ return programState;
+};
diff --git a/cocos2d/shaders/CCShaderCache.js b/cocos2d/shaders/CCShaderCache.js
index b064719f8d..462f208d21 100644
--- a/cocos2d/shaders/CCShaderCache.js
+++ b/cocos2d/shaders/CCShaderCache.js
@@ -110,10 +110,25 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
*/
TYPE_MAX: 11,
+ _keyMap: [
+ cc.SHADER_POSITION_TEXTURECOLOR,
+ cc.SHADER_POSITION_TEXTURECOLORALPHATEST,
+ cc.SHADER_POSITION_COLOR,
+ cc.SHADER_POSITION_TEXTURE,
+ cc.SHADER_POSITION_TEXTURE_UCOLOR,
+ cc.SHADER_POSITION_TEXTUREA8COLOR,
+ cc.SHADER_POSITION_UCOLOR,
+ cc.SHADER_POSITION_LENGTHTEXTURECOLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST,
+ cc.SHADER_SPRITE_POSITION_COLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY
+ ],
+
_programs: {},
_init: function () {
- // this.loadDefaultShaders();
+ this.loadDefaultShaders();
return true;
},
@@ -200,6 +215,10 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
* loads the default shaders
*/
loadDefaultShaders: function () {
+ for (var i = 0; i < this.TYPE_MAX; ++i) {
+ var key = this._keyMap[i];
+ this.programForKey(key);
+ }
},
/**
@@ -211,62 +230,62 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
// Position Texture Color shader
var program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURECOLOR);
// Sprite Position Texture Color shader
program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR);
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
// Position Texture Color alpha test
program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
// Sprite Position Texture Color alpha shader
program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
program.reset();
- this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST);
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
//
// Position, Color shader
//
program = this.programForKey(cc.SHADER_POSITION_COLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_COLOR);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_COLOR);
//
// Position Texture shader
//
program = this.programForKey(cc.SHADER_POSITION_TEXTURE);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURE);
//Position Texture Gray shader
program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG);
program.reset();
- this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR_GRAY);
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG);
//
// Position, Texture attribs, 1 Color as uniform shader
//
program = this.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_UCOLOR);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURE_UCOLOR);
//
// Position Texture A8 Color shader
//
program = this.programForKey(cc.SHADER_POSITION_TEXTUREA8COLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_A8COLOR);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTUREA8COLOR);
//
// Position and 1 color passed as a uniform (to similate glColor4ub )
//
program = this.programForKey(cc.SHADER_POSITION_UCOLOR);
program.reset();
- this._loadDefaultShader(program, this.TYPE_POSITION_UCOLOR);
+ this._loadDefaultShader(program, cc.SHADER_POSITION_UCOLOR);
},
/**
diff --git a/cocos2d/shape-nodes/CCDrawNode.js b/cocos2d/shape-nodes/CCDrawNode.js
index 732bd8cda8..48caafa13f 100644
--- a/cocos2d/shape-nodes/CCDrawNode.js
+++ b/cocos2d/shape-nodes/CCDrawNode.js
@@ -530,6 +530,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
},
onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
if (this._occupiedSize < this._bufferCapacity) {
this._ensureCapacity(this._bufferCapacity);
}
@@ -539,6 +540,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
if (!this.manualRelease) {
this.release();
}
+ cc.Node.prototype.onExit.call(this);
},
release: function () {
@@ -570,7 +572,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
// Copy old data
if (prev !== 0 && prevOffset !== offset) {
// offset is in byte, we need to transform to float32 index
- var last = (prevOffset + prev) / 4;
+ var last = prevOffset / 4 + prev * FLOAT_PER_VERTEX;
for (var i = offset / 4, j = prevOffset / 4; j < last; i++, j++) {
_sharedBuffer.dataArray[i] = _sharedBuffer.dataArray[j];
}
diff --git a/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js b/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js
index 771f852748..92189454b7 100644
--- a/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js
+++ b/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js
@@ -44,7 +44,7 @@
cc.extend(cc.DrawNode.CanvasRenderCmd.prototype, {
rendering: function (ctx, scaleX, scaleY) {
var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), node = this._node;
- var alpha = node._displayedOpacity / 255;
+ var alpha = this._displayedOpacity / 255;
if (alpha === 0)
return;
diff --git a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js
index ef9d443c98..cd7ea5125c 100644
--- a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js
+++ b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js
@@ -45,8 +45,7 @@
this._matrix.mat[13] = wt.ty;
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
node._render();
}
};
diff --git a/extensions/ccui/base-classes/CCProtectedNode.js b/extensions/ccui/base-classes/CCProtectedNode.js
index 4a2bcd367a..1925572fa5 100644
--- a/extensions/ccui/base-classes/CCProtectedNode.js
+++ b/extensions/ccui/base-classes/CCProtectedNode.js
@@ -47,15 +47,19 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
},
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- var renderer = cc.renderer, cmd = this._renderCmd;
+ var renderer = cc.renderer;
var i, children = this._children, len = children.length, child;
var j, pChildren = this._protectedChildren, pLen = pChildren.length, pChild;
- cmd.visit(parent && parent._renderCmd);
+ cmd.visit(parentCmd);
var locGrid = this.grid;
if (locGrid && locGrid._active)
diff --git a/extensions/ccui/base-classes/UIScale9Sprite.js b/extensions/ccui/base-classes/UIScale9Sprite.js
index ae32c96a5b..95df94cbc7 100644
--- a/extensions/ccui/base-classes/UIScale9Sprite.js
+++ b/extensions/ccui/base-classes/UIScale9Sprite.js
@@ -1,3 +1,5 @@
+/* global ccui */
+
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011-2012 cocos2d-x.org
@@ -367,6 +369,7 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit
_uvsDirty: true,
_isTriangle: false,
_isTrimmedContentSize: false,
+ _textureLoaded: false,
//v3.3
_flippedX: false,
@@ -414,6 +417,10 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit
}
},
+ textureLoaded: function () {
+ return this._textureLoaded;
+ },
+
getCapInsets: function () {
return cc.rect(this._capInsetsInternal);
},
@@ -477,6 +484,7 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit
}
var locLoaded = texture.isLoaded();
+ this._textureLoaded = locLoaded;
this._loader.clear();
if (!locLoaded) {
this._loader.once(texture, function () {
@@ -608,10 +616,12 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit
if (cc.sizeEqualToSize(self._contentSize, cc.size(0, 0))) {
self.setContentSize(self._spriteFrame._rect);
}
+ self._textureLoaded = true;
self._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
cc.renderer.childrenOrderDirty = true;
};
- if (spriteFrame.textureLoaded()) {
+ self._textureLoaded = spriteFrame.textureLoaded();
+ if (self._textureLoaded) {
onResourceDataLoaded();
} else {
this._loader.clear();
diff --git a/extensions/ccui/layouts/UILayout.js b/extensions/ccui/layouts/UILayout.js
index 695f7e40f4..34361aa8a9 100644
--- a/extensions/ccui/layouts/UILayout.js
+++ b/extensions/ccui/layouts/UILayout.js
@@ -134,14 +134,18 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{
* @param {cc.Node} [parent]
*/
visit: function (parent) {
- if (!this._visible)
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
this._adaptRenderers();
this._doLayout();
- var renderer = cc.renderer, cmd = this._renderCmd;
- var parentCmd = parent && parent._renderCmd;
+ var renderer = cc.renderer;
cmd.visit(parentCmd);
var stencilClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_STENCIL;
diff --git a/extensions/ccui/uiwidgets/UIButton.js b/extensions/ccui/uiwidgets/UIButton.js
index 4feff73686..4741e2e767 100644
--- a/extensions/ccui/uiwidgets/UIButton.js
+++ b/extensions/ccui/uiwidgets/UIButton.js
@@ -33,7 +33,7 @@
* @property {String} titleFont - The content string font of the button title
* @property {Number} titleFontSize - The content string font size of the button title
* @property {String} titleFontName - The content string font name of the button title
- * @property {cc.Color} titleFontColor - The content string font color of the button title
+ * @property {cc.Color} titleColor - The content string font color of the button title
* @property {Boolean} pressedActionEnabled - Indicate whether button has zoom effect when clicked
*/
ccui.Button = ccui.Widget.extend(/** @lends ccui.Button# */{
diff --git a/extensions/ccui/uiwidgets/UIImageView.js b/extensions/ccui/uiwidgets/UIImageView.js
index 970d015160..fed3c958db 100644
--- a/extensions/ccui/uiwidgets/UIImageView.js
+++ b/extensions/ccui/uiwidgets/UIImageView.js
@@ -83,20 +83,6 @@ ccui.ImageView = ccui.Widget.extend(/** @lends ccui.ImageView# */{
this._imageTexType = texType;
var imageRenderer = self._imageRenderer;
- if(!imageRenderer._textureLoaded){
- imageRenderer.addEventListener("load", function(){
- if(!self._ignoreSize && cc.sizeEqualToSize(self._customSize, cc.size(0, 0))) {
- self._customSize = self._imageRenderer.getContentSize();
- }
-
- self._imageTextureSize = imageRenderer.getContentSize();
-
- self._updateChildrenDisplayedRGBA();
-
- self._updateContentSizeWithTextureSize(self._imageTextureSize);
- });
- }
-
switch (self._imageTexType) {
case ccui.Widget.LOCAL_TEXTURE:
if(self._scale9Enabled){
@@ -120,6 +106,24 @@ ccui.ImageView = ccui.Widget.extend(/** @lends ccui.ImageView# */{
break;
}
+ if(!imageRenderer._textureLoaded){
+ var handleTextureLoadedEvent = function(){
+ imageRenderer.removeEventListener("load", handleTextureLoadedEvent);
+
+ if(!self._ignoreSize && cc.sizeEqualToSize(self._customSize, cc.size(0, 0))) {
+ self._customSize = self._imageRenderer.getContentSize();
+ }
+
+ self._imageTextureSize = imageRenderer.getContentSize();
+
+ self._updateChildrenDisplayedRGBA();
+
+ self._updateContentSizeWithTextureSize(self._imageTextureSize);
+ };
+
+ imageRenderer.addEventListener("load", handleTextureLoadedEvent);
+ }
+
if(!this._ignoreSize && cc.sizeEqualToSize(this._customSize, cc.size(0, 0))) {
this._customSize = this._imageRenderer.getContentSize();
}
diff --git a/extensions/ccui/uiwidgets/UIText.js b/extensions/ccui/uiwidgets/UIText.js
index adc25f3573..5d72e061c4 100644
--- a/extensions/ccui/uiwidgets/UIText.js
+++ b/extensions/ccui/uiwidgets/UIText.js
@@ -99,15 +99,12 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
*/
setString: function (text) {
if(text === this._labelRenderer.getString()) return;
+ this._setString(text);
- this._labelRenderer.setString(text);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
_setString: function (text) {
- if(text === this._labelRenderer.getString()) return;
-
this._labelRenderer.setString(text);
this._labelRendererAdaptDirty = true;
},
@@ -143,10 +140,8 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
* @param {Number} size
*/
setFontSize: function (size) {
- this._labelRenderer.setFontSize(size);
- this._fontSize = size;
+ this._setFontSize(size);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
_setFontSize: function (size) {
@@ -168,10 +163,8 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
* @return {String} name
*/
setFontName: function (name) {
- this._fontName = name;
- this._labelRenderer.setFontName(name);
+ this._setFontName(name);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
_setFontName: function (name) {
@@ -218,12 +211,8 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
* @param {cc.Size} size
*/
setTextAreaSize: function (size) {
- this._labelRenderer.setDimensions(size);
- if (!this._ignoreSize) {
- this._customSize = size;
- }
+ this._setTextAreaSize(size);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
_setTextAreaSize: function (size) {
@@ -247,9 +236,8 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
* @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment
*/
setTextHorizontalAlignment: function (alignment) {
- this._labelRenderer.setHorizontalAlignment(alignment);
+ this._setTextHorizontalAlignment(alignment);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
@@ -271,9 +259,8 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
* @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} alignment
*/
setTextVerticalAlignment: function (alignment) {
- this._labelRenderer.setVerticalAlignment(alignment);
+ this._setTextVerticalAlignment(alignment);
this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
- this._labelRendererAdaptDirty = true;
},
_setTextVerticalAlignment: function (alignment) {
@@ -364,7 +351,6 @@ ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
_labelScaleChangedWithSize: function () {
var locContentSize = this._contentSize;
if (this._ignoreSize) {
- this._labelRenderer.setDimensions(0, 0);
this._labelRenderer.setScale(1.0);
this._normalScaleValueX = this._normalScaleValueY = 1;
} else {
diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js
index cbdadaad21..79741c9525 100644
--- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js
+++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js
@@ -124,14 +124,18 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{
},
visit: function (parent) {
- if (!this._visible)
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
this._adaptRenderers();
this._doLayout();
- var renderer = cc.renderer, cmd = this._renderCmd;
- var parentCmd = parent && parent._renderCmd;
+ var renderer = cc.renderer;
cmd.visit(parentCmd);
renderer.pushRenderCommand(cmd);
diff --git a/extensions/cocostudio/armature/CCArmature.js b/extensions/cocostudio/armature/CCArmature.js
index 29de0934e5..3836c34afd 100644
--- a/extensions/cocostudio/armature/CCArmature.js
+++ b/extensions/cocostudio/armature/CCArmature.js
@@ -151,12 +151,16 @@ ccs.Armature = ccs.Node.extend(/** @lends ccs.Armature# */{
},
visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
// quick return if not visible
- if (!this._visible)
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
return;
+ }
- this._renderCmd.visit(parent && parent._renderCmd);
- this._renderCmd._dirtyFlag = 0;
+ cmd.visit(parentCmd);
+ cmd._dirtyFlag = 0;
},
addChild: function (child, localZOrder, tag) {
diff --git a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js
index bf48084815..6f24c7b677 100644
--- a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js
+++ b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js
@@ -118,7 +118,7 @@
};
proto.setShaderProgram = function (shaderProgram) {
- this._shaderProgram = shaderProgram;
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
};
proto._updateColorAndOpacity = function (skinRenderCmd, bone) {
diff --git a/extensions/cocostudio/loader/parsers/timelineParser-2.x.js b/extensions/cocostudio/loader/parsers/timelineParser-2.x.js
index e79ab9b791..c823ce8737 100644
--- a/extensions/cocostudio/loader/parsers/timelineParser-2.x.js
+++ b/extensions/cocostudio/loader/parsers/timelineParser-2.x.js
@@ -1078,18 +1078,18 @@
* @returns {ccui.TextBMFont}
*/
parser.initTextBMFont = function (json, resourcePath) {
-
var widget = new ccui.TextBMFont();
this.widgetAttributes(widget, json);
- var text = json["LabelText"];
- widget.setString(text);
-
loadTexture(json["LabelBMFontFile_CNB"], resourcePath, function (path, type) {
if (!cc.loader.getRes(path))
cc.log("%s need to be pre loaded", path);
widget.setFntFile(path);
});
+
+ var text = json["LabelText"];
+ widget.setString(text);
+
widget.ignoreContentAdaptWithSize(true);
return widget;
};
diff --git a/extensions/cocostudio/timeline/CCSkeletonNode.js b/extensions/cocostudio/timeline/CCSkeletonNode.js
index 28517649d1..2bd075f51e 100644
--- a/extensions/cocostudio/timeline/CCSkeletonNode.js
+++ b/extensions/cocostudio/timeline/CCSkeletonNode.js
@@ -145,10 +145,14 @@ ccs.SkeletonNode = (function () {
},
_visit: function (parentCmd) {
- if (!this._visible)
- return;
var cmd = this._renderCmd;
parentCmd = parentCmd || cmd.getParentRenderCmd();
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
cmd._syncStatus(parentCmd);
var i, node;
diff --git a/extensions/editbox/CCEditBox.js b/extensions/editbox/CCEditBox.js
index 758f04934f..3a535438f2 100644
--- a/extensions/editbox/CCEditBox.js
+++ b/extensions/editbox/CCEditBox.js
@@ -154,14 +154,14 @@ cc.EditBoxDelegate = cc.Class.extend({
* This method is called when an edit box gains focus after keyboard is shown.
* @param {cc.EditBox} sender
*/
- editBoxEditingDidBegan: function (sender) {
+ editBoxEditingDidBegin: function (sender) {
},
/**
* This method is called when an edit box loses focus after keyboard is hidden.
* @param {cc.EditBox} sender
*/
- editBoxEditingDidEnded: function (sender) {
+ editBoxEditingDidEnd: function (sender) {
},
/**
@@ -176,7 +176,7 @@ cc.EditBoxDelegate = cc.Class.extend({
* This method is called when the return button was pressed.
* @param {cc.EditBox} sender
*/
- editBoxEditingReturn: function (sender) {
+ editBoxReturn: function (sender) {
}
});
@@ -186,7 +186,7 @@ cc.EditBoxDelegate = cc.Class.extend({
* You can use this widget to gather small amounts of text from the user.
@@ -78,7 +52,6 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
_premultipliedAlpha: false,
_ownsSkeletonData: null,
_atlas: null,
- _blendFunc: null,
/**
* The constructor of sp.Skeleton. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
@@ -105,10 +78,18 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
init: function () {
cc.Node.prototype.init.call(this);
this._premultipliedAlpha = (cc._renderType === cc.game.RENDER_TYPE_WEBGL && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA);
- this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ },
+
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
this.scheduleUpdate();
},
+ onExit: function () {
+ this.unscheduleUpdate();
+ cc.Node.prototype.onExit.call(this);
+ },
+
/**
* Sets whether open debug slots.
* @param {boolean} enable true to open, false to close.
@@ -171,7 +152,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Initializes sp.Skeleton with Data.
- * @param {spine.SkeletonData|String} skeletonDataFile
+ * @param {sp.spine.SkeletonData|String} skeletonDataFile
* @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
* @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
*/
@@ -211,19 +192,20 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
*/
getBoundingBox: function () {
var minX = cc.FLT_MAX, minY = cc.FLT_MAX, maxX = cc.FLT_MIN, maxY = cc.FLT_MIN;
- var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices = [],
+ var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices,
slots = this._skeleton.slots, VERTEX = spine.RegionAttachment;
for (var i = 0, slotCount = slots.length; i < slotCount; ++i) {
var slot = slots[i];
var attachment = slot.attachment;
- if (!attachment || ! (attachment instanceof spine.RegionAttachment))
+ if (!attachment || !(attachment instanceof spine.RegionAttachment))
continue;
- vertices = attachment.updateWorldVertices(slot, false);
- minX = Math.min(minX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- minY = Math.min(minY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
- maxX = Math.max(maxX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- maxY = Math.max(maxY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
+ vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ minX = Math.min(minX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ minY = Math.min(minY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
+ maxX = Math.max(maxX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ maxY = Math.max(maxY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
}
var position = this.getPosition();
return cc.rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
@@ -260,7 +242,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a bone by name. This does a string comparison for every bone.
* @param {String} boneName
- * @returns {spine.Bone}
+ * @returns {sp.spine.Bone}
*/
findBone: function (boneName) {
return this._skeleton.findBone(boneName);
@@ -269,7 +251,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a slot by name. This does a string comparison for every slot.
* @param {String} slotName
- * @returns {spine.Slot}
+ * @returns {sp.spine.Slot}
*/
findSlot: function (slotName) {
return this._skeleton.findSlot(slotName);
@@ -278,7 +260,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a skin by name and makes it the active skin. This does a string comparison for every skin. Note that setting the skin does not change which attachments are visible.
* @param {string} skinName
- * @returns {spine.Skin}
+ * @returns {sp.spine.Skin}
*/
setSkin: function (skinName) {
return this._skeleton.setSkinByName(skinName);
@@ -288,7 +270,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* Returns the attachment for the slot and attachment name. The skeleton looks first in its skin, then in the skeleton data’s default skin.
* @param {String} slotName
* @param {String} attachmentName
- * @returns {spine.RegionAttachment|spine.BoundingBoxAttachment}
+ * @returns {sp.spine.Attachment}
*/
getAttachment: function (slotName, attachmentName) {
return this._skeleton.getAttachmentByName(slotName, attachmentName);
@@ -321,8 +303,8 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Sets skeleton data to sp.Skeleton.
- * @param {spine.SkeletonData} skeletonData
- * @param {spine.SkeletonData} ownsSkeletonData
+ * @param {sp.spine.SkeletonData} skeletonData
+ * @param {sp.spine.SkeletonData} ownsSkeletonData
*/
setSkeletonData: function (skeletonData, ownsSkeletonData) {
if(skeletonData.width != null && skeletonData.height != null)
@@ -338,8 +320,8 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Return the renderer of attachment.
- * @param {spine.RegionAttachment|spine.BoundingBoxAttachment} regionAttachment
- * @returns {cc.Node}
+ * @param {sp.spine.RegionAttachment|sp.spine.BoundingBoxAttachment} regionAttachment
+ * @returns {sp.spine.TextureAtlasRegion}
*/
getTextureAtlas: function (regionAttachment) {
return regionAttachment.region;
@@ -350,23 +332,23 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* @returns {cc.BlendFunc}
*/
getBlendFunc: function () {
- return this._blendFunc;
+ var slot = this._skeleton.drawOrder[0];
+ if (slot) {
+ var blend = this._renderCmd._getBlendFunc(slot.data.blendMode, this._premultipliedAlpha);
+ return blend;
+ }
+ else {
+ return {};
+ }
},
/**
- * Sets the blendFunc of sp.Skeleton.
+ * Sets the blendFunc of sp.Skeleton, it won't have any effect for skeleton, skeleton is using slot's data to determine the blend function.
* @param {cc.BlendFunc|Number} src
* @param {Number} [dst]
*/
setBlendFunc: function (src, dst) {
- var locBlendFunc = this._blendFunc;
- if (dst === undefined) {
- locBlendFunc.src = src.src;
- locBlendFunc.dst = src.dst;
- } else {
- locBlendFunc.src = src;
- locBlendFunc.dst = dst;
- }
+ return;
},
/**
@@ -378,6 +360,14 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
}
});
+cc.defineGetterSetter(sp.Skeleton.prototype, "opacityModifyRGB", sp.Skeleton.prototype.isOpacityModifyRGB);
+
+// For renderer webgl to identify skeleton's default texture and blend function
+cc.defineGetterSetter(sp.Skeleton.prototype, "_blendFunc", sp.Skeleton.prototype.getBlendFunc);
+cc.defineGetterSetter(sp.Skeleton.prototype, '_texture', function () {
+ return this._renderCmd._currTexture;
+});
+
/**
* Creates a skeleton object.
* @deprecated since v3.0, please use new sp.Skeleton(skeletonDataFile, atlasFile, scale) instead.
diff --git a/extensions/spine/CCSkeletonAnimation.js b/extensions/spine/CCSkeletonAnimation.js
index 339bd08f15..17f0f25675 100644
--- a/extensions/spine/CCSkeletonAnimation.js
+++ b/extensions/spine/CCSkeletonAnimation.js
@@ -32,8 +32,7 @@ sp._atlasLoader = {
load:function(line){
var texturePath = cc.path.join(cc.path.dirname(this.spAtlasFile), line);
var texture = cc.textureCache.addImage(texturePath);
- var tex = new sp.SkeletonTexture();
- tex._image = { width: texture.getPixelsWide(), height: texture.getPixelsHigh() };
+ var tex = new sp.SkeletonTexture({ width: texture.getPixelsWide(), height: texture.getPixelsHigh() });
tex.setRealTexture(texture);
return tex;
},
@@ -55,7 +54,7 @@ sp.ANIMATION_EVENT_TYPE = {
EVENT: 5
};
-sp.TrackEntryListeners = function(startListener, endListener, completeListener, eventListener, interruptListener, disposeListener){
+sp.TrackEntryListeners = function (startListener, endListener, completeListener, eventListener, interruptListener, disposeListener) {
this.startListener = startListener || null;
this.endListener = endListener || null;
this.completeListener = completeListener || null;
@@ -156,7 +155,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
/**
* Sets animation state data to sp.SkeletonAnimation.
- * @param {spine.AnimationStateData} stateData
+ * @param {sp.spine.AnimationStateData} stateData
*/
setAnimationStateData: function (stateData) {
var state = new spine.AnimationState(stateData);
@@ -192,7 +191,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Number} trackIndex
* @param {String} name
* @param {Boolean} loop
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
setAnimation: function (trackIndex, name, loop) {
var animation = this._skeleton.data.findAnimation(name);
@@ -209,7 +208,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {String} name
* @param {Boolean} loop
* @param {Number} [delay=0]
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
addAnimation: function (trackIndex, name, loop, delay) {
delay = delay == null ? 0 : delay;
@@ -221,10 +220,19 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
return this._state.addAnimationWith(trackIndex, animation, loop, delay);
},
+ /**
+ * Find animation with specified name
+ * @param {String} name
+ * @returns {sp.spine.Animation|null}
+ */
+ findAnimation: function (name) {
+ return this._skeleton.data.findAnimation(name);
+ },
+
/**
* Returns track entry by trackIndex.
* @param trackIndex
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
getCurrent: function (trackIndex) {
return this._state.getCurrent(trackIndex);
@@ -254,6 +262,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
update: function (dt) {
this._super(dt);
dt *= this._timeScale;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
this._state.update(dt);
this._state.apply(this._skeleton);
this._skeleton.updateWorldTransform();
@@ -339,4 +348,4 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
*/
sp.SkeletonAnimation.createWithJsonFile = sp.SkeletonAnimation.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
return new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale);
-};
\ No newline at end of file
+};
diff --git a/extensions/spine/CCSkeletonCanvasRenderCmd.js b/extensions/spine/CCSkeletonCanvasRenderCmd.js
index 2b20f3f97c..f31924ec19 100644
--- a/extensions/spine/CCSkeletonCanvasRenderCmd.js
+++ b/extensions/spine/CCSkeletonCanvasRenderCmd.js
@@ -23,208 +23,225 @@
****************************************************************************/
(function () {
- sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
- this._rootCtor(renderableObject);
- this._needDraw = true;
- };
-
- var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
- proto.constructor = sp.Skeleton.CanvasRenderCmd;
-
- proto.rendering = function (wrapper, scaleX, scaleY) {
- var node = this._node, i, n, slot, slotNode;
- wrapper = wrapper || cc._renderContext;
-
- var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
- for (i = 0, n = drawOrder.length; i < n; i++) {
- slot = drawOrder[i];
- slotNode = slot._slotNode;
- if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
- slotNode._renderCmd.transform(this, true);
- slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
- slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
- }
- }
- if (!node._debugSlots && !node._debugBones)
- return;
-
- wrapper.setTransform(this._worldTransform, scaleX, scaleY);
- wrapper.setGlobalAlpha(1);
- var attachment, drawingUtil = cc._drawingUtil;
- if (node._debugSlots) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- var points = [];
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
- continue;
- attachment = slot.attachment;
- this._updateRegionAttachmentSlot(attachment, slot, points);
- drawingUtil.drawPoly(points, 4, true);
- }
- }
+var spine = sp.spine;
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.a + bone.worldX;
- var y = bone.data.length * bone.c + bone.worldY;
- drawingUtil.drawLine(
- {x: bone.worldX, y: bone.worldY},
- {x: x, y: y});
- }
+sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+};
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+proto.constructor = sp.Skeleton.CanvasRenderCmd;
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY});
- if (i === 0)
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+proto.rendering = function (wrapper, scaleX, scaleY) {
+ var node = this._node, i, n, slot, slotNode;
+ wrapper = wrapper || cc._renderContext;
+
+ var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
+ for (i = 0, n = drawOrder.length; i < n; i++) {
+ slot = drawOrder[i];
+ slotNode = slot._slotNode;
+ if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
+ slotNode._renderCmd.transform(this, true);
+ slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
+ slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
}
- };
-
- proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
- if (!points)
- return;
-
- var vertices = attachment.updateWorldVertices(slot, false);
- var VERTEX = spine.RegionAttachment;
- points.length = 0;
- points.push(cc.p(vertices[VERTEX.X1], vertices[VERTEX.Y1]));
- points.push(cc.p(vertices[VERTEX.X4], vertices[VERTEX.Y4]));
- points.push(cc.p(vertices[VERTEX.X3], vertices[VERTEX.Y3]));
- points.push(cc.p(vertices[VERTEX.X2], vertices[VERTEX.Y2]));
- };
-
- proto._createChildFormSkeletonData = function () {
- var node = this._node;
- var locSkeleton = node._skeleton, spriteName, sprite;
- for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
- var slot = locSkeleton.slots[i], attachment = slot.attachment;
- var slotNode = new cc.Node();
- slot._slotNode = slotNode;
-
- if (attachment instanceof spine.RegionAttachment) {
- spriteName = attachment.region.name;
- sprite = this._createSprite(slot, attachment);
- slot.currentSprite = sprite;
- slot.currentSpriteName = spriteName;
- slotNode.addChild(sprite);
- } else if (attachment instanceof spine.MeshAttachment) {
- //todo for mesh
- }
+ }
+
+ if (!node._debugSlots && !node._debugBones)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setGlobalAlpha(1);
+ var attachment, drawingUtil = cc._drawingUtil;
+ if (node._debugSlots) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ var points = [];
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
+ continue;
+ attachment = slot.attachment;
+ this._updateRegionAttachmentSlot(attachment, slot, points);
+ drawingUtil.drawPoly(points, 4, true);
}
- };
-
- var loaded = function (sprite, texture, rendererObject, attachment) {
- var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
- sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
- sprite._rect.width = attachment.width;
- sprite._rect.height = attachment.height;
- sprite.setContentSize(attachment.width, attachment.height);
- sprite.setRotation(-attachment.rotation);
- sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
- rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
- };
-
- proto._createSprite = function (slot, attachment) {
- var rendererObject = attachment.region;
- var texture = rendererObject.texture.getRealTexture();
- var sprite = new cc.Sprite();
- if (texture.isLoaded()) {
- loaded(sprite, texture, rendererObject, attachment);
- } else {
- texture.addEventListener('load', function () {
- loaded(sprite, texture, rendererObject, attachment);
- }, this);
+ }
+
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(
+ {x: bone.worldX, y: bone.worldY},
+ {x: x, y: y});
}
- slot.sprites = slot.sprites || {};
- slot.sprites[rendererObject.name] = sprite;
- return sprite;
- };
-
- proto._updateChild = function () {
- var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
- var color = this._displayedColor, opacity = this._displayedOpacity;
- var i, n, selSprite, ax, ay;
-
- var slot, attachment, slotNode;
- for (i = 0, n = slots.length; i < n; i++) {
- slot = slots[i];
- attachment = slot.attachment;
- slotNode = slot._slotNode;
- if (!attachment) {
- slotNode.setVisible(false);
- continue;
- }
- if (attachment instanceof spine.RegionAttachment){
- if (attachment.region) {
- if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
- var spriteName = attachment.region.name;
- if (slot.currentSprite !== undefined)
- slot.currentSprite.setVisible(false);
- slot.sprites = slot.sprites || {};
- if (slot.sprites[spriteName] !== undefined)
- slot.sprites[spriteName].setVisible(true);
- else {
- var sprite = this._createSprite(slot, attachment);
- slotNode.addChild(sprite);
- }
- slot.currentSprite = slot.sprites[spriteName];
- slot.currentSpriteName = spriteName;
+
+ // Bone origins.
+ var pointSize = 4;
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY}, pointSize);
+ if (i === 0)
+ drawingUtil.setDrawColor(0, 255, 0, 255);
+ }
+ }
+};
+
+proto.updateStatus = function() {
+ this.originUpdateStatus();
+ this._updateCurrentRegions();
+ this._regionFlag = cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble;
+ this._dirtyFlag &= ~cc.Node._dirtyFlags.contentDirty;
+};
+
+proto.getLocalBB = function() {
+ return this._node.getBoundingBox();
+};
+
+proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
+ if (!points)
+ return;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ var VERTEX = spine.RegionAttachment;
+ points.length = 0;
+ points.push(cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]));
+ points.push(cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4]));
+ points.push(cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]));
+ points.push(cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]));
+};
+
+proto._createChildFormSkeletonData = function () {
+ var node = this._node;
+ var locSkeleton = node._skeleton, spriteName, sprite;
+ for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var slot = locSkeleton.slots[i], attachment = slot.attachment;
+ var slotNode = new cc.Node();
+ slot._slotNode = slotNode;
+
+ if (attachment instanceof spine.RegionAttachment) {
+ spriteName = attachment.region.name;
+ sprite = this._createSprite(slot, attachment);
+ slot.currentSprite = sprite;
+ slot.currentSpriteName = spriteName;
+ slotNode.addChild(sprite);
+ } else if (attachment instanceof spine.MeshAttachment) {
+ //todo for mesh
+ }
+ }
+};
+
+var loaded = function (sprite, texture, attachment) {
+ var rendererObject = attachment.region;
+ var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
+ sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
+ sprite._rect.width = attachment.width;
+ sprite._rect.height = attachment.height;
+ sprite.setContentSize(attachment.width, attachment.height);
+ sprite.setRotation(-attachment.rotation);
+ sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
+ rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
+};
+
+proto._createSprite = function (slot, attachment) {
+ var rendererObject = attachment.region;
+ var texture = rendererObject.texture.getRealTexture();
+ var sprite = new cc.Sprite();
+ if (texture.isLoaded()) {
+ loaded(sprite, texture, attachment);
+ } else {
+ texture.addEventListener('load', function () {
+ loaded(sprite, texture, attachment);
+ }, this);
+ }
+ slot.sprites = slot.sprites || {};
+ slot.sprites[rendererObject.name] = sprite;
+ return sprite;
+};
+
+proto._updateChild = function () {
+ var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
+ var color = this._displayedColor, opacity = this._displayedOpacity;
+ var i, n, selSprite, ax, ay;
+
+ var slot, attachment, slotNode;
+ for (i = 0, n = slots.length; i < n; i++) {
+ slot = slots[i];
+ attachment = slot.attachment;
+ slotNode = slot._slotNode;
+ if (!attachment) {
+ slotNode.setVisible(false);
+ continue;
+ }
+ if (attachment instanceof spine.RegionAttachment) {
+ if (attachment.region) {
+ if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
+ var spriteName = attachment.region.name;
+ if (slot.currentSprite !== undefined)
+ slot.currentSprite.setVisible(false);
+ slot.sprites = slot.sprites || {};
+ if (slot.sprites[spriteName] !== undefined)
+ slot.sprites[spriteName].setVisible(true);
+ else {
+ var sprite = this._createSprite(slot, attachment);
+ slotNode.addChild(sprite);
}
+ slot.currentSprite = slot.sprites[spriteName];
+ slot.currentSpriteName = spriteName;
}
- var bone = slot.bone;
- if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
- ax = attachment.x;
- ay = attachment.y;
- }
- else {
- //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
- //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
- ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
- ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
- }
- slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
- slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
-
- //set the color and opacity
- selSprite = slot.currentSprite;
- selSprite._flippedX = bone.skeleton.flipX;
- selSprite._flippedY = bone.skeleton.flipY;
- if (selSprite._flippedY || selSprite._flippedX) {
- slotNode.setRotation(bone.getWorldRotationX());
- selSprite.setRotation(attachment.rotation);
- } else {
- slotNode.setRotation(-bone.getWorldRotationX());
- selSprite.setRotation(-attachment.rotation);
- }
-
- //hack for sprite
- selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
- var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
- selSprite.setColor(cc.color(r, g, b));
- selSprite._renderCmd._updateColor();
- } else if (attachment instanceof spine.MeshAttachment) {
- //todo for mesh
+ }
+ var bone = slot.bone;
+ if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
+ ax = attachment.x;
+ ay = attachment.y;
+ }
+ else {
+ //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
+ //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
+ ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
+ ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
+ }
+ slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
+ slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
+
+ //set the color and opacity
+ selSprite = slot.currentSprite;
+ selSprite._flippedX = bone.skeleton.flipX;
+ selSprite._flippedY = bone.skeleton.flipY;
+ if (selSprite._flippedY || selSprite._flippedX) {
+ slotNode.setRotation(bone.getWorldRotationX());
+ selSprite.setRotation(attachment.rotation);
} else {
- slotNode.setVisible(false);
- continue;
+ slotNode.setRotation(-bone.getWorldRotationX());
+ selSprite.setRotation(-attachment.rotation);
}
- slotNode.setVisible(true);
+
+ //hack for sprite
+ selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
+ var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
+ selSprite.setColor(cc.color(r, g, b));
+ selSprite._renderCmd._updateColor();
+ } else if (attachment instanceof spine.MeshAttachment) {
+ // Can not render mesh
+ } else {
+ slotNode.setVisible(false);
+ continue;
}
- };
+ slotNode.setVisible(true);
+ }
+};
+
})();
diff --git a/extensions/spine/CCSkeletonTexture.js b/extensions/spine/CCSkeletonTexture.js
index 997065b339..9250369c30 100644
--- a/extensions/spine/CCSkeletonTexture.js
+++ b/extensions/spine/CCSkeletonTexture.js
@@ -22,7 +22,11 @@
THE SOFTWARE.
****************************************************************************/
-sp.SkeletonTexture = cc.Class.extend({
+sp.SkeletonTexture = function (image) {
+ sp.spine.Texture.call(this, image);
+};
+cc.inherits(sp.SkeletonTexture, sp.spine.Texture);
+cc.extend(sp.SkeletonTexture.prototype, {
name: 'sp.SkeletonTexture',
_texture: null,
@@ -60,9 +64,4 @@ sp.SkeletonTexture = cc.Class.extend({
cc.glBindTexture2D(this._texture);
}
}
-});
-
-var proto = sp.SkeletonTexture.prototype;
-cc.extend(proto, spine.Texture.prototype);
-// proto.constructor = spine.Texture;
-
+});
\ No newline at end of file
diff --git a/extensions/spine/CCSkeletonWebGLRenderCmd.js b/extensions/spine/CCSkeletonWebGLRenderCmd.js
index e9fc27601a..535e4c0ac5 100644
--- a/extensions/spine/CCSkeletonWebGLRenderCmd.js
+++ b/extensions/spine/CCSkeletonWebGLRenderCmd.js
@@ -23,289 +23,325 @@
****************************************************************************/
(function () {
- sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
- this._rootCtor(renderableObject);
- this._needDraw = true;
- this._matrix = new cc.math.Matrix4();
- this._matrix.identity();
- this.vertexType = cc.renderer.VertexType.CUSTOM;
- this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
- };
- var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
- proto.constructor = sp.Skeleton.WebGLRenderCmd;
-
- proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+var spine = sp.spine;
+
+sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ this._currTexture = null;
+ this._currBlendFunc = {};
+ this.vertexType = cc.renderer.VertexType.CUSTOM;
+ this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR));
+};
+
+var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+proto.constructor = sp.Skeleton.WebGLRenderCmd;
+
+proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+ var node = this._node;
+ var color = this._displayedColor, locSkeleton = node._skeleton;
+
+ var attachment, slot, i, n;
+ var premultiAlpha = node._premultipliedAlpha;
+
+ locSkeleton.r = color.r / 255;
+ locSkeleton.g = color.g / 255;
+ locSkeleton.b = color.b / 255;
+ locSkeleton.a = this._displayedOpacity / 255;
+ if (premultiAlpha) {
+ locSkeleton.r *= locSkeleton.a;
+ locSkeleton.g *= locSkeleton.a;
+ locSkeleton.b *= locSkeleton.a;
+ }
+
+ var debugSlotsInfo = null;
+ if (this._node._debugSlots) {
+ debugSlotsInfo = [];
+ }
+
+ for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment)
+ continue;
+ attachment = slot.attachment;
+
+ // get the vertices length
+ var vertCount = 0;
+ if (attachment instanceof spine.RegionAttachment) {
+ vertCount = 6; // a quad = two triangles = six vertices
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ vertCount = attachment.regionUVs.length / 2;
+ }
+ else {
+ continue;
+ }
- // rendering the cached data first
- cc.renderer._batchRendering();
- vertexDataOffset = 0;
+ // no vertices to render
+ if (vertCount === 0) {
+ continue;
+ }
- var node = this._node;
- var color = node.getColor(), locSkeleton = node._skeleton;
+ var regionTextureAtlas = node.getTextureAtlas(attachment);
- var textureAtlas, attachment, slot, i, n;
- var premultiAlpha = node._premultipliedAlpha;
- var blendMode = -1;
- var dataInited = false;
- var cachedVertices = 0;
+ // Broken for changing batch info
+ this._currTexture = regionTextureAtlas.texture.getRealTexture();
+ var batchBroken = cc.renderer._updateBatchedInfo(this._currTexture, this._getBlendFunc(slot.data.blendMode, premultiAlpha), this._glProgramState);
- var wt = this._worldTransform, mat = this._matrix.mat;
- mat[0] = wt.a;
- mat[4] = wt.c;
- mat[12] = wt.tx;
- mat[1] = wt.b;
- mat[5] = wt.d;
- mat[13] = wt.ty;
+ // keep the same logic with RendererWebGL.js, avoid vertex data overflow
+ var uploadAll = vertexDataOffset / 6 + vertCount > (cc.BATCH_VERTEX_COUNT - 200) * 0.5;
+ // Broken for vertex data overflow
+ if (!batchBroken && uploadAll) {
+ // render the cached data
+ cc.renderer._batchRendering();
+ batchBroken = true;
+ }
+ if (batchBroken) {
+ vertexDataOffset = 0;
+ }
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
- locSkeleton.r = color.r / 255;
- locSkeleton.g = color.g / 255;
- locSkeleton.b = color.b / 255;
- locSkeleton.a = node.getOpacity() / 255;
- if (premultiAlpha) {
- locSkeleton.r *= locSkeleton.a;
- locSkeleton.g *= locSkeleton.a;
- locSkeleton.b *= locSkeleton.a;
+ // update the vertex buffer
+ var slotDebugPoints = null;
+ if (attachment instanceof spine.RegionAttachment) {
+ slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else {
+ continue;
}
- var debugSlotsInfo = null;
if (this._node._debugSlots) {
- debugSlotsInfo = [];
+ debugSlotsInfo[i] = slotDebugPoints;
}
- for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment)
- continue;
- attachment = slot.attachment;
-
- // get the vertices length
- var vertCount = 0;
- if (attachment instanceof spine.RegionAttachment) {
- vertCount = 6; // a quad = two triangles = six vertices
- }
- else if (attachment instanceof spine.MeshAttachment) {
- vertCount = attachment.regionUVs.length / 2;
- }
- else {
- continue;
- }
-
- // no vertices to render
- if (vertCount === 0) {
- continue;
- }
- var regionTextureAtlas = node.getTextureAtlas(attachment);
- // init data at the first time
- if (!dataInited) {
- textureAtlas = regionTextureAtlas;
- blendMode = slot.data.blendMode;
- cc.renderer._updateBatchedInfo(textureAtlas.texture.getRealTexture(), this._getBlendFunc(blendMode, premultiAlpha), this.getShaderProgram());
- dataInited = true;
- }
+ // update the index buffer
+ if (attachment instanceof spine.RegionAttachment) {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
+ } else {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ }
- // if data changed or the vertices will be overflow
- if ((cachedVertices + vertCount) * 6 > f32buffer.length ||
- textureAtlas !== regionTextureAtlas ||
- blendMode !== slot.data.blendMode) {
- // render the cached data
- cc.renderer._batchRendering();
- vertexDataOffset = 0;
- cachedVertices = 0;
-
- // update the batched info
- textureAtlas = regionTextureAtlas;
- blendMode = slot.data.blendMode;
- cc.renderer._updateBatchedInfo(textureAtlas.texture.getRealTexture(), this._getBlendFunc(blendMode, premultiAlpha), this.getShaderProgram());
- }
+ // update the index data
+ vertexDataOffset += vertCount * 6;
+ }
- // update the vertex buffer
- var slotDebugPoints = null;
- if (attachment instanceof spine.RegionAttachment) {
- slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
- }
- else if (attachment instanceof spine.MeshAttachment) {
- this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
- }
- else {
- continue;
- }
-
- if (this._node._debugSlots) {
- debugSlotsInfo[i] = slotDebugPoints;
- }
+ if (node._debugBones || node._debugSlots) {
+ // flush previous vertices
+ cc.renderer._batchRendering();
- // update the index buffer
- if (attachment instanceof spine.RegionAttachment) {
- cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
- } else {
- cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ var wt = this._worldTransform, mat = this._matrix.mat;
+ mat[0] = wt.a;
+ mat[4] = wt.c;
+ mat[12] = wt.tx;
+ mat[1] = wt.b;
+ mat[5] = wt.d;
+ mat[13] = wt.ty;
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.current_stack.stack.push(cc.current_stack.top);
+ cc.current_stack.top = this._matrix;
+ var drawingUtil = cc._drawingUtil;
+
+ if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var points = debugSlotsInfo[i];
+ if (points) {
+ drawingUtil.drawPoly(points, 4, true);
+ }
}
-
- // update the index data
- cachedVertices += vertCount;
- vertexDataOffset += vertCount * 6;
}
- // render the left vertices
- if (cachedVertices > 0) {
- cc.renderer._batchRendering();
- }
-
- if (node._debugBones || node._debugSlots) {
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- cc.current_stack.stack.push(cc.current_stack.top);
- cc.current_stack.top = this._matrix;
- var drawingUtil = cc._drawingUtil;
-
- if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- var points = debugSlotsInfo[i];
- if (points) {
- drawingUtil.drawPoly(points, 4, true);
- }
- }
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
}
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.a + bone.worldX;
- var y = bone.data.length * bone.c + bone.worldY;
- drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
- }
-
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+ // Bone origins.
+ drawingUtil.setPointSize(4);
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
- if (i == 0) {
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
+ if (i == 0) {
+ drawingUtil.setDrawColor(0, 255, 0, 255);
}
}
- cc.kmGLPopMatrix();
}
+ cc.kmGLPopMatrix();
+ }
+
+ return 0;
+};
+
+proto._getBlendFunc = function (blendMode, premultiAlpha) {
+ var ret = this._currBlendFunc;
+ switch (blendMode) {
+ case spine.BlendMode.Normal:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Additive:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE;
+ break;
+ case spine.BlendMode.Multiply:
+ ret.src = cc.DST_COLOR;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Screen:
+ ret.src = cc.ONE;
+ ret.dst = cc.ONE_MINUS_SRC_COLOR;
+ break;
+ default:
+ ret = this._node._blendFunc;
+ break;
+ }
+
+ return ret;
+};
+
+proto._createChildFormSkeletonData = function(){};
+
+proto._updateChild = function(){};
+
+proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ // the vertices in format:
+ // [
+ // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
+ // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
+ // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
+ // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
+ // ]
+ //
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color;
+ var slotColor = slot.color;
+ var regionColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * regionColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
+ skeletonColor.g * slotColor.g * regionColor.g * multiplier,
+ skeletonColor.b * slotColor.b * regionColor.b * multiplier,
+ alpha);
+
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+
+ var offset = vertexDataOffset;
+ // generate 6 vertices data (two triangles) from the quad vertices
+ // using two angles : (0, 1, 2) & (0, 2, 3)
+ for (var i = 0; i < 6; i++) {
+ var srcIdx = i < 4 ? i % 3 : i - 2;
+ var vx = vertices[srcIdx * 2],
+ vy = vertices[srcIdx * 2 + 1];
+ var x = vx * wa + vy * wc + wx,
+ y = vx * wb + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[srcIdx * 2];
+ f32buffer[offset + 5] = uvs[srcIdx * 2 + 1];
+ offset += 6;
+ }
+
+ if (this._node._debugSlots) {
+ // return the quad points info if debug slot enabled
+ var VERTEX = spine.RegionAttachment;
+ return [
+ cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]),
+ cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]),
+ cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]),
+ cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4])
+ ];
+ }
+};
+
+proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+ // get the vertex data
+ var verticesLength = attachment.worldVerticesLength;
+ var vertices = spine.Utils.setArraySize(new Array(), verticesLength, 0);
+ attachment.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color, slotColor = slot.color, meshColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * meshColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
+ skeletonColor.g * slotColor.g * meshColor.g * multiplier,
+ skeletonColor.b * slotColor.b * meshColor.b * multiplier,
+ alpha);
+
+ var offset = vertexDataOffset;
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+ for (var i = 0, n = vertices.length; i < n; i += 2) {
+ var vx = vertices[i],
+ vy = vertices[i + 1];
+ var x = vx * wa + vy * wb + wx,
+ y = vx * wc + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[i];
+ f32buffer[offset + 5] = uvs[i + 1];
+ offset += 6;
+ }
+};
- return 0;
- };
-
- proto._getBlendFunc = function (blendMode, premultiAlpha) {
- var ret = {};
- switch (blendMode) {
- case spine.BlendMode.Normal:
- ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
- ret.dst = cc.ONE_MINUS_SRC_ALPHA;
- break;
- case spine.BlendMode.Additive:
- ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
- ret.dst = cc.ONE;
- break;
- case spine.BlendMode.Multiply:
- ret.src = cc.DST_COLOR;
- ret.dst = cc.ONE_MINUS_SRC_ALPHA;
- break;
- case spine.BlendMode.Screen:
- ret.src = cc.ONE;
- ret.dst = cc.ONE_MINUS_SRC_COLOR;
- break;
- default:
- ret = this._node._blendFunc;
- break;
- }
-
- return ret;
- };
-
- proto._createChildFormSkeletonData = function () {
- };
-
- proto._updateChild = function () {
- };
-
- proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
- // the vertices in format:
- // [
- // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
- // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
- // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
- // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
- // ]
- //
- var nodeColor = this._displayedColor;
- var nodeR = nodeColor.r,
- nodeG = nodeColor.g,
- nodeB = nodeColor.b,
- nodeA = nodeColor.a;
- var vertices = attachment.updateWorldVertices(slot, premultipliedAlpha);
- var offset = vertexDataOffset;
- // generate 6 vertices data (two triangles) from the quad vertices
- // using two angles : (0, 1, 2) & (0, 2, 3)
- for (var i = 0; i < 6; i++) {
- var srcIdx = i < 4 ? i % 3 : i - 2;
- var r = vertices[srcIdx * 8 + 2] * nodeR,
- g = vertices[srcIdx * 8 + 3] * nodeG,
- b = vertices[srcIdx * 8 + 4] * nodeB,
- a = vertices[srcIdx * 8 + 5] * nodeA;
- var color = ((a<<24) | (b<<16) | (g<<8) | r);
- f32buffer[offset] = vertices[srcIdx * 8];
- f32buffer[offset + 1] = vertices[srcIdx * 8 + 1];
- f32buffer[offset + 2] = this._node.vertexZ;
- ui32buffer[offset + 3] = color;
- f32buffer[offset + 4] = vertices[srcIdx * 8 + 6];
- f32buffer[offset + 5] = vertices[srcIdx * 8 + 7];
- offset += 6;
- }
-
- if (this._node._debugSlots) {
- // return the quad points info if debug slot enabled
- var VERTEX = spine.RegionAttachment;
- return [
- cc.p(vertices[VERTEX.X1], vertices[VERTEX.Y1]),
- cc.p(vertices[VERTEX.X2], vertices[VERTEX.Y2]),
- cc.p(vertices[VERTEX.X3], vertices[VERTEX.Y3]),
- cc.p(vertices[VERTEX.X4], vertices[VERTEX.Y4])
- ];
- }
- };
-
- proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
- // get the vertex data
- var vertices = attachment.updateWorldVertices(slot, premultipliedAlpha);
- var offset = vertexDataOffset;
- var nodeColor = this._displayedColor;
- var nodeR = nodeColor.r,
- nodeG = nodeColor.g,
- nodeB = nodeColor.b,
- nodeA = nodeColor.a;
- for (var i = 0, n = vertices.length; i < n; i += 8) {
- var r = vertices[i + 2] * nodeR,
- g = vertices[i + 3] * nodeG,
- b = vertices[i + 4] * nodeB,
- a = vertices[i + 5] * nodeA;
- var color = ((a<<24) | (b<<16) | (g<<8) | r);
-
- f32buffer[offset] = vertices[i];
- f32buffer[offset + 1] = vertices[i + 1];
- f32buffer[offset + 2] = this._node.vertexZ;
- ui32buffer[offset + 3] = color;
- f32buffer[offset + 4] = vertices[i + 6];
- f32buffer[offset + 5] = vertices[i + 7];
- offset += 6;
- }
- };
})();
diff --git a/extensions/spine/LICENSE b/extensions/spine/LICENSE
new file mode 100644
index 0000000000..daceab94a4
--- /dev/null
+++ b/extensions/spine/LICENSE
@@ -0,0 +1,27 @@
+Spine Runtimes Software License v2.5
+
+Copyright (c) 2013-2016, Esoteric Software
+All rights reserved.
+
+You are granted a perpetual, non-exclusive, non-sublicensable, and
+non-transferable license to use, install, execute, and perform the Spine
+Runtimes software and derivative works solely for personal or internal
+use. Without the written permission of Esoteric Software (see Section 2 of
+the Spine Software License Agreement), you may not (a) modify, translate,
+adapt, or develop new applications using the Spine Runtimes or otherwise
+create derivative works or improvements of the Spine Runtimes or (b) remove,
+delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+or other intellectual property or proprietary rights notices on or in the
+Software, including any copy thereof. Redistributions in binary or source
+form must include this license and terms.
+
+THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/extensions/spine/Spine.js b/extensions/spine/Spine.js
index 0d4533c3f0..e7c0d894ea 100644
--- a/extensions/spine/Spine.js
+++ b/extensions/spine/Spine.js
@@ -1,8 +1,15 @@
-var __extends = (this && this.__extends) || function (d, b) {
- for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
+// Spine runtime version 3.6.39
+
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
var spine;
(function (spine) {
var Animation = (function () {
@@ -15,7 +22,7 @@ var spine;
this.timelines = timelines;
this.duration = duration;
}
- Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, setupPose, mixingOut) {
+ Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, pose, direction) {
if (skeleton == null)
throw new Error("skeleton cannot be null.");
if (loop && this.duration != 0) {
@@ -25,7 +32,7 @@ var spine;
}
var timelines = this.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, alpha, setupPose, mixingOut);
+ timelines[i].apply(skeleton, lastTime, time, events, alpha, pose, direction);
};
Animation.binarySearch = function (values, target, step) {
if (step === void 0) { step = 1; }
@@ -53,6 +60,18 @@ var spine;
return Animation;
}());
spine.Animation = Animation;
+ var MixPose;
+ (function (MixPose) {
+ MixPose[MixPose["setup"] = 0] = "setup";
+ MixPose[MixPose["current"] = 1] = "current";
+ MixPose[MixPose["currentLayered"] = 2] = "currentLayered";
+ })(MixPose = spine.MixPose || (spine.MixPose = {}));
+ var MixDirection;
+ (function (MixDirection) {
+ MixDirection[MixDirection["in"] = 0] = "in";
+ MixDirection[MixDirection["out"] = 1] = "out";
+ })(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
+ var TimelineType;
(function (TimelineType) {
TimelineType[TimelineType["rotate"] = 0] = "rotate";
TimelineType[TimelineType["translate"] = 1] = "translate";
@@ -68,8 +87,8 @@ var spine;
TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition";
TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing";
TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix";
- })(spine.TimelineType || (spine.TimelineType = {}));
- var TimelineType = spine.TimelineType;
+ TimelineType[TimelineType["twoColor"] = 14] = "twoColor";
+ })(TimelineType = spine.TimelineType || (spine.TimelineType = {}));
var CurveTimeline = (function () {
function CurveTimeline(frameCount) {
if (frameCount <= 0)
@@ -145,18 +164,19 @@ var spine;
var y = curves[i - 1];
return y + (1 - y) * (percent - x) / (1 - x);
};
- CurveTimeline.LINEAR = 0;
- CurveTimeline.STEPPED = 1;
- CurveTimeline.BEZIER = 2;
- CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
return CurveTimeline;
}());
+ CurveTimeline.LINEAR = 0;
+ CurveTimeline.STEPPED = 1;
+ CurveTimeline.BEZIER = 2;
+ CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
spine.CurveTimeline = CurveTimeline;
var RotateTimeline = (function (_super) {
__extends(RotateTimeline, _super);
function RotateTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ return _this;
}
RotateTimeline.prototype.getPropertyId = function () {
return (TimelineType.rotate << 24) + this.boneIndex;
@@ -166,21 +186,28 @@ var spine;
this.frames[frameIndex] = time;
this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
};
- RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose)
- bone.rotation = bone.data.rotation;
+ switch (pose) {
+ case MixPose.setup:
+ bone.rotation = bone.data.rotation;
+ return;
+ case MixPose.current:
+ var r_1 = bone.data.rotation - bone.rotation;
+ r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
+ bone.rotation += r_1 * alpha;
+ }
return;
}
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) {
- if (setupPose)
+ if (pose == MixPose.setup)
bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha;
else {
- var r_1 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
- r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
- bone.rotation += r_1 * alpha;
+ var r_2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
+ r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
+ bone.rotation += r_2 * alpha;
}
return;
}
@@ -191,7 +218,7 @@ var spine;
var r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
r = prevRotation + r * percent;
- if (setupPose) {
+ if (pose == MixPose.setup) {
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
bone.rotation = bone.data.rotation + r * alpha;
}
@@ -201,18 +228,19 @@ var spine;
bone.rotation += r * alpha;
}
};
- RotateTimeline.ENTRIES = 2;
- RotateTimeline.PREV_TIME = -2;
- RotateTimeline.PREV_ROTATION = -1;
- RotateTimeline.ROTATION = 1;
return RotateTimeline;
}(CurveTimeline));
+ RotateTimeline.ENTRIES = 2;
+ RotateTimeline.PREV_TIME = -2;
+ RotateTimeline.PREV_ROTATION = -1;
+ RotateTimeline.ROTATION = 1;
spine.RotateTimeline = RotateTimeline;
var TranslateTimeline = (function (_super) {
__extends(TranslateTimeline, _super);
function TranslateTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ return _this;
}
TranslateTimeline.prototype.getPropertyId = function () {
return (TimelineType.translate << 24) + this.boneIndex;
@@ -223,13 +251,18 @@ var spine;
this.frames[frameIndex + TranslateTimeline.X] = x;
this.frames[frameIndex + TranslateTimeline.Y] = y;
};
- TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.x = bone.data.x;
- bone.y = bone.data.y;
+ switch (pose) {
+ case MixPose.setup:
+ bone.x = bone.data.x;
+ bone.y = bone.data.y;
+ return;
+ case MixPose.current:
+ bone.x += (bone.data.x - bone.x) * alpha;
+ bone.y += (bone.data.y - bone.y) * alpha;
}
return;
}
@@ -247,7 +280,7 @@ var spine;
x += (frames[frame + TranslateTimeline.X] - x) * percent;
y += (frames[frame + TranslateTimeline.Y] - y) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
bone.x = bone.data.x + x * alpha;
bone.y = bone.data.y + y * alpha;
}
@@ -256,30 +289,35 @@ var spine;
bone.y += (bone.data.y + y - bone.y) * alpha;
}
};
- TranslateTimeline.ENTRIES = 3;
- TranslateTimeline.PREV_TIME = -3;
- TranslateTimeline.PREV_X = -2;
- TranslateTimeline.PREV_Y = -1;
- TranslateTimeline.X = 1;
- TranslateTimeline.Y = 2;
return TranslateTimeline;
}(CurveTimeline));
+ TranslateTimeline.ENTRIES = 3;
+ TranslateTimeline.PREV_TIME = -3;
+ TranslateTimeline.PREV_X = -2;
+ TranslateTimeline.PREV_Y = -1;
+ TranslateTimeline.X = 1;
+ TranslateTimeline.Y = 2;
spine.TranslateTimeline = TranslateTimeline;
var ScaleTimeline = (function (_super) {
__extends(ScaleTimeline, _super);
function ScaleTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
ScaleTimeline.prototype.getPropertyId = function () {
return (TimelineType.scale << 24) + this.boneIndex;
};
- ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.scaleX = bone.data.scaleX;
- bone.scaleY = bone.data.scaleY;
+ switch (pose) {
+ case MixPose.setup:
+ bone.scaleX = bone.data.scaleX;
+ bone.scaleY = bone.data.scaleY;
+ return;
+ case MixPose.current:
+ bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
+ bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
}
return;
}
@@ -303,7 +341,7 @@ var spine;
}
else {
var bx = 0, by = 0;
- if (setupPose) {
+ if (pose == MixPose.setup) {
bx = bone.data.scaleX;
by = bone.data.scaleY;
}
@@ -311,7 +349,7 @@ var spine;
bx = bone.scaleX;
by = bone.scaleY;
}
- if (mixingOut) {
+ if (direction == MixDirection.out) {
x = Math.abs(x) * spine.MathUtils.signum(bx);
y = Math.abs(y) * spine.MathUtils.signum(by);
}
@@ -329,18 +367,23 @@ var spine;
var ShearTimeline = (function (_super) {
__extends(ShearTimeline, _super);
function ShearTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
ShearTimeline.prototype.getPropertyId = function () {
return (TimelineType.shear << 24) + this.boneIndex;
};
- ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.shearX = bone.data.shearX;
- bone.shearY = bone.data.shearY;
+ switch (pose) {
+ case MixPose.setup:
+ bone.shearX = bone.data.shearX;
+ bone.shearY = bone.data.shearY;
+ return;
+ case MixPose.current:
+ bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
}
return;
}
@@ -358,7 +401,7 @@ var spine;
x = x + (frames[frame + ShearTimeline.X] - x) * percent;
y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
bone.shearX = bone.data.shearX + x * alpha;
bone.shearY = bone.data.shearY + y * alpha;
}
@@ -373,8 +416,9 @@ var spine;
var ColorTimeline = (function (_super) {
__extends(ColorTimeline, _super);
function ColorTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ return _this;
}
ColorTimeline.prototype.getPropertyId = function () {
return (TimelineType.color << 24) + this.slotIndex;
@@ -387,12 +431,18 @@ var spine;
this.frames[frameIndex + ColorTimeline.B] = b;
this.frames[frameIndex + ColorTimeline.A] = a;
};
- ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose)
- slot.color.setFromColor(slot.data.color);
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ return;
+ case MixPose.current:
+ var color = slot.color, setup = slot.data.color;
+ color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);
+ }
return;
}
var r = 0, g = 0, b = 0, a = 0;
@@ -420,24 +470,124 @@ var spine;
slot.color.set(r, g, b, a);
else {
var color = slot.color;
- if (setupPose)
+ if (pose == MixPose.setup)
color.setFromColor(slot.data.color);
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
}
};
- ColorTimeline.ENTRIES = 5;
- ColorTimeline.PREV_TIME = -5;
- ColorTimeline.PREV_R = -4;
- ColorTimeline.PREV_G = -3;
- ColorTimeline.PREV_B = -2;
- ColorTimeline.PREV_A = -1;
- ColorTimeline.R = 1;
- ColorTimeline.G = 2;
- ColorTimeline.B = 3;
- ColorTimeline.A = 4;
return ColorTimeline;
}(CurveTimeline));
+ ColorTimeline.ENTRIES = 5;
+ ColorTimeline.PREV_TIME = -5;
+ ColorTimeline.PREV_R = -4;
+ ColorTimeline.PREV_G = -3;
+ ColorTimeline.PREV_B = -2;
+ ColorTimeline.PREV_A = -1;
+ ColorTimeline.R = 1;
+ ColorTimeline.G = 2;
+ ColorTimeline.B = 3;
+ ColorTimeline.A = 4;
spine.ColorTimeline = ColorTimeline;
+ var TwoColorTimeline = (function (_super) {
+ __extends(TwoColorTimeline, _super);
+ function TwoColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
+ return _this;
+ }
+ TwoColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.twoColor << 24) + this.slotIndex;
+ };
+ TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) {
+ frameIndex *= TwoColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TwoColorTimeline.R] = r;
+ this.frames[frameIndex + TwoColorTimeline.G] = g;
+ this.frames[frameIndex + TwoColorTimeline.B] = b;
+ this.frames[frameIndex + TwoColorTimeline.A] = a;
+ this.frames[frameIndex + TwoColorTimeline.R2] = r2;
+ this.frames[frameIndex + TwoColorTimeline.G2] = g2;
+ this.frames[frameIndex + TwoColorTimeline.B2] = b2;
+ };
+ TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ slot.darkColor.setFromColor(slot.data.darkColor);
+ return;
+ case MixPose.current:
+ var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
+ light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);
+ dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
+ if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + TwoColorTimeline.PREV_R];
+ g = frames[i + TwoColorTimeline.PREV_G];
+ b = frames[i + TwoColorTimeline.PREV_B];
+ a = frames[i + TwoColorTimeline.PREV_A];
+ r2 = frames[i + TwoColorTimeline.PREV_R2];
+ g2 = frames[i + TwoColorTimeline.PREV_G2];
+ b2 = frames[i + TwoColorTimeline.PREV_B2];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES);
+ r = frames[frame + TwoColorTimeline.PREV_R];
+ g = frames[frame + TwoColorTimeline.PREV_G];
+ b = frames[frame + TwoColorTimeline.PREV_B];
+ a = frames[frame + TwoColorTimeline.PREV_A];
+ r2 = frames[frame + TwoColorTimeline.PREV_R2];
+ g2 = frames[frame + TwoColorTimeline.PREV_G2];
+ b2 = frames[frame + TwoColorTimeline.PREV_B2];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + TwoColorTimeline.R] - r) * percent;
+ g += (frames[frame + TwoColorTimeline.G] - g) * percent;
+ b += (frames[frame + TwoColorTimeline.B] - b) * percent;
+ a += (frames[frame + TwoColorTimeline.A] - a) * percent;
+ r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent;
+ g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent;
+ b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent;
+ }
+ if (alpha == 1) {
+ slot.color.set(r, g, b, a);
+ slot.darkColor.set(r2, g2, b2, 1);
+ }
+ else {
+ var light = slot.color, dark = slot.darkColor;
+ if (pose == MixPose.setup) {
+ light.setFromColor(slot.data.color);
+ dark.setFromColor(slot.data.darkColor);
+ }
+ light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
+ dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
+ }
+ };
+ return TwoColorTimeline;
+ }(CurveTimeline));
+ TwoColorTimeline.ENTRIES = 8;
+ TwoColorTimeline.PREV_TIME = -8;
+ TwoColorTimeline.PREV_R = -7;
+ TwoColorTimeline.PREV_G = -6;
+ TwoColorTimeline.PREV_B = -5;
+ TwoColorTimeline.PREV_A = -4;
+ TwoColorTimeline.PREV_R2 = -3;
+ TwoColorTimeline.PREV_G2 = -2;
+ TwoColorTimeline.PREV_B2 = -1;
+ TwoColorTimeline.R = 1;
+ TwoColorTimeline.G = 2;
+ TwoColorTimeline.B = 3;
+ TwoColorTimeline.A = 4;
+ TwoColorTimeline.R2 = 5;
+ TwoColorTimeline.G2 = 6;
+ TwoColorTimeline.B2 = 7;
+ spine.TwoColorTimeline = TwoColorTimeline;
var AttachmentTimeline = (function () {
function AttachmentTimeline(frameCount) {
this.frames = spine.Utils.newFloatArray(frameCount);
@@ -453,16 +603,16 @@ var spine;
this.frames[frameIndex] = time;
this.attachmentNames[frameIndex] = attachmentName;
};
- AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
- if (mixingOut && setupPose) {
+ if (direction == MixDirection.out && pose == MixPose.setup) {
var attachmentName_1 = slot.data.attachmentName;
slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
return;
}
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose) {
+ if (pose == MixPose.setup) {
var attachmentName_2 = slot.data.attachmentName;
slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2));
}
@@ -480,59 +630,87 @@ var spine;
return AttachmentTimeline;
}());
spine.AttachmentTimeline = AttachmentTimeline;
+ var zeros = null;
var DeformTimeline = (function (_super) {
__extends(DeformTimeline, _super);
function DeformTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount);
- this.frameVertices = new Array(frameCount);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount);
+ _this.frameVertices = new Array(frameCount);
+ if (zeros == null)
+ zeros = spine.Utils.newFloatArray(64);
+ return _this;
}
DeformTimeline.prototype.getPropertyId = function () {
- return (TimelineType.deform << 24) + this.slotIndex;
+ return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
};
DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) {
this.frames[frameIndex] = time;
this.frameVertices[frameIndex] = vertices;
};
- DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
var slotAttachment = slot.getAttachment();
if (!(slotAttachment instanceof spine.VertexAttachment) || !slotAttachment.applyDeform(this.attachment))
return;
- var frames = this.frames;
var verticesArray = slot.attachmentVertices;
- if (time < frames[0]) {
- if (setupPose)
- spine.Utils.setArraySize(verticesArray, 0);
- return;
- }
var frameVertices = this.frameVertices;
var vertexCount = frameVertices[0].length;
- if (verticesArray.length != vertexCount)
- alpha = 1;
var vertices = spine.Utils.setArraySize(verticesArray, vertexCount);
+ var frames = this.frames;
+ if (time < frames[0]) {
+ var vertexAttachment = slotAttachment;
+ switch (pose) {
+ case MixPose.setup:
+ var zeroVertices;
+ if (vertexAttachment.bones == null) {
+ zeroVertices = vertexAttachment.vertices;
+ }
+ else {
+ zeroVertices = zeros;
+ if (zeroVertices.length < vertexCount)
+ zeros = zeroVertices = spine.Utils.newFloatArray(vertexCount);
+ }
+ spine.Utils.arrayCopy(zeroVertices, 0, vertices, 0, vertexCount);
+ return;
+ case MixPose.current:
+ if (alpha == 1)
+ break;
+ if (vertexAttachment.bones == null) {
+ var setupVertices = vertexAttachment.vertices;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
+ }
+ else {
+ alpha = 1 - alpha;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] *= alpha;
+ }
+ }
+ return;
+ }
if (time >= frames[frames.length - 1]) {
var lastVertices = frameVertices[frames.length - 1];
if (alpha == 1) {
spine.Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
}
- else if (setupPose) {
+ else if (pose == MixPose.setup) {
var vertexAttachment = slotAttachment;
if (vertexAttachment.bones == null) {
- var setupVertices = vertexAttachment.vertices;
- for (var i = 0; i < vertexCount; i++) {
- var setup = setupVertices[i];
- vertices[i] = setup + (lastVertices[i] - setup) * alpha;
+ var setupVertices_1 = vertexAttachment.vertices;
+ for (var i_1 = 0; i_1 < vertexCount; i_1++) {
+ var setup = setupVertices_1[i_1];
+ vertices[i_1] = setup + (lastVertices[i_1] - setup) * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] = lastVertices[i] * alpha;
+ for (var i_2 = 0; i_2 < vertexCount; i_2++)
+ vertices[i_2] = lastVertices[i_2] * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
+ for (var i_3 = 0; i_3 < vertexCount; i_3++)
+ vertices[i_3] += (lastVertices[i_3] - vertices[i_3]) * alpha;
}
return;
}
@@ -542,31 +720,31 @@ var spine;
var frameTime = frames[frame];
var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
if (alpha == 1) {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = prev + (nextVertices[i] - prev) * percent;
+ for (var i_4 = 0; i_4 < vertexCount; i_4++) {
+ var prev = prevVertices[i_4];
+ vertices[i_4] = prev + (nextVertices[i_4] - prev) * percent;
}
}
- else if (setupPose) {
+ else if (pose == MixPose.setup) {
var vertexAttachment = slotAttachment;
if (vertexAttachment.bones == null) {
- var setupVertices = vertexAttachment.vertices;
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i], setup = setupVertices[i];
- vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
+ var setupVertices_2 = vertexAttachment.vertices;
+ for (var i_5 = 0; i_5 < vertexCount; i_5++) {
+ var prev = prevVertices[i_5], setup = setupVertices_2[i_5];
+ vertices[i_5] = setup + (prev + (nextVertices[i_5] - prev) * percent - setup) * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
+ for (var i_6 = 0; i_6 < vertexCount; i_6++) {
+ var prev = prevVertices[i_6];
+ vertices[i_6] = (prev + (nextVertices[i_6] - prev) * percent) * alpha;
}
}
}
else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
+ for (var i_7 = 0; i_7 < vertexCount; i_7++) {
+ var prev = prevVertices[i_7];
+ vertices[i_7] += (prev + (nextVertices[i_7] - prev) * percent - vertices[i_7]) * alpha;
}
}
};
@@ -588,13 +766,13 @@ var spine;
this.frames[frameIndex] = event.time;
this.events[frameIndex] = event;
};
- EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
if (firedEvents == null)
return;
var frames = this.frames;
var frameCount = this.frames.length;
if (lastTime > time) {
- this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, setupPose, mixingOut);
+ this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, pose, direction);
lastTime = -1;
}
else if (lastTime >= frames[frameCount - 1])
@@ -634,16 +812,16 @@ var spine;
this.frames[frameIndex] = time;
this.drawOrders[frameIndex] = drawOrder;
};
- DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var drawOrder = skeleton.drawOrder;
var slots = skeleton.slots;
- if (mixingOut && setupPose) {
+ if (direction == MixDirection.out && pose == MixPose.setup) {
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return;
}
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose)
+ if (pose == MixPose.setup)
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return;
}
@@ -666,8 +844,9 @@ var spine;
var IkConstraintTimeline = (function (_super) {
__extends(IkConstraintTimeline, _super);
function IkConstraintTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ return _this;
}
IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
@@ -678,25 +857,30 @@ var spine;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
};
- IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- constraint.mix = constraint.data.mix;
- constraint.bendDirection = constraint.data.bendDirection;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.mix = constraint.data.mix;
+ constraint.bendDirection = constraint.data.bendDirection;
+ return;
+ case MixPose.current:
+ constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
+ constraint.bendDirection = constraint.data.bendDirection;
}
return;
}
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
- constraint.bendDirection = mixingOut ? constraint.data.bendDirection
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
- if (!mixingOut)
+ if (direction == MixDirection["in"])
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
return;
@@ -705,30 +889,31 @@ var spine;
var mix = frames[frame + IkConstraintTimeline.PREV_MIX];
var frameTime = frames[frame];
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
- constraint.bendDirection = mixingOut ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
- if (!mixingOut)
+ if (direction == MixDirection["in"])
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
};
- IkConstraintTimeline.ENTRIES = 3;
- IkConstraintTimeline.PREV_TIME = -3;
- IkConstraintTimeline.PREV_MIX = -2;
- IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
- IkConstraintTimeline.MIX = 1;
- IkConstraintTimeline.BEND_DIRECTION = 2;
return IkConstraintTimeline;
}(CurveTimeline));
+ IkConstraintTimeline.ENTRIES = 3;
+ IkConstraintTimeline.PREV_TIME = -3;
+ IkConstraintTimeline.PREV_MIX = -2;
+ IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
+ IkConstraintTimeline.MIX = 1;
+ IkConstraintTimeline.BEND_DIRECTION = 2;
spine.IkConstraintTimeline = IkConstraintTimeline;
var TransformConstraintTimeline = (function (_super) {
__extends(TransformConstraintTimeline, _super);
function TransformConstraintTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ return _this;
}
TransformConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
@@ -741,16 +926,23 @@ var spine;
this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix;
this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
};
- TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- var data = constraint.data;
- constraint.rotateMix = data.rotateMix;
- constraint.translateMix = data.rotateMix;
- constraint.scaleMix = data.scaleMix;
- constraint.shearMix = data.shearMix;
+ var data = constraint.data;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ constraint.scaleMix = data.scaleMix;
+ constraint.shearMix = data.shearMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
+ constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
+ constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
}
return;
}
@@ -775,7 +967,7 @@ var spine;
scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
var data = constraint.data;
constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
@@ -789,24 +981,25 @@ var spine;
constraint.shearMix += (shear - constraint.shearMix) * alpha;
}
};
- TransformConstraintTimeline.ENTRIES = 5;
- TransformConstraintTimeline.PREV_TIME = -5;
- TransformConstraintTimeline.PREV_ROTATE = -4;
- TransformConstraintTimeline.PREV_TRANSLATE = -3;
- TransformConstraintTimeline.PREV_SCALE = -2;
- TransformConstraintTimeline.PREV_SHEAR = -1;
- TransformConstraintTimeline.ROTATE = 1;
- TransformConstraintTimeline.TRANSLATE = 2;
- TransformConstraintTimeline.SCALE = 3;
- TransformConstraintTimeline.SHEAR = 4;
return TransformConstraintTimeline;
}(CurveTimeline));
+ TransformConstraintTimeline.ENTRIES = 5;
+ TransformConstraintTimeline.PREV_TIME = -5;
+ TransformConstraintTimeline.PREV_ROTATE = -4;
+ TransformConstraintTimeline.PREV_TRANSLATE = -3;
+ TransformConstraintTimeline.PREV_SCALE = -2;
+ TransformConstraintTimeline.PREV_SHEAR = -1;
+ TransformConstraintTimeline.ROTATE = 1;
+ TransformConstraintTimeline.TRANSLATE = 2;
+ TransformConstraintTimeline.SCALE = 3;
+ TransformConstraintTimeline.SHEAR = 4;
spine.TransformConstraintTimeline = TransformConstraintTimeline;
var PathConstraintPositionTimeline = (function (_super) {
__extends(PathConstraintPositionTimeline, _super);
function PathConstraintPositionTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ return _this;
}
PathConstraintPositionTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
@@ -816,12 +1009,17 @@ var spine;
this.frames[frameIndex] = time;
this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
};
- PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose)
- constraint.position = constraint.data.position;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.position = constraint.data.position;
+ return;
+ case MixPose.current:
+ constraint.position += (constraint.data.position - constraint.position) * alpha;
+ }
return;
}
var position = 0;
@@ -834,32 +1032,37 @@ var spine;
var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
}
- if (setupPose)
+ if (pose == MixPose.setup)
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
else
constraint.position += (position - constraint.position) * alpha;
};
- PathConstraintPositionTimeline.ENTRIES = 2;
- PathConstraintPositionTimeline.PREV_TIME = -2;
- PathConstraintPositionTimeline.PREV_VALUE = -1;
- PathConstraintPositionTimeline.VALUE = 1;
return PathConstraintPositionTimeline;
}(CurveTimeline));
+ PathConstraintPositionTimeline.ENTRIES = 2;
+ PathConstraintPositionTimeline.PREV_TIME = -2;
+ PathConstraintPositionTimeline.PREV_VALUE = -1;
+ PathConstraintPositionTimeline.VALUE = 1;
spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
var PathConstraintSpacingTimeline = (function (_super) {
__extends(PathConstraintSpacingTimeline, _super);
function PathConstraintSpacingTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
PathConstraintSpacingTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
};
- PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose)
- constraint.spacing = constraint.data.spacing;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.spacing = constraint.data.spacing;
+ return;
+ case MixPose.current:
+ constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
+ }
return;
}
var spacing = 0;
@@ -872,7 +1075,7 @@ var spine;
var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
}
- if (setupPose)
+ if (pose == MixPose.setup)
constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
else
constraint.spacing += (spacing - constraint.spacing) * alpha;
@@ -883,8 +1086,9 @@ var spine;
var PathConstraintMixTimeline = (function (_super) {
__extends(PathConstraintMixTimeline, _super);
function PathConstraintMixTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ return _this;
}
PathConstraintMixTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
@@ -895,13 +1099,18 @@ var spine;
this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix;
this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
};
- PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- constraint.rotateMix = constraint.data.rotateMix;
- constraint.translateMix = constraint.data.translateMix;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = constraint.data.rotateMix;
+ constraint.translateMix = constraint.data.translateMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
}
return;
}
@@ -919,7 +1128,7 @@ var spine;
rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
}
@@ -928,14 +1137,14 @@ var spine;
constraint.translateMix += (translate - constraint.translateMix) * alpha;
}
};
- PathConstraintMixTimeline.ENTRIES = 3;
- PathConstraintMixTimeline.PREV_TIME = -3;
- PathConstraintMixTimeline.PREV_ROTATE = -2;
- PathConstraintMixTimeline.PREV_TRANSLATE = -1;
- PathConstraintMixTimeline.ROTATE = 1;
- PathConstraintMixTimeline.TRANSLATE = 2;
return PathConstraintMixTimeline;
}(CurveTimeline));
+ PathConstraintMixTimeline.ENTRIES = 3;
+ PathConstraintMixTimeline.PREV_TIME = -3;
+ PathConstraintMixTimeline.PREV_ROTATE = -2;
+ PathConstraintMixTimeline.PREV_TRANSLATE = -1;
+ PathConstraintMixTimeline.ROTATE = 1;
+ PathConstraintMixTimeline.TRANSLATE = 2;
spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
})(spine || (spine = {}));
var spine;
@@ -947,6 +1156,7 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
+ this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@@ -984,33 +1194,42 @@ var spine;
continue;
}
}
- else {
- if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
- tracks[i] = null;
- this.queue.end(current);
- this.disposeNext(current);
- continue;
+ else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+ tracks[i] = null;
+ this.queue.end(current);
+ this.disposeNext(current);
+ continue;
+ }
+ if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
+ var from = current.mixingFrom;
+ current.mixingFrom = null;
+ while (from != null) {
+ this.queue.end(from);
+ from = from.mixingFrom;
}
}
- this.updateMixingFrom(current, delta);
current.trackTime += currentDelta;
}
this.queue.drain();
};
- AnimationState.prototype.updateMixingFrom = function (entry, delta) {
- var from = entry.mixingFrom;
+ AnimationState.prototype.updateMixingFrom = function (to, delta) {
+ var from = to.mixingFrom;
if (from == null)
- return;
- this.updateMixingFrom(from, delta);
- if (entry.mixTime >= entry.mixDuration && from.mixingFrom != null && entry.mixTime > 0) {
- entry.mixingFrom = null;
- this.queue.end(from);
- return;
+ return true;
+ var finished = this.updateMixingFrom(from, delta);
+ if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+ if (from.totalAlpha == 0 || to.mixDuration == 0) {
+ to.mixingFrom = from.mixingFrom;
+ to.interruptAlpha = from.interruptAlpha;
+ this.queue.end(from);
+ }
+ return finished;
}
from.animationLast = from.nextAnimationLast;
from.trackLast = from.nextTrackLast;
from.trackTime += delta * from.timeScale;
- entry.mixTime += delta * from.timeScale;
+ to.mixTime += delta * to.timeScale;
+ return false;
};
AnimationState.prototype.apply = function (skeleton) {
if (skeleton == null)
@@ -1019,52 +1238,58 @@ var spine;
this._animationsChanged();
var events = this.events;
var tracks = this.tracks;
+ var applied = false;
for (var i = 0, n = tracks.length; i < n; i++) {
var current = tracks[i];
if (current == null || current.delay > 0)
continue;
+ applied = true;
+ var currentPose = i == 0 ? spine.MixPose.current : spine.MixPose.currentLayered;
var mix = current.alpha;
if (current.mixingFrom != null)
- mix *= this.applyMixingFrom(current, skeleton);
- else if (current.trackTime >= current.trackEnd)
+ mix *= this.applyMixingFrom(current, skeleton, currentPose);
+ else if (current.trackTime >= current.trackEnd && current.next == null)
mix = 0;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1) {
for (var ii = 0; ii < timelineCount; ii++)
- timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, true, false);
+ timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, spine.MixPose.setup, spine.MixDirection["in"]);
}
else {
+ var timelineData = current.timelineData;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
- var timelinesFirst = current.timelinesFirst;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
+ var pose = timelineData[ii] >= AnimationState.FIRST ? spine.MixPose.setup : currentPose;
if (timeline instanceof spine.RotateTimeline) {
- this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelinesFirst[ii], timelinesRotation, ii << 1, firstFrame);
+ this.applyRotateTimeline(timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
}
else
- timeline.apply(skeleton, animationLast, animationTime, events, mix, timelinesFirst[ii], false);
+ timeline.apply(skeleton, animationLast, animationTime, events, mix, pose, spine.MixDirection["in"]);
}
}
this.queueEvents(current, animationTime);
+ events.length = 0;
current.nextAnimationLast = animationTime;
current.nextTrackLast = current.trackTime;
}
this.queue.drain();
+ return applied;
};
- AnimationState.prototype.applyMixingFrom = function (entry, skeleton) {
- var from = entry.mixingFrom;
+ AnimationState.prototype.applyMixingFrom = function (to, skeleton, currentPose) {
+ var from = to.mixingFrom;
if (from.mixingFrom != null)
- this.applyMixingFrom(from, skeleton);
+ this.applyMixingFrom(from, skeleton, currentPose);
var mix = 0;
- if (entry.mixDuration == 0)
+ if (to.mixDuration == 0)
mix = 1;
else {
- mix = entry.mixTime / entry.mixDuration;
+ mix = to.mixTime / to.mixDuration;
if (mix > 1)
mix = 1;
}
@@ -1073,44 +1298,67 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
- var timelinesFirst = from.timelinesFirst;
- var alpha = from.alpha * entry.mixAlpha * (1 - mix);
+ var timelineData = from.timelineData;
+ var timelineDipMix = from.timelineDipMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = from.timelinesRotation;
+ var pose;
+ var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha = 0;
+ from.totalAlpha = 0;
for (var i = 0; i < timelineCount; i++) {
var timeline = timelines[i];
- var setupPose = timelinesFirst[i];
- if (timeline instanceof spine.RotateTimeline)
- this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, setupPose, timelinesRotation, i << 1, firstFrame);
- else {
- if (!setupPose) {
+ switch (timelineData[i]) {
+ case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
continue;
- }
- timeline.apply(skeleton, animationLast, animationTime, events, alpha, setupPose, true);
+ pose = currentPose;
+ alpha = alphaMix;
+ break;
+ case AnimationState.FIRST:
+ pose = spine.MixPose.setup;
+ alpha = alphaMix;
+ break;
+ case AnimationState.DIP:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ break;
+ default:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ var dipMix = timelineDipMix[i];
+ alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
+ break;
+ }
+ from.totalAlpha += alpha;
+ if (timeline instanceof spine.RotateTimeline)
+ this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame);
+ else {
+ timeline.apply(skeleton, animationLast, animationTime, events, alpha, pose, spine.MixDirection.out);
}
}
- this.queueEvents(from, animationTime);
+ if (to.mixDuration > 0)
+ this.queueEvents(from, animationTime);
+ this.events.length = 0;
from.nextAnimationLast = animationTime;
from.nextTrackLast = from.trackTime;
return mix;
};
- AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, setupPose, timelinesRotation, i, firstFrame) {
+ AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, pose, timelinesRotation, i, firstFrame) {
if (firstFrame)
timelinesRotation[i] = 0;
if (alpha == 1) {
- timeline.apply(skeleton, 0, time, null, 1, setupPose, false);
+ timeline.apply(skeleton, 0, time, null, 1, pose, spine.MixDirection["in"]);
return;
}
var rotateTimeline = timeline;
var frames = rotateTimeline.frames;
var bone = skeleton.bones[rotateTimeline.boneIndex];
if (time < frames[0]) {
- if (setupPose)
+ if (pose == spine.MixPose.setup)
bone.rotation = bone.data.rotation;
return;
}
@@ -1127,7 +1375,7 @@ var spine;
r2 = prevRotation + r2 * percent + bone.data.rotation;
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
}
- var r1 = setupPose ? bone.data.rotation : bone.rotation;
+ var r1 = pose == spine.MixPose.setup ? bone.data.rotation : bone.rotation;
var total = 0, diff = r2 - r1;
if (diff == 0) {
total = timelinesRotation[i];
@@ -1182,14 +1430,14 @@ var spine;
continue;
this.queue.event(entry, events[i]);
}
- this.events.length = 0;
};
AnimationState.prototype.clearTracks = function () {
+ var oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true;
for (var i = 0, n = this.tracks.length; i < n; i++)
this.clearTrack(i);
this.tracks.length = 0;
- this.queue.drainDisabled = false;
+ this.queue.drainDisabled = oldDrainDisabled;
this.queue.drain();
};
AnimationState.prototype.clearTrack = function (trackIndex) {
@@ -1220,9 +1468,9 @@ var spine;
this.queue.interrupt(from);
current.mixingFrom = from;
current.mixTime = 0;
+ if (from.mixingFrom != null && from.mixDuration > 0)
+ current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
from.timelinesRotation.length = 0;
- if (from.mixingFrom != null)
- current.mixAlpha *= Math.min(from.mixTime / from.mixDuration, 1);
}
this.queue.start(current);
};
@@ -1301,13 +1549,14 @@ var spine;
return entry;
};
AnimationState.prototype.setEmptyAnimations = function (mixDuration) {
+ var oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true;
for (var i = 0, n = this.tracks.length; i < n; i++) {
var current = this.tracks[i];
if (current != null)
this.setEmptyAnimation(current.trackIndex, mixDuration);
}
- this.queue.drainDisabled = false;
+ this.queue.drainDisabled = oldDrainDisabled;
this.queue.drain();
};
AnimationState.prototype.expandToIndex = function (index) {
@@ -1333,10 +1582,10 @@ var spine;
entry.trackTime = 0;
entry.trackLast = -1;
entry.nextTrackLast = -1;
- entry.trackEnd = loop ? Number.MAX_VALUE : entry.animationEnd;
+ entry.trackEnd = Number.MAX_VALUE;
entry.timeScale = 1;
entry.alpha = 1;
- entry.mixAlpha = 1;
+ entry.interruptAlpha = 1;
entry.mixTime = 0;
entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
return entry;
@@ -1352,50 +1601,14 @@ var spine;
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
- var i = 0, n = this.tracks.length;
propertyIDs.clear();
- for (; i < n; i++) {
- var entry = this.tracks[i];
- if (entry == null)
- continue;
- this.setTimelinesFirst(entry);
- i++;
- break;
- }
- for (; i < n; i++) {
+ var mixingTo = this.mixingTo;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null)
- this.checkTimelinesFirst(entry);
- }
- };
- AnimationState.prototype.setTimelinesFirst = function (entry) {
- if (entry.mixingFrom != null) {
- this.setTimelinesFirst(entry.mixingFrom);
- this.checkTimelinesUsage(entry, entry.timelinesFirst);
- return;
- }
- var propertyIDs = this.propertyIDs;
- var timelines = entry.animation.timelines;
- var n = timelines.length;
- var usage = spine.Utils.setArraySize(entry.timelinesFirst, n, false);
- for (var i = 0; i < n; i++) {
- propertyIDs.add(timelines[i].getPropertyId());
- usage[i] = true;
+ entry.setTimelineData(null, mixingTo, propertyIDs);
}
};
- AnimationState.prototype.checkTimelinesFirst = function (entry) {
- if (entry.mixingFrom != null)
- this.checkTimelinesFirst(entry.mixingFrom);
- this.checkTimelinesUsage(entry, entry.timelinesFirst);
- };
- AnimationState.prototype.checkTimelinesUsage = function (entry, usageArray) {
- var propertyIDs = this.propertyIDs;
- var timelines = entry.animation.timelines;
- var n = timelines.length;
- var usage = spine.Utils.setArraySize(usageArray, n);
- for (var i = 0; i < n; i++)
- usage[i] = propertyIDs.add(timelines[i].getPropertyId());
- };
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@@ -1417,13 +1630,18 @@ var spine;
AnimationState.prototype.clearListenerNotifications = function () {
this.queue.clear();
};
- AnimationState.emptyAnimation = new spine.Animation("