From 03123d713e3866e952618bbc79216a8eebaf50b3 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Sat, 11 Jun 2016 22:46:39 +0800 Subject: [PATCH 01/15] Draft implementation of v3.12 renderer --- cocos2d/actions/CCActionCamera.js | 293 --------- .../CCClippingNodeWebGLRenderCmd.js | 2 +- cocos2d/core/CCCamera.js | 282 --------- cocos2d/core/CCDirector.js | 2 +- cocos2d/core/CCDirectorWebGL.js | 8 +- .../base-nodes/CCAtlasNodeWebGLRenderCmd.js | 13 +- cocos2d/core/base-nodes/CCNode.js | 15 +- .../core/base-nodes/CCNodeCanvasRenderCmd.js | 283 +++++---- .../core/base-nodes/CCNodeWebGLRenderCmd.js | 84 --- cocos2d/core/labelttf/CCLabelTTF.js | 5 - .../core/labelttf/CCLabelTTFWebGLRenderCmd.js | 2 - cocos2d/core/layers/CCLayerWebGLRenderCmd.js | 23 +- cocos2d/core/renderer/RendererWebGL.js | 578 ++++-------------- cocos2d/core/sprites/CCSprite.js | 32 +- cocos2d/core/sprites/CCSpriteBatchNode.js | 414 +++---------- .../CCSpriteBatchNodeCanvasRenderCmd.js | 100 --- .../CCSpriteBatchNodeWebGLRenderCmd.js | 243 -------- .../core/sprites/CCSpriteCanvasRenderCmd.js | 37 -- .../core/sprites/CCSpriteWebGLRenderCmd.js | 419 ++----------- cocos2d/core/utils/CCProfiler.js | 3 +- cocos2d/labels/CCLabelBMFont.js | 21 +- .../labels/CCLabelBMFontCanvasRenderCmd.js | 17 +- cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js | 32 +- .../CCMotionStreakWebGLRenderCmd.js | 13 +- cocos2d/parallax/CCParallaxNodeRenderCmd.js | 4 +- .../CCParticleBatchNodeWebGLRenderCmd.js | 21 +- .../CCParticleSystemWebGLRenderCmd.js | 13 +- .../physics/CCPhysicsSpriteWebGLRenderCmd.js | 10 - .../shape-nodes/CCDrawNodeWebGLRenderCmd.js | 12 +- cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js | 4 +- cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js | 8 +- .../CCProtectedNodeWebGLRenderCmd.js | 66 +- .../UIScale9SpriteWebGLRenderCmd.js | 2 +- moduleConfig.json | 6 - 34 files changed, 529 insertions(+), 2538 deletions(-) delete mode 100644 cocos2d/actions/CCActionCamera.js delete mode 100644 cocos2d/core/CCCamera.js delete mode 100644 cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js delete mode 100644 cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js diff --git a/cocos2d/actions/CCActionCamera.js b/cocos2d/actions/CCActionCamera.js deleted file mode 100644 index c420fb9eb1..0000000000 --- a/cocos2d/actions/CCActionCamera.js +++ /dev/null @@ -1,293 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * Base class for cc.Camera actions - * @class - * @extends cc.ActionInterval - */ -cc.ActionCamera = cc.ActionInterval.extend(/** @lends cc.ActionCamera# */{ - _centerXOrig:0, - _centerYOrig:0, - _centerZOrig:0, - _eyeXOrig:0, - _eyeYOrig:0, - _eyeZOrig:0, - _upXOrig:0, - _upYOrig:0, - _upZOrig:0, - - /** - * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. - */ - ctor:function(){ - var _t = this; - cc.ActionInterval.prototype.ctor.call(_t); - - _t._centerXOrig=0; - _t._centerYOrig=0; - _t._centerZOrig=0; - _t._eyeXOrig=0; - _t._eyeYOrig=0; - _t._eyeZOrig=0; - _t._upXOrig=0; - _t._upYOrig=0; - _t._upZOrig=0; - }, - - /** - * called before the action start. It will also set the target. - * - * @param {cc.Node} target - */ - startWithTarget:function (target) { - var _t = this; - cc.ActionInterval.prototype.startWithTarget.call(_t, target); - - var camera = target.getCamera(); - var centerXYZ = camera.getCenter(); - _t._centerXOrig = centerXYZ.x; - _t._centerYOrig = centerXYZ.y; - _t._centerZOrig = centerXYZ.z; - - var eyeXYZ = camera.getEye(); - _t._eyeXOrig = eyeXYZ.x; - _t._eyeYOrig = eyeXYZ.y; - _t._eyeZOrig = eyeXYZ.z; - - var upXYZ = camera.getUp(); - _t._upXOrig = upXYZ.x; - _t._upYOrig = upXYZ.y; - _t._upZOrig = upXYZ.z; - }, - - /** - * to copy object with deep copy. - * returns a new clone of the action - * - * @returns {cc.ActionCamera} - */ - clone:function(){ - return new cc.ActionCamera(); - }, - - /** - * returns a reversed action.
- * For example:
- * - The action will be x coordinates of 0 move to 100.
- * - The reversed action will be x of 100 move to 0. - * - Will be rewritten - * @return {?cc.Action} - */ - reverse:function () { - return new cc.ReverseTime(this); - } -}); - -/** - * Orbits the camera around the center of the screen using spherical coordinates. - * - * @param {Number} t time - * @param {Number} radius - * @param {Number} deltaRadius - * @param {Number} angleZ - * @param {Number} deltaAngleZ - * @param {Number} angleX - * @param {Number} deltaAngleX - * - * @class - * @extends cc.ActionCamera - */ -cc.OrbitCamera = cc.ActionCamera.extend(/** @lends cc.OrbitCamera# */{ - _radius: 0.0, - _deltaRadius: 0.0, - _angleZ: 0.0, - _deltaAngleZ: 0.0, - _angleX: 0.0, - _deltaAngleX: 0.0, - _radZ: 0.0, - _radDeltaZ: 0.0, - _radX: 0.0, - _radDeltaX: 0.0, - - /** - * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
- * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX. - * @param {Number} t time - * @param {Number} radius - * @param {Number} deltaRadius - * @param {Number} angleZ - * @param {Number} deltaAngleZ - * @param {Number} angleX - * @param {Number} deltaAngleX - */ - ctor:function(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX){ - cc.ActionCamera.prototype.ctor.call(this); - - deltaAngleX !== undefined && this.initWithDuration(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX); - }, - - /** - * initializes a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX - * @param {Number} t time - * @param {Number} radius - * @param {Number} deltaRadius - * @param {Number} angleZ - * @param {Number} deltaAngleZ - * @param {Number} angleX - * @param {Number} deltaAngleX - * @return {Boolean} - */ - initWithDuration:function (t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX) { - if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { - var _t = this; - _t._radius = radius; - _t._deltaRadius = deltaRadius; - _t._angleZ = angleZ; - _t._deltaAngleZ = deltaAngleZ; - _t._angleX = angleX; - _t._deltaAngleX = deltaAngleX; - - _t._radDeltaZ = cc.degreesToRadians(deltaAngleZ); - _t._radDeltaX = cc.degreesToRadians(deltaAngleX); - return true; - } - return false; - }, - - /** - * positions the camera according to spherical coordinates - * @return {Object} - */ - sphericalRadius:function () { - var newRadius, zenith, azimuth; - var camera = this.target.getCamera(); - var eyeXYZ = camera.getEye(); - var centerXYZ = camera.getCenter(); - - var x = eyeXYZ.x - centerXYZ.x, y = eyeXYZ.y - centerXYZ.y, z = eyeXYZ.z - centerXYZ.z; - - var r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); - var s = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - if (s === 0.0) - s = cc.FLT_EPSILON; - if (r === 0.0) - r = cc.FLT_EPSILON; - - zenith = Math.acos(z / r); - if (x < 0) - azimuth = Math.PI - Math.asin(y / s); - else - azimuth = Math.asin(y / s); - newRadius = r / cc.Camera.getZEye(); - return {newRadius:newRadius, zenith:zenith, azimuth:azimuth}; - }, - - /** - * called before the action start. It will also set the target. - * - * @param {cc.Node} target - */ - startWithTarget:function (target) { - var _t = this; - cc.ActionInterval.prototype.startWithTarget.call(_t, target); - var retValue = _t.sphericalRadius(); - if (isNaN(_t._radius)) - _t._radius = retValue.newRadius; - - if (isNaN(_t._angleZ)) - _t._angleZ = cc.radiansToDegrees(retValue.zenith); - - if (isNaN(_t._angleX)) - _t._angleX = cc.radiansToDegrees(retValue.azimuth); - - _t._radZ = cc.degreesToRadians(_t._angleZ); - _t._radX = cc.degreesToRadians(_t._angleX); - }, - - /** - * to copy object with deep copy. - * returns a new clone of the action - * - * @returns {cc.ActionCamera} - */ - clone:function(){ - var a = new cc.OrbitCamera(), _t = this; - a.initWithDuration(_t._duration, _t._radius, _t._deltaRadius, _t._angleZ, _t._deltaAngleZ, _t._angleX, _t._deltaAngleX); - return a; - }, - - /** - * Called once per frame. Time is the number of seconds of a frame interval. - * - * @param {Number} dt - */ - update:function (dt) { - dt = this._computeEaseTime(dt); - var r = (this._radius + this._deltaRadius * dt) * cc.Camera.getZEye(); - var za = this._radZ + this._radDeltaZ * dt; - var xa = this._radX + this._radDeltaX * dt; - - var i = Math.sin(za) * Math.cos(xa) * r + this._centerXOrig; - var j = Math.sin(za) * Math.sin(xa) * r + this._centerYOrig; - var k = Math.cos(za) * r + this._centerZOrig; - - this.target.getCamera().setEye(i, j, k); - this.target.setNodeDirty(); - } -}); - -/** - * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX - * @function - * @param {Number} t time - * @param {Number} radius - * @param {Number} deltaRadius - * @param {Number} angleZ - * @param {Number} deltaAngleZ - * @param {Number} angleX - * @param {Number} deltaAngleX - * @return {cc.OrbitCamera} - */ -cc.orbitCamera = function (t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX) { - return new cc.OrbitCamera(t, radius, deltaRadius, angleZ, deltaAngleZ, angleX, deltaAngleX); -}; - -/** - * Please use cc.orbitCamera instead - * creates a cc.OrbitCamera action with radius, delta-radius, z, deltaZ, x, deltaX - * @param {Number} t time - * @param {Number} radius - * @param {Number} deltaRadius - * @param {Number} angleZ - * @param {Number} deltaAngleZ - * @param {Number} angleX - * @param {Number} deltaAngleX - * @return {cc.OrbitCamera} - * @static - * @deprecated since v3.0 please use cc.orbitCamera() instead. - */ -cc.OrbitCamera.create = cc.orbitCamera; diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js index 45ae710cc7..3bf0914793 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js @@ -90,7 +90,7 @@ cc.log("Nesting more than " + cc.stencilBits + "stencils is not supported. Everything will be drawn without stencil for this node and its children."); cc.ClippingNode.WebGLRenderCmd._visit_once = false; } - // draw everything, as if there where no stencil + // draw everything, as if there were no stencil cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); return; } diff --git a/cocos2d/core/CCCamera.js b/cocos2d/core/CCCamera.js deleted file mode 100644 index 198ce78add..0000000000 --- a/cocos2d/core/CCCamera.js +++ /dev/null @@ -1,282 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - *

- * A CCCamera is used in every CCNode.
- * The OpenGL gluLookAt() function is used to locate the camera.
- *
- * If the object is transformed by any of the scale, rotation or position attributes, then they will override the camera.
- *
- * IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both.
- * World coordinates won't work if you use the camera.
- *
- * Limitations:
- * - Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors)
- * using the camera.
- *
- * - It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object.
- *
- * - It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate. * - *

- */ -cc.Camera = cc.Class.extend(/** @lends cc.Camera# */{ - _eyeX:null, - _eyeY:null, - _eyeZ:null, - - _centerX:null, - _centerY:null, - _centerZ:null, - - _upX:null, - _upY:null, - _upZ:null, - - _dirty:false, - _lookupMatrix:null, - /** - * constructor of cc.Camera - */ - ctor:function () { - this._lookupMatrix = new cc.math.Matrix4(); - this.restore(); - }, - - /** - * Description of cc.Camera - * @return {String} - */ - description:function () { - return ""; - }, - - /** - * sets the dirty value - * @param value - */ - setDirty:function (value) { - this._dirty = value; - }, - - /** - * get the dirty value - * @return {Boolean} - */ - isDirty:function () { - return this._dirty; - }, - - /** - * sets the camera in the default position - */ - restore:function () { - this._eyeX = this._eyeY = 0.0; - this._eyeZ = cc.Camera.getZEye(); - - this._centerX = this._centerY = this._centerZ = 0.0; - - this._upX = 0.0; - this._upY = 1.0; - this._upZ = 0.0; - - this._lookupMatrix.identity(); - - this._dirty = false; - }, - - /** - * Sets the camera using gluLookAt using its eye, center and up_vector - */ - locate:function () { - if (this._dirty) { - var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ), - center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ), - up = new cc.math.Vec3(this._upX, this._upY, this._upZ); - this._lookupMatrix.lookAt(eye, center, up); - this._dirty = false; - } - cc.kmGLMultMatrix( this._lookupMatrix); - }, - - _locateForRenderer: function(matrix){ - if (this._dirty) { - var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ), - center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ), - up = new cc.math.Vec3(this._upX, this._upY, this._upZ); - this._lookupMatrix.lookAt(eye, center, up); - this._dirty = false; - } - matrix.multiply(this._lookupMatrix); - }, - - /** - * sets the eye values in points - * @param {Number} eyeX - * @param {Number} eyeY - * @param {Number} eyeZ - * @deprecated This function will be deprecated sooner or later please use setEye instead. - */ - setEyeXYZ:function (eyeX, eyeY, eyeZ) { - this.setEye(eyeX,eyeY,eyeZ); - }, - - /** - * sets the eye values in points - * @param {Number} eyeX - * @param {Number} eyeY - * @param {Number} eyeZ - */ - setEye:function (eyeX, eyeY, eyeZ) { - this._eyeX = eyeX ; - this._eyeY = eyeY ; - this._eyeZ = eyeZ ; - - this._dirty = true; - }, - - /** - * sets the center values in points - * @param {Number} centerX - * @param {Number} centerY - * @param {Number} centerZ - * @deprecated This function will be deprecated sooner or later please use setCenter instead. - */ - setCenterXYZ:function (centerX, centerY, centerZ) { - this.setCenter(centerX,centerY,centerZ); - }, - - /** - * sets the center values in points - * @param {Number} centerX - * @param {Number} centerY - * @param {Number} centerZ - */ - setCenter:function (centerX, centerY, centerZ) { - this._centerX = centerX ; - this._centerY = centerY ; - this._centerZ = centerZ ; - - this._dirty = true; - }, - - /** - * sets the up values - * @param {Number} upX - * @param {Number} upY - * @param {Number} upZ - * @deprecated This function will be deprecated sooner or later. - */ - setUpXYZ:function (upX, upY, upZ) { - this.setUp(upX, upY, upZ); - }, - - /** - * sets the up values - * @param {Number} upX - * @param {Number} upY - * @param {Number} upZ - */ - setUp:function (upX, upY, upZ) { - this._upX = upX; - this._upY = upY; - this._upZ = upZ; - - this._dirty = true; - }, - - /** - * get the eye vector values in points (return an object like {x:1,y:1,z:1} in HTML5) - * @param {Number} eyeX - * @param {Number} eyeY - * @param {Number} eyeZ - * @return {Object} - * @deprecated This function will be deprecated sooner or later, please use getEye instead. - */ - getEyeXYZ:function (eyeX, eyeY, eyeZ) { - return {x:this._eyeX , y:this._eyeY , z: this._eyeZ }; - }, - - /** - * get the eye vector values in points (return an object like {x:1,y:1,z:1} in HTML5) - * @return {Object} - */ - getEye:function () { - return {x:this._eyeX , y:this._eyeY , z: this._eyeZ }; - }, - - /** - * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5) - * @param {Number} centerX - * @param {Number} centerY - * @param {Number} centerZ - * @return {Object} - * @deprecated This function will be deprecated sooner or later,please use getCenter instead. - */ - getCenterXYZ:function (centerX, centerY, centerZ) { - return {x:this._centerX ,y:this._centerY ,z:this._centerZ }; - }, - - /** - * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5) - * @return {Object} - */ - getCenter:function () { - return {x:this._centerX ,y:this._centerY ,z:this._centerZ }; - }, - - /** - * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5) - * @param {Number} upX - * @param {Number} upY - * @param {Number} upZ - * @return {Object} - * @deprecated This function will be deprecated sooner or later,please use getUp instead. - */ - getUpXYZ:function (upX, upY, upZ) { - return {x:this._upX,y:this._upY,z:this._upZ}; - }, - - /** - * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5) - * @return {Object} - */ - getUp:function () { - return {x:this._upX,y:this._upY,z:this._upZ}; - }, - - _DISALLOW_COPY_AND_ASSIGN:function (CCCamera) { - - } -}); - -/** - * returns the Z eye - * @return {Number} - */ -cc.Camera.getZEye = function () { - return cc.FLT_EPSILON; -}; diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js index 31e3a41727..686504a892 100644 --- a/cocos2d/core/CCDirector.js +++ b/cocos2d/core/CCDirector.js @@ -936,4 +936,4 @@ cc.Director.PROJECTION_CUSTOM = 3; * @constant * @type {Number} */ -cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D; +cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_2D; diff --git a/cocos2d/core/CCDirectorWebGL.js b/cocos2d/core/CCDirectorWebGL.js index bad8b75e21..75212759ed 100644 --- a/cocos2d/core/CCDirectorWebGL.js +++ b/cocos2d/core/CCDirectorWebGL.js @@ -78,10 +78,10 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); cc.kmGLLoadIdentity(); var orthoMatrix = cc.math.Matrix4.createOrthographicProjection( - -ox, - size.width - ox, - -oy, - size.height - oy, + 0, + size.width, + 0, + size.height, -1024, 1024); cc.kmGLMultMatrix(orthoMatrix); cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); diff --git a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js index d398f20eef..53551bfb17 100644 --- a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js +++ b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js @@ -34,6 +34,9 @@ this._colorF32Array = null; this._uniformColor = null; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); + //shader stuff this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR); this._uniformColor = cc._renderContext.getUniformLocation(this._shaderProgram.getProgram(), "u_color"); @@ -57,8 +60,16 @@ proto.rendering = function (ctx) { var context = ctx || cc._renderContext, node = this._node; + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(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 ddc6d221fc..7ebad4c3b3 100644 --- a/cocos2d/core/base-nodes/CCNode.js +++ b/cocos2d/core/base-nodes/CCNode.js @@ -85,7 +85,6 @@ cc.s_globalOrderOfArrival = 1; * -# The node will be rotated (rotation)
* -# The node will be scaled (scale)
* -# The grid will capture the screen
- * -# The node will be moved according to the camera values (camera)
* -# The grid will render the captured screen

* * @class @@ -187,8 +186,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{ _renderCmd:null, - _camera: null, - /** * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. * @function @@ -2164,19 +2161,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{ }, /** - * Returns a camera object that lets you move the node using a gluLookAt + * Returns null * @function - * @return {cc.Camera} A CCCamera object that lets you move the node using a gluLookAt + * @return {null} * @deprecated since v3.0, no alternative function - * @example - * var camera = node.getCamera(); - * camera.setEye(0, 0, 415/2); - * camera.setCenter(0, 0, 0); */ getCamera: function () { - if (!this._camera) - this._camera = new cc.Camera(); - return this._camera; + return null; }, /** diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js index bc35a60aa3..daa43d495e 100644 --- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js @@ -119,6 +119,159 @@ cc.Node.RenderCmd.prototype = { return null; }, + transform: function (parentCmd, recursive) { + // transform for canvas + var node = this._node, + dirty = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty, + pt = parentCmd ? parentCmd._worldTransform : null, + t = this._transform, + wt = this._worldTransform; //get the world transform + + if (node._usingNormalizedPosition && node._parent) { + var conSize = node._parent._contentSize; + node._position.x = node._normalizedPosition.x * conSize.width; + node._position.y = node._normalizedPosition.y * conSize.height; + node._normalizedPositionDirty = false; + dirty = true; + } + + if (dirty) { + var hasRotation = this._rotationX || this._rotationY; + var hasSkew = node._skewX || node._skewY; + if (hasRotation || hasSkew) { + var sx = node._scaleX, sy = node._scaleY; + var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; + + // position + t.tx = node._position.x; + t.ty = node._position.y; + + // rotation + if (hasRotation) { + var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance + c = Math.sin(rotationRadiansX); + d = Math.cos(rotationRadiansX); + if (node._rotationY === node._rotationX) { + a = d; + b = -c; + } + else { + var rotationRadiansY = node._rotationY * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance + a = Math.cos(rotationRadiansY); + b = -Math.sin(rotationRadiansY); + } + } + + // scale + a *= sx; + b *= sx; + c *= sy; + d *= sy; + + // skew + if (hasSkew) { + // offset the anchorpoint + var skx = Math.tan(-node._skewX * Math.PI / 180); + var sky = Math.tan(-node._skewY * Math.PI / 180); + if (skx === Infinity) + skx = 99999999; + if (sky === Infinity) + sky = 99999999; + var xx = appY * skx; + var yy = appX * sky; + t.a = a - c * sky; + t.b = b - d * sky; + t.c = c - a * skx; + t.d = d - b * skx; + t.tx += a * xx + c * yy; + t.ty += b * xx + d * yy; + } + + // adjust anchorPoint + if (!node._ignoreAnchorPointForPosition && (appX || appY)) { + t.tx -= t.a * appX + t.c * appY; + t.ty -= t.b * appX + t.d * appY; + } + + if (pt) { + // cc.AffineTransformConcat is incorrect at get world transform + wt.a = t.a * pt.a + t.b * pt.c; //a + wt.b = t.a * pt.b + t.b * pt.d; //b + wt.c = t.c * pt.a + t.d * pt.c; //c + wt.d = t.c * pt.b + t.d * pt.d; //d + wt.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; + wt.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; + } else { + wt.a = t.a; + wt.b = t.b; + wt.c = t.c; + wt.d = t.d; + wt.tx = t.tx; + wt.ty = t.ty; + } + } + else { + t.a = node._scaleX; + t.b = 0; + t.c = 0; + t.d = node._scaleY; + if (node._ignoreAnchorPointForPosition) { + t.tx = node._position.x; + t.ty = node._position.y; + } + else { + t.tx = node._position.x - this._anchorPointInPoints.x * t.a; + t.ty = node._position.y - this._anchorPointInPoints.y * t.d; + } + + if (pt) { + wt.a = t.a * pt.a + t.b * pt.c; + wt.b = t.a * pt.b + t.b * pt.d; + wt.c = t.c * pt.a + t.d * pt.c; + wt.d = t.c * pt.b + t.d * pt.d; + wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx; + wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty; + } else { + wt.a = t.a; + wt.b = t.b; + wt.c = t.c; + wt.d = t.d; + wt.tx = t.tx; + wt.ty = t.ty; + } + } + + if (node._additionalTransformDirty) { + this._transform = cc.affineTransformConcat(t, node._additionalTransform); + } + } + + if (recursive) { + var locChildren = this._node._children; + if (!locChildren || locChildren.length === 0) + return; + var i, len; + for (i = 0, len = locChildren.length; i < len; i++) { + locChildren[i]._renderCmd.transform(this, recursive); + } + } + + this._cacheDirty = true; + }, + + visit: function (parentCmd) { + var node = this._node; + // quick return if not visible + if (!node._visible) + return; + + parentCmd = parentCmd || this.getParentRenderCmd(); + if (parentCmd) + this._curLevel = parentCmd._curLevel + 1; + this._syncStatus(parentCmd); + this.visitChildren(); + }, + _updateDisplayColor: function (parentColor) { var node = this._node; var locDispColor = this._displayedColor, locRealColor = node._realColor; @@ -247,87 +400,8 @@ cc.Node.RenderCmd.prototype = { }, getNodeToParentTransform: function () { - var node = this._node; - if (node._usingNormalizedPosition && node._parent) { //TODO need refactor - var conSize = node._parent._contentSize; - node._position.x = node._normalizedPosition.x * conSize.width; - node._position.y = node._normalizedPosition.y * conSize.height; - node._normalizedPositionDirty = false; - this._dirtyFlag = this._dirtyFlag | cc.Node._dirtyFlags.transformDirty; - } if (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) { - var t = this._transform;// quick reference - - // base position - t.tx = node._position.x; - t.ty = node._position.y; - - // rotation Cos and Sin - var a = 1, b = 0, - c = 0, d = 1; - if (node._rotationX) { - var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance - c = Math.sin(rotationRadiansX); - d = Math.cos(rotationRadiansX); - } - - if (node._rotationY) { - var rotationRadiansY = node._rotationY * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance - a = Math.cos(rotationRadiansY); - b = -Math.sin(rotationRadiansY); - } - t.a = a; - t.b = b; - t.c = c; - t.d = d; - - var lScaleX = node._scaleX, lScaleY = node._scaleY; - var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; - - // Firefox on Vista and XP crashes - // GPU thread in case of scale(0.0, 0.0) - var sx = (lScaleX < 0.000001 && lScaleX > -0.000001) ? 0.000001 : lScaleX, - sy = (lScaleY < 0.000001 && lScaleY > -0.000001) ? 0.000001 : lScaleY; - - // scale - if (lScaleX !== 1 || lScaleY !== 1) { - a = t.a *= sx; - b = t.b *= sx; - c = t.c *= sy; - d = t.d *= sy; - } - - // skew - if (node._skewX || node._skewY) { - // offset the anchorpoint - var skx = Math.tan(-node._skewX * Math.PI / 180); - var sky = Math.tan(-node._skewY * Math.PI / 180); - if (skx === Infinity) - skx = 99999999; - if (sky === Infinity) - sky = 99999999; - var xx = appY * skx; - var yy = appX * sky; - t.a = a - c * sky; - t.b = b - d * sky; - t.c = c - a * skx; - t.d = d - b * skx; - t.tx += a * xx + c * yy; - t.ty += b * xx + d * yy; - } - - // adjust anchorPoint - t.tx -= a * appX + c * appY; - t.ty -= b * appX + d * appY; - - // if ignore anchorPoint - if (node._ignoreAnchorPointForPosition) { - t.tx += appX; - t.ty += appY; - } - - if (node._additionalTransformDirty) - this._transform = cc.affineTransformConcat(t, node._additionalTransform); + this.transform(); } return this._transform; }, @@ -424,6 +498,8 @@ cc.Node.RenderCmd.prototype = { } }; +cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform; + //-----------------------Canvas --------------------------- (function() { @@ -437,53 +513,6 @@ cc.Node.RenderCmd.prototype = { var proto = cc.Node.CanvasRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype); proto.constructor = cc.Node.CanvasRenderCmd; - proto.transform = function (parentCmd, recursive) { - // transform for canvas - var t = this.getNodeToParentTransform(), - worldT = this._worldTransform; //get the world transform - this._cacheDirty = true; - if (parentCmd) { - var pt = parentCmd._worldTransform; - // cc.AffineTransformConcat is incorrect at get world transform - worldT.a = t.a * pt.a + t.b * pt.c; //a - worldT.b = t.a * pt.b + t.b * pt.d; //b - worldT.c = t.c * pt.a + t.d * pt.c; //c - worldT.d = t.c * pt.b + t.d * pt.d; //d - - worldT.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; - worldT.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; - } else { - worldT.a = t.a; - worldT.b = t.b; - worldT.c = t.c; - worldT.d = t.d; - worldT.tx = t.tx; - worldT.ty = t.ty; - } - if (recursive) { - var locChildren = this._node._children; - if (!locChildren || locChildren.length === 0) - return; - var i, len; - for (i = 0, len = locChildren.length; i < len; i++) { - locChildren[i]._renderCmd.transform(this, recursive); - } - } - }; - - proto.visit = function (parentCmd) { - var node = this._node; - // quick return if not visible - if (!node._visible) - return; - - parentCmd = parentCmd || this.getParentRenderCmd(); - if (parentCmd) - this._curLevel = parentCmd._curLevel + 1; - this._syncStatus(parentCmd); - this.visitChildren(); - }; - proto.setDirtyFlag = function (dirtyFlag, child) { cc.Node.RenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag, child); this._setCacheDirty(child); //TODO it should remove from here. diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js index aa0fec69d9..4859e7acbc 100644 --- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js @@ -26,11 +26,6 @@ cc.Node.WebGLRenderCmd = function (renderable) { cc.Node.RenderCmd.call(this, renderable); - var mat4 = new cc.math.Matrix4(), mat = mat4.mat; - mat[2] = mat[3] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[14] = 0.0; - mat[10] = mat[15] = 1.0; - this._transform4x4 = mat4; - this._stackMatrix = new cc.math.Matrix4(); this._shaderProgram = null; this._camera = null; @@ -44,85 +39,6 @@ proto._updateColor = function(){}; - proto.visit = function (parentCmd) { - var node = this._node; - // quick return if not visible - if (!node._visible) - return; - - parentCmd = parentCmd || this.getParentRenderCmd(); - if (node._parent && node._parent._renderCmd) - this._curLevel = node._parent._renderCmd._curLevel + 1; - - var currentStack = cc.current_stack; - - //optimize performance for javascript - currentStack.stack.push(currentStack.top); - this._syncStatus(parentCmd); - currentStack.top = this._stackMatrix; - this.visitChildren(); - //optimize performance for javascript - currentStack.top = currentStack.stack.pop(); - }; - - proto.transform = function (parentCmd, recursive) { - var t4x4 = this._transform4x4, stackMatrix = this._stackMatrix, node = this._node; - parentCmd = parentCmd || this.getParentRenderCmd(); - var parentMatrix = (parentCmd ? parentCmd._stackMatrix : cc.current_stack.top); - - // Convert 3x3 into 4x4 matrix - var trans = this.getNodeToParentTransform(); - - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag; - - var t4x4Mat = t4x4.mat; - t4x4Mat[0] = trans.a; - t4x4Mat[4] = trans.c; - t4x4Mat[12] = trans.tx; - t4x4Mat[1] = trans.b; - t4x4Mat[5] = trans.d; - t4x4Mat[13] = trans.ty; - - //optimize performance for Javascript - cc.kmMat4Multiply(stackMatrix, parentMatrix, t4x4); - - // Update Z depth - t4x4Mat[14] = node._vertexZ; - - // XXX: Expensive calls. Camera should be integrated into the cached affine matrix - if (node._camera !== null && !(node.grid !== null && node.grid.isActive())) { - var apx = this._anchorPointInPoints.x, apy = this._anchorPointInPoints.y; - var translate = (apx !== 0.0 || apy !== 0.0); - if (translate){ - if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { - apx = 0 | apx; - apy = 0 | apy; - } - //cc.kmGLTranslatef(apx, apy, 0); - var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix - stackMatrix.multiply(translation); - - node._camera._locateForRenderer(stackMatrix); - - //cc.kmGLTranslatef(-apx, -apy, 0); optimize at here : kmGLTranslatef - translation = cc.math.Matrix4.createByTranslation(-apx, -apy, 0, translation); - stackMatrix.multiply(translation); - t4x4.identity(); //reset t4x4; - } else { - node._camera._locateForRenderer(stackMatrix); - } - } - - if (!recursive || !node._children) { - return; - } - - var i, len, locChildren = node._children; - for(i = 0, len = locChildren.length; i< len; i++){ - locChildren[i]._renderCmd.transform(this, recursive); - } - }; - proto.setShaderProgram = function (shaderProgram) { this._shaderProgram = shaderProgram; }; diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js index a67f9e4c5d..882e9ab3a6 100644 --- a/cocos2d/core/labelttf/CCLabelTTF.js +++ b/cocos2d/core/labelttf/CCLabelTTF.js @@ -813,11 +813,6 @@ cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment, */ cc.LabelTTF.createWithFontDefinition = cc.LabelTTF.create; -if (cc.USE_LA88_LABELS) - cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR; -else - cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR; - cc.LabelTTF.__labelHeightDiv = document.createElement("div"); cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial"; cc.LabelTTF.__labelHeightDiv.style.position = "absolute"; diff --git a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js index 9d6de1e586..0ade49ed2b 100644 --- a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js +++ b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js @@ -27,10 +27,8 @@ cc.LabelTTF.WebGLRenderCmd = function (renderable) { cc.Sprite.WebGLRenderCmd.call(this, renderable); cc.LabelTTF.CacheRenderCmd.call(this); - this.setShaderProgram(cc.shaderCache.programForKey(cc.LabelTTF._SHADER_PROGRAM)); }; var proto = cc.LabelTTF.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); - proto._supportBatch = false; cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto); proto.constructor = cc.LabelTTF.WebGLRenderCmd; diff --git a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js index 4084153cde..92682ddc9b 100644 --- a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js +++ b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js @@ -54,6 +54,9 @@ cc.Layer.WebGLRenderCmd.call(this, renderable); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); + // var _t = this; _t._squareVerticesAB = new ArrayBuffer(32); @@ -79,8 +82,16 @@ var context = ctx || cc._renderContext; var node = this._node; + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); @@ -283,9 +294,17 @@ context.enable(context.SCISSOR_TEST); cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height); + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + //draw gradient layer this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 05b0a346ff..7eb4b6ca64 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -32,14 +32,9 @@ function removeByLastSwap (array, i) { } } -var CACHING_BUFFER = true; -var ACTIVATE_AUTO_BATCH = true; - // Internal variables - // Global vertex buffers, shared by sprites -var _gbuffers = [], // Batching general informations - _batchedInfo = { +var _batchedInfo = { // The batched texture, all batching element should have the same texture texture: null, // The batched blend source, all batching element should have the same blend source @@ -49,89 +44,70 @@ var _gbuffers = [], // The batched shader, all batching element should have the same shader shader: null }, - // to compare with the batched info - _currentInfo = { - texture: null, - blendSrc: null, - blendDst: null, - shader: null - }, - // The current virtual buffer - _currentBuffer = null, - _batchBufferPool = new cc.SimplePool(), - _orderDirtyInFrame = false, - _bufferError = false, - _prevRenderCmds = [], - _quadIndexBuffer = { - buffer: null, - maxQuads: 0 - }; + + _quadIndexBuffer = null, + _quadVertexBuffer = null, + // Total vertex size + _vertexSize = 0, + // Current batching vertex size + _batchingSize = 0, + _sizePerVertex = 6, + // buffer data and views + _vertexData = null, + _vertexDataSize = 0, + _vertexDataF32 = null, + _vertexDataUI32 = null; + // Inspired from @Heishe's gotta-batch-them-all branch // https://github.com/Talisca/cocos2d-html5/commit/de731f16414eb9bcaa20480006897ca6576d362c -function updateQuadIndexBuffer (numQuads) { - if (!_quadIndexBuffer.buffer) { - return; - } +function updateQuadBuffer (numQuads) { var gl = cc._renderContext; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _quadIndexBuffer.buffer); - - var indices = new Uint16Array(numQuads * 6); - var currentQuad = 0; - for (var i = 0, len = numQuads * 6; i < len; i += 6) { - indices[i] = currentQuad + 0; - indices[i + 1] = currentQuad + 1; - indices[i + 2] = currentQuad + 2; - indices[i + 3] = currentQuad + 1; - indices[i + 4] = currentQuad + 2; - indices[i + 5] = currentQuad + 3; - currentQuad += 4; + // Update index buffer and fill up + if (_quadIndexBuffer) { + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _quadIndexBuffer); + + var indices = new Uint16Array(numQuads * 6); + var currentQuad = 0; + for (var i = 0, len = numQuads * 6; i < len; i += 6) { + indices[i] = currentQuad + 0; + indices[i + 1] = currentQuad + 1; + indices[i + 2] = currentQuad + 2; + indices[i + 3] = currentQuad + 1; + indices[i + 4] = currentQuad + 2; + indices[i + 5] = currentQuad + 3; + currentQuad += 4; + } + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); } - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); - _quadIndexBuffer.maxQuads = numQuads; + + if (_quadVertexBuffer) { + _vertexDataSize = numQuads * 4 * _sizePerVertex; + var byteLength = _vertexDataSize * 4; + _vertexData = new ArrayBuffer(byteLength); + _vertexDataF32 = new Float32Array(_vertexData); + _vertexDataUI32 = new Uint32Array(_vertexData); + // Init buffer data + gl.bindBuffer(gl.ARRAY_BUFFER, _quadVertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); + } + _vertexSize = numQuads * 4; } // Inspired from @Heishe's gotta-batch-them-all branch // https://github.com/Talisca/cocos2d-html5/commit/de731f16414eb9bcaa20480006897ca6576d362c -function getQuadIndexBuffer (numQuads) { - if (_quadIndexBuffer.buffer === null) { - _quadIndexBuffer.buffer = cc._renderContext.createBuffer(); - } - - if (_quadIndexBuffer.maxQuads < numQuads) { - updateQuadIndexBuffer(numQuads); - } - - return _quadIndexBuffer.buffer; -} +function initQuadBuffer (numQuads) { + var gl = cc._renderContext; + if (_quadIndexBuffer === null) { + // TODO do user need to release the memory ? + _quadVertexBuffer = gl.createBuffer(); + _quadIndexBuffer = gl.createBuffer(); -function createVirtualBuffer (buffer, vertexOffset, totalBufferSize, count, data) { - var float32View, uint32View; - if (data) { - float32View = new Float32Array(data, vertexOffset, totalBufferSize / 4); - uint32View = new Uint32Array(data, vertexOffset, totalBufferSize / 4); + updateQuadBuffer(numQuads); } else { - float32View = new Float32Array(totalBufferSize / 4); - uint32View = new Uint32Array(float32View.buffer); + updateQuadBuffer(numQuads); } - var vBuf = { - // The object contains real WebGL buffers, it's created or retrieved via getBatchBuffer - buffer: buffer, - // The vertex data array (Float32Array) - float32View: float32View, - // Uint32 view - uint32View: uint32View, - // The start offset in the vertex buffer, in bytes - vertexOffset: vertexOffset, - // Total vertex array buffer size, including vertex data, in bytes - totalBufferSize: totalBufferSize, - // Render command count - count: count, - // Valid flag, indicate whether the buffer is valid or not - valid: true - }; - return vBuf; } return { @@ -153,32 +129,7 @@ return { init: function () { this.mat4Identity = new cc.math.Matrix4(); this.mat4Identity.identity(); - getQuadIndexBuffer(1000); - }, - - requestBuffer: function (size) { - var i, len = _gbuffers.length, buffer, - gl = cc._renderContext, - result; - for (i = 0; i < len; ++i) { - buffer = _gbuffers[i]; - if (buffer.gl === gl) { - result = buffer.requestBuffer(size); - if (result) { - return result; - } - } - } - - if (!result) { - buffer = new GlobalVertexBuffer(gl); - _gbuffers.push(buffer); - result = buffer.requestBuffer(size); - } - if (!result) { - cc.error('Request WebGL buffer failed'); - } - return result; + initQuadBuffer(2000); }, getRenderCmd: function (renderableObject) { @@ -218,10 +169,6 @@ return { renderTextureId = renderTextureId || this._currentID; var locCmds = this._cacheToBufferCmds[renderTextureId], i, len; var ctx = cc._renderContext; - // Update all global buffers (only invoke bufferSubData when buffer is dirty) - for (i = 0, len = _gbuffers.length; i < len; ++i) { - _gbuffers[i].update(); - } // Reset buffer cache to avoid issue gl.bindBuffer(gl.ARRAY_BUFFER, null); for (i = 0, len = locCmds.length; i < len; i++) { @@ -239,7 +186,6 @@ return { //reset renderer's flag resetFlag: function () { if (this.childrenOrderDirty) { - _orderDirtyInFrame = true; this.childrenOrderDirty = false; } this._transformNodePool.length = 0; @@ -274,16 +220,6 @@ return { clearRenderCommands: function () { // Copy previous command list for late check in rendering - if (CACHING_BUFFER) { - var locCmds = this._renderCmds; - var i, len = locCmds.length, cmd; - for (i = 0; i < len; ++i) { - cmd = locCmds[i]; - cmd._currId = -1; - _prevRenderCmds[i] = cmd; - } - _prevRenderCmds.length = len; - } this._renderCmds.length = 0; }, @@ -321,330 +257,44 @@ return { } }, - // Auto batch implementation inspired from @Heishe 's PR - // Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248 - createBatchBuffer: function (bufferSize) { - var arrayBuffer = gl.createBuffer(); - - this.initBatchBuffers(arrayBuffer, bufferSize); - - return {arrayBuffer: arrayBuffer, bufferSize: bufferSize}; - }, - - // Auto batch implementation inspired from @Heishe 's PR - // Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248 - initBatchBuffers: function (arrayBuffer, bufferSize) { - gl.bindBuffer(gl.ARRAY_BUFFER, arrayBuffer); - gl.bufferData(gl.ARRAY_BUFFER, bufferSize, gl.DYNAMIC_DRAW); - }, - - // Auto batch implementation inspired from @Heishe 's PR - // Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248 - - // Returns an object with {arrayBuffer, size}, - // where size denotes how many unit fit in the buffer (no need for bufferData if it's already big enough, bufferSubData enough) - getBatchBuffer: function(bufferSize) - { - if (_batchBufferPool.size() > 0) { - var minSize = Number.MAX_VALUE; - var minBufIndex = -1; - - var buf = _batchBufferPool.find(function (i, buf) { - // Find available buffer with suitable size - if (buf.bufferSize >= bufferSize) { - return true; - } - - // Track the smallest found buffer because that one will be re-initialized and returned if no fitting buffer can be found - if (buf.bufferSize < minSize) - { - minSize = buf.bufferSize; - minBufIndex = i; - } - }, function () { - return minBufIndex; - }); - - if (buf) { - this.initBatchBuffers(buf.arrayBuffer, bufferSize); - buf.bufferSize = bufferSize; - return buf; - } + _uploadBufferData: function (cmd) { + if (_batchingSize >= _vertexSize) { + this._batchRendering(); } - return this.createBatchBuffer(bufferSize); - }, - - _refreshVirtualBuffers: function () { - var renderCmds = this._renderCmds, - len = _prevRenderCmds.length, - currLen = renderCmds.length, - i = 0, j = 0, end, cmd1, cmd2, next, - newBuf, currBuf, - startId, count, size; - - // Loop previous render command list to compare with current command list - for (; i < len; ++i) { - cmd1 = _prevRenderCmds[i]; - currBuf = cmd1._vBuffer; - matched = false; - // Check to update virtual buffer - if (currBuf && currBuf.valid) { - j = cmd1._currId; - // Removed from the command list - if (j < 0 || j >= currLen) { - cmd1._vBuffer = null; - continue; - } - - cmd1.getBatchInfo(_batchedInfo); - startId = i; - count = 0; - // Remains in the command list - cmd2 = renderCmds[j]; - while (cmd1 && cmd1 === cmd2 && cmd1._vBuffer === currBuf) { - ++count; - ++j; - cmd1 = _prevRenderCmds[i+count]; - cmd2 = renderCmds[j]; - } - end = i + count; - - // No valid batch - if (count <= 1) { - cmd1 = _prevRenderCmds[i]; - cmd1._vBuffer = null; - if (cmd2) { - cmd2._vBuffer = null; - } - continue; - } - - // The next command in the current list support batch - if (cmd2 && cmd2._supportBatch) { - cmd2.getBatchInfo(_currentInfo); - if (_currentInfo.texture === _batchedInfo.texture && - _currentInfo.blendSrc === _batchedInfo.blendSrc && - _currentInfo.blendDst === _batchedInfo.blendDst && - _currentInfo.shader === _batchedInfo.shader) { - // Old batch dirty, clean up v buffer properties - for (; i < end; ++i) { - _prevRenderCmds[i]._vBuffer = null; - } - // keeping i correct, it should run through all elements - i--; - continue; - } - } - - // Perfect match - if (currBuf.count === count) { - i = i + count - 1; - } - // Sub match - else if (count > 1) { - // First command in buffer - cmd1 = _prevRenderCmds[i]; - // cmd2 = _prevRenderCmds[i+count-1]; - size = count * cmd1.bytesPerUnit; - newBuf = createVirtualBuffer(currBuf.buffer, - cmd1._vertexOffset * 4, - size, - count, - currBuf.float32View.buffer); - for (; i < end; ++i) { - _prevRenderCmds[i]._vBuffer = newBuf; - } - // keeping i correct, it should run through all elements - i--; - } - } + // Check batching + var texture = cmd._node._texture; + var blendSrc = cmd._node._blendFunc.src; + var blendDst = cmd._node._blendFunc.dst; + var shader = cmd._shaderProgram; + if (_batchedInfo.texture !== texture || + _batchedInfo.blendSrc !== blendSrc || + _batchedInfo.blendDst !== blendDst || + _batchedInfo.shader !== shader) { + // Draw batched elements + this._batchRendering(); + // Update _batchedInfo + _batchedInfo.texture = texture; + _batchedInfo.blendSrc = blendSrc; + _batchedInfo.blendDst = blendDst; + _batchedInfo.shader = shader; } - // Forward batch other commands - len = renderCmds.length; - for (i = 0; i < len; ++i) { - cmd1 = renderCmds[i]; - // Already batched command, do not update - if (cmd1._vBuffer) { - continue; - } - - next = renderCmds[i+1]; - // Batching - if (cmd1._supportBatch && next && next._supportBatch) { - count = this._forwardBatch(i); - if (count > 1) { - // i will increase by 1 each loop - i += count - 1; - continue; - } - } + // Upload vertex data + var uploaded = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex); + if (uploaded) { + _batchingSize += 4; } - _prevRenderCmds.length = 0; - _bufferError = false; }, - // Forward search commands that are in the same virtual buffer, - // If size match then no problem to render - // Otherwise, the virtual buffer need to be updated - _forwardCheck: function (first) { - var renderCmds = this._renderCmds, - cmd = renderCmds[first], - last = first, length = renderCmds.length, - vbuffer = cmd._vBuffer; - - // Reset current buffer and batched info - cmd.getBatchInfo(_batchedInfo); - _currentBuffer = null; - - // Protection, vbuffer invalid or doesn't match the command - if (cmd._vertexOffset !== vbuffer.vertexOffset || !vbuffer.valid || !vbuffer.buffer) { - _bufferError = true; - return 0; - } - - // Forward check - var vertexBuffer; - for (; last < length; ++last) { - cmd = renderCmds[last]; - if (vbuffer !== cmd._vBuffer) { - break; - } - - // Lazy update vertex in buffer - if (cmd._bufferDirty) { - if (!vertexBuffer) { - // Bind buffer - vertexBuffer = vbuffer; - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.buffer.arrayBuffer); - } - cmd.batchVertexBuffer(vertexBuffer.float32View, vertexBuffer.uint32View, cmd._vertexOffset); - cmd._bufferDirty = false; - } - } - // Send last buffer to WebGLBuffer - if (vertexBuffer) { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexBuffer.float32View); - } - - var size = last - first; - // no problem - if (vbuffer.count === size) { - _currentBuffer = vbuffer; - return size; - } - // buffer errored - // need to update virtual buffers in next frame - else { - for (last = first; last < first + size; ++last) { - cmd = renderCmds[last]; - cmd._vBuffer = null; - } - _bufferError = true; - return 0; - } - }, - - // Auto batch implementation inspired from @Heishe 's PR - // Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248 - // Forward search commands that can be batched together - _forwardBatch: function (first) { - var renderCmds = this._renderCmds, - cmd = renderCmds[first], - last = first + 1, length = renderCmds.length; - - if (!cmd || !cmd._supportBatch) - return 0; - - // Initialize batched info - cmd.getBatchInfo(_batchedInfo); - if (!_batchedInfo.texture) - return 0; - - var totalBufferSize = cmd.bytesPerUnit; - - // Forward search and collect batch informations - cmd = renderCmds[last]; - while (cmd) { - if (cmd._supportBatch) { - cmd.getBatchInfo(_currentInfo); - } - else { - break; - } - // Batch info don't match, break batching - if (_currentInfo.texture !== _batchedInfo.texture || - _currentInfo.blendSrc !== _batchedInfo.blendSrc || - _currentInfo.blendDst !== _batchedInfo.blendDst || - _currentInfo.shader !== _batchedInfo.shader) { - break; - } - else { - totalBufferSize += cmd.bytesPerUnit; - } - ++last; - cmd = renderCmds[last]; - } - - var count = last - first; - // Can't batch, fall back to original render command - if (count <= 1) { - return count; - } - - var buffer = this.getBatchBuffer(totalBufferSize); - - // Create a virtual buffer - var vbuffer = createVirtualBuffer(buffer, - 0, - totalBufferSize, - count); - _currentBuffer = vbuffer; - var uploadBuffer = vbuffer.float32View; - - //all of the divisions by 4 are just because we work with Float32Arrays instead of uint8 arrays so all indexes need to be shortened by the factor of 4 - var vertexDataOffset = 0; - - // Bind vertex data buffer - gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer.buffer.arrayBuffer); - - // Fill in vertex data command by command - var i; - for (i = first; i < last; ++i) { - cmd = renderCmds[i]; - cmd.batchVertexBuffer(uploadBuffer, vbuffer.uint32View, vertexDataOffset); - - if (CACHING_BUFFER) { - cmd._vBuffer = vbuffer; - cmd._vertexOffset = vertexDataOffset; - } - if (cmd._savedDirtyFlag) { - cmd._savedDirtyFlag = false; - } - - vertexDataOffset += cmd.vertexBytesPerUnit / 4; - } - - // Submit vertex data in one bufferSubData call - gl.bufferSubData(gl.ARRAY_BUFFER, 0, uploadBuffer); - - if (!CACHING_BUFFER) { - _batchBufferPool.put(buffer); + _batchRendering: function () { + if (_batchingSize === 0 || !_batchedInfo.texture) { + return; } - return count; - }, - // Auto batch implementation inspired from @Heishe 's PR - // Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248 - // Batch rendering using result collected in `_forwardBatch` - _batchRendering: function () { - // var node = this._node; var texture = _batchedInfo.texture; var shader = _batchedInfo.shader; - var count = _currentBuffer.count; - - var bytesPerRow = 16; //4 floats with 4 bytes each + var count = _batchingSize / 4; shader.use(); shader._updateProjectionUniform(); @@ -652,22 +302,31 @@ return { cc.glBlendFunc(_batchedInfo.blendSrc, _batchedInfo.blendDst); cc.glBindTexture2DN(0, texture); // = cc.glBindTexture2D(texture); - gl.bindBuffer(gl.ARRAY_BUFFER, _currentBuffer.buffer.arrayBuffer); - - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); + var _bufferchanged = !gl.bindBuffer(gl.ARRAY_BUFFER, _quadVertexBuffer); + // upload the vertex data to the gl buffer + if (_batchingSize > _vertexSize * 0.5) { + gl.bufferSubData(gl.ARRAY_BUFFER, 0, _vertexDataF32); + } + else { + var view = _vertexDataF32.subarray(0, _batchingSize * _sizePerVertex); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); + } - var vertexOffset = _currentBuffer.vertexOffset; - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, vertexOffset); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, vertexOffset + 12); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, vertexOffset + 16); + if (_bufferchanged) { + gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); + gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); + gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); + gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); + gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); + gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); + } - var elemBuffer = getQuadIndexBuffer(count); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _quadIndexBuffer); gl.drawElements(gl.TRIANGLES, count * 6, gl.UNSIGNED_SHORT, 0); cc.g_NumberOfDraws++; + + _batchingSize = 0; }, /** @@ -679,41 +338,24 @@ return { i, len, cmd, next, batchCount, context = ctx || cc._renderContext; - // Update all global buffers (only invoke bufferData when buffer is dirty) - for (i = 0, len = _gbuffers.length; i < len; ++i) { - _gbuffers[i].update(); - } - - // Only update virtual buffers if children order dirty in the current frame - if (ACTIVATE_AUTO_BATCH && (_orderDirtyInFrame || _bufferError)) { - this._refreshVirtualBuffers(); - } - // Reset buffer for rendering context.bindBuffer(gl.ARRAY_BUFFER, null); for (i = 0, len = locCmds.length; i < len; ++i) { cmd = locCmds[i]; - next = locCmds[i+1]; - - if (ACTIVATE_AUTO_BATCH) { - // Already batched in buffer - if (cmd._vBuffer) { - batchCount = this._forwardCheck(i); - if (batchCount > 1) { - this._batchRendering(); - // i will increase by 1 each loop - i += batchCount - 1; - continue; - } + + if (cmd.uploadData) { + this._uploadBufferData(cmd); + } + else { + if (cmd._batchingSize > 0) { + this._batchRendering(); } + cmd.rendering(context); } - - cmd.rendering(context); - } - if (_orderDirtyInFrame) { - _orderDirtyInFrame = false; } + this._batchRendering(); + _batchedInfo.texture = null; } }; })(); \ No newline at end of file diff --git a/cocos2d/core/sprites/CCSprite.js b/cocos2d/core/sprites/CCSprite.js index dc4b35a637..ac75c4bf2a 100644 --- a/cocos2d/core/sprites/CCSprite.js +++ b/cocos2d/core/sprites/CCSprite.js @@ -132,20 +132,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ self._softInit(fileName, rect, rotated); }, - onEnter: function () { - this._super(); - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { - this._renderCmd.updateBuffer(); - } - }, - - cleanup: function () { - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { - this._renderCmd.freeBuffer(); - } - this._super(); - }, - /** * Returns whether the texture have been loaded * @returns {boolean} @@ -584,7 +570,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ * @return {cc.V3F_C4B_T2F_Quad|null} Returns a cc.V3F_C4B_T2F_Quad object when render mode is WebGL, returns null when render mode is Canvas. */ getQuad:function () { - return this._renderCmd.getQuad(); + return null; }, /** @@ -634,7 +620,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ _t._offsetPosition.y = 0; _t._hasChildren = false; - this._renderCmd._init(); // updated in "useSelfRender" // Atlas: TexCoords _t.setTextureRect(cc.rect(0, 0, 0, 0), false, cc.size(0, 0)); @@ -709,8 +694,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ _t._offsetPosition.y = 0; _t._hasChildren = false; - this._renderCmd._init(); - var locTextureLoaded = texture.isLoaded(); _t._textureLoaded = locTextureLoaded; @@ -772,21 +755,10 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ if (_t._batchNode) { // update dirty, don't update _recursiveDirty _t.dirty = true; - } else { - // self rendering - // Atlas: Vertex - this._renderCmd._resetForBatchNode(); } }, // BatchNode methods - /** - * Updates the quad according the the rotation, position, scale values. - * @function - */ - updateTransform: function(){ - this._renderCmd.updateTransform(); - }, /** * Add child to sprite (override cc.Node) @@ -917,8 +889,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ _t.textureAtlas = null; _t._recursiveDirty = false; _t.dirty = false; - - this._renderCmd._resetForBatchNode(); } else { // using batch _t._transformToBatch = cc.affineTransformIdentity(); diff --git a/cocos2d/core/sprites/CCSpriteBatchNode.js b/cocos2d/core/sprites/CCSpriteBatchNode.js index 2cf7e5791c..583b22933f 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNode.js +++ b/cocos2d/core/sprites/CCSpriteBatchNode.js @@ -42,15 +42,14 @@ * @extends cc.Node * * @param {String|cc.Texture2D} fileImage - * @param {Number} capacity * @example * * // 1. create a SpriteBatchNode with image path - * var spriteBatchNode = new cc.SpriteBatchNode("res/animations/grossini.png", 50); + * var spriteBatchNode = new cc.SpriteBatchNode("res/animations/grossini.png"); * * // 2. create a SpriteBatchNode with texture * var texture = cc.textureCache.addImage("res/animations/grossini.png"); - * var spriteBatchNode = new cc.SpriteBatchNode(texture,50); + * var spriteBatchNode = new cc.SpriteBatchNode(texture); * * @property {cc.TextureAtlas} textureAtlas - The texture atlas * @property {Array} descendants - <@readonly> Descendants of sprite batch node @@ -58,16 +57,14 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ _blendFunc: null, // all descendants: chlidren, gran children, etc... - _descendants: null, + _texture: null, _className: "SpriteBatchNode", - ctor: function (fileImage, capacity) { + ctor: function (fileImage) { cc.Node.prototype.ctor.call(this); - this._descendants = []; this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST); var texture2D; - capacity = capacity || cc.SpriteBatchNode.DEFAULT_CAPACITY; if (cc.isString(fileImage)) { texture2D = cc.textureCache.getTextureForKey(fileImage); if (!texture2D) @@ -75,72 +72,48 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ }else if (fileImage instanceof cc.Texture2D) texture2D = fileImage; - texture2D && this.initWithTexture(texture2D, capacity); + texture2D && this.initWithTexture(texture2D); }, /** *

- * This is the opposite of "addQuadFromSprite.
- * It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
+ * Same as addChild *

* @param {cc.Sprite} child * @param {Number} z zOrder * @param {Number} aTag * @return {cc.SpriteBatchNode} + * @deprecated since v3.12 */ addSpriteWithoutQuad: function (child, z, aTag) { - cc.assert(child, cc._LogInfos.SpriteBatchNode_addSpriteWithoutQuad_2); - - if (!(child instanceof cc.Sprite)) { - cc.log(cc._LogInfos.SpriteBatchNode_addSpriteWithoutQuad); - return null; - } - - // quad index is Z - child.atlasIndex = z; - - // XXX: optimize with a binary search - var i = 0, len, locDescendants = this._descendants; - if (locDescendants && locDescendants.length > 0) { - for (i = 0, len = locDescendants.length; i < len; i++) { - var obj = locDescendants[i]; - if (obj && (obj.atlasIndex >= z)) - break; - } - } - locDescendants.splice(i, 0, child); - - // IMPORTANT: Call super, and not self. Avoid adding it to the texture atlas array - cc.Node.prototype.addChild.call(this, child, z, aTag); - - //#issue 1262 don't use lazy sorting, tiles are added as quads not as sprites, so sprites need to be added in order - this.reorderBatch(false); + this.addChild(child, z, aTag); return this; }, // property /** - * Return TextureAtlas of cc.SpriteBatchNode + * Return null, no texture atlas is used any more * @return {cc.TextureAtlas} + * @deprecated since v3.12 */ getTextureAtlas: function () { - return this._renderCmd.getTextureAtlas(); + return null; }, /** * TextureAtlas of cc.SpriteBatchNode setter * @param {cc.TextureAtlas} textureAtlas + * @deprecated since v3.12 */ - setTextureAtlas: function (textureAtlas) { - this._renderCmd.getTextureAtlas(textureAtlas); - }, + setTextureAtlas: function (textureAtlas) {}, /** * Return Descendants of cc.SpriteBatchNode * @return {Array} + * @deprecated since v3.12 */ getDescendants: function () { - return this._descendants; + return this._children; }, /** @@ -161,11 +134,6 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ return this.initWithTexture(texture2D, capacity); }, - _setNodeDirtyForCache: function () { - if(this._renderCmd && this._renderCmd._setNodeDirtyForCache) - this._renderCmd._setNodeDirtyForCache(); - }, - /** *

* initializes a cc.SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
@@ -185,11 +153,10 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ }, /** - * Increase Atlas Capacity + * Do nothing + * @deprecated since v3.12 */ - increaseAtlasCapacity: function () { - this._renderCmd.increaseAtlasCapacity(); - }, + increaseAtlasCapacity: function () {}, /** * Removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter. @@ -202,32 +169,13 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ }, /** - * Rebuild index in order for child + * Do nothing * @param {cc.Sprite} pobParent * @param {Number} index * @return {Number} + * @deprecated since v3.12 */ rebuildIndexInOrder: function (pobParent, index) { - var children = pobParent.children; - if (children && children.length > 0) { - for (var i = 0; i < children.length; i++) { - var obj = children[i]; - if (obj && (obj.zIndex < 0)) - index = this.rebuildIndexInOrder(obj, index); - } - } - // ignore self (batch node) - if (!pobParent === this) { - pobParent.atlasIndex = index; - index++; - } - if (children && children.length > 0) { - for (i = 0; i < children.length; i++) { - obj = children[i]; - if (obj && (obj.zIndex >= 0)) - index = this.rebuildIndexInOrder(obj, index); - } - } return index; }, @@ -235,12 +183,12 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * Returns highest atlas index in child * @param {cc.Sprite} sprite * @return {Number} + * @deprecated since v3.12 */ highestAtlasIndexInChild: function (sprite) { var children = sprite.children; - if (!children || children.length === 0) - return sprite.atlasIndex; + return sprite.zIndex; else return this.highestAtlasIndexInChild(children[children.length - 1]); }, @@ -249,60 +197,30 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * Returns lowest atlas index in child * @param {cc.Sprite} sprite * @return {Number} + * @deprecated since v3.12 */ lowestAtlasIndexInChild: function (sprite) { var children = sprite.children; if (!children || children.length === 0) - return sprite.atlasIndex; + return sprite.zIndex; else return this.lowestAtlasIndexInChild(children[children.length - 1]); }, /** - * Returns atlas index for child + * Returns index for child * @param {cc.Sprite} sprite - * @param {Number} nZ * @return {Number} + * @deprecated since v3.12 */ - atlasIndexForChild: function (sprite, nZ) { - var selParent = sprite.parent; - var brothers = selParent.children; - var childIndex = brothers.indexOf(sprite); - - // ignore parent Z if parent is spriteSheet - var ignoreParent = selParent === this; - var previous = null; - if (childIndex > 0 && childIndex < cc.UINT_MAX) - previous = brothers[childIndex - 1]; - - // first child of the sprite sheet - if (ignoreParent) { - if (childIndex === 0) - return 0; - return this.highestAtlasIndexInChild(previous) + 1; - } - - // parent is a cc.Sprite, so, it must be taken into account - // first child of an cc.Sprite ? - if (childIndex === 0) { - // less than parent and brothers - if (nZ < 0) - return selParent.atlasIndex; - else - return selParent.atlasIndex + 1; - } else { - // previous & sprite belong to the same branch - if ((previous.zIndex < 0 && nZ < 0) || (previous.zIndex >= 0 && nZ >= 0)) - return this.highestAtlasIndexInChild(previous) + 1; - - // else (previous < 0 and sprite >= 0 ) - return selParent.atlasIndex + 1; - } + atlasIndexForChild: function (sprite) { + return sprite.zIndex; }, /** * Sprites use this to start sortChildren, don't call this manually * @param {Boolean} reorder + * @deprecated since v3.12 */ reorderBatch: function (reorder) { this._reorderChildDirty = reorder; @@ -328,45 +246,6 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ return new cc.BlendFunc(this._blendFunc.src,this._blendFunc.dst); }, - /** - * Reorder children (override reorderChild of cc.Node) - * @override - * @param {cc.Sprite} child - * @param {Number} zOrder - */ - reorderChild: function (child, zOrder) { - cc.assert(child, cc._LogInfos.SpriteBatchNode_reorderChild_2); - if (this._children.indexOf(child) === -1) { - cc.log(cc._LogInfos.SpriteBatchNode_reorderChild); - return; - } - if (zOrder === child.zIndex) - return; - - //set the z-order and sort later - cc.Node.prototype.reorderChild.call(this, child, zOrder); - //this.setNodeDirty(); - }, - - /** - * Removes a child from cc.SpriteBatchNode (override removeChild of cc.Node) - * @param {cc.Sprite} child - * @param {Boolean} cleanup - */ - removeChild: function (child, cleanup) { - // explicit null handling - if (child == null) - return; - if (this._children.indexOf(child) === -1) { - cc.log(cc._LogInfos.SpriteBatchNode_removeChild); - return; - } - - // cleanup before removing - this.removeSpriteFromAtlas(child); - cc.Node.prototype.removeChild.call(this, child, cleanup); - }, - /** *

* Updates a quad at a certain index into the texture atlas. The CCSprite won't be added into the children array.
@@ -383,155 +262,71 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ cc.log(cc._LogInfos.CCSpriteBatchNode_updateQuadFromSprite); return; } - this._renderCmd.checkAtlasCapacity(); // // update the quad directly. Don't add the sprite to the scene graph // - sprite.batchNode = this; - sprite.atlasIndex = index; sprite.dirty = true; // UpdateTransform updates the textureAtlas quad - sprite.updateTransform(); + sprite._renderCmd.transform(this._renderCmd, true); }, /** *

- * Inserts a quad at a certain index into the texture atlas. The cc.Sprite won't be added into the children array.
- * This method should be called only when you are dealing with very big AtlasSprite and when most of the cc.Sprite won't be updated.
- * For example: a tile map (cc.TMXMap) or a label with lots of characters (cc.LabelBMFont) + * Same as addChild(sprite, index) *

* @function * @param {cc.Sprite} sprite * @param {Number} index + * @deprecated since v3.12 */ insertQuadFromSprite: function (sprite, index) { - cc.assert(sprite, cc._LogInfos.CCSpriteBatchNode_insertQuadFromSprite_2); - if (!(sprite instanceof cc.Sprite)) { - cc.log(cc._LogInfos.CCSpriteBatchNode_insertQuadFromSprite); - return; - } - this._renderCmd.insertQuad(sprite, index); - - // - // update the quad directly. Don't add the sprite to the scene graph - // - sprite.batchNode = this; - sprite.atlasIndex = index; - - // XXX: updateTransform will update the textureAtlas too, using updateQuad. - // XXX: so, it should be AFTER the insertQuad - sprite.dirty = true; - sprite.updateTransform(); - this._renderCmd.cutting(sprite, index); + this.addChild(sprite, index); }, /** - *

- * Initializes a cc.SpriteBatchNode with a texture2d and capacity of children.
- * The capacity will be increased in 33% in runtime if it run out of space.
- * Please pass parameters to constructor to initialize the sprite batch node, do not call this function yourself. - *

- * @function - * @param {cc.Texture2D} tex - * @param {Number} [capacity] - * @return {Boolean} - */ - initWithTexture: function (tex, capacity) { - this._children.length = 0; - this._descendants.length = 0; - - capacity = capacity || cc.SpriteBatchNode.DEFAULT_CAPACITY; - this._renderCmd.initWithTexture(tex, capacity); - return true; - }, - - /** - * Insert a child + * Same as addChild(sprite, index) * @param {cc.Sprite} sprite The child sprite * @param {Number} index The insert index + * @deprecated since v3.12 */ insertChild: function (sprite, index) { - //TODO WebGL only ? - sprite.batchNode = this; - sprite.atlasIndex = index; - sprite.dirty = true; - - this._renderCmd.insertQuad(sprite, index); - this._descendants.splice(index, 0, sprite); - - // update indices - var i = index + 1, locDescendant = this._descendants; - if (locDescendant && locDescendant.length > 0) { - for (; i < locDescendant.length; i++) - locDescendant[i].atlasIndex++; - } - - // add children recursively - var locChildren = sprite.children, child, l; - if (locChildren) { - for (i = 0, l = locChildren.length || 0; i < l; i++) { - child = locChildren[i]; - if (child) { - var getIndex = this.atlasIndexForChild(child, child.zIndex); - this.insertChild(child, getIndex); - } - } - } + this.addChild(sprite, index); }, /** - * Add child at the end, faster than insert child + * Add child at the end * @function * @param {cc.Sprite} sprite */ appendChild: function (sprite) { - this._reorderChildDirty = true; - sprite.batchNode = this; - sprite.dirty = true; - - this._descendants.push(sprite); - var index = this._descendants.length - 1; - - sprite.atlasIndex = index; - this._renderCmd.insertQuad(sprite, index); - - // add children recursively - var children = sprite.children; - for (var i = 0, l = children.length || 0; i < l; i++) - this.appendChild(children[i]); + this.sortAllChildren(); + var lastLocalZOrder = this._children[this._children.length-1]._localZOrder; + this.addChild(sprite. lastLocalZOrder + 1); }, /** - * Removes sprite from TextureAtlas + * Same as removeChild * @function * @param {cc.Sprite} sprite + * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise. + * @deprecated since v3.12 */ - removeSpriteFromAtlas: function (sprite) { - this._renderCmd.removeQuadAtIndex(sprite.atlasIndex); - - // Cleanup sprite. It might be reused (issue #569) - sprite.batchNode = null; - var locDescendants = this._descendants; - var index = locDescendants.indexOf(sprite); - if (index !== -1) { - locDescendants.splice(index, 1); - - // update all sprites beyond this one - var len = locDescendants.length; - for (; index < len; ++index) { - var s = locDescendants[index]; - s.atlasIndex--; - } - } + removeSpriteFromAtlas: function (sprite, cleanup) { + this.removeChild(sprite, cleanup); + }, - // remove children recursively - var children = sprite.children; - if (children) { - for (var i = 0, l = children.length || 0; i < l; i++) - children[i] && this.removeSpriteFromAtlas(children[i]); - } + /** + * Set the texture property + * @function + * @param {cc.Texture2D} tex + * @return {Boolean} + */ + initWithTexture: function (tex) { + this._texture = tex; + return true; }, + // CCTextureProtocol /** * Returns texture of the sprite batch node @@ -539,7 +334,7 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * @return {cc.Texture2D} */ getTexture: function () { - return this._renderCmd.getTexture(); + return this._texture; }, /** @@ -548,7 +343,8 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * @param {cc.Texture2D} texture */ setTexture: function(texture){ - this._renderCmd.setTexture(texture); + this._texture = texture; + // Set children texture and children texture rect ? }, /** @@ -560,77 +356,26 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * @param {Number} [tag] */ addChild: function (child, zOrder, tag) { - cc.assert(child != null, cc._LogInfos.CCSpriteBatchNode_addChild_3); + cc.assert(child !== undefined, cc._LogInfos.CCSpriteBatchNode_addChild_3); - if(!this._renderCmd.isValidChild(child)) + if(!this._isValidChild(child)) return; - zOrder = (zOrder == null) ? child.zIndex : zOrder; - tag = (tag == null) ? child.tag : tag; + zOrder = (zOrder === undefined) ? child.zIndex : zOrder; + tag = (tag === undefined) ? child.tag : tag; cc.Node.prototype.addChild.call(this, child, zOrder, tag); - this.appendChild(child); - //this.setNodeDirty(); }, - /** - * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
- * (override removeAllChildren of cc.Node) - * @function - * @param {Boolean} [cleanup=true] - */ - removeAllChildren: function (cleanup) { - // Invalidate atlas index. issue #569 - // useSelfRender should be performed on all descendants. issue #1216 - var locDescendants = this._descendants; - if (locDescendants && locDescendants.length > 0) { - for (var i = 0, len = locDescendants.length; i < len; i++) { - if (locDescendants[i]) - locDescendants[i].batchNode = null; - } + _isValidChild: function (child) { + if (!(child instanceof cc.Sprite)) { + cc.log(cc._LogInfos.Sprite_addChild_4); + return false; } - cc.Node.prototype.removeAllChildren.call(this, cleanup); - this._descendants.length = 0; - this._renderCmd.removeAllQuads(); - }, - - /** - * Sort all children nodes (override draw of cc.Node) - */ - sortAllChildren: function () { - if (this._reorderChildDirty) { - var childrenArr = this._children; - var i, j = 0, length = childrenArr.length, tempChild; - //insertion sort - for (i = 1; i < length; i++) { - var tempItem = childrenArr[i]; - j = i - 1; - tempChild = childrenArr[j]; - - //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller - while (j >= 0 && ( tempItem._localZOrder < tempChild._localZOrder || - ( tempItem._localZOrder === tempChild._localZOrder && tempItem.arrivalOrder < tempChild.arrivalOrder ))) { - childrenArr[j + 1] = tempChild; - j = j - 1; - tempChild = childrenArr[j]; - } - childrenArr[j + 1] = tempItem; - } - - //sorted now check all children - if (childrenArr.length > 0) { - //first sort all children recursively based on zOrder - this._arrayMakeObjectsPerformSelector(childrenArr, cc.Node._stateCallbackType.sortAllChildren); - this._renderCmd.updateChildrenAtlasIndex(childrenArr); - } - this._reorderChildDirty = false; + if (child.texture !== this._texture) { + cc.log(cc._LogInfos.Sprite_addChild_5); + return false; } - }, - - _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.SpriteBatchNode.CanvasRenderCmd(this); - else - return new cc.SpriteBatchNode.WebGLRenderCmd(this); + return true; } }); @@ -638,20 +383,8 @@ var _p = cc.SpriteBatchNode.prototype; // Override properties cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture); -cc.defineGetterSetter(_p, "textureAtlas", _p.getTextureAtlas, _p.setTextureAtlas); - -// Extended properties -/** @expose */ -_p.descendants; -cc.defineGetterSetter(_p, "descendants", _p.getDescendants); -/** - * @constant - * @type Number - */ -cc.SpriteBatchNode.DEFAULT_CAPACITY = 29; - /** *

* creates a cc.SpriteBatchNodeCanvas with a file image (.png, .jpg etc) with a default capacity of 29 children.
@@ -661,11 +394,10 @@ cc.SpriteBatchNode.DEFAULT_CAPACITY = 29; * @deprecated since v3.0, please use new construction instead * @see cc.SpriteBatchNode * @param {String|cc.Texture2D} fileImage - * @param {Number} capacity * @return {cc.SpriteBatchNode} */ -cc.SpriteBatchNode.create = function (fileImage, capacity) { - return new cc.SpriteBatchNode(fileImage, capacity); +cc.SpriteBatchNode.create = function (fileImage) { + return new cc.SpriteBatchNode(fileImage); }; /** diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js deleted file mode 100644 index facfbb0277..0000000000 --- a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - //SpriteBatchNode's canvas render command - cc.SpriteBatchNode.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - - this._texture = null; - this._textureToRender = null; - }; - - var proto = cc.SpriteBatchNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.SpriteBatchNode.CanvasRenderCmd; - - proto.checkAtlasCapacity = function(){}; - - proto.isValidChild = function(child){ - if (!(child instanceof cc.Sprite)) { - cc.log(cc._LogInfos.Sprite_addChild_4); - return false; - } - return true; - }; - - proto.initWithTexture = function(texture, capacity){ - this._textureToRender = this._texture = texture; - }; - - proto.insertQuad = function(sprite, index){}; - - proto.increaseAtlasCapacity = function(){}; - - proto.removeQuadAtIndex = function(){}; - - proto.removeAllQuads = function(){}; - - proto.getTexture = function(){ - return this._texture; - }; - - proto.setTexture = function(texture){ - this._texture = texture; - var locChildren = this._node._children; - for (var i = 0; i < locChildren.length; i++) - locChildren[i].setTexture(texture); - }; - - proto.updateChildrenAtlasIndex = function(children){ - this._node._descendants.length = 0; - //update _descendants after sortAllChildren - for (var i = 0, len = children.length; i < len; i++) - this._updateAtlasIndex(children[i]); - }; - - proto._updateAtlasIndex = function (sprite) { - var locDescendants = this._node._descendants; - var pArray = sprite.children, i, len = pArray.length; - for (i = 0; i < len; i++) { - if (pArray[i]._localZOrder < 0) { - locDescendants.push(pArray[i]); - } else - break - } - locDescendants.push(sprite); - for (; i < len; i++) { - locDescendants.push(pArray[i]); - } - }; - - proto.getTextureAtlas = function(){}; - - proto.setTextureAtlas = function(textureAtlas){}; - - proto.cutting = function(sprite, index){ - var node = this._node; - node._children.splice(index, 0, sprite); - } -})(); \ No newline at end of file diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js deleted file mode 100644 index d61973d7e7..0000000000 --- a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - //SpriteBatchNode's WebGL render command - cc.SpriteBatchNode.WebGLRenderCmd = function(renderable){ - cc.Node.WebGLRenderCmd.call(this, renderable); - this._needDraw = true; - - this._textureAtlas = null; - }; - - var proto = cc.SpriteBatchNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); - proto.constructor = cc.SpriteBatchNode.WebGLRenderCmd; - - proto.isValidChild = function(child){ - if (!(child instanceof cc.Sprite)) { - cc.log(cc._LogInfos.Sprite_addChild_4); - return false; - } - if (child.texture != this.getTexture()) { - cc.log(cc._LogInfos.Sprite_addChild_5); - return false; - } - return true; - }; - - proto.rendering = function () { - var node = this._node; - if (this._textureAtlas.totalQuads === 0) - return; - - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); - node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform); - cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - - this._textureAtlas.drawQuads(); - }; - - proto.visit = function(parentCmd){ - var node = this._node; - // quick return if not visible - if (!node._visible) - return; - - if (node._parent && node._parent._renderCmd) - this._curLevel = node._parent._renderCmd._curLevel + 1; - - var currentStack = cc.current_stack; - - //optimize performance for javascript - currentStack.stack.push(currentStack.top); - - if(!(this._dirtyFlag & cc.Node._dirtyFlags.transformDirty)) //batchNode's transform must update in visit - this.transform(parentCmd); - this.updateStatus(parentCmd); //because batchNode doesn't visit its children. - currentStack.top = this._stackMatrix; - - node.sortAllChildren(); - - cc.renderer.pushRenderCommand(this); - - this._dirtyFlag = 0; - //optimize performance for javascript - currentStack.top = currentStack.stack.pop(); - }; - - proto.checkAtlasCapacity = function(index){ - // make needed room - var locAtlas = this._textureAtlas; - while (index >= locAtlas.capacity || locAtlas.capacity === locAtlas.totalQuads) { - this.increaseAtlasCapacity(); - } - }; - - proto.increaseAtlasCapacity = function(){ - // if we're going beyond the current TextureAtlas's capacity, - // all the previously initialized sprites will need to redo their texture coords - // this is likely computationally expensive - var locCapacity = this._textureAtlas.capacity; - var quantity = Math.floor((locCapacity + 1) * 4 / 3); - - cc.log(cc._LogInfos.SpriteBatchNode_increaseAtlasCapacity, locCapacity, quantity); - - if (!this._textureAtlas.resizeCapacity(quantity)) { - // serious problems - cc.log(cc._LogInfos.SpriteBatchNode_increaseAtlasCapacity_2); - } - }; - - proto.initWithTexture = function(texture, capacity){ - this._textureAtlas = new cc.TextureAtlas(); - this._textureAtlas.initWithTexture(texture, capacity); - this._updateBlendFunc(); - this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR); - }; - - proto.insertQuad = function(sprite, index){ - var locTextureAtlas = this._textureAtlas; - if (locTextureAtlas.totalQuads >= locTextureAtlas.capacity) - this.increaseAtlasCapacity(); - locTextureAtlas.insertQuad(sprite.quad, index); - }; - - proto.removeQuadAtIndex = function(index){ - this._textureAtlas.removeQuadAtIndex(index); // remove from TextureAtlas - }; - - proto.getTexture = function(){ - return this._textureAtlas.texture; - }; - - proto.setTexture = function(texture){ - this._textureAtlas.setTexture(texture); - if(texture) - this._updateBlendFunc(); - }; - - proto.removeAllQuads = function(){ - this._textureAtlas.removeAllQuads(); - }; - - proto._swap = function (oldIndex, newIndex) { - var locDescendants = this._node._descendants; - var locTextureAtlas = this._textureAtlas; - var quads = locTextureAtlas.quads; - var tempItem = locDescendants[oldIndex]; - var tempIteQuad = cc.V3F_C4B_T2F_QuadCopy(quads[oldIndex]); - - //update the index of other swapped item - locDescendants[newIndex].atlasIndex = oldIndex; - locDescendants[oldIndex] = locDescendants[newIndex]; - - locTextureAtlas.updateQuad(quads[newIndex], oldIndex); - locDescendants[newIndex] = tempItem; - locTextureAtlas.updateQuad(tempIteQuad, newIndex); - }; - - proto._updateAtlasIndex = function (sprite, curIndex) { - var count = 0; - var pArray = sprite.children; - if (pArray) - count = pArray.length; - - var oldIndex = 0; - if (count === 0) { - oldIndex = sprite.atlasIndex; - sprite.atlasIndex = curIndex; - sprite.arrivalOrder = 0; - if (oldIndex !== curIndex) - this._swap(oldIndex, curIndex); - curIndex++; - } else { - var needNewIndex = true; - if (pArray[0].zIndex >= 0) { - //all children are in front of the parent - oldIndex = sprite.atlasIndex; - sprite.atlasIndex = curIndex; - sprite.arrivalOrder = 0; - if (oldIndex !== curIndex) - this._swap(oldIndex, curIndex); - curIndex++; - needNewIndex = false; - } - for (var i = 0; i < pArray.length; i++) { - var child = pArray[i]; - if (needNewIndex && child.zIndex >= 0) { - oldIndex = sprite.atlasIndex; - sprite.atlasIndex = curIndex; - sprite.arrivalOrder = 0; - if (oldIndex !== curIndex) { - this._swap(oldIndex, curIndex); - } - curIndex++; - needNewIndex = false; - } - curIndex = this._updateAtlasIndex(child, curIndex); - } - - if (needNewIndex) { - //all children have a zOrder < 0) - oldIndex = sprite.atlasIndex; - sprite.atlasIndex = curIndex; - sprite.arrivalOrder = 0; - if (oldIndex !== curIndex) { - this._swap(oldIndex, curIndex); - } - curIndex++; - } - } - return curIndex; - }; - - proto.updateChildrenAtlasIndex = function(children){ - var index = 0; - //fast dispatch, give every child a new atlasIndex based on their relative zOrder (keep parent -> child relations intact) - // and at the same time reorder descedants and the quads to the right index - for (var i = 0; i < children.length; i++) - index = this._updateAtlasIndex(children[i], index); - }; - - proto._updateBlendFunc = function () { - if (!this._textureAtlas.texture.hasPremultipliedAlpha()) { - var blendFunc = this._node._blendFunc; - blendFunc.src = cc.SRC_ALPHA; - blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA; - } - }; - - proto.getTextureAtlas = function(){ - return this._textureAtlas; - }; - - proto.setTextureAtlas = function(textureAtlas){ - if (textureAtlas !== this._textureAtlas) { - this._textureAtlas = textureAtlas; - } - }; - - proto.cutting = function(){}; -})(); diff --git a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js index 572141bb16..2401418b58 100644 --- a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js @@ -44,12 +44,8 @@ var proto = cc.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); proto.constructor = cc.Sprite.CanvasRenderCmd; - proto._init = function () {}; - proto.setDirtyRecursively = function (value) {}; - proto._resetForBatchNode = function () {}; - proto._setTexture = function (texture) { var node = this._node; if (node._texture !== texture) { @@ -189,11 +185,6 @@ } }; - proto.getQuad = function () { - //throw an error. it doesn't support this function. - return null; - }; - proto._updateForSetSpriteFrame = function (pNewTexture, textureLoaded){ this._colorized = false; this._textureCoord.renderX = this._textureCoord.x; @@ -206,34 +197,6 @@ } }; - proto.updateTransform = function () { //TODO need delete, because Canvas needn't - var _t = this, node = this._node; - - // re-calculate matrix only if it is dirty - if (node.dirty) { - // If it is not visible, or one of its ancestors is not visible, then do nothing: - var locParent = node._parent; - if (!node._visible || ( locParent && locParent !== node._batchNode && locParent._shouldBeHidden)) { - node._shouldBeHidden = true; - } else { - node._shouldBeHidden = false; - - if (!locParent || locParent === node._batchNode) { - node._transformToBatch = _t.getNodeToParentTransform(); - } else { - //cc.assert(_t._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite"); - node._transformToBatch = cc.affineTransformConcat(_t.getNodeToParentTransform(), locParent._transformToBatch); - } - } - node._recursiveDirty = false; - node.dirty = false; - } - - // recursively iterate over children - if (node._hasChildren) - node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform); - }; - proto._spriteFrameLoadedCallback = function (spriteFrame) { var node = this; node.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize()); diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index 35fac68ccb..8e6f4d6977 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -25,47 +25,20 @@ //Sprite's WebGL render command (function() { - var _resetPointers = true; - cc.Sprite.WebGLRenderCmd = function (renderable) { cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; this._vertices = [ - {x: 0, y: 0, z: 0}, // tl - {x: 0, y: 0, z: 0}, // bl - {x: 0, y: 0, z: 0}, // tr - {x: 0, y: 0, z: 0} // br + {x: 0, y: 0, u: 0, v: 0}, // tl + {x: 0, y: 0, u: 0, v: 0}, // bl + {x: 0, y: 0, u: 0, v: 0}, // tr + {x: 0, y: 0, u: 0, v: 0} // br ]; - var length = this.vertexBytesPerUnit; - var bufInfo = cc.renderer.requestBuffer(length); - this._buffer = bufInfo.buffer; - this._bufferOffset = bufInfo.offset; - this._quad = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._buffer.data, this._bufferOffset); - this._float32View = new Float32Array(this._buffer.data, this._bufferOffset, length / 4); - this._uint32View = new Uint32Array(this._buffer.data, this._bufferOffset, length / 4); - - // Separated webgl buffer implementation - // this._buffer = new ArrayBuffer(length); - // this._bufferOffset = 0; - // this._quad = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._buffer, this._bufferOffset); - // this._float32View = new Float32Array(this._buffer, this._bufferOffset, length / 4); - // this._uint32View = new Uint32Array(this._buffer, this._bufferOffset, length / 4); - // // Init buffer - // var gl = cc._renderContext; - // this._glBuffer = gl.createBuffer(); - // gl.bindBuffer(gl.ARRAY_BUFFER, this._glBuffer); - // gl.bufferData(gl.ARRAY_BUFFER, length, gl.DYNAMIC_DRAW); - this._dirty = false; - this._bufferDirty = false; this._recursiveDirty = false; - this._vBuffer = null; - this._vertexOffset = 0; - if (!proto.batchShader) { - proto.batchShader = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST); - } + this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST); }; var proto = cc.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); @@ -78,47 +51,6 @@ proto.verticesPerUnit = 4; proto._supportBatch = true; - proto.batchShader = null; - - proto.getBatchInfo = function (info) { - info.texture = this._node._texture; - info.blendSrc = this._node._blendFunc.src; - info.blendDst = this._node._blendFunc.dst; - info.shader = this.batchShader; - }; - - proto._invalidBatch = function () { - if (this._vBuffer) { - this._vBuffer.valid = false; - } - }; - - proto.updateBuffer = function () { - if (!this._buffer) { - var length = this.vertexBytesPerUnit; - var bufInfo = cc.renderer.requestBuffer(length); - this._buffer = bufInfo.buffer; - this._bufferOffset = bufInfo.offset; - this._quad = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._buffer.data, this._bufferOffset); - this._float32View = new Float32Array(this._quad.arrayBuffer, this._bufferOffset, length / 4); - this._uint32View = new Uint32Array(this._quad.arrayBuffer, this._bufferOffset, length / 4); - - this._setTextureCoords(this._node._rect); - this._updateColor(); - this._updateVertexBuffer(); - } - }; - - proto.freeBuffer = function () { - if (this._buffer) { - this._buffer.freeBuffer(this._bufferOffset, this.vertexBytesPerUnit); - this._buffer = null; - this._bufferOffset = 0; - this._quad = null; - this._float32View = null; - } - }; - proto.updateBlendFunc = function (blendFunc) {}; proto.setDirtyFlag = function(dirtyFlag){ @@ -165,38 +97,6 @@ && cc.pointEqualToPoint(frame.getOffset(), node._unflippedOffsetPositionFromCenter)); }; - proto._init = function () { - this.updateBuffer(); - var tempColor = {r: 255, g: 255, b: 255, a: 255}, quad = this._quad; - quad.bl.colors = tempColor; - quad.br.colors = tempColor; - quad.tl.colors = tempColor; - quad.tr.colors = tempColor; - this._bufferDirty = true; - this._buffer.setDirty(); - }; - - proto._resetForBatchNode = function () { - var node = this._node; - var x1 = node._offsetPosition.x; - var y1 = node._offsetPosition.y; - var x2 = x1 + node._rect.width; - var y2 = y1 + node._rect.height; - var vertices = this._vertices; - vertices[0].x = x1; vertices[0].y = y2; // tl - vertices[1].x = x1; vertices[1].y = y1; // bl - vertices[2].x = x2; vertices[2].y = y2; // tr - vertices[3].x = x2; vertices[3].y = y1; // br - this._bufferDirty = true; - if (this._buffer) { - this._buffer.setDirty(); - } - }; - - proto.getQuad = function () { - return this._quad; - }; - proto._updateForSetSpriteFrame = function () {}; proto._spriteFrameLoadedCallback = function (spriteFrame) { @@ -225,6 +125,9 @@ // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render" this.setBatchNode(this._batchNode); this.dispatchEvent("load"); + + // Force refresh the render command list + cc.renderer.childrenOrderDirty = true; }; proto._setTextureCoords = function (rect, needConvert) { @@ -232,10 +135,11 @@ needConvert = true; if (needConvert) rect = cc.rectPointsToPixels(rect); - var node = this._node, locQuad = this._quad; + var node = this._node; var tex = node._batchNode ? node.textureAtlas.texture : node._texture; - if (!tex || !locQuad) + var uvs = this._vertices; + if (!tex) return; var atlasWidth = tex.pixelsWidth; @@ -267,14 +171,14 @@ right = tempSwap; } - locQuad.bl.texCoords.u = left; - locQuad.bl.texCoords.v = top; - locQuad.br.texCoords.u = left; - locQuad.br.texCoords.v = bottom; - locQuad.tl.texCoords.u = right; - locQuad.tl.texCoords.v = top; - locQuad.tr.texCoords.u = right; - locQuad.tr.texCoords.v = bottom; + uvs[0].u = right; // tl + uvs[0].v = top; // tl + uvs[1].u = left; // bl + uvs[1].v = top; // bl + uvs[2].u = right; // tr + uvs[2].v = bottom; // tr + uvs[3].u = left; // br + uvs[3].v = bottom; // br } else { if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { left = (2 * rect.x + 1) / (2 * atlasWidth); @@ -300,49 +204,17 @@ bottom = tempSwap; } - locQuad.bl.texCoords.u = left; - locQuad.bl.texCoords.v = bottom; - locQuad.br.texCoords.u = right; - locQuad.br.texCoords.v = bottom; - locQuad.tl.texCoords.u = left; - locQuad.tl.texCoords.v = top; - locQuad.tr.texCoords.u = right; - locQuad.tr.texCoords.v = top; - } - this._bufferDirty = true; - this._buffer.setDirty(); - }; - - proto._updateVertexBuffer = function () { - if (this._buffer) { - var mat = this._stackMatrix.mat, - vertices = this._vertices, - buffer = this._float32View, - i, x, y, offset = 0, - row = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT / 16; - - for (i = 0; i < 4; ++i) { - x = vertices[i].x; - y = vertices[i].y; - buffer[offset] = x * mat[0] + y * mat[4] + mat[12]; - buffer[offset+1] = x * mat[1] + y * mat[5] + mat[13]; - buffer[offset+2] = mat[14]; - offset += row; - } - - this._bufferDirty = true; - this._buffer.setDirty(); + uvs[0].u = left; // tl + uvs[0].v = top; // tl + uvs[1].u = left; // bl + uvs[1].v = bottom; // bl + uvs[2].u = right; // tr + uvs[2].v = top; // tr + uvs[3].u = right; // br + uvs[3].v = bottom; // br } }; - proto.transform = function (parentCmd, recursive) { - cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); - - this._updateVertexBuffer(); - this._dirty = true; //use for batching - this._savedDirtyFlag = true; - }; - proto._setColorDirty = function () {}; proto._updateColor = function () { @@ -354,26 +226,6 @@ color4.g *= locDisplayedOpacity / 255.0; color4.b *= locDisplayedOpacity / 255.0; } - var locQuad = this._quad; - if (locQuad) { - locQuad.bl.colors = color4; - locQuad.br.colors = color4; - locQuad.tl.colors = color4; - locQuad.tr.colors = color4; - this._buffer.setDirty(); - } - - // renders using Sprite Manager - if (node._batchNode) { - if (node.atlasIndex !== cc.Sprite.INDEX_NOT_INITIALIZED) { - node.textureAtlas.updateQuad(locQuad, node.atlasIndex); - } else { - // no need to set it recursively - // update dirty_, don't update recursiveDirty_ - this._dirty = true; - } - } - this._bufferDirty = true; }; proto._updateBlendFunc = function () { @@ -396,7 +248,6 @@ } node.opacityModifyRGB = true; } - this._invalidBatch(); }; proto._setTexture = function (texture) { @@ -413,102 +264,13 @@ node._texture = texture; // This will invalid current batch this._updateBlendFunc(); - } - } - - if (texture) - this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST); - else - this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_COLOR); - }; - - proto.updateTransform = function () { //called only at batching. - var _t = this, node = this._node; - - // recalculate matrix only if it is dirty - if (this._dirty) { - var locQuad = _t._quad, locParent = node._parent; - // If it is not visible, or one of its ancestors is not visible, then do nothing: - if (!node._visible || ( locParent && locParent !== node._batchNode && locParent._shouldBeHidden)) { - locQuad.br.vertices = locQuad.tl.vertices = locQuad.tr.vertices = locQuad.bl.vertices = {x: 0, y: 0, z: 0}; - node._shouldBeHidden = true; - } else { - node._shouldBeHidden = false; - if(this._dirtyFlag !== 0){ //because changing color and opacity uses dirty flag at visit, but visit doesn't call at batching. - this.updateStatus(); - this._dirtyFlag = 0; - } - - if (!locParent || locParent === node._batchNode) { - node._transformToBatch = _t.getNodeToParentTransform(); - } else { - node._transformToBatch = cc.affineTransformConcat(_t.getNodeToParentTransform(), locParent._transformToBatch); - } - // - // calculate the Quad based on the Affine Matrix - // - var locTransformToBatch = node._transformToBatch; - var rect = node._rect; - var x1 = node._offsetPosition.x; - var y1 = node._offsetPosition.y; - - var x2 = x1 + rect.width; - var y2 = y1 + rect.height; - var x = locTransformToBatch.tx; - var y = locTransformToBatch.ty; - - var cr = locTransformToBatch.a; - var sr = locTransformToBatch.b; - var cr2 = locTransformToBatch.d; - var sr2 = -locTransformToBatch.c; - var ax = x1 * cr - y1 * sr2 + x; - var ay = x1 * sr + y1 * cr2 + y; - - var bx = x2 * cr - y1 * sr2 + x; - var by = x2 * sr + y1 * cr2 + y; - - var cx = x2 * cr - y2 * sr2 + x; - var cy = x2 * sr + y2 * cr2 + y; - - var dx = x1 * cr - y2 * sr2 + x; - var dy = x1 * sr + y2 * cr2 + y; - - var locVertexZ = node._vertexZ; - if (!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { - ax = 0 | ax; - ay = 0 | ay; - bx = 0 | bx; - by = 0 | by; - cx = 0 | cx; - cy = 0 | cy; - dx = 0 | dx; - dy = 0 | dy; + if (node._textureLoaded) { + // Force refresh the render command list + cc.renderer.childrenOrderDirty = true; } - locQuad.bl.vertices = {x: ax, y: ay, z: locVertexZ}; - locQuad.br.vertices = {x: bx, y: by, z: locVertexZ}; - locQuad.tl.vertices = {x: dx, y: dy, z: locVertexZ}; - locQuad.tr.vertices = {x: cx, y: cy, z: locVertexZ}; } - node.textureAtlas.updateQuad(locQuad, node.atlasIndex); - node._recursiveDirty = false; - this._dirty = false; } - - // recursively iterate over children - if (node._hasChildren) - node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform); - - /*if (cc.SPRITE_DEBUG_DRAW) { //TODO - // draw bounding box - var vertices = [ - cc.p(_t._quad.bl.vertices.x, _t._quad.bl.vertices.y), - cc.p(_t._quad.br.vertices.x, _t._quad.br.vertices.y), - cc.p(_t._quad.tr.vertices.x, _t._quad.tr.vertices.y), - cc.p(_t._quad.tl.vertices.x, _t._quad.tl.vertices.y) - ]; - cc._drawingUtil.drawPoly(vertices, 4, true); - }*/ }; proto._checkTextureBoundary = function (texture, rect, rotated) { @@ -531,106 +293,45 @@ }; proto.needDraw = function () { - return (this._buffer && this._needDraw); + var node = this._node, locTexture = node._texture; + return (this._needDraw && locTexture); }; - proto.rendering = function (ctx) { + proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) { var node = this._node, locTexture = node._texture; - if (!this._buffer || (locTexture && (!locTexture._textureLoaded || !node._rect.width || !node._rect.height)) || !this._displayedOpacity) - return; + if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity) + return false; - var gl = ctx || cc._renderContext; - //cc.assert(!_t._batchNode, "If cc.Sprite is being rendered by cc.SpriteBatchNode, cc.Sprite#draw SHOULD NOT be called"); - - var program = this._shaderProgram; - if (locTexture) { - if (locTexture._textureLoaded) { - program.use(); - program._updateProjectionUniform(); - - cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - //optimize performance for javascript - cc.glBindTexture2DN(0, locTexture); - - var _bufferchanged = !gl.bindBuffer(gl.ARRAY_BUFFER, this._buffer.vertexBuffer); - // if (this._bufferDirty) { - // gl.bufferSubData(gl.ARRAY_BUFFER, this._bufferOffset, this._float32View); - // this._bufferDirty = false; - // } - if (_resetPointers || _bufferchanged) { - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); - _resetPointers = false; - } - gl.drawArrays(gl.TRIANGLE_STRIP, this._bufferOffset / (this.vertexBytesPerUnit/4), 4); - } - } else { - program.use(); - program._updateProjectionUniform(); - - cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._buffer.vertexBuffer); - // if (this._bufferDirty) { - // gl.bufferSubData(gl.ARRAY_BUFFER, this._bufferOffset, this._float32View); - // this._bufferDirty = false; - // } - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); - gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); - gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); - gl.drawArrays(gl.TRIANGLE_STRIP, this._bufferOffset / (this.vertexBytesPerUnit/4), 4); - _resetPointers = true; - } - cc.g_NumberOfDraws++; + var lx = node._offsetPosition.x, rx = lx + node._rect.width, + by = node._offsetPosition.y, ty = by + node._rect.height, + wt = this._worldTransform; - if (cc.SPRITE_DEBUG_DRAW === 0 && !node._showNode) - return; + offset = vertexDataOffset; - cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); - //cc.kmGLPushMatrixWitMat4(node._stackMatrix); - cc.current_stack.stack.push(cc.current_stack.top); - cc.current_stack.top = this._stackMatrix; - - if (cc.SPRITE_DEBUG_DRAW === 1 || node._showNode) { - // draw bounding box - var vertices = this._vertices; - var verticesG1 = [ - cc.p(vertices[0].x, vertices[0].y), - cc.p(vertices[2].x, vertices[2].y), - cc.p(vertices[3].x, vertices[3].y), - cc.p(vertices[1].x, vertices[1].y) - ]; - cc._drawingUtil.drawPoly(verticesG1, 4, true); - } else if (cc.SPRITE_DEBUG_DRAW === 2) { - // draw texture box - var drawRectG2 = node.getTextureRect(); - var offsetPixG2 = node.getOffsetPosition(); - var verticesG2 = [cc.p(offsetPixG2.x, offsetPixG2.y), cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y), - cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y + drawRectG2.height), cc.p(offsetPixG2.x, offsetPixG2.y + drawRectG2.height)]; - cc._drawingUtil.drawPoly(verticesG2, 4, true); - } // CC_SPRITE_DEBUG_DRAW - cc.current_stack.top = cc.current_stack.stack.pop(); - }; + f32buffer[offset] = lx * wt.a + ty * wt.c + wt.tx; // tl + f32buffer[offset + 1] = lx * wt.b + ty * wt.d + wt.ty; + f32buffer[offset + 6] = lx * wt.a + by * wt.c + wt.tx; // bl + f32buffer[offset + 7] = lx * wt.b + by * wt.d + wt.ty; + f32buffer[offset + 12] = rx * wt.a + ty * wt.c + wt.tx; // tr + f32buffer[offset + 13] = rx * wt.b + ty * wt.d + wt.ty; + f32buffer[offset + 18] = rx * wt.a + by * wt.c + wt.tx; // br + f32buffer[offset + 19] = rx * wt.b + by * wt.d + wt.ty; - proto.batchVertexBuffer = function (f32buffer, int32buffer, vertexDataOffset) { // Fill in vertex data with quad information (4 vertices for sprite) - var float32Data = this._float32View; - var uint32Data = this._uint32View; - var i, len = float32Data.length, colorId = 3; + var vertices = this._vertices; + var opacity = this._displayedOpacity; + var color = this._displayedColor, r, g, b; + var i, len = vertices.length, offset, vertex, colorView; for (i = 0; i < len; ++i) { - if (i === colorId) { - int32buffer[vertexDataOffset + i] = uint32Data[i]; - // 6 data per index - colorId += 6; - } - else { - f32buffer[vertexDataOffset + i] = float32Data[i]; - } + offset = vertexDataOffset + i * 6; + vertex = vertices[i]; + f32buffer[offset + 2] = node._vertexZ; + f32buffer[offset + 4] = vertex.u; + f32buffer[offset + 5] = vertex.v; + + ui32buffer[offset + 3] = ((color.r<<24) | (color.g<<16) | (color.b)<<8 | opacity); } + + return true; }; })(); \ No newline at end of file diff --git a/cocos2d/core/utils/CCProfiler.js b/cocos2d/core/utils/CCProfiler.js index e84c76dec1..60bfc59c58 100644 --- a/cocos2d/core/utils/CCProfiler.js +++ b/cocos2d/core/utils/CCProfiler.js @@ -1,5 +1,6 @@ cc.profiler = (function () { - var _inited = false, _showFPS = false; + var _showFPS = false; + window._inited = false; var _frames = 0, _frameRate = 0, _lastSPF = 0, _accumDt = 0; var _afterVisitListener = null, _FPSLabel = document.createElement('div'), diff --git a/cocos2d/labels/CCLabelBMFont.js b/cocos2d/labels/CCLabelBMFont.js index 474eb0067a..7f19b6789c 100644 --- a/cocos2d/labels/CCLabelBMFont.js +++ b/cocos2d/labels/CCLabelBMFont.js @@ -108,8 +108,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ _lineBreakWithoutSpaces: false, _imageOffset: null, - _reusedChar: null, - _textureLoaded: false, _className: "LabelBMFont", @@ -153,7 +151,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ ctor: function (str, fntFile, width, alignment, imageOffset) { cc.SpriteBatchNode.prototype.ctor.call(this); this._imageOffset = cc.p(0, 0); - this._reusedChar = []; this._cascadeColorEnabled = true; this._cascadeOpacityEnabled = true; this.initWithString(str, fntFile, width, alignment, imageOffset); @@ -224,7 +221,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ */ initWithString: function (str, fntFile, width, alignment, imageOffset) { var self = this, theString = str || ""; - var cmd = this._renderCmd; if (self._config) cc.log("cc.LabelBMFont.initWithString(): re-init is no longer supported"); @@ -262,7 +258,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ if (self.initWithTexture(texture, theString.length)) { self._alignment = alignment || cc.TEXT_ALIGNMENT_LEFT; self._imageOffset = imageOffset || cc.p(0, 0); - self._width = (width == null) ? -1 : width; + self._width = (width === undefined) ? -1 : width; self._realOpacity = 255; self._realColor = cc.color(255, 255, 255, 255); @@ -272,8 +268,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ self.setAnchorPoint(0.5, 0.5); - this._renderCmd._initBatchTexture(); - self.setString(theString, true); return true; } @@ -286,7 +280,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ createFontChars: function () { var self = this; var cmd = this._renderCmd; - var locTexture = cmd._texture || self.textureAtlas.texture; + var locTexture = cmd._texture || this._texture; var nextFontPositionX = 0; @@ -312,6 +306,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var nextFontPositionY = -(locCommonH - locCommonH * quantityOfLines); var prev = -1; + var fontDef; for (i = 0; i < stringLen; i++) { var key = locStr.charCodeAt(i); if (key === 0) continue; @@ -324,7 +319,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ } var kerningAmount = locKerningDict[(prev << 16) | (key & 0xffff)] || 0; - var fontDef = locFontDict[key]; + fontDef = locFontDict[key]; if (!fontDef) { cc.log("cocos2d: LabelBMFont: character not found " + locStr[i]); @@ -348,18 +343,18 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var fontChar = self.getChildByTag(i); - if(!fontChar){ + if (!fontChar) { fontChar = new cc.Sprite(); fontChar.initWithTexture(locTexture, rect, false); fontChar._newTextureWhenChangeColor = true; this.addChild(fontChar, 0, i); - }else{ - this._renderCmd._updateCharTexture(fontChar, rect, key); + } else { + cmd._updateCharTexture(fontChar, rect, key); } // Apply label properties fontChar.opacityModifyRGB = this._opacityModifyRGB; - this._renderCmd._updateCharColorAndOpacity(fontChar); + cmd._updateCharColorAndOpacity(fontChar); var yOffset = locCfg.commonHeight - fontDef.yOffset; var fontPos = cc.p(nextFontPositionX + fontDef.xOffset + fontDef.rect.width * 0.5 + kerningAmount, diff --git a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js index 1d43842993..5f4800b67d 100644 --- a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js @@ -32,11 +32,11 @@ (function(){ cc.LabelBMFont.CanvasRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderableObject); + cc.Node.CanvasRenderCmd.call(this, renderableObject); this._needDraw = true; }; - var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype); + var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); proto.constructor = cc.LabelBMFont.CanvasRenderCmd; proto.rendering = function(){ @@ -70,27 +70,28 @@ var selChild = locChildren[i]; var cm = selChild._renderCmd; var childDColor = cm._displayedColor; - if (this._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r || + if (node._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r || childDColor.g !== locDisplayedColor.g || childDColor.b !== locDisplayedColor.b)) continue; selChild.texture = texture; } - this._texture = texture; + node._texture = texture; }; proto._changeTextureColor = function(){ var node = this._node; - var texture = this._textureToRender, + var texture = node._texture, contentSize = texture.getContentSize(); var oTexture = node._texture, oElement = oTexture.getHtmlElementObj(); var disColor = this._displayedColor; var textureRect = cc.rect(0, 0, oElement.width, oElement.height); - if(texture && contentSize.width > 0){ + if (texture && contentSize.width > 0) { if(!oElement) return; - this._textureToRender = oTexture._generateColorTexture(disColor.r, disColor.g, disColor.b, textureRect); + var textureToRender = oTexture._generateColorTexture(disColor.r, disColor.g, disColor.b, textureRect); + node.setTexture(textureToRender); } }; @@ -102,6 +103,4 @@ cc.Node.prototype.updateDisplayedColor.call(locChild, this._displayedColor); }; - proto._initBatchTexture = function(){}; - })(); \ No newline at end of file diff --git a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js index 69c126cf6d..955d681db0 100644 --- a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js @@ -32,13 +32,17 @@ (function(){ cc.LabelBMFont.WebGLRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.WebGLRenderCmd.call(this, renderableObject); + cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; }; - var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.SpriteBatchNode.WebGLRenderCmd.prototype); + var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.LabelBMFont.WebGLRenderCmd; + proto.setTexture = function (texture) { + this._node._texture = texture; + }; + proto._updateCharTexture = function(fontChar, rect, key){ // updating previous sprite fontChar.setTextureRect(rect, false); @@ -56,29 +60,5 @@ locChild.updateDisplayedColor(this._displayedColor); }; - proto._initBatchTexture = function(){ - var node = this._node; - var locTexture = node.textureAtlas.texture; - node._opacityModifyRGB = locTexture.hasPremultipliedAlpha(); - - var reusedChar = node._reusedChar = new cc.Sprite(); - reusedChar.initWithTexture(locTexture, cc.rect(0, 0, 0, 0), false); - reusedChar.batchNode = node; - }; - - proto.rendering = function(ctx){ - cc.SpriteBatchNode.WebGLRenderCmd.prototype.rendering.call(this, ctx); - - var node = this._node; - //LabelBMFont - Debug draw - if (cc.LABELBMFONT_DEBUG_DRAW) { - var size = node.getContentSize(); - var pos = cc.p(0 | ( -this._anchorPointInPoints.x), 0 | ( -this._anchorPointInPoints.y)); - var vertices = [cc.p(pos.x, pos.y), cc.p(pos.x + size.width, pos.y), cc.p(pos.x + size.width, pos.y + size.height), cc.p(pos.x, pos.y + size.height)]; - cc._drawingUtil.setDrawColor(0, 255, 0, 255); - cc._drawingUtil.drawPoly(vertices, 4, true); - } - }; - proto._updateCharColorAndOpacity = function(){}; })(); \ No newline at end of file diff --git a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js index 7e04f94bc0..69f4f12f5f 100644 --- a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js +++ b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js @@ -25,6 +25,8 @@ cc.MotionStreak.WebGLRenderCmd = function(renderableObject){ cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR); }; @@ -38,8 +40,17 @@ cc.MotionStreak.WebGLRenderCmd.prototype.rendering = function(ctx){ if (node.texture && node.texture.isLoaded()) { ctx = ctx || cc._renderContext; + + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); cc.glBindTexture2D(node.texture); diff --git a/cocos2d/parallax/CCParallaxNodeRenderCmd.js b/cocos2d/parallax/CCParallaxNodeRenderCmd.js index 8a248b737e..572c10e3e1 100644 --- a/cocos2d/parallax/CCParallaxNodeRenderCmd.js +++ b/cocos2d/parallax/CCParallaxNodeRenderCmd.js @@ -41,7 +41,7 @@ proto._syncStatus = function(parentCmd){ this._node._updateParallaxPosition(); cc.Node.CanvasRenderCmd.prototype._syncStatus.call(this, parentCmd); - } + }; })(); cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { @@ -64,6 +64,6 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { proto._syncStatus = function(parentCmd){ this._node._updateParallaxPosition(); cc.Node.WebGLRenderCmd.prototype._syncStatus.call(this, parentCmd); - } + }; }); diff --git a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js index 16da24b496..44cea2f052 100644 --- a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js +++ b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js @@ -29,6 +29,8 @@ cc.ParticleBatchNode.WebGLRenderCmd = function(renderable){ cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); }; var proto = cc.ParticleBatchNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); @@ -39,8 +41,16 @@ if (_t.textureAtlas.totalQuads === 0) return; + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); cc.glBlendFuncForParticle(_t._blendFunc.src, _t._blendFunc.dst); _t.textureAtlas.drawQuads(); }; @@ -61,14 +71,13 @@ if (!node._visible) return; - var currentStack = cc.current_stack; - currentStack.stack.push(currentStack.top); + parentCmd = parentCmd || this.getParentRenderCmd(); + if (parentCmd) + this._curLevel = parentCmd._curLevel + 1; this._syncStatus(parentCmd); - currentStack.top = this._stackMatrix; - //this.draw(ctx); + cc.renderer.pushRenderCommand(this); this._dirtyFlag = 0; - cc.kmGLPopMatrix(); }; })(); \ No newline at end of file diff --git a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js index 4a398fe70f..8e684256d3 100644 --- a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js +++ b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js @@ -30,6 +30,9 @@ cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); + this._buffersVBO = [0, 0]; this._quads = []; this._indices = []; @@ -186,8 +189,16 @@ var gl = ctx || cc._renderContext; + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); //; + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); //; cc.glBindTexture2D(node._texture); cc.glBlendFuncForParticle(node._blendFunc.src, node._blendFunc.dst); diff --git a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js index 339610ed36..dbe46428cd 100644 --- a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js @@ -79,14 +79,4 @@ return this._transform; }; - - proto.updateTransform = function(){ - var node = this._node; - var dirty = node.isDirty(); - if(dirty){ - var cmd = node._renderCmd; - cmd && cmd.setDirtyRecursively(true); - } - cc.Sprite.WebGLRenderCmd.prototype.updateTransform.call(this); - }; })(); \ No newline at end of file diff --git a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js index e9f65f4765..55c2457772 100644 --- a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js +++ b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js @@ -26,6 +26,8 @@ cc.DrawNode.WebGLRenderCmd = function (renderableObject) { cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); }; cc.DrawNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); @@ -34,9 +36,17 @@ cc.DrawNode.WebGLRenderCmd.prototype.rendering = function (ctx) { var node = this._node; if (node._buffer.length > 0) { + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); node._render(); } }; diff --git a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js index 79a1ff197d..6f7d6c7882 100644 --- a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js @@ -24,7 +24,7 @@ (function(){ cc.TMXLayer.CanvasRenderCmd = function(renderable){ - cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderable); + cc.Node.CanvasRenderCmd.call(this, renderable); this._needDraw = true; this._realWorldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0}; @@ -42,7 +42,7 @@ this._cacheDirty = false; }; - var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype); + var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); proto.constructor = cc.TMXLayer.CanvasRenderCmd; //set the cache dirty flag for canvas diff --git a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js index 8c1906f640..ebd532912a 100644 --- a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js @@ -24,25 +24,25 @@ (function(){ cc.TMXLayer.WebGLRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.WebGLRenderCmd.call(this, renderableObject); + cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; }; - var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.SpriteBatchNode.WebGLRenderCmd.prototype); + var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.TMXLayer.WebGLRenderCmd; proto._updateCacheContext = function(){}; proto.initImageSize = function(){ var node = this._node; - node.tileset.imageSize = this._textureAtlas.texture.getContentSizeInPixels(); + node.tileset.imageSize = node._texture.getContentSizeInPixels(); // By default all the tiles are aliased // pros: // - easier to render // cons: // - difficult to scale / rotate / etc. - this._textureAtlas.texture.setAliasTexParameters(); + node._texture.setAliasTexParameters(); }; proto._reusedTileWithRect = function(rect){ diff --git a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js index 864ef2ee82..0adec0ea1a 100644 --- a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js @@ -38,19 +38,14 @@ // quick return if not visible if (!node._visible) return; - var i, j, currentStack = cc.current_stack; + var i, j; - //optimize performance for javascript - currentStack.stack.push(currentStack.top); this._syncStatus(parentCmd); - currentStack.top = this._stackMatrix; var locGrid = node.grid; if (locGrid && locGrid._active) locGrid.beforeDraw(); - //node.transform(node._parent && node._parent._renderCmd); - var locChildren = node._children, locProtectedChildren = node._protectedChildren; var childLen = locChildren.length, pLen = locProtectedChildren.length; node.sortAllChildren(); @@ -90,66 +85,13 @@ locGrid.afterDraw(node); this._dirtyFlag = 0; - //optimize performance for javascript - currentStack.top = currentStack.stack.pop(); }; proto.transform = function(parentCmd, recursive){ - var node = this._node; - var t4x4 = this._transform4x4, stackMatrix = this._stackMatrix, - parentMatrix = parentCmd ? parentCmd._stackMatrix : cc.current_stack.top; - - // Convert 3x3 into 4x4 matrix - var trans = node.getNodeToParentTransform(); - - if(node._changePosition) - node._changePosition(); - - var t4x4Mat = t4x4.mat; - t4x4Mat[0] = trans.a; - t4x4Mat[4] = trans.c; - t4x4Mat[12] = trans.tx; - t4x4Mat[1] = trans.b; - t4x4Mat[5] = trans.d; - t4x4Mat[13] = trans.ty; - - //optimize performance for Javascript - cc.kmMat4Multiply(stackMatrix, parentMatrix, t4x4); - - // Update Z depth - t4x4Mat[14] = node._vertexZ; - - // XXX: Expensive calls. Camera should be integrated into the cached affine matrix - if (node._camera !== null && !(node.grid !== null && node.grid.isActive())) { - var apx = this._anchorPointInPoints.x, apy = this._anchorPointInPoints.y; - var translate = (apx !== 0.0 || apy !== 0.0); - if (translate){ - if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { - apx = 0 | apx; - apy = 0 | apy; - } - //cc.kmGLTranslatef(apx, apy, 0); - var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix - stackMatrix.multiply(translate); - - node._camera._locateForRenderer(stackMatrix); - - //cc.kmGLTranslatef(-apx, -apy, 0); - translation = cc.math.Matrix4.createByTranslation(-apx, -apy, 0, translation); - stackMatrix.multiply(translation); - t4x4.identity(); //reset t4x4; - } else { - node._camera._locateForRenderer(stackMatrix); - } - } + this.originTransform(parentCmd, recursive); - var i, len, locChildren = node._children; - if(recursive && locChildren && locChildren.length !== 0){ - for(i = 0, len = locChildren.length; i< len; i++){ - locChildren[i]._renderCmd.transform(this, recursive); - } - } - locChildren = node._protectedChildren; + var i, len, + locChildren = this._node._protectedChildren; if(recursive && locChildren && locChildren.length !== 0){ for(i = 0, len = locChildren.length; i< len; i++){ locChildren[i]._renderCmd.transform(this, recursive); diff --git a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js index a7b8b7a9fc..daccb03fad 100644 --- a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js @@ -77,7 +77,7 @@ proto.transform = function(parentCmd, recursive){ var node = this._node; parentCmd = parentCmd || this.getParentRenderCmd(); - cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.originTransform(parentCmd, recursive); if (node._positionsAreDirty) { node._updatePositions(); node._positionsAreDirty = false; diff --git a/moduleConfig.json b/moduleConfig.json index b0498b41be..6527ce8a27 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -6,7 +6,6 @@ "cocos2d/actions/CCAction.js", "cocos2d/actions/CCActionInterval.js", "cocos2d/actions/CCActionInstant.js", - "cocos2d/actions/CCActionCamera.js", "cocos2d/actions/CCActionEase.js", "cocos2d/actions/CCActionCatmullRom.js", "cocos2d/actions/CCActionTween.js" @@ -42,7 +41,6 @@ "core" : [ "cocos2d/core/event-manager/CCEventHelper.js", "CCDebugger.js", - "cocos2d/core/utils/CCSimplePool.js", "cocos2d/core/utils/BinaryLoader.js", "Base64Images.js", "cocos2d/core/platform/CCClass.js", @@ -74,7 +72,6 @@ "cocos2d/core/event-manager/CCEventManager.js", "cocos2d/core/event-manager/CCEventExtension.js", - "cocos2d/core/renderer/GlobalVertexBuffer.js", "cocos2d/core/renderer/RendererCanvas.js", "cocos2d/core/renderer/RendererWebGL.js", @@ -104,8 +101,6 @@ "cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js", "cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js", "cocos2d/core/sprites/CCSpriteBatchNode.js", - "cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js", - "cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js", "cocos2d/core/sprites/CCBakeSprite.js", "cocos2d/core/sprites/CCAnimation.js", "cocos2d/core/sprites/CCAnimationCache.js", @@ -117,7 +112,6 @@ "cocos2d/core/CCDirectorCanvas.js", "cocos2d/core/CCDirectorWebGL.js", - "cocos2d/core/CCCamera.js", "cocos2d/core/CCScheduler.js", "cocos2d/core/CCDrawingPrimitivesCanvas.js", "cocos2d/core/CCDrawingPrimitivesWebGL.js", From b57847383942948935385e08c15f25f7a18560be Mon Sep 17 00:00:00 2001 From: pandamicro Date: Sun, 12 Jun 2016 12:05:18 +0800 Subject: [PATCH 02/15] Improve transform calculation --- .../core/base-nodes/CCNodeCanvasRenderCmd.js | 203 +++++++++--------- 1 file changed, 99 insertions(+), 104 deletions(-) diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js index daa43d495e..376bf5d7d9 100644 --- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js @@ -120,9 +120,7 @@ cc.Node.RenderCmd.prototype = { }, transform: function (parentCmd, recursive) { - // transform for canvas var node = this._node, - dirty = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty, pt = parentCmd ? parentCmd._worldTransform : null, t = this._transform, wt = this._worldTransform; //get the world transform @@ -132,120 +130,117 @@ cc.Node.RenderCmd.prototype = { node._position.x = node._normalizedPosition.x * conSize.width; node._position.y = node._normalizedPosition.y * conSize.height; node._normalizedPositionDirty = false; - dirty = true; } - if (dirty) { - var hasRotation = this._rotationX || this._rotationY; - var hasSkew = node._skewX || node._skewY; - if (hasRotation || hasSkew) { - var sx = node._scaleX, sy = node._scaleY; - var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; - - // position - t.tx = node._position.x; - t.ty = node._position.y; - - // rotation - if (hasRotation) { - var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance - c = Math.sin(rotationRadiansX); - d = Math.cos(rotationRadiansX); - if (node._rotationY === node._rotationX) { - a = d; - b = -c; - } - else { - var rotationRadiansY = node._rotationY * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance - a = Math.cos(rotationRadiansY); - b = -Math.sin(rotationRadiansY); - } + var hasRotation = node._rotationX || node._rotationY; + var hasSkew = node._skewX || node._skewY; + if (hasRotation || hasSkew) { + var sx = node._scaleX, sy = node._scaleY; + var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; + + // position + t.tx = node._position.x; + t.ty = node._position.y; + + // rotation + if (hasRotation) { + var rotationRadiansX = node._rotationX * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance + c = Math.sin(rotationRadiansX); + d = Math.cos(rotationRadiansX); + if (node._rotationY === node._rotationX) { + a = d; + b = -c; } - - // scale - a *= sx; - b *= sx; - c *= sy; - d *= sy; - - // skew - if (hasSkew) { - // offset the anchorpoint - var skx = Math.tan(-node._skewX * Math.PI / 180); - var sky = Math.tan(-node._skewY * Math.PI / 180); - if (skx === Infinity) - skx = 99999999; - if (sky === Infinity) - sky = 99999999; - var xx = appY * skx; - var yy = appX * sky; - t.a = a - c * sky; - t.b = b - d * sky; - t.c = c - a * skx; - t.d = d - b * skx; - t.tx += a * xx + c * yy; - t.ty += b * xx + d * yy; + else { + var rotationRadiansY = node._rotationY * 0.017453292519943295; //0.017453292519943295 = (Math.PI / 180); for performance + a = Math.cos(rotationRadiansY); + b = -Math.sin(rotationRadiansY); } + } - // adjust anchorPoint - if (!node._ignoreAnchorPointForPosition && (appX || appY)) { - t.tx -= t.a * appX + t.c * appY; - t.ty -= t.b * appX + t.d * appY; - } + // scale + t.a = a *= sx; + t.b = b *= sx; + t.c = c *= sy; + t.d = d *= sy; + + // skew + if (hasSkew) { + // offset the anchorpoint + var skx = Math.tan(-node._skewX * Math.PI / 180); + var sky = Math.tan(-node._skewY * Math.PI / 180); + if (skx === Infinity) + skx = 99999999; + if (sky === Infinity) + sky = 99999999; + var xx = appY * skx; + var yy = appX * sky; + t.a = a - c * sky; + t.b = b - d * sky; + t.c = c - a * skx; + t.d = d - b * skx; + t.tx += a * xx + c * yy; + t.ty += b * xx + d * yy; + } - if (pt) { - // cc.AffineTransformConcat is incorrect at get world transform - wt.a = t.a * pt.a + t.b * pt.c; //a - wt.b = t.a * pt.b + t.b * pt.d; //b - wt.c = t.c * pt.a + t.d * pt.c; //c - wt.d = t.c * pt.b + t.d * pt.d; //d - wt.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; - wt.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; - } else { - wt.a = t.a; - wt.b = t.b; - wt.c = t.c; - wt.d = t.d; - wt.tx = t.tx; - wt.ty = t.ty; - } + // adjust anchorPoint + if (!node._ignoreAnchorPointForPosition && (appX || appY)) { + t.tx -= t.a * appX + t.c * appY; + t.ty -= t.b * appX + t.d * appY; } - else { - t.a = node._scaleX; - t.b = 0; - t.c = 0; - t.d = node._scaleY; - if (node._ignoreAnchorPointForPosition) { - t.tx = node._position.x; - t.ty = node._position.y; - } - else { - t.tx = node._position.x - this._anchorPointInPoints.x * t.a; - t.ty = node._position.y - this._anchorPointInPoints.y * t.d; - } - if (pt) { - wt.a = t.a * pt.a + t.b * pt.c; - wt.b = t.a * pt.b + t.b * pt.d; - wt.c = t.c * pt.a + t.d * pt.c; - wt.d = t.c * pt.b + t.d * pt.d; - wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx; - wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty; - } else { - wt.a = t.a; - wt.b = t.b; - wt.c = t.c; - wt.d = t.d; - wt.tx = t.tx; - wt.ty = t.ty; - } + if (pt) { + // cc.AffineTransformConcat is incorrect at get world transform + wt.a = t.a * pt.a + t.b * pt.c; //a + wt.b = t.a * pt.b + t.b * pt.d; //b + wt.c = t.c * pt.a + t.d * pt.c; //c + wt.d = t.c * pt.b + t.d * pt.d; //d + wt.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; + wt.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; + } else { + wt.a = t.a; + wt.b = t.b; + wt.c = t.c; + wt.d = t.d; + wt.tx = t.tx; + wt.ty = t.ty; + } + } + else { + t.a = node._scaleX; + t.b = 0; + t.c = 0; + t.d = node._scaleY; + if (node._ignoreAnchorPointForPosition) { + t.tx = node._position.x; + t.ty = node._position.y; + } + else { + t.tx = node._position.x - this._anchorPointInPoints.x * t.a; + t.ty = node._position.y - this._anchorPointInPoints.y * t.d; } - if (node._additionalTransformDirty) { - this._transform = cc.affineTransformConcat(t, node._additionalTransform); + if (pt) { + wt.a = t.a * pt.a + t.b * pt.c; + wt.b = t.a * pt.b + t.b * pt.d; + wt.c = t.c * pt.a + t.d * pt.c; + wt.d = t.c * pt.b + t.d * pt.d; + wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx; + wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty; + } else { + wt.a = t.a; + wt.b = t.b; + wt.c = t.c; + wt.d = t.d; + wt.tx = t.tx; + wt.ty = t.ty; } } + if (node._additionalTransformDirty) { + this._transform = cc.affineTransformConcat(t, node._additionalTransform); + } + if (recursive) { var locChildren = this._node._children; if (!locChildren || locChildren.length === 0) @@ -451,7 +446,7 @@ cc.Node.RenderCmd.prototype = { if (locFlag & flags.transformDirty) //update the transform - this.transform(parentCmd, true); + this.transform(parentCmd); if (locFlag & flags.orderDirty) this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag; From 06733488368e9614b7399a5ebec6c2f41af0380f Mon Sep 17 00:00:00 2001 From: pandamicro Date: Mon, 13 Jun 2016 10:40:46 +0800 Subject: [PATCH 03/15] Fix issues in draft implementation of new renderer --- .../base-nodes/CCAtlasNodeWebGLRenderCmd.js | 12 ++- .../core/labelttf/CCLabelTTFWebGLRenderCmd.js | 1 - cocos2d/core/renderer/RendererWebGL.js | 16 +++- cocos2d/core/sprites/CCSpriteBatchNode.js | 2 +- .../core/sprites/CCSpriteWebGLRenderCmd.js | 49 +++++------ cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js | 28 +++++-- cocos2d/labels/CCLabelBMFont.js | 17 ++-- .../labels/CCLabelBMFontCanvasRenderCmd.js | 5 -- cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js | 11 +-- .../CCProgressTimerCanvasRenderCmd.js | 12 ++- .../CCProgressTimerWebGLRenderCmd.js | 84 ++++++++++++------- cocos2d/transitions/CCTransition.js | 4 - cocos2d/transitions/CCTransitionProgress.js | 18 ++++ .../ccui/base-classes/UIScale9Sprite.js | 56 +++++++++---- 14 files changed, 199 insertions(+), 116 deletions(-) diff --git a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js index 53551bfb17..70f7aa0724 100644 --- a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js +++ b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js @@ -127,10 +127,14 @@ } }; - proto._updateColor = function(){ - var locDisplayedColor = this._displayedColor; - this._colorF32Array = new Float32Array([locDisplayedColor.r / 255.0, locDisplayedColor.g / 255.0, - locDisplayedColor.b / 255.0, this._displayedOpacity / 255.0]); + proto._updateColor = function () { + if (this._colorF32Array) { + var locDisplayedColor = this._displayedColor; + this._colorF32Array[0] = locDisplayedColor.r / 255.0; + this._colorF32Array[1] = locDisplayedColor.g / 255.0; + this._colorF32Array[2] = locDisplayedColor.b / 255.0; + this._colorF32Array[3] = this._displayedOpacity / 255.0; + } }; proto.getTexture = function(){ diff --git a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js index 0ade49ed2b..9cc24fd7d5 100644 --- a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js +++ b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js @@ -34,6 +34,5 @@ proto.constructor = cc.LabelTTF.WebGLRenderCmd; proto._updateColor = function () { this._updateTexture(); - cc.Sprite.WebGLRenderCmd.prototype._updateColor.call(this); }; })(); \ No newline at end of file diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 7eb4b6ca64..33b7df20ce 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -171,9 +171,21 @@ return { var ctx = cc._renderContext; // Reset buffer cache to avoid issue gl.bindBuffer(gl.ARRAY_BUFFER, null); - for (i = 0, len = locCmds.length; i < len; i++) { - locCmds[i].rendering(ctx); + for (i = 0, len = locCmds.length; i < len; ++i) { + cmd = locCmds[i]; + + if (cmd.uploadData) { + this._uploadBufferData(cmd); + } + else { + if (cmd._batchingSize > 0) { + this._batchRendering(); + } + cmd.rendering(ctx); + } } + this._batchRendering(); + _batchedInfo.texture = null; this._removeCache(renderTextureId); var locIDs = this._cacheInstanceIds; diff --git a/cocos2d/core/sprites/CCSpriteBatchNode.js b/cocos2d/core/sprites/CCSpriteBatchNode.js index 583b22933f..80d8d26e86 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNode.js +++ b/cocos2d/core/sprites/CCSpriteBatchNode.js @@ -323,7 +323,7 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ * @return {Boolean} */ initWithTexture: function (tex) { - this._texture = tex; + this.setTexture(tex); return true; }, diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index 8e6f4d6977..ae0f78d2ee 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -29,11 +29,11 @@ cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; - this._vertices = [ - {x: 0, y: 0, u: 0, v: 0}, // tl - {x: 0, y: 0, u: 0, v: 0}, // bl - {x: 0, y: 0, u: 0, v: 0}, // tr - {x: 0, y: 0, u: 0, v: 0} // br + this._uvs = [ + {u: 0, v: 0}, // tl + {u: 0, v: 0}, // bl + {u: 0, v: 0}, // tr + {u: 0, v: 0} // br ]; this._dirty = false; this._recursiveDirty = false; @@ -49,7 +49,6 @@ proto.bytesPerUnit = proto.vertexBytesPerUnit; proto.indicesPerUnit = 6; proto.verticesPerUnit = 4; - proto._supportBatch = true; proto.updateBlendFunc = function (blendFunc) {}; @@ -138,7 +137,7 @@ var node = this._node; var tex = node._batchNode ? node.textureAtlas.texture : node._texture; - var uvs = this._vertices; + var uvs = this._uvs; if (!tex) return; @@ -217,17 +216,6 @@ proto._setColorDirty = function () {}; - proto._updateColor = function () { - var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity, node = this._node; - var color4 = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: locDisplayedOpacity}; - // special opacity for premultiplied textures - if (node._opacityModifyRGB) { - color4.r *= locDisplayedOpacity / 255.0; - color4.g *= locDisplayedOpacity / 255.0; - color4.b *= locDisplayedOpacity / 255.0; - } - }; - proto._updateBlendFunc = function () { if (this._batchNode) { cc.log(cc._LogInfos.Sprite__updateBlendFunc); @@ -318,18 +306,27 @@ f32buffer[offset + 19] = rx * wt.b + by * wt.d + wt.ty; // Fill in vertex data with quad information (4 vertices for sprite) - var vertices = this._vertices; - var opacity = this._displayedOpacity; - var color = this._displayedColor, r, g, b; - var i, len = vertices.length, offset, vertex, colorView; + var uvs = this._uvs; + var opacity = Math.floor(this._displayedOpacity); + var r = this._displayedColor.r, + g = this._displayedColor.g, + b = this._displayedColor.b; + if (node._opacityModifyRGB) { + var a = opacity / 255; + r *= a; + g *= a; + b *= a; + } + + var i, len = uvs.length, offset, uv, colorView; for (i = 0; i < len; ++i) { offset = vertexDataOffset + i * 6; - vertex = vertices[i]; + uv = uvs[i]; f32buffer[offset + 2] = node._vertexZ; - f32buffer[offset + 4] = vertex.u; - f32buffer[offset + 5] = vertex.v; + f32buffer[offset + 4] = uv.u; + f32buffer[offset + 5] = uv.v; - ui32buffer[offset + 3] = ((color.r<<24) | (color.g<<16) | (color.b)<<8 | opacity); + ui32buffer[offset + 3] = ((opacity<<24) | (b<<16) | (g<<8) | r); } return true; diff --git a/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js b/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js index ca1eded21d..9a7484d1ba 100644 --- a/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js +++ b/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js @@ -31,6 +31,25 @@ var proto = cc.LabelAtlas.WebGLRenderCmd.prototype = Object.create(cc.AtlasNode.WebGLRenderCmd.prototype); proto.constructor = cc.LabelAtlas.WebGLRenderCmd; + proto._updateColor = function () { + if (this._colorF32Array) { + var locDisplayedColor = this._displayedColor; + var a = this._displayedOpacity / 255; + if (this._node._opacityModifyRGB) { + this._colorF32Array[0] = locDisplayedColor.r * a / 255; + this._colorF32Array[1] = locDisplayedColor.g * a / 255; + this._colorF32Array[2] = locDisplayedColor.b * a / 255; + this._colorF32Array[3] = a; + } + else { + this._colorF32Array[0] = locDisplayedColor.r / 255; + this._colorF32Array[1] = locDisplayedColor.g / 255; + this._colorF32Array[2] = locDisplayedColor.b / 255; + this._colorF32Array[3] = a; + } + } + }; + proto.setCascade = function(){ var node = this._node; node._cascadeOpacityEnabled = true; @@ -71,8 +90,6 @@ if (n > locTextureAtlas.getCapacity()) cc.log("cc.LabelAtlas._updateAtlasValues(): Invalid String length"); var quads = locTextureAtlas.quads; - var locDisplayedColor = this._displayedColor; - var curColor = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: node._displayedOpacity}; var locItemWidth = node._itemWidth; var locItemHeight = node._itemHeight; for (var i = 0, cr = -1; i < n; i++) { @@ -121,11 +138,10 @@ locQuadTR.vertices.x = cr * locItemWidth + locItemWidth; locQuadTR.vertices.y = node._itemHeight; locQuadTR.vertices.z = 0.0; - locQuadTL.colors = curColor; - locQuadTR.colors = curColor; - locQuadBL.colors = curColor; - locQuadBR.colors = curColor; } + + this._updateColor(); + this.updateContentSize(i, cr+1); if (n > 0) { locTextureAtlas.dirty = true; diff --git a/cocos2d/labels/CCLabelBMFont.js b/cocos2d/labels/CCLabelBMFont.js index 7f19b6789c..0dd628e128 100644 --- a/cocos2d/labels/CCLabelBMFont.js +++ b/cocos2d/labels/CCLabelBMFont.js @@ -29,11 +29,6 @@ http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java) http://www.angelcode.com/products/bmfont/ (Free, Windows only) ****************************************************************************/ -/** - * @constant - * @type Number - */ -cc.LABEL_AUTOMATIC_WIDTH = -1; /** *

cc.LabelBMFont is a subclass of cc.SpriteBatchNode.

@@ -718,12 +713,11 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var texture = cc.textureCache.addImage(newConf.atlasName); var locIsLoaded = texture.isLoaded(); self._textureLoaded = locIsLoaded; - self.texture = texture; if (!locIsLoaded) { texture.addEventListener("load", function (sender) { var self1 = this; self1._textureLoaded = true; - self1.texture = sender; + self1.setTexture(sender); self1.createFontChars(); self1._changeTextureColor(); self1.updateLabel(); @@ -731,6 +725,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ self1.dispatchEvent("load"); }, self); } else { + self.setTexture(texture); self.createFontChars(); } } @@ -745,6 +740,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ }, setTexture: function(texture){ + this._texture = texture; this._renderCmd.setTexture(texture); }, @@ -844,6 +840,9 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ /** @expose */ p.textAlign; cc.defineGetterSetter(p, "textAlign", p._getAlignment, p.setAlignment); + + // Override properties + cc.defineGetterSetter(p, "texture", p.getTexture, p.setTexture); })(); /** @@ -860,7 +859,7 @@ cc.LabelBMFont.create = function (str, fntFile, width, alignment, imageOffset) { return new cc.LabelBMFont(str, fntFile, width, alignment, imageOffset); }; -cc._fntLoader = { +var _fntLoader = { INFO_EXP: /info [^\n]*(\n|$)/gi, COMMON_EXP: /common [^\n]*(\n|$)/gi, PAGE_EXP: /page [^\n]*(\n|$)/gi, @@ -960,4 +959,4 @@ cc._fntLoader = { }); } }; -cc.loader.register(["fnt"], cc._fntLoader); +cc.loader.register(["fnt"], _fntLoader); diff --git a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js index 5f4800b67d..1f34cd6cb4 100644 --- a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js @@ -33,16 +33,11 @@ (function(){ cc.LabelBMFont.CanvasRenderCmd = function(renderableObject){ cc.Node.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; }; var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); proto.constructor = cc.LabelBMFont.CanvasRenderCmd; - proto.rendering = function(){ - void 0; - }; - proto._updateCharTexture = function(fontChar, rect, key){ if (key === 32) { fontChar.setTextureRect(rect, false, cc.size(0, 0)); diff --git a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js index 955d681db0..68d5c374a7 100644 --- a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js @@ -33,14 +33,13 @@ (function(){ cc.LabelBMFont.WebGLRenderCmd = function(renderableObject){ cc.Node.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; }; var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.LabelBMFont.WebGLRenderCmd; proto.setTexture = function (texture) { - this._node._texture = texture; + this._node.setOpacityModifyRGB(this._node._texture.hasPremultipliedAlpha()); }; proto._updateCharTexture = function(fontChar, rect, key){ @@ -52,13 +51,5 @@ proto._changeTextureColor = function(){}; - proto._updateChildrenDisplayedOpacity = function(locChild){ - locChild.updateDisplayedOpacity(this._displayedOpacity); - }; - - proto._updateChildrenDisplayedColor = function(locChild){ - locChild.updateDisplayedColor(this._displayedColor); - }; - proto._updateCharColorAndOpacity = function(){}; })(); \ No newline at end of file diff --git a/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js index 689cbf76fb..0df263bf28 100644 --- a/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js +++ b/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js @@ -192,8 +192,6 @@ } }; - proto._updateColor = function(){}; - proto._syncStatus = function (parentCmd) { var node = this._node; if(!node._sprite) @@ -220,15 +218,18 @@ if (colorDirty){ spriteCmd._syncDisplayColor(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag; } if (opacityDirty){ spriteCmd._syncDisplayOpacity(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag; } if(colorDirty || opacityDirty){ spriteCmd._updateColor(); - //this._updateColor(); } if (locFlag & flags.transformDirty) { @@ -254,15 +255,18 @@ if(colorDirty){ spriteCmd._updateDisplayColor(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag; } if(opacityDirty){ spriteCmd._updateDisplayOpacity(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag; } if(colorDirty || opacityDirty){ spriteCmd._updateColor(); - //this._updateColor(); } if(locFlag & flags.transformDirty){ diff --git a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js index e903e7f12b..03bee42d9c 100644 --- a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js +++ b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js @@ -33,6 +33,9 @@ this._needDraw = true; this._progressDirty = true; + this._bl = cc.p(); + this._tr = cc.p(); + this.initCmd(); }; @@ -41,7 +44,16 @@ proto.transform = function (parentCmd, recursive) { cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); - this._node._sprite._renderCmd.transform(this, recursive); + var sp = this._node._sprite; + sp._renderCmd.transform(this, recursive); + + var lx = sp._offsetPosition.x, rx = lx + sp._rect.width, + by = sp._offsetPosition.y, ty = by + sp._rect.height, + wt = this._worldTransform; + this._bl.x = lx * wt.a + by * wt.c + wt.tx; + this._bl.y = lx * wt.b + by * wt.d + wt.ty; + this._tr.x = rx * wt.a + ty * wt.c + wt.tx; + this._tr.y = rx * wt.b + ty * wt.d + wt.ty; }; proto.rendering = function (ctx) { @@ -104,19 +116,22 @@ var spriteCmd = node._sprite._renderCmd; var spriteFlag = spriteCmd._dirtyFlag; - var colorDirty = spriteFlag & flags.colorDirty, - opacityDirty = spriteFlag & flags.opacityDirty; + var colorDirty = (locFlag | spriteFlag) & flags.colorDirty, + opacityDirty = (locFlag | spriteFlag) & flags.opacityDirty; if (colorDirty){ spriteCmd._syncDisplayColor(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag; } if (opacityDirty){ spriteCmd._syncDisplayOpacity(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag; + this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag; } if(colorDirty || opacityDirty){ - spriteCmd._updateColor(); this._updateColor(); } @@ -141,21 +156,22 @@ var spriteCmd = node._sprite._renderCmd; var spriteFlag = spriteCmd._dirtyFlag; - var colorDirty = spriteFlag & flags.colorDirty, - opacityDirty = spriteFlag & flags.opacityDirty; + var colorDirty = (locFlag | spriteFlag) & flags.colorDirty, + opacityDirty = (locFlag | spriteFlag) & flags.opacityDirty; if(colorDirty){ spriteCmd._updateDisplayColor(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag; this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag; } if(opacityDirty){ spriteCmd._updateDisplayOpacity(); + spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag; this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag; } if(colorDirty || opacityDirty){ - spriteCmd._updateColor(); this._updateColor(); } @@ -470,44 +486,52 @@ coords.v = 0; return; } - var quad = locSprite.quad; - var min = cc.p(quad.bl.texCoords.u, quad.bl.texCoords.v); - var max = cc.p(quad.tr.texCoords.u, quad.tr.texCoords.v); + var uvs = locSprite._renderCmd._uvs, + bl = uvs[1], + tr = uvs[2]; + var min = cc.p(bl.u, bl.v); + var max = cc.p(tr.u, tr.v); // Fix bug #1303 so that progress timer handles sprite frame texture rotation if (locSprite.textureRectRotated) { - var temp = alpha.x; - alpha.x = alpha.y; - alpha.y = temp; + var temp = ax; + ax = ay; + ay = temp; } coords.u = min.x * (1 - ax) + max.x * ax; coords.v = min.y * (1 - ay) + max.y * ay; }; proto._vertexFromAlphaPoint = function (vertex, ax, ay) { - var spriteCmd = this._node._sprite._renderCmd; - if (!spriteCmd) { - vertex.x = 0; - vertex.y = 0; - return; - } - var quad = spriteCmd._quad; - var min = cc.p(quad.bl.vertices.x, quad.bl.vertices.y); - var max = cc.p(quad.tr.vertices.x, quad.tr.vertices.y); - vertex.x = min.x * (1 - ax) + max.x * ax; - vertex.y = min.y * (1 - ay) + max.y * ay; - vertex.z = quad.bl.vertices.z; + vertex.x = this._bl.x * (1 - ax) + this._tr.x * ax; + vertex.y = this._bl.y * (1 - ay) + this._tr.y * ay; + vertex.z = this._node._vertexZ; }; proto._updateColor = function(){ - var node = this._node; - if (!node._sprite || !this._vertexDataCount) + var sp = this._node._sprite; + if (!this._vertexDataCount || !sp) return; - var sc = node._sprite.quad.tl.colors; + var color = this._displayedColor; + var spColor = sp._renderCmd._displayedColor; + var r = spColor.r; + var g = spColor.g; + var b = spColor.b; + var a = sp._renderCmd._displayedOpacity / 255; + if (sp._opacityModifyRGB) { + r *= a; + g *= a; + b *= a; + } + color.r = r; + color.g = g; + color.b = b; + color.a = sp._renderCmd._displayedOpacity; var locVertexData = this._vertexData; - for (var i = 0, len = this._vertexDataCount; i < len; ++i) - locVertexData[i].colors = sc; + for (var i = 0, len = this._vertexDataCount; i < len; ++i) { + locVertexData[i].colors = color; + } this._vertexDataDirty = true; }; })(); \ No newline at end of file diff --git a/cocos2d/transitions/CCTransition.js b/cocos2d/transitions/CCTransition.js index 529c4dc146..bd10515f29 100644 --- a/cocos2d/transitions/CCTransition.js +++ b/cocos2d/transitions/CCTransition.js @@ -217,8 +217,6 @@ cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{ scale: 1.0, rotation: 0.0 }); - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) - this._inScene.getCamera().restore(); this._outScene.attr({ visible: false, @@ -227,8 +225,6 @@ cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{ scale: 1.0, rotation: 0.0 }); - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) - this._outScene.getCamera().restore(); //[self schedule:@selector(setNewScene:) interval:0]; this.schedule(this._setNewScene, 0); diff --git a/cocos2d/transitions/CCTransitionProgress.js b/cocos2d/transitions/CCTransitionProgress.js index c86dbe7e0b..38e67e2d5f 100644 --- a/cocos2d/transitions/CCTransitionProgress.js +++ b/cocos2d/transitions/CCTransitionProgress.js @@ -169,6 +169,9 @@ cc.TransitionProgressRadialCCW = cc.TransitionProgress.extend(/** @lends cc.Tran var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_RADIAL; // Return the radial type that we want to use @@ -217,6 +220,9 @@ cc.TransitionProgressRadialCW = cc.TransitionProgress.extend(/** @lends cc.Trans var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_RADIAL; // Return the radial type that we want to use @@ -267,6 +273,9 @@ cc.TransitionProgressHorizontal = cc.TransitionProgress.extend(/** @lends cc.Tra var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_BAR; pNode.midPoint = cc.p(1, 0); @@ -314,6 +323,9 @@ cc.TransitionProgressVertical = cc.TransitionProgress.extend(/** @lends cc.Trans var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_BAR; pNode.midPoint = cc.p(0, 0); @@ -357,6 +369,9 @@ cc.TransitionProgressInOut = cc.TransitionProgress.extend(/** @lends cc.Transiti _progressTimerNodeWithRenderTexture:function (texture) { var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_BAR; pNode.midPoint = cc.p(0.5, 0.5); @@ -409,6 +424,9 @@ cc.TransitionProgressOutIn = cc.TransitionProgress.extend(/** @lends cc.Transiti _progressTimerNodeWithRenderTexture:function (texture) { var size = cc.director.getWinSize(); var pNode = new cc.ProgressTimer(texture.sprite); + // but it is flipped upside down so we flip the sprite + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) + pNode.sprite.flippedY = true; pNode.type = cc.ProgressTimer.TYPE_BAR; pNode.midPoint = cc.p(0.5, 0.5); diff --git a/extensions/ccui/base-classes/UIScale9Sprite.js b/extensions/ccui/base-classes/UIScale9Sprite.js index 2a52aec982..dde829eb2e 100644 --- a/extensions/ccui/base-classes/UIScale9Sprite.js +++ b/extensions/ccui/base-classes/UIScale9Sprite.js @@ -488,12 +488,16 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit this._textureLoaded = locLoaded; if(!locLoaded){ texture.addEventListener("load", function(sender){ - // the texture is rotated on Canvas render mode, so isRotated always is false. - var preferredSize = this._preferredSize, restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; - if (restorePreferredSize) preferredSize = cc.size(preferredSize.width, preferredSize.height); + var preferredSize = this._preferredSize, + restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; + if (restorePreferredSize) { + preferredSize = cc.size(preferredSize.width, preferredSize.height); + } var size = sender.getContentSize(); this.updateWithBatchNode(this._scale9Image, cc.rect(0,0,size.width,size.height), false, this._capInsets); - if (restorePreferredSize)this.setPreferredSize(preferredSize); + if (restorePreferredSize) { + this.setPreferredSize(preferredSize); + } this._positionsAreDirty = true; this.setNodeDirty(); this.dispatchEvent("load"); @@ -522,11 +526,15 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit this._textureLoaded = locLoaded; if(!locLoaded){ spriteFrame.addEventListener("load", function(sender){ - // the texture is rotated on Canvas render mode, so isRotated always is false. - var preferredSize = this._preferredSize, restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; - if (restorePreferredSize) preferredSize = cc.size(preferredSize.width, preferredSize.height); + var preferredSize = this._preferredSize, + restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; + if (restorePreferredSize) { + preferredSize = cc.size(preferredSize.width, preferredSize.height); + } this.updateWithBatchNode(this._scale9Image, sender.getRect(), cc._renderType === cc.game.RENDER_TYPE_WEBGL && sender.isRotated(), this._capInsets); - if (restorePreferredSize)this.setPreferredSize(preferredSize); + if (restorePreferredSize) { + this.setPreferredSize(preferredSize); + } this._positionsAreDirty = true; this.setNodeDirty(); this.dispatchEvent("load"); @@ -857,8 +865,16 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit this._textureLoaded = locLoaded; if(!locLoaded){ tmpTexture.addEventListener("load", function(sender){ - this._positionsAreDirty = true; + var preferredSize = this._preferredSize, + restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; + if (restorePreferredSize) { + preferredSize = cc.size(preferredSize.width, preferredSize.height); + } this.updateWithSprite(sprite, spriteRect, spriteFrameRotated, offset, originalSize, capInsets); + if (restorePreferredSize) { + this.setPreferredSize(preferredSize); + } + this._positionsAreDirty = true; this.setVisible(true); this.setNodeDirty(); this.dispatchEvent("load"); @@ -914,8 +930,16 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit this._textureLoaded = locLoaded; if(!locLoaded){ tmpTexture.addEventListener("load", function(sender){ - this._positionsAreDirty = true; + var preferredSize = this._preferredSize, + restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; + if (restorePreferredSize) { + preferredSize = cc.size(preferredSize.width, preferredSize.height); + } this.updateWithBatchNode(batchNode, originalRect, rotated, capInsets); + if (restorePreferredSize) { + this.setPreferredSize(preferredSize); + } + this._positionsAreDirty = true; this.setVisible(true); this.setNodeDirty(); this.dispatchEvent("load"); @@ -940,11 +964,15 @@ ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprit this._textureLoaded = locLoaded; if(!locLoaded){ spriteFrame.addEventListener("load", function(sender){ - // the texture is rotated on Canvas render mode, so isRotated always is false. - var preferredSize = this._preferredSize, restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; - if (restorePreferredSize) preferredSize = cc.size(preferredSize.width, preferredSize.height); + var preferredSize = this._preferredSize, + restorePreferredSize = preferredSize.width !== 0 && preferredSize.height !== 0; + if (restorePreferredSize) { + preferredSize = cc.size(preferredSize.width, preferredSize.height); + } this.updateWithBatchNode(this._scale9Image, sender.getRect(), cc._renderType === cc.game.RENDER_TYPE_WEBGL && sender.isRotated(), this._capInsets); - if (restorePreferredSize)this.setPreferredSize(preferredSize); + if (restorePreferredSize) { + this.setPreferredSize(preferredSize); + } this._positionsAreDirty = true; this.setNodeDirty(); this.dispatchEvent("load"); From 90d2e797a2e1e9c8f5a468b2dbf1a5d81238d998 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Mon, 13 Jun 2016 11:03:39 +0800 Subject: [PATCH 04/15] Support WebGL on Chrome 30+ --- CCBoot.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CCBoot.js b/CCBoot.js index 0532c798ca..135523c47f 100644 --- a/CCBoot.js +++ b/CCBoot.js @@ -1857,12 +1857,12 @@ var _initSys = function () { } if (_supportWebGL && sys.os === sys.OS_ANDROID) { + var browserVer = parseFloat(sys.browserVersion); switch (sys.browserType) { case sys.BROWSER_TYPE_MOBILE_QQ: case sys.BROWSER_TYPE_BAIDU: case sys.BROWSER_TYPE_BAIDU_APP: // QQ & Baidu Brwoser 6.2+ (using blink kernel) - var browserVer = parseFloat(sys.browserVersion); if (browserVer >= 6.2) { _supportWebGL = true; } @@ -1870,6 +1870,14 @@ var _initSys = function () { _supportWebGL = false; } break; + case sys.BROWSER_TYPE_CHROME: + // Chrome on android supports WebGL from v.30 + if(browserVer >= 30.0) { + _supportWebGL = true; + } else { + _supportWebGL = false; + } + break; case sys.BROWSER_TYPE_ANDROID: // Android 5+ default browser if (sys.osMainVersion && sys.osMainVersion >= 5) { From 5d1a764b0a2556ce2c7b740aebe93b865b557809 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Mon, 13 Jun 2016 18:09:20 +0800 Subject: [PATCH 05/15] Fix bugs in scroll view rendering, cache mode, and TTF updateColor --- .../core/labelttf/CCLabelTTFWebGLRenderCmd.js | 4 +- cocos2d/core/renderer/RendererWebGL.js | 37 +++++++------------ .../UIScrollViewWebGLRenderCmd.js | 20 ++++++++-- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js index 9cc24fd7d5..6b7e25f8b6 100644 --- a/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js +++ b/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js @@ -32,7 +32,5 @@ cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto); proto.constructor = cc.LabelTTF.WebGLRenderCmd; - proto._updateColor = function () { - this._updateTexture(); - }; + proto._updateColor = function () {}; })(); \ No newline at end of file diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 33b7df20ce..1680299890 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -140,8 +140,15 @@ return { _turnToCacheMode: function (renderTextureID) { this._isCacheToBufferOn = true; renderTextureID = renderTextureID || 0; - this._cacheToBufferCmds[renderTextureID] = []; - this._cacheInstanceIds.push(renderTextureID); + if (!this._cacheToBufferCmds[renderTextureID]) { + this._cacheToBufferCmds[renderTextureID] = []; + } + else { + this._cacheToBufferCmds[renderTextureID].length = 0; + } + if (this._cacheInstanceIds.indexOf(renderTextureID) === -1) { + this._cacheInstanceIds.push(renderTextureID); + } this._currentID = renderTextureID; }, @@ -169,23 +176,7 @@ return { renderTextureId = renderTextureId || this._currentID; var locCmds = this._cacheToBufferCmds[renderTextureId], i, len; var ctx = cc._renderContext; - // Reset buffer cache to avoid issue - gl.bindBuffer(gl.ARRAY_BUFFER, null); - for (i = 0, len = locCmds.length; i < len; ++i) { - cmd = locCmds[i]; - - if (cmd.uploadData) { - this._uploadBufferData(cmd); - } - else { - if (cmd._batchingSize > 0) { - this._batchRendering(); - } - cmd.rendering(ctx); - } - } - this._batchRendering(); - _batchedInfo.texture = null; + this.rendering(ctx, locCmds); this._removeCache(renderTextureId); var locIDs = this._cacheInstanceIds; @@ -317,11 +308,11 @@ return { var _bufferchanged = !gl.bindBuffer(gl.ARRAY_BUFFER, _quadVertexBuffer); // upload the vertex data to the gl buffer if (_batchingSize > _vertexSize * 0.5) { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, _vertexDataF32); + gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); } else { var view = _vertexDataF32.subarray(0, _batchingSize * _sizePerVertex); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); + gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW); } if (_bufferchanged) { @@ -345,8 +336,8 @@ return { * drawing all renderer command to context (default is cc._renderContext) * @param {WebGLRenderingContext} [ctx=cc._renderContext] */ - rendering: function (ctx) { - var locCmds = this._renderCmds, + rendering: function (ctx, cmds) { + var locCmds = cmds || this._renderCmds, i, len, cmd, next, batchCount, context = ctx || cc._renderContext; diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js index d7c167656c..40ebeae5e6 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js @@ -31,7 +31,7 @@ proto.rendering = function(ctx){ var currentID = this._node.__instanceId, locCmds = cc.renderer._cacheToBufferCmds[currentID], - i, len, checkNode, + i, len, checkNode, cmd, context = ctx || cc._renderContext; if (!locCmds) { return; @@ -39,13 +39,27 @@ this._node.updateChildren(); + // Reset buffer for rendering + context.bindBuffer(gl.ARRAY_BUFFER, null); + for (i = 0, len = locCmds.length; i < len; i++) { - checkNode = locCmds[i]._node; + cmd = locCmds[i]; + checkNode = cmd._node; if(checkNode instanceof ccui.ScrollView) continue; if(checkNode && checkNode._parent && checkNode._parent._inViewRect === false) continue; - locCmds[i].rendering(context); + + if (cmd.uploadData) { + cc.renderer._uploadBufferData(cmd); + } + else { + if (cmd._batchingSize > 0) { + cc.renderer._batchRendering(); + } + cmd.rendering(context); + } + cc.renderer._batchRendering(); } }; })(); From 0e2db6297d873c02dae82123f5fa5e45d5a3cf91 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 11:39:40 +0800 Subject: [PATCH 06/15] Fix gl.bindBuffer issue --- cocos2d/shaders/CCGLStateCache.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cocos2d/shaders/CCGLStateCache.js b/cocos2d/shaders/CCGLStateCache.js index a5a4e7acb0..cb1aa164e2 100644 --- a/cocos2d/shaders/CCGLStateCache.js +++ b/cocos2d/shaders/CCGLStateCache.js @@ -38,17 +38,12 @@ if (cc.ENABLE_GL_STATE_CACHE) { cc._uVAO = 0; var _currBuffers = {}; - var _currBuffer; WebGLRenderingContext.prototype.glBindBuffer = WebGLRenderingContext.prototype.bindBuffer; WebGLRenderingContext.prototype.bindBuffer = function (target, buffer) { if (_currBuffers[target] !== buffer) { - _currBuffers[target] = buffer; this.glBindBuffer(target, buffer); - } - - if (!_currBuffer || _currBuffer !== buffer) { - _currBuffer = buffer; + _currBuffers[target] = buffer; return false; } else { From cf4cd3aa55bcd26b7a92e9bb8103c3fb76f4d34e Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 11:39:56 +0800 Subject: [PATCH 07/15] Use bufferData instead of bufferSubData on iOS --- cocos2d/core/renderer/RendererWebGL.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 1680299890..06436c94b3 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -24,14 +24,6 @@ cc.rendererWebGL = (function () { -function removeByLastSwap (array, i) { - var len = array.length; - if (len > 0 && i >= 0 && i < len) { - array[i] = array[len - 1]; - array.length--; - } -} - // Internal variables // Batching general informations var _batchedInfo = { @@ -56,7 +48,8 @@ var _batchedInfo = { _vertexData = null, _vertexDataSize = 0, _vertexDataF32 = null, - _vertexDataUI32 = null; + _vertexDataUI32 = null, + _IS_IOS = false; // Inspired from @Heishe's gotta-batch-them-all branch @@ -130,6 +123,9 @@ return { this.mat4Identity = new cc.math.Matrix4(); this.mat4Identity.identity(); initQuadBuffer(2000); + if (cc.sys.os === cc.sys.OS_IOS) { + _IS_IOS = true; + } }, getRenderCmd: function (renderableObject) { @@ -308,11 +304,13 @@ return { var _bufferchanged = !gl.bindBuffer(gl.ARRAY_BUFFER, _quadVertexBuffer); // upload the vertex data to the gl buffer if (_batchingSize > _vertexSize * 0.5) { - gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); + if (_IS_IOS) gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); + else gl.bufferSubData(gl.ARRAY_BUFFER, 0, _vertexDataF32); } else { var view = _vertexDataF32.subarray(0, _batchingSize * _sizePerVertex); - gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW); + if (_IS_IOS) gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW); + else gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); } if (_bufferchanged) { From 32f0c8eeba4ff803c2ba97e49be4966320c4707b Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 18:47:51 +0800 Subject: [PATCH 08/15] Improve transform / visit performance --- .../CCClippingNodeCanvasRenderCmd.js | 4 +-- .../CCClippingNodeWebGLRenderCmd.js | 6 ++-- .../core/base-nodes/CCNodeCanvasRenderCmd.js | 1 + cocos2d/core/layers/CCLayerCanvasRenderCmd.js | 4 +-- .../CCProtectedNodeCanvasRenderCmd.js | 32 ++++--------------- .../CCProtectedNodeWebGLRenderCmd.js | 3 ++ .../UIScale9SpriteCanvasRenderCmd.js | 2 +- .../UIScale9SpriteWebGLRenderCmd.js | 2 +- .../ccui/base-classes/UIWidgetRenderCmd.js | 14 +++++--- .../ccui/layouts/UILayoutCanvasRenderCmd.js | 4 ++- .../ccui/layouts/UILayoutWebGLRenderCmd.js | 11 ++++--- .../UIScrollViewCanvasRenderCmd.js | 2 +- .../UIScrollViewWebGLRenderCmd.js | 2 +- 13 files changed, 41 insertions(+), 46 deletions(-) diff --git a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js index 5c60928ab0..73a7887946 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js @@ -174,7 +174,7 @@ this._clipElemType = !(!this._cangodhelpme() && node._stencil instanceof cc.DrawNode); if (!node._stencil || !node._stencil.visible) { if (this.inverted) - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); // draw everything + this.originVisit(parentCmd); // draw everything return; } @@ -182,7 +182,7 @@ cc.renderer.pushRenderCommand(this._rendererSaveCmd); if(this._clipElemType){ // Draw everything first using node visit function - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); }else{ node._stencil.visit(this); } diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js index 3bf0914793..c5ef90edb7 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js @@ -74,13 +74,13 @@ // if stencil buffer disabled if (cc.stencilBits < 1) { // draw everything, as if there were no stencil - cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); return; } if (!node._stencil || !node._stencil.visible) { if (node.inverted) - cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); // draw everything + this.originVisit(parentCmd); // draw everything return; } @@ -91,7 +91,7 @@ cc.ClippingNode.WebGLRenderCmd._visit_once = false; } // draw everything, as if there were no stencil - cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); return; } diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js index 376bf5d7d9..3c6aa4c546 100644 --- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js @@ -493,6 +493,7 @@ cc.Node.RenderCmd.prototype = { } }; +cc.Node.RenderCmd.prototype.originVisit = cc.Node.RenderCmd.prototype.visit; cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform; //-----------------------Canvas --------------------------- diff --git a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js index 42ac328cc8..2c8b11f3c8 100644 --- a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js +++ b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js @@ -160,7 +160,7 @@ proto.visit = function(parentCmd){ if(!this._isBaked){ - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); return; } @@ -309,7 +309,7 @@ proto.visit = function(parentCmd){ if(!this._isBaked){ - cc.Node.CanvasRenderCmd.prototype.visit.call(this); + this.originVisit(); return; } diff --git a/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js b/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js index c3ecd0bb7d..1e36802e0d 100644 --- a/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js +++ b/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js @@ -205,36 +205,16 @@ if(node._changePosition) node._changePosition(); - var t = node.getNodeToParentTransform(), worldT = this._worldTransform; - if (parentCmd) { - var pt = parentCmd._worldTransform; - // cc.AffineTransformConcat is incorrect at get world transform - worldT.a = t.a * pt.a + t.b * pt.c; //a - worldT.b = t.a * pt.b + t.b * pt.d; //b - worldT.c = t.c * pt.a + t.d * pt.c; //c - worldT.d = t.c * pt.b + t.d * pt.d; //d - - worldT.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; - worldT.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; - } else { - worldT.a = t.a; - worldT.b = t.b; - worldT.c = t.c; - worldT.d = t.d; - worldT.tx = t.tx; - worldT.ty = t.ty; - } - var i, len, locChildren = node._children; - if(recursive && locChildren && locChildren.length !== 0){ - for(i = 0, len = locChildren.length; i< len; i++){ - locChildren[i]._renderCmd.transform(this, recursive); - } - } - locChildren = node._protectedChildren; + this.originTransform(parentCmd, recursive); + + var i, len, locChildren = node._protectedChildren; if(recursive && locChildren && locChildren.length !== 0){ for(i = 0, len = locChildren.length; i< len; i++){ locChildren[i]._renderCmd.transform(this, recursive); } } }; + + proto.pNodeVisit = proto.visit; + proto.pNodeTransform = proto.transform; })(); \ No newline at end of file diff --git a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js index 0adec0ea1a..6640c7cf9b 100644 --- a/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js @@ -98,4 +98,7 @@ } } }; + + proto.pNodeVisit = proto.visit; + proto.pNodeTransform = proto.transform; })(); \ No newline at end of file diff --git a/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js b/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js index e4814ef912..35f940b784 100644 --- a/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js +++ b/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js @@ -55,7 +55,7 @@ node._positionsAreDirty = false; } - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); }; proto.transform = function(parentCmd){ diff --git a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js index daccb03fad..ceb2ba680e 100644 --- a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js @@ -71,7 +71,7 @@ node._scale9Image._renderCmd.visit(this); } this._dirtyFlag = 0; - cc.Node.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.originVisit(parentCmd); }; proto.transform = function(parentCmd, recursive){ diff --git a/extensions/ccui/base-classes/UIWidgetRenderCmd.js b/extensions/ccui/base-classes/UIWidgetRenderCmd.js index 07e1a004af..99deeaad51 100644 --- a/extensions/ccui/base-classes/UIWidgetRenderCmd.js +++ b/extensions/ccui/base-classes/UIWidgetRenderCmd.js @@ -36,7 +36,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { var node = this._node; if (node._visible) { node._adaptRenderers(); - cc.ProtectedNode.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.pNodeVisit(parentCmd); } }; @@ -55,9 +55,12 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { } } } - cc.ProtectedNode.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.pNodeTransform(parentCmd, recursive); } }; + + proto.widgetVisit = proto.visit; + proto.widgetTransform = proto.transform; } else { ccui.Widget.WebGLRenderCmd = function (renderable) { cc.ProtectedNode.WebGLRenderCmd.call(this, renderable); @@ -71,7 +74,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { var node = this._node; if (node._visible) { node._adaptRenderers(); - cc.ProtectedNode.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.pNodeVisit(parentCmd); } }; @@ -90,8 +93,11 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { } } } - cc.ProtectedNode.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.pNodeTransform(parentCmd, recursive); } }; + + proto.widgetVisit = proto.visit; + proto.widgetTransform = proto.transform; } }); diff --git a/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js b/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js index ea06506246..1b38960ba7 100644 --- a/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js +++ b/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js @@ -58,10 +58,12 @@ break; } } else { - ccui.Widget.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.widgetVisit(parentCmd); } }; + proto.layoutVisit = proto.visit; + proto._onRenderSaveCmd = function(ctx, scaleX, scaleY){ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); if (this._clipElemType) { diff --git a/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js b/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js index 5eec045254..f42c88c79d 100644 --- a/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js +++ b/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js @@ -68,10 +68,13 @@ default: break; } - } else - ccui.ProtectedNode.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + } else { + this.pNodeVisit(parentCmd); + } }; + proto.layoutVisit = proto.visit; + proto._onBeforeVisitStencil = function(ctx){ var gl = ctx || cc._renderContext; @@ -164,7 +167,7 @@ proto.transform = function(parentCmd, recursive){ var node = this._node; - ccui.ProtectedNode.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.pNodeTransform(parentCmd, recursive); if(node._clippingStencil) node._clippingStencil._renderCmd.transform(this, recursive); }; @@ -236,7 +239,7 @@ proto.scissorClippingVisit = function(parentCmd){ cc.renderer.pushRenderCommand(this._beforeVisitCmdScissor); - ccui.ProtectedNode.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.pNodeVisit(parentCmd); cc.renderer.pushRenderCommand(this._afterVisitCmdScissor); }; diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js index 81bda66e7f..59feac0c4b 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js @@ -19,7 +19,7 @@ cc.renderer.pushRenderCommand(this); cc.renderer._turnToCacheMode(currentID); - ccui.Layout.CanvasRenderCmd.prototype.visit.call(this, parentCmd); + this.layoutVisit(parentCmd); this._dirtyFlag = 0; cc.renderer._turnToNormalMode(); diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js index 40ebeae5e6..413d23aff0 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js @@ -20,7 +20,7 @@ cc.renderer.pushRenderCommand(this); cc.renderer._turnToCacheMode(currentID); - ccui.Layout.WebGLRenderCmd.prototype.visit.call(this, parentCmd); + this.layoutVisit(parentCmd); // Need to update children after do layout node.updateChildren(); From d6f60cfa1dc50ef99d188eeeff01036ecd9594ce Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 18:48:41 +0800 Subject: [PATCH 09/15] Improve Scissor clipping performance --- cocos2d/core/platform/CCEGLView.js | 24 ++++++++++--------- .../ccui/layouts/UILayoutWebGLRenderCmd.js | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cocos2d/core/platform/CCEGLView.js b/cocos2d/core/platform/CCEGLView.js index 949fd6e6b1..8f42a9f762 100644 --- a/cocos2d/core/platform/CCEGLView.js +++ b/cocos2d/core/platform/CCEGLView.js @@ -102,6 +102,8 @@ switch(cc.__BrowserGetter.adaptationType){ break; } +var _scissorRect = cc.rect(); + /** * cc.view is the singleton object which represents the game window.
* It's main task include:
@@ -768,11 +770,15 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ * @param {Number} h */ setScissorInPoints: function (x, y, w, h) { - var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY; - cc._renderContext.scissor((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor), - (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor), - (w * locScaleX * locFrameZoomFactor), - (h * locScaleY * locFrameZoomFactor)); + var zoomFactor = this._frameZoomFactor, scaleX = this._scaleX, scaleY = this._scaleY; + _scissorRect.x = x; + _scissorRect.y = y; + _scissorRect.width = w; + _scissorRect.height = h; + cc._renderContext.scissor(x * scaleX * zoomFactor + this._viewPortRect.x * zoomFactor, + y * scaleY * zoomFactor + this._viewPortRect.y * zoomFactor, + w * scaleX * zoomFactor, + h * scaleY * zoomFactor); }, /** @@ -780,8 +786,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ * @return {Boolean} */ isScissorEnabled: function () { - var gl = cc._renderContext; - return gl.isEnabled(gl.SCISSOR_TEST); + return cc._renderContext.isEnabled(gl.SCISSOR_TEST); }, /** @@ -789,10 +794,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ * @return {cc.Rect} */ getScissorRect: function () { - var gl = cc._renderContext, scaleX = this._scaleX, scaleY = this._scaleY; - var boxArr = gl.getParameter(gl.SCISSOR_BOX); - return cc.rect((boxArr[0] - this._viewPortRect.x) / scaleX, (boxArr[1] - this._viewPortRect.y) / scaleY, - boxArr[2] / scaleX, boxArr[3] / scaleY); + return cc.rect(_scissorRect); }, /** diff --git a/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js b/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js index f42c88c79d..9fd8544f8c 100644 --- a/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js +++ b/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js @@ -133,32 +133,30 @@ var clippingRect = this._node._getClippingRect(); var gl = ctx || cc._renderContext; - this._scissorOldState = cc.view.isScissorEnabled(); + this._scissorOldState = gl.isEnabled(gl.SCISSOR_TEST); - if(!this._scissorOldState) + if (!this._scissorOldState) { gl.enable(gl.SCISSOR_TEST); - - this._clippingOldRect = cc.view.getScissorRect(); - - if(!cc.rectEqualToRect(this._clippingOldRect, clippingRect)) cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height); + } + else { + this._clippingOldRect = cc.view.getScissorRect(); + if (!cc.rectEqualToRect(this._clippingOldRect, clippingRect)) + cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height); + } }; proto._onAfterVisitScissor = function(ctx){ var gl = ctx || cc._renderContext; - if(this._scissorOldState) - { - if(!cc.rectEqualToRect(this._clippingOldRect, this._node._clippingRect)) - { + if (this._scissorOldState) { + if (!cc.rectEqualToRect(this._clippingOldRect, this._node._clippingRect)) { cc.view.setScissorInPoints( this._clippingOldRect.x, this._clippingOldRect.y, this._clippingOldRect.width, this._clippingOldRect.height); } - } - else - { + else { gl.disable(gl.SCISSOR_TEST); } }; From 576d61bb1b50219ba7d3282adf689009af35924d Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 18:49:41 +0800 Subject: [PATCH 10/15] Refactor Sprite vertices calculation and add Culling --- .../core/sprites/CCSpriteWebGLRenderCmd.js | 75 ++++++++++--------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index ae0f78d2ee..17e1ad18dd 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -29,11 +29,11 @@ cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; - this._uvs = [ - {u: 0, v: 0}, // tl - {u: 0, v: 0}, // bl - {u: 0, v: 0}, // tr - {u: 0, v: 0} // br + this._vertices = [ + {x: 0, y: 0, u: 0, v: 0}, // tl + {x: 0, y: 0, u: 0, v: 0}, // bl + {x: 0, y: 0, u: 0, v: 0}, // tr + {x: 0, y: 0, u: 0, v: 0} // br ]; this._dirty = false; this._recursiveDirty = false; @@ -44,12 +44,6 @@ var proto = cc.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.Sprite.WebGLRenderCmd; - // The following static properties must be provided for a auto batchable command - proto.vertexBytesPerUnit = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; - proto.bytesPerUnit = proto.vertexBytesPerUnit; - proto.indicesPerUnit = 6; - proto.verticesPerUnit = 4; - proto.updateBlendFunc = function (blendFunc) {}; proto.setDirtyFlag = function(dirtyFlag){ @@ -104,7 +98,6 @@ }; proto._textureLoadedCallback = function (sender) { - var renderCmd = this._renderCmd; if (this._textureLoaded) return; @@ -137,7 +130,7 @@ var node = this._node; var tex = node._batchNode ? node.textureAtlas.texture : node._texture; - var uvs = this._uvs; + var uvs = this._vertices; if (!tex) return; @@ -280,6 +273,25 @@ } }; + proto.transform = function (parentCmd, recursive) { + this.originTransform(parentCmd, recursive); + + var node = this._node, + lx = node._offsetPosition.x, rx = lx + node._rect.width, + by = node._offsetPosition.y, ty = by + node._rect.height, + wt = this._worldTransform; + + var vertices = this._vertices; + vertices[0].x = lx * wt.a + ty * wt.c + wt.tx; // tl + vertices[0].y = lx * wt.b + ty * wt.d + wt.ty; + vertices[1].x = lx * wt.a + by * wt.c + wt.tx; // bl + vertices[1].y = lx * wt.b + by * wt.d + wt.ty; + vertices[2].x = rx * wt.a + ty * wt.c + wt.tx; // tr + vertices[2].y = rx * wt.b + ty * wt.d + wt.ty; + vertices[3].x = rx * wt.a + by * wt.c + wt.tx; // br + vertices[3].y = rx * wt.b + by * wt.d + wt.ty; + }; + proto.needDraw = function () { var node = this._node, locTexture = node._texture; return (this._needDraw && locTexture); @@ -290,24 +302,18 @@ if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity) return false; - var lx = node._offsetPosition.x, rx = lx + node._rect.width, - by = node._offsetPosition.y, ty = by + node._rect.height, - wt = this._worldTransform; - - offset = vertexDataOffset; - - f32buffer[offset] = lx * wt.a + ty * wt.c + wt.tx; // tl - f32buffer[offset + 1] = lx * wt.b + ty * wt.d + wt.ty; - f32buffer[offset + 6] = lx * wt.a + by * wt.c + wt.tx; // bl - f32buffer[offset + 7] = lx * wt.b + by * wt.d + wt.ty; - f32buffer[offset + 12] = rx * wt.a + ty * wt.c + wt.tx; // tr - f32buffer[offset + 13] = rx * wt.b + ty * wt.d + wt.ty; - f32buffer[offset + 18] = rx * wt.a + by * wt.c + wt.tx; // br - f32buffer[offset + 19] = rx * wt.b + by * wt.d + wt.ty; + var vertices = this._vertices; + var visibleRect = cc.view._visibleRect; + var tl = vertices[0], bl = vertices[1], tr = vertices[2], br = vertices[3]; + if (Math.max(tl.x, bl.x, tr.x, br.x) < visibleRect.x || + Math.max(tl.y, bl.y, tr.y, br.y) < visibleRect.y || + Math.min(tl.x, bl.x, tr.x, br.x) > visibleRect.x + visibleRect.width || + Math.min(tl.y, bl.y, tr.y, br.y) > visibleRect.y + visibleRect.height) { + return false; + } // Fill in vertex data with quad information (4 vertices for sprite) - var uvs = this._uvs; - var opacity = Math.floor(this._displayedOpacity); + var opacity = this._displayedOpacity; var r = this._displayedColor.r, g = this._displayedColor.g, b = this._displayedColor.b; @@ -318,15 +324,16 @@ b *= a; } - var i, len = uvs.length, offset, uv, colorView; + var i, len = vertices.length, vertex, offset = vertexDataOffset; for (i = 0; i < len; ++i) { offset = vertexDataOffset + i * 6; - uv = uvs[i]; + vertex = vertices[i]; + f32buffer[offset] = vertex.x; + f32buffer[offset + 1] = vertex.y; f32buffer[offset + 2] = node._vertexZ; - f32buffer[offset + 4] = uv.u; - f32buffer[offset + 5] = uv.v; - ui32buffer[offset + 3] = ((opacity<<24) | (b<<16) | (g<<8) | r); + f32buffer[offset + 4] = vertex.u; + f32buffer[offset + 5] = vertex.v; } return true; From 45069a96609118d1d5257e4f7145ed48d221bb8a Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 14 Jun 2016 18:50:12 +0800 Subject: [PATCH 11/15] Small changes and change version --- cocos2d/core/CCDirectorWebGL.js | 3 --- cocos2d/core/platform/CCConfig.js | 2 +- cocos2d/core/platform/CCEGLView.js | 30 +++++++++++++------------- cocos2d/core/renderer/RendererWebGL.js | 4 ++++ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/cocos2d/core/CCDirectorWebGL.js b/cocos2d/core/CCDirectorWebGL.js index 75212759ed..9194220714 100644 --- a/cocos2d/core/CCDirectorWebGL.js +++ b/cocos2d/core/CCDirectorWebGL.js @@ -245,9 +245,6 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { _p.setGLDefaultValues = function () { var _t = this; _t.setAlphaBlending(true); - // XXX: Fix me, should enable/disable depth test according the depth format as cocos2d-iphone did - // [self setDepthTest: view_.depthFormat]; - _t.setDepthTest(false); _t.setProjection(_t._projection); // set other opengl default values diff --git a/cocos2d/core/platform/CCConfig.js b/cocos2d/core/platform/CCConfig.js index cc7d1a957a..e69fa92518 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.11"; +window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.12 Beta0"; /** *

diff --git a/cocos2d/core/platform/CCEGLView.js b/cocos2d/core/platform/CCEGLView.js index 8f42a9f762..045f56e531 100644 --- a/cocos2d/core/platform/CCEGLView.js +++ b/cocos2d/core/platform/CCEGLView.js @@ -35,7 +35,7 @@ cc.DENSITYDPI_HIGH = "high-dpi"; cc.DENSITYDPI_MEDIUM = "medium-dpi"; cc.DENSITYDPI_LOW = "low-dpi"; -cc.__BrowserGetter = { +var __BrowserGetter = { init: function(){ this.html = document.getElementsByTagName("html")[0]; }, @@ -58,36 +58,36 @@ cc.__BrowserGetter = { }; if(window.navigator.userAgent.indexOf("OS 8_1_") > -1) //this mistake like MIUI, so use of MIUI treatment method - cc.__BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_MIUI; + __BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_MIUI; if(cc.sys.os === cc.sys.OS_IOS) // All browsers are WebView - cc.__BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_SAFARI; + __BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_SAFARI; -switch(cc.__BrowserGetter.adaptationType){ +switch(__BrowserGetter.adaptationType){ case cc.sys.BROWSER_TYPE_SAFARI: - cc.__BrowserGetter.meta["minimal-ui"] = "true"; - cc.__BrowserGetter.availWidth = function(frame){ + __BrowserGetter.meta["minimal-ui"] = "true"; + __BrowserGetter.availWidth = function(frame){ return frame.clientWidth; }; - cc.__BrowserGetter.availHeight = function(frame){ + __BrowserGetter.availHeight = function(frame){ return frame.clientHeight; }; break; case cc.sys.BROWSER_TYPE_CHROME: - cc.__BrowserGetter.__defineGetter__("target-densitydpi", function(){ + __BrowserGetter.__defineGetter__("target-densitydpi", function(){ return cc.view._targetDensityDPI; }); case cc.sys.BROWSER_TYPE_SOUGOU: case cc.sys.BROWSER_TYPE_UC: - cc.__BrowserGetter.availWidth = function(frame){ + __BrowserGetter.availWidth = function(frame){ return frame.clientWidth; }; - cc.__BrowserGetter.availHeight = function(frame){ + __BrowserGetter.availHeight = function(frame){ return frame.clientHeight; }; break; case cc.sys.BROWSER_TYPE_MIUI: - cc.__BrowserGetter.init = function(view){ + __BrowserGetter.init = function(view){ if(view.__resizeWithBrowserSize) return; var resize = function(){ view.setDesignResolutionSize( @@ -169,7 +169,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ ctor: function () { var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy; - cc.__BrowserGetter.init(this); + __BrowserGetter.init(this); _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode; _t._frameSize = cc.size(0, 0); @@ -301,8 +301,8 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ _initFrameSize: function () { var locFrameSize = this._frameSize; - var w = cc.__BrowserGetter.availWidth(this._frame); - var h = cc.__BrowserGetter.availHeight(this._frame); + var w = __BrowserGetter.availWidth(this._frame); + var h = __BrowserGetter.availHeight(this._frame); var isLandscape = w >= h; if (!cc.sys.isMobile || @@ -371,7 +371,7 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ _adjustViewportMeta: function () { if (this._isAdjustViewPort) { - this._setViewportMeta(cc.__BrowserGetter.meta, false); + this._setViewportMeta(__BrowserGetter.meta, false); // Only adjust viewport once this._isAdjustViewPort = false; } diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 06436c94b3..e74e2f9ddc 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -120,6 +120,10 @@ return { _clearColor: cc.color(), //background color,default BLACK init: function () { + var gl = cc._renderContext; + gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + this.mat4Identity = new cc.math.Matrix4(); this.mat4Identity.identity(); initQuadBuffer(2000); From cb0060bdab99d0fffc662fb39b4e3171f69ff236 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Wed, 15 Jun 2016 14:31:07 +0800 Subject: [PATCH 12/15] Remove culling and use bufferData instead of bufferSubData --- cocos2d/core/renderer/RendererWebGL.js | 6 ++---- cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js | 11 +---------- cocos2d/core/utils/CCProfiler.js | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index e74e2f9ddc..442b113a91 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -308,13 +308,11 @@ return { var _bufferchanged = !gl.bindBuffer(gl.ARRAY_BUFFER, _quadVertexBuffer); // upload the vertex data to the gl buffer if (_batchingSize > _vertexSize * 0.5) { - if (_IS_IOS) gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); - else gl.bufferSubData(gl.ARRAY_BUFFER, 0, _vertexDataF32); + gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW); } else { var view = _vertexDataF32.subarray(0, _batchingSize * _sizePerVertex); - if (_IS_IOS) gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW); - else gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); + gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW); } if (_bufferchanged) { diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index 17e1ad18dd..a36cd2cbe4 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -302,16 +302,6 @@ if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity) return false; - var vertices = this._vertices; - var visibleRect = cc.view._visibleRect; - var tl = vertices[0], bl = vertices[1], tr = vertices[2], br = vertices[3]; - if (Math.max(tl.x, bl.x, tr.x, br.x) < visibleRect.x || - Math.max(tl.y, bl.y, tr.y, br.y) < visibleRect.y || - Math.min(tl.x, bl.x, tr.x, br.x) > visibleRect.x + visibleRect.width || - Math.min(tl.y, bl.y, tr.y, br.y) > visibleRect.y + visibleRect.height) { - return false; - } - // Fill in vertex data with quad information (4 vertices for sprite) var opacity = this._displayedOpacity; var r = this._displayedColor.r, @@ -324,6 +314,7 @@ b *= a; } + var vertices = this._vertices; var i, len = vertices.length, vertex, offset = vertexDataOffset; for (i = 0; i < len; ++i) { offset = vertexDataOffset + i * 6; diff --git a/cocos2d/core/utils/CCProfiler.js b/cocos2d/core/utils/CCProfiler.js index 60bfc59c58..704f8697eb 100644 --- a/cocos2d/core/utils/CCProfiler.js +++ b/cocos2d/core/utils/CCProfiler.js @@ -1,6 +1,6 @@ cc.profiler = (function () { var _showFPS = false; - window._inited = false; + var _inited = false; var _frames = 0, _frameRate = 0, _lastSPF = 0, _accumDt = 0; var _afterVisitListener = null, _FPSLabel = document.createElement('div'), From ce9be4f5fb5d4d2c64a4e2fd179163906fc95cfd Mon Sep 17 00:00:00 2001 From: pandamicro Date: Thu, 16 Jun 2016 17:49:50 +0800 Subject: [PATCH 13/15] Bug fixes --- .../CCClippingNodeWebGLRenderCmd.js | 2 +- cocos2d/core/CCDirector.js | 39 +- cocos2d/core/CCDirectorWebGL.js | 34 -- .../core/base-nodes/CCNodeCanvasRenderCmd.js | 71 ++- cocos2d/core/layers/CCLayer.js | 18 - cocos2d/core/layers/CCLayerCanvasRenderCmd.js | 26 +- cocos2d/core/layers/CCLayerWebGLRenderCmd.js | 148 +++--- cocos2d/core/platform/CCInputManager.js | 21 +- cocos2d/core/renderer/RendererWebGL.js | 24 +- cocos2d/core/sprites/CCSprite.js | 6 - cocos2d/core/sprites/CCSpriteBatchNode.js | 30 +- .../core/sprites/CCSpriteWebGLRenderCmd.js | 11 +- cocos2d/core/textures/CCTextureCache.js | 3 +- cocos2d/core/textures/TexturesWebGL.js | 3 +- cocos2d/effects/CCGrid.js | 47 +- .../CCPhysicsDebugNodeWebGLRenderCmd.js | 12 +- cocos2d/physics/CCPhysicsSprite.js | 37 +- .../physics/CCPhysicsSpriteCanvasRenderCmd.js | 43 -- .../physics/CCPhysicsSpriteWebGLRenderCmd.js | 39 +- .../CCProgressTimerWebGLRenderCmd.js | 2 +- cocos2d/tilemap/CCTMXLayer.js | 81 ++- cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js | 2 +- cocos2d/transitions/CCTransition.js | 470 ------------------ .../UIScale9SpriteWebGLRenderCmd.js | 2 + .../armature/CCArmatureWebGLRenderCmd.js | 105 ++-- .../armature/display/CCDisplayFactory.js | 6 +- .../cocostudio/armature/display/CCSkin.js | 10 +- ...nCanvasRenderCmd.js => CCSkinRenderCmd.js} | 49 +- .../armature/display/CCSkinWebGLRenderCmd.js | 94 ---- extensions/spine/CCSkeletonWebGLRenderCmd.js | 17 +- moduleConfig.json | 3 +- tools/build.xml | 3 +- 32 files changed, 409 insertions(+), 1049 deletions(-) rename extensions/cocostudio/armature/display/{CCSkinCanvasRenderCmd.js => CCSkinRenderCmd.js} (54%) delete mode 100644 extensions/cocostudio/armature/display/CCSkinWebGLRenderCmd.js diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js index c5ef90edb7..6aa7360e72 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js @@ -56,7 +56,7 @@ proto.transform = function(parentCmd, recursive){ var node = this._node; - cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.originTransform(parentCmd, recursive); if(node._stencil) { node._stencil._renderCmd.transform(this, recursive); } diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js index 686504a892..4c859ee07a 100644 --- a/cocos2d/core/CCDirector.js +++ b/cocos2d/core/CCDirector.js @@ -26,16 +26,6 @@ cc.g_NumberOfDraws = 0; -cc.GLToClipTransform = function (transformOut) { - //var projection = new cc.math.Matrix4(); - //cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection); - cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, transformOut); - - var modelview = new cc.math.Matrix4(); - cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, modelview); - - transformOut.multiply(modelview); -}; //---------------------------------------------------------------------------------------------------------------------- /** @@ -191,7 +181,16 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{ * @param {cc.Point} uiPoint * @return {cc.Point} */ - convertToGL: null, + convertToGL: function (uiPoint) { + var docElem = document.documentElement; + var view = cc.view; + var box = element.getBoundingClientRect(); + box.left += window.pageXOffset - docElem.clientLeft; + box.top += window.pageYOffset - docElem.clientTop; + var x = view._devicePixelRatio * (uiPoint.x - box.left); + var y = view._devicePixelRatio * (box.top + box.height - uiPoint.y); + return view._isRotated ? {x: view._viewPortRect.width - y, y: x} : {x: x, y: y}; + }, /** * Converts an WebGL coordinate to a view coordinate
@@ -201,7 +200,23 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{ * @param {cc.Point} glPoint * @return {cc.Point} */ - convertToUI: null, + convertToUI: function (glPoint) { + var docElem = document.documentElement; + var view = cc.view; + var box = element.getBoundingClientRect(); + box.left += window.pageXOffset - docElem.clientLeft; + box.top += window.pageYOffset - docElem.clientTop; + var uiPoint = {x: 0, y: 0}; + if (view._isRotated) { + uiPoint.x = box.left + glPoint.y / view._devicePixelRatio; + uiPoint.y = box.top + box.height - (view._viewPortRect.width - glPoint.x) / view._devicePixelRatio; + } + else { + uiPoint.x = box.left + glPoint.x / view._devicePixelRatio; + uiPoint.y = box.top + box.height - glPoint.y / view._devicePixelRatio; + } + return uiPoint; + }, /** * Draw the scene. This method is called every frame. Don't call it manually. diff --git a/cocos2d/core/CCDirectorWebGL.js b/cocos2d/core/CCDirectorWebGL.js index 9194220714..0ad67fda4a 100644 --- a/cocos2d/core/CCDirectorWebGL.js +++ b/cocos2d/core/CCDirectorWebGL.js @@ -164,40 +164,6 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); }; - _p._beforeVisitScene = function () { - cc.kmGLPushMatrix(); - }; - - _p._afterVisitScene = function () { - cc.kmGLPopMatrix(); - }; - - _p.convertToGL = function (uiPoint) { - var transform = new cc.math.Matrix4(); - cc.GLToClipTransform(transform); - - var transformInv = transform.inverse(); - - // Calculate z=0 using -> transform*[0, 0, 0, 1]/w - var zClip = transform.mat[14] / transform.mat[15]; - var glSize = this._openGLView.getDesignResolutionSize(); - var glCoord = new cc.math.Vec3(2.0 * uiPoint.x / glSize.width - 1.0, 1.0 - 2.0 * uiPoint.y / glSize.height, zClip); - glCoord.transformCoord(transformInv); - return cc.p(glCoord.x, glCoord.y); - }; - - _p.convertToUI = function (glPoint) { - var transform = new cc.math.Matrix4(); - cc.GLToClipTransform(transform); - - var clipCoord = new cc.math.Vec3(glPoint.x, glPoint.y, 0.0); - // Need to calculate the zero depth from the transform. - clipCoord.transformCoord(transform); - - var glSize = this._openGLView.getDesignResolutionSize(); - return cc.p(glSize.width * (clipCoord.x * 0.5 + 0.5), glSize.height * (-clipCoord.y * 0.5 + 0.5)); - }; - _p.getVisibleSize = function () { //if (this._openGLView) { return this._openGLView.getVisibleSize(); diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js index 3c6aa4c546..2437476a91 100644 --- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js @@ -134,10 +134,10 @@ cc.Node.RenderCmd.prototype = { var hasRotation = node._rotationX || node._rotationY; var hasSkew = node._skewX || node._skewY; + var sx = node._scaleX, sy = node._scaleY; + var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; + var a = 1, b = 0, c = 0, d = 1; if (hasRotation || hasSkew) { - var sx = node._scaleX, sy = node._scaleY; - var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y; - // position t.tx = node._position.x; t.ty = node._position.y; @@ -166,27 +166,26 @@ cc.Node.RenderCmd.prototype = { // skew if (hasSkew) { - // offset the anchorpoint - var skx = Math.tan(-node._skewX * Math.PI / 180); - var sky = Math.tan(-node._skewY * Math.PI / 180); + var skx = Math.tan(node._skewX * Math.PI / 180); + var sky = Math.tan(node._skewY * Math.PI / 180); if (skx === Infinity) skx = 99999999; if (sky === Infinity) sky = 99999999; - var xx = appY * skx; - var yy = appX * sky; - t.a = a - c * sky; - t.b = b - d * sky; - t.c = c - a * skx; - t.d = d - b * skx; - t.tx += a * xx + c * yy; - t.ty += b * xx + d * yy; + t.a = a + b * sky; + t.b = b + a * sky; + t.c = c + d * skx; + t.d = d + c * skx; } - // adjust anchorPoint - if (!node._ignoreAnchorPointForPosition && (appX || appY)) { + if (appX || appY) { t.tx -= t.a * appX + t.c * appY; t.ty -= t.b * appX + t.d * appY; + // adjust anchorPoint + if (node._ignoreAnchorPointForPosition) { + t.tx += appX; + t.ty += appY; + } } if (pt) { @@ -207,17 +206,21 @@ cc.Node.RenderCmd.prototype = { } } else { - t.a = node._scaleX; + t.a = sx; t.b = 0; t.c = 0; - t.d = node._scaleY; - if (node._ignoreAnchorPointForPosition) { - t.tx = node._position.x; - t.ty = node._position.y; - } - else { - t.tx = node._position.x - this._anchorPointInPoints.x * t.a; - t.ty = node._position.y - this._anchorPointInPoints.y * t.d; + t.d = sy; + t.tx = node._position.x; + t.ty = node._position.y; + + if (appX || appY) { + t.tx -= t.a * appX; + t.ty -= t.d * appY; + // adjust anchorPoint + if (node._ignoreAnchorPointForPosition) { + t.tx += appX; + t.ty += appY; + } } if (pt) { @@ -255,7 +258,7 @@ cc.Node.RenderCmd.prototype = { }, visit: function (parentCmd) { - var node = this._node; + var node = this._node, renderer = cc.renderer; // quick return if not visible if (!node._visible) return; @@ -263,6 +266,12 @@ cc.Node.RenderCmd.prototype = { parentCmd = parentCmd || this.getParentRenderCmd(); if (parentCmd) this._curLevel = parentCmd._curLevel + 1; + + if (isNaN(node._customZ)) { + node._vertexZ = renderer.assignedZ; + renderer.assignedZ += renderer.assignedZStep; + } + this._syncStatus(parentCmd); this.visitChildren(); }, @@ -471,22 +480,12 @@ cc.Node.RenderCmd.prototype = { } } - if (isNaN(node._customZ)) { - node._vertexZ = renderer.assignedZ; - renderer.assignedZ += renderer.assignedZStep; - } - renderer.pushRenderCommand(this); for (; i < len; i++) { child = children[i]; child._renderCmd.visit(this); } } else { - if (isNaN(node._customZ)) { - node._vertexZ = renderer.assignedZ; - renderer.assignedZ += renderer.assignedZStep; - } - renderer.pushRenderCommand(this); } this._dirtyFlag = 0; diff --git a/cocos2d/core/layers/CCLayer.js b/cocos2d/core/layers/CCLayer.js index f5599f9678..36dff5a9ee 100644 --- a/cocos2d/core/layers/CCLayer.js +++ b/cocos2d/core/layers/CCLayer.js @@ -203,9 +203,6 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{ * @return {Boolean} */ init: function (color, width, height) { - if (cc._renderType !== cc.game.RENDER_TYPE_CANVAS) - this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR); - var winSize = cc.director.getWinSize(); color = color || cc.color(0, 0, 0, 255); width = width === undefined ? winSize.width : width; @@ -239,21 +236,6 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{ this._renderCmd.updateBlendFunc(locBlendFunc); }, - _setWidth: function(width){ - cc.Node.prototype._setWidth.call(this, width); - this._renderCmd._updateSquareVerticesWidth(width); - }, - - _setHeight: function(height){ - cc.Node.prototype._setHeight.call(this, height); - this._renderCmd._updateSquareVerticesHeight(height); - }, - - setContentSize: function(size, height){ - cc.Layer.prototype.setContentSize.call(this, size, height); - this._renderCmd._updateSquareVertices(size, height); - }, - _createRenderCmd: function(){ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) return new cc.LayerColor.CanvasRenderCmd(this); diff --git a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js index 2c8b11f3c8..14cb6adbeb 100644 --- a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js +++ b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js @@ -355,18 +355,6 @@ * cc.LayerGradient's rendering objects of Canvas */ (function(){ - cc.LayerGradient.RenderCmd = { - updateStatus: function () { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - if (locFlag & flags.gradientDirty) { - this._dirtyFlag |= flags.colorDirty; - this._dirtyFlag = this._dirtyFlag & flags.gradientDirty ^ this._dirtyFlag; - } - - cc.Node.RenderCmd.prototype.updateStatus.call(this); - } - }; - cc.LayerGradient.CanvasRenderCmd = function(renderable){ cc.LayerColor.CanvasRenderCmd.call(this, renderable); this._needDraw = true; @@ -376,7 +364,6 @@ this._endStopStr = null; }; var proto = cc.LayerGradient.CanvasRenderCmd.prototype = Object.create(cc.LayerColor.CanvasRenderCmd.prototype); - cc.inject(cc.LayerGradient.RenderCmd, proto); proto.constructor = cc.LayerGradient.CanvasRenderCmd; proto.rendering = function (ctx, scaleX, scaleY) { @@ -409,6 +396,16 @@ cc.g_NumberOfDraws++; }; + proto.updateStatus = function () { + var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; + if (locFlag & flags.gradientDirty) { + this._dirtyFlag |= flags.colorDirty; + this._dirtyFlag = this._dirtyFlag & flags.gradientDirty ^ this._dirtyFlag; + } + + cc.Node.RenderCmd.prototype.updateStatus.call(this); + }; + proto._syncStatus = function (parentCmd) { var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; if (locFlag & flags.gradientDirty) { @@ -419,11 +416,10 @@ cc.Node.RenderCmd.prototype._syncStatus.call(this, parentCmd); }; - proto._updateColor = function(){ + proto._updateColor = function() { var node = this._node; var contentSize = node._contentSize; var tWidth = contentSize.width * 0.5, tHeight = contentSize.height * 0.5; - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.gradientDirty ^ this._dirtyFlag; //fix the bug of gradient layer var angle = cc.pAngleSigned(cc.p(0, -1), node._alongVector); diff --git a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js index 92682ddc9b..8051a50abe 100644 --- a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js +++ b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js @@ -59,21 +59,23 @@ // var _t = this; - _t._squareVerticesAB = new ArrayBuffer(32); + _t._squareVerticesAB = new ArrayBuffer(48); _t._squareColorsAB = new ArrayBuffer(16); var locSquareVerticesAB = _t._squareVerticesAB, locSquareColorsAB = _t._squareColorsAB; - var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT; - _t._squareVertices = [new cc.Vertex2F(0, 0, locSquareVerticesAB, 0), - new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen), - new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 2), - new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 3)]; + var locVertex3FLen = cc.Vertex3F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT; + _t._squareVertices = [new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, 0), + new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen), + new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * 2), + new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * 3)]; _t._squareColors = [cc.color(0, 0, 0, 255, locSquareColorsAB, 0), cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen), cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 2), cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 3)]; _t._verticesFloat32Buffer = cc._renderContext.createBuffer(); _t._colorsUint8Buffer = cc._renderContext.createBuffer(); + + this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR); }; var proto = cc.LayerColor.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype); proto.constructor = cc.LayerColor.WebGLRenderCmd; @@ -100,7 +102,7 @@ // Attributes // context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer); - context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0); + context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, context.FLOAT, false, 0, 0); context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer); context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0); @@ -108,33 +110,23 @@ context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length); }; - proto._updateSquareVertices = function(size, height){ - var locSquareVertices = this._squareVertices; - if (height === undefined) { - locSquareVertices[1].x = size.width; - locSquareVertices[2].y = size.height; - locSquareVertices[3].x = size.width; - locSquareVertices[3].y = size.height; - } else { - locSquareVertices[1].x = size; - locSquareVertices[2].y = height; - locSquareVertices[3].x = size; - locSquareVertices[3].y = height; - } - this._bindLayerVerticesBufferData(); - }; + proto.transform = function (parentCmd, recursive) { + this.originTransform(parentCmd, recursive); - proto._updateSquareVerticesWidth = function(width){ - var locSquareVertices = this._squareVertices; - locSquareVertices[1].x = width; - locSquareVertices[3].x = width; - this._bindLayerVerticesBufferData(); - }; + var node = this._node, + width = node._contentSize.width, + height = node._contentSize.height; - proto._updateSquareVerticesHeight = function(height){ var locSquareVertices = this._squareVertices; + locSquareVertices[1].x = width; locSquareVertices[2].y = height; + locSquareVertices[3].x = width; locSquareVertices[3].y = height; + locSquareVertices[0].z = + locSquareVertices[1].z = + locSquareVertices[2].z = + locSquareVertices[3].z = node._vertexZ; + this._bindLayerVerticesBufferData(); }; @@ -153,7 +145,7 @@ proto._bindLayerVerticesBufferData = function(){ var glContext = cc._renderContext; glContext.bindBuffer(glContext.ARRAY_BUFFER, this._verticesFloat32Buffer); - glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB, glContext.STATIC_DRAW); + glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB, glContext.DYNAMIC_DRAW); }; proto._bindLayerColorsBufferData = function(){ @@ -176,62 +168,51 @@ this._clippingRectDirty = false; }; var proto = cc.LayerGradient.WebGLRenderCmd.prototype = Object.create(cc.LayerColor.WebGLRenderCmd.prototype); - cc.inject(cc.LayerGradient.RenderCmd, proto); proto.constructor = cc.LayerGradient.WebGLRenderCmd; - proto._syncStatus = function (parentCmd) { + proto.updateStatus = function () { var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - var parentNode = parentCmd ? parentCmd._node : null; - - if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty)) - locFlag |= flags.colorDirty; - - if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty)) - locFlag |= flags.opacityDirty; - - if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty)) - locFlag |= flags.transformDirty; - - var colorDirty = locFlag & flags.colorDirty, - opacityDirty = locFlag & flags.opacityDirty; - - this._dirtyFlag = locFlag; + if (locFlag & flags.gradientDirty) { + this._dirtyFlag |= flags.colorDirty; + this._updateVertex(); + this._dirtyFlag = locFlag & flags.gradientDirty ^ locFlag; + } - if (colorDirty) - this._syncDisplayColor(); + cc.Node.RenderCmd.prototype.updateStatus.call(this); + }; - if (opacityDirty) - this._syncDisplayOpacity(); + proto._syncStatus = function (parentCmd) { + var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; + if (locFlag & flags.gradientDirty) { + this._dirtyFlag |= flags.colorDirty; + this._updateVertex(); + this._dirtyFlag = locFlag & flags.gradientDirty ^ locFlag; + } - //if (locFlag & flags.transformDirty) { - //update the transform - this.transform(parentCmd); - //} + cc.Node.RenderCmd.prototype._syncStatus.call(this, parentCmd); + }; - if (colorDirty || opacityDirty || (locFlag & flags.gradientDirty)){ - this._updateColor(); - } + proto.transform = function (parentCmd, recursive) { + this.originTransform(parentCmd, recursive); + this._updateVertex(); }; - proto._updateColor = function(){ - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.gradientDirty ^ this._dirtyFlag; + proto._updateVertex = function () { var node = this._node, stops = node._colorStops; if(!stops || stops.length < 2) return; this._clippingRectDirty = true; var stopsLen = stops.length, verticesLen = stopsLen * 2, i, contentSize = node._contentSize; - this._squareVerticesAB = new ArrayBuffer(verticesLen * 8); - this._squareColorsAB = new ArrayBuffer(verticesLen * 4); - var locVertices = this._squareVertices, locColors = this._squareColors; - locVertices.length = 0; - locColors.length = 0; - - var locSquareVerticesAB = this._squareVerticesAB, locSquareColorsAB = this._squareColorsAB; - var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT; - for(i = 0; i < verticesLen; i++){ - locVertices.push(new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * i)); - locColors.push(cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * i)) + var locVertices = this._squareVertices; + if (locVertices.length < verticesLen) { + this._squareVerticesAB = new ArrayBuffer(verticesLen * 12); + locVertices.length = 0; + var locSquareVerticesAB = this._squareVerticesAB; + var locVertex3FLen = cc.Vertex3F.BYTES_PER_ELEMENT; + for(i = 0; i < verticesLen; i++){ + locVertices.push(new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * i)); + } } //init vertex @@ -262,12 +243,34 @@ var p0 = cc.pointApplyAffineTransform(- locAnchor.x , y - locAnchor.y, transMat); locVertices[i * 2].x = p0.x; locVertices[i * 2].y = p0.y; + locVertices[i * 2].z = node._vertexZ; var p1 = cc.pointApplyAffineTransform(contentSize.width - locAnchor.x, y - locAnchor.y, transMat); locVertices[i * 2 + 1].x = p1.x; locVertices[i * 2 + 1].y = p1.y; + locVertices[i * 2 + 1].z = node._vertexZ; } + this._bindLayerVerticesBufferData(); + }; + + proto._updateColor = function() { + var node = this._node, stops = node._colorStops; + if(!stops || stops.length < 2) + return; + //init color + var stopsLen = stops.length; + var locColors = this._squareColors, verticesLen = stopsLen * 2; + if (locColors.length < verticesLen) { + this._squareColorsAB = new ArrayBuffer(verticesLen * 4); + locColors.length = 0; + var locSquareColorsAB = this._squareColorsAB; + var locColorLen = cc.Color.BYTES_PER_ELEMENT; + for(i = 0; i < verticesLen; i++){ + locColors.push(cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * i)); + } + } + var opacityf = this._displayedOpacity / 255.0; //, displayColor = this._displayedColor; for(i = 0; i < stopsLen; i++){ var stopColor = stops[i].color, locSquareColor0 = locColors[i * 2], locSquareColor1 = locColors[i * 2 + 1]; @@ -281,7 +284,6 @@ locSquareColor1.b = stopColor.b; locSquareColor1.a = stopColor.a * opacityf; } - this._bindLayerVerticesBufferData(); this._bindLayerColorsBufferData(); }; @@ -312,7 +314,7 @@ // Attributes // context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer); - context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0); + context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, context.FLOAT, false, 0, 0); context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer); context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0); context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length); diff --git a/cocos2d/core/platform/CCInputManager.js b/cocos2d/core/platform/CCInputManager.js index 1bbb1677d2..7d655130f7 100644 --- a/cocos2d/core/platform/CCInputManager.js +++ b/cocos2d/core/platform/CCInputManager.js @@ -232,21 +232,12 @@ cc.inputManager = /** @lends cc.inputManager# */{ if (cc.isFunction(element.getBoundingClientRect)) { box = element.getBoundingClientRect(); } else { - if (element instanceof HTMLCanvasElement) { - box = { - left: 0, - top: 0, - width: element.width, - height: element.height - }; - } else { - box = { - left: 0, - top: 0, - width: parseInt(element.style.width), - height: parseInt(element.style.height) - }; - } + box = { + left: 0, + top: 0, + width: parseInt(element.style.width), + height: parseInt(element.style.height) + }; } return { left: box.left + win.pageXOffset - docElem.clientLeft, diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index 442b113a91..a0c3a5ec7e 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -108,7 +108,7 @@ return { childrenOrderDirty: true, assignedZ: 0, - assignedZStep: 1/10000, + assignedZStep: 1/100, _transformNodePool: [], //save nodes transform dirty _renderCmds: [], //save renderer commands @@ -132,6 +132,10 @@ return { } }, + getVertexSize: function () { + return _vertexSize; + }, + getRenderCmd: function (renderableObject) { //TODO Add renderCmd pool here return renderableObject._createRenderCmd(); @@ -260,6 +264,10 @@ return { } }, + _increaseBatchingSize: function (increment) { + _batchingSize += increment; + }, + _uploadBufferData: function (cmd) { if (_batchingSize >= _vertexSize) { this._batchRendering(); @@ -284,9 +292,9 @@ return { } // Upload vertex data - var uploaded = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex); - if (uploaded) { - _batchingSize += 4; + var len = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex); + if (len > 0) { + _batchingSize += len; } }, @@ -299,8 +307,10 @@ return { var shader = _batchedInfo.shader; var count = _batchingSize / 4; - shader.use(); - shader._updateProjectionUniform(); + if (shader) { + shader.use(); + shader._updateProjectionUniform(); + } cc.glBlendFunc(_batchedInfo.blendSrc, _batchedInfo.blendDst); cc.glBindTexture2DN(0, texture); // = cc.glBindTexture2D(texture); @@ -351,7 +361,7 @@ return { this._uploadBufferData(cmd); } else { - if (cmd._batchingSize > 0) { + if (_batchingSize > 0) { this._batchRendering(); } cmd.rendering(context); diff --git a/cocos2d/core/sprites/CCSprite.js b/cocos2d/core/sprites/CCSprite.js index ac75c4bf2a..1c6c8f03a2 100644 --- a/cocos2d/core/sprites/CCSprite.js +++ b/cocos2d/core/sprites/CCSprite.js @@ -750,12 +750,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ var locRect = _t._rect; _t._offsetPosition.x = relativeOffsetX + (_t._contentSize.width - locRect.width) / 2; _t._offsetPosition.y = relativeOffsetY + (_t._contentSize.height - locRect.height) / 2; - - // rendering using batch node - if (_t._batchNode) { - // update dirty, don't update _recursiveDirty - _t.dirty = true; - } }, // BatchNode methods diff --git a/cocos2d/core/sprites/CCSpriteBatchNode.js b/cocos2d/core/sprites/CCSpriteBatchNode.js index 80d8d26e86..d8044af074 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNode.js +++ b/cocos2d/core/sprites/CCSpriteBatchNode.js @@ -344,7 +344,29 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ */ setTexture: function(texture){ this._texture = texture; - // Set children texture and children texture rect ? + + if (texture._textureLoaded) { + var children = this._children, i, len = children.length; + for (i = 0; i < len; ++i) { + children[i].setTexture(texture); + } + } + else { + texture.addEventListener("load", function(){ + var children = this._children, i, len = children.length; + for (i = 0; i < len; ++i) { + children[i].setTexture(texture); + } + }, this); + } + }, + + setShaderProgram: function (newShaderProgram) { + this._renderCmd.setShaderProgram(newShaderProgram); + var children = this._children, i, len = children.length; + for (i = 0; i < len; ++i) { + children[i].setShaderProgram(newShaderProgram); + } }, /** @@ -364,6 +386,11 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ zOrder = (zOrder === undefined) ? child.zIndex : zOrder; tag = (tag === undefined) ? child.tag : tag; cc.Node.prototype.addChild.call(this, child, zOrder, tag); + + // Apply shader + if (this._renderCmd._shaderProgram) { + child.shaderProgram = this._renderCmd._shaderProgram; + } }, _isValidChild: function (child) { @@ -383,6 +410,7 @@ var _p = cc.SpriteBatchNode.prototype; // Override properties cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture); +cc.defineGetterSetter(_p, "shaderProgram", _p.getShaderProgram, _p.setShaderProgram); /** diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index a36cd2cbe4..a5ef8b4057 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -35,6 +35,7 @@ {x: 0, y: 0, u: 0, v: 0}, // tr {x: 0, y: 0, u: 0, v: 0} // br ]; + this._color = new Uint32Array(1); this._dirty = false; this._recursiveDirty = false; @@ -313,20 +314,22 @@ g *= a; b *= a; } + this._color[0] = ((opacity<<24) | (b<<16) | (g<<8) | r); + var z = node._vertexZ; var vertices = this._vertices; var i, len = vertices.length, vertex, offset = vertexDataOffset; for (i = 0; i < len; ++i) { - offset = vertexDataOffset + i * 6; vertex = vertices[i]; f32buffer[offset] = vertex.x; f32buffer[offset + 1] = vertex.y; - f32buffer[offset + 2] = node._vertexZ; - ui32buffer[offset + 3] = ((opacity<<24) | (b<<16) | (g<<8) | r); + f32buffer[offset + 2] = z; + ui32buffer[offset + 3] = this._color[0]; f32buffer[offset + 4] = vertex.u; f32buffer[offset + 5] = vertex.v; + offset += 6; } - return true; + return len; }; })(); \ No newline at end of file diff --git a/cocos2d/core/textures/CCTextureCache.js b/cocos2d/core/textures/CCTextureCache.js index a0763e209d..dcef25dc39 100644 --- a/cocos2d/core/textures/CCTextureCache.js +++ b/cocos2d/core/textures/CCTextureCache.js @@ -358,7 +358,8 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { tex = locTexs[url] = new cc.Texture2D(); tex.url = url; - cc.loader.loadImg(url, function (err, img) { + var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath; + cc.loader.loadImg(cc.path.join(basePath || "", url), function (err, img) { if (err) return cb && cb.call(target, err); diff --git a/cocos2d/core/textures/TexturesWebGL.js b/cocos2d/core/textures/TexturesWebGL.js index 21a1097724..dc92de6636 100644 --- a/cocos2d/core/textures/TexturesWebGL.js +++ b/cocos2d/core/textures/TexturesWebGL.js @@ -914,7 +914,8 @@ cc._tmp.WebGLTextureCache = function () { tex = locTexs[url] = new cc.Texture2D(); tex.url = url; - cc.loader.loadImg(url, function (err, img) { + var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath; + cc.loader.loadImg(cc.path.join(basePath || "", url), function (err, img) { if (err) return cb && cb.call(target, err); diff --git a/cocos2d/effects/CCGrid.js b/cocos2d/effects/CCGrid.js index e58352707f..8c5cd08a22 100644 --- a/cocos2d/effects/CCGrid.js +++ b/cocos2d/effects/CCGrid.js @@ -250,26 +250,6 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ //cc.director.setProjection(this._directorProjection); cc.director.setViewport(); - if (target && target.getCamera().isDirty()) { - var offset = target.getAnchorPointInPoints(); - - //TODO hack - var stackMatrix = target._renderCmd._stackMatrix; - // - // XXX: Camera should be applied in the AnchorPoint - // - //cc.kmGLTranslatef(offset.x, offset.y, 0); - var translation = cc.math.Matrix4.createByTranslation(offset.x, offset.y, 0); - stackMatrix.multiply(translation); - - //target.getCamera().locate(); - target._camera._locateForRenderer(stackMatrix); - - //cc.kmGLTranslatef(-offset.x, -offset.y, 0); - translation = cc.math.Matrix4.createByTranslation(-offset.x, -offset.y, 0, translation); - stackMatrix.multiply(translation); - } - cc.glBindTexture2D(this._texture); this.beforeBlit(); this.blit(target); @@ -362,6 +342,9 @@ cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{ this._verticesBuffer=null; this._indicesBuffer=null; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); + if(gridSize !== undefined) this.initWithSize(gridSize, texture, flipped, rect); }, @@ -452,9 +435,18 @@ cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{ blit:function (target) { var n = this._gridSize.width * this._gridSize.height; + + var wt = target._renderCmd._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); //this._shaderProgram.setUniformsForBuiltins(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(target._renderCmd._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); var gl = cc._renderContext, locDirty = this._dirty; @@ -625,6 +617,9 @@ cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{ this._verticesBuffer=null; this._indicesBuffer=null; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); + if(gridSize !== undefined) this.initWithSize(gridSize, texture, flipped, rect); }, @@ -712,8 +707,16 @@ cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{ blit: function (target) { var n = this._gridSize.width * this._gridSize.height; + var wt = target._renderCmd._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(target._renderCmd._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); //this._shaderProgram.setUniformsForBuiltins(); // diff --git a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js index 38ddf9f630..e2f16f8560 100644 --- a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js @@ -29,6 +29,8 @@ cc.PhysicsDebugNode.WebGLRenderCmd = function (renderableObject) { cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); }; cc.PhysicsDebugNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); @@ -42,10 +44,18 @@ node._space.eachShape(cc.DrawShape.bind(node)); node._space.eachConstraint(cc.DrawConstraint.bind(node)); + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + //cc.DrawNode.prototype.draw.call(node); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); node._render(); node.clear(); diff --git a/cocos2d/physics/CCPhysicsSprite.js b/cocos2d/physics/CCPhysicsSprite.js index 442c416236..80df018400 100644 --- a/cocos2d/physics/CCPhysicsSprite.js +++ b/cocos2d/physics/CCPhysicsSprite.js @@ -174,28 +174,22 @@ } this.setNodeDirty(); }, + _syncPosition:function () { - var pos = this._body.GetPosition(); - this._position.x = pos.x * this._PTMRatio; - this._position.y = pos.y * this._PTMRatio; - this._rotationRadians = this._rotation * (Math.PI / 180); + var locPosition = this._position, + pos = this._body.GetPosition(), + x = pos.x * this._PTMRatio, + y = pos.y * this._PTMRatio; + if (locPosition.x !== pos.x || locPosition.y !== pos.y) { + cc.Sprite.prototype.setPosition.call(this, x, y); + } }, _syncRotation:function () { this._rotationRadians = this._body.GetAngle(); - }, - /** - * visit - */ - visit:function () { - if (this._body && this._PTMRatio) { - this._syncPosition(); - if (!this._ignoreBodyRotation) - this._syncRotation(); - } - else { - cc.log("PhysicsSprite body or PTIMRatio was not set"); + var a = cc.radiansToDegrees(this._rotationRadians); + if (this._rotationX !== a) { + cc.Sprite.prototype.setRotation.call(this, a); } - this._super(); }, /** @@ -324,7 +318,6 @@ this._body.p.x = newPosOrxValue; this._body.p.y = yValue; } - //this._syncPosition(); }, /** @@ -333,7 +326,6 @@ */ setPositionX:function (xValue) { this._body.p.x = xValue; - //this._syncPosition(); }, /** @@ -342,7 +334,6 @@ */ setPositionY:function (yValue) { this._body.p.y = yValue; - //this._syncPosition(); }, _syncPosition:function () { @@ -369,12 +360,12 @@ cc.Sprite.prototype.setRotation.call(this, r); } else { this._body.a = -cc.degreesToRadians(r); - //this._syncRotation(); } }, _syncRotation:function () { - if (this._rotationX !== -cc.radiansToDegrees(this._body.a)) { - cc.Sprite.prototype.setRotation.call(this, -cc.radiansToDegrees(this._body.a)); + var a = -cc.radiansToDegrees(this._body.a); + if (this._rotationX !== a) { + cc.Sprite.prototype.setRotation.call(this, a); } }, diff --git a/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js b/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js index ae95d94df9..705749d259 100644 --- a/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js +++ b/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js @@ -47,47 +47,4 @@ cc.Sprite.CanvasRenderCmd.prototype.rendering.call(this, ctx, scaleX, scaleY); }; - proto.getNodeToParentTransform = function(){ - var node = this._node; - - var t = this._transform;// quick reference - // base position - var locBody = node._body, locScaleX = node._scaleX, locScaleY = node._scaleY, locAnchorPIP = this._anchorPointInPoints; - t.tx = locBody.p.x; - t.ty = locBody.p.y; - - // rotation Cos and Sin - var radians = -locBody.a; - var Cos = 1, Sin = 0; - if (radians && !node._ignoreBodyRotation) { - Cos = Math.cos(radians); - Sin = Math.sin(radians); - } - - // base abcd - t.a = t.d = Cos; - t.b = -Sin; - t.c = Sin; - - // scale - if (locScaleX !== 1 || locScaleY !== 1) { - t.a *= locScaleX; - t.c *= locScaleX; - t.b *= locScaleY; - t.d *= locScaleY; - } - - // adjust anchorPoint - t.tx += Cos * -locAnchorPIP.x * locScaleX + -Sin * locAnchorPIP.y * locScaleY; - t.ty -= Sin * -locAnchorPIP.x * locScaleX + Cos * locAnchorPIP.y * locScaleY; - - // if ignore anchorPoint - if (this._ignoreAnchorPointForPosition) { - t.tx += locAnchorPIP.x; - t.ty += locAnchorPIP.y; - } - - return this._transform; - }; - })(); \ No newline at end of file diff --git a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js index dbe46428cd..d2e6b25c25 100644 --- a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js @@ -34,7 +34,9 @@ var proto = cc.PhysicsSprite.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); proto.constructor = cc.PhysicsSprite.WebGLRenderCmd; - proto.rendering = function(ctx){ + proto.spUploadData = cc.Sprite.WebGLRenderCmd.prototype.uploadData; + + proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) { // This is a special class // Sprite can not obtain sign // So here must to calculate of each frame @@ -44,39 +46,6 @@ node._syncRotation(); this.transform(this.getParentRenderCmd(), true); - cc.Sprite.WebGLRenderCmd.prototype.rendering.call(this, ctx); - }; - - proto.getNodeToParentTransform = function(){ - var node = this._node; - var locBody = node._body, locAnchorPIP = this._anchorPointInPoints, locScaleX = node._scaleX, locScaleY = node._scaleY; - var x = locBody.p.x; - var y = locBody.p.y; - - if (this._ignoreAnchorPointForPosition) { - x += locAnchorPIP.x; - y += locAnchorPIP.y; - } - - // Make matrix - var radians = locBody.a, c = 1, s=0; - if (radians && !node._ignoreBodyRotation) { - c = Math.cos(radians); - s = Math.sin(radians); - } - - // Although scale is not used by physics engines, it is calculated just in case - // the sprite is animated (scaled up/down) using actions. - // For more info see: http://www.cocos2d-iphone.org/forum/topic/68990 - if (!cc._rectEqualToZero(locAnchorPIP)) { - x += c * -locAnchorPIP.x * locScaleX + -s * -locAnchorPIP.y * locScaleY; - y += s * -locAnchorPIP.x * locScaleX + c * -locAnchorPIP.y * locScaleY; - } - - // Rot, Translate Matrix - this._transform = cc.affineTransformMake(c * locScaleX, s * locScaleX, - -s * locScaleY, c * locScaleY, x, y); - - return this._transform; + return this.spUploadData(f32buffer, ui32buffer, vertexDataOffset); }; })(); \ No newline at end of file diff --git a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js index 03bee42d9c..cf20db187f 100644 --- a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js +++ b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js @@ -486,7 +486,7 @@ coords.v = 0; return; } - var uvs = locSprite._renderCmd._uvs, + var uvs = locSprite._renderCmd._vertices, bl = uvs[1], tr = uvs[2]; var min = cc.p(bl.u, bl.v); diff --git a/cocos2d/tilemap/CCTMXLayer.js b/cocos2d/tilemap/CCTMXLayer.js index 99f05c192f..7ab275fcd9 100644 --- a/cocos2d/tilemap/CCTMXLayer.js +++ b/cocos2d/tilemap/CCTMXLayer.js @@ -56,11 +56,11 @@ * @property {Number} tileHeight - Height of a tile */ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ - tiles: null, - tileset: null, - layerOrientation: null, - properties: null, - layerName: "", + tiles: null, + tileset: null, + layerOrientation: null, + properties: null, + layerName: "", //size of the layer in tiles _layerSize: null, @@ -112,19 +112,10 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ * @param {Number} [height] The untransformed size's height of the TMXLayer. */ setContentSize:function (size, height) { - cc.Node.prototype.setContentSize.call(this, size, height); + cc.Node.prototype.setContentSize.call(this, size, height); this._renderCmd._updateCacheContext(size, height); }, - /** - * Return texture of cc.SpriteBatchNode - * @function - * @return {cc.Texture2D} - */ - getTexture: function(){ - return this._renderCmd.getTexture(); - }, - /** * Gets layer size. * @return {cc.Size} @@ -142,18 +133,18 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ this._layerSize.height = Var.height; }, - _getLayerWidth: function () { - return this._layerSize.width; - }, - _setLayerWidth: function (width) { - this._layerSize.width = width; - }, - _getLayerHeight: function () { - return this._layerSize.height; - }, - _setLayerHeight: function (height) { - this._layerSize.height = height; - }, + _getLayerWidth: function () { + return this._layerSize.width; + }, + _setLayerWidth: function (width) { + this._layerSize.width = width; + }, + _getLayerHeight: function () { + return this._layerSize.height; + }, + _setLayerHeight: function (height) { + this._layerSize.height = height; + }, /** * Size of the map's tile (could be different from the tile's size) @@ -172,18 +163,18 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ this._mapTileSize.height = Var.height; }, - _getTileWidth: function () { - return this._mapTileSize.width; - }, - _setTileWidth: function (width) { - this._mapTileSize.width = width; - }, - _getTileHeight: function () { - return this._mapTileSize.height; - }, - _setTileHeight: function (height) { - this._mapTileSize.height = height; - }, + _getTileWidth: function () { + return this._mapTileSize.width; + }, + _setTileWidth: function (width) { + this._mapTileSize.width = width; + }, + _getTileHeight: function () { + return this._mapTileSize.height; + }, + _setTileHeight: function (height) { + this._mapTileSize.height = height; + }, /** * Pointer to the map of tiles @@ -352,7 +343,7 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ tile.setPosition(this.getPositionAt(pos)); tile.vertexZ = this._vertexZForPos(pos); tile.anchorX = 0; - tile.anchorY = 0; + tile.anchorY = 0; tile.opacity = this._opacity; var indexForZ = this._atlasIndexForExistantZ(z); @@ -789,7 +780,7 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ sprite.tag = z; sprite.anchorX = 0; - sprite.anchorY = 0; + sprite.anchorY = 0; sprite.opacity = this._opacity; if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { sprite.rotation = 0.0; @@ -802,9 +793,9 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) { // put the anchor in the middle for ease of rotation. sprite.anchorX = 0.5; - sprite.anchorY = 0.5; + sprite.anchorY = 0.5; sprite.x = this.getPositionAt(pos).x + sprite.width / 2; - sprite.y = this.getPositionAt(pos).y + sprite.height / 2; + sprite.y = this.getPositionAt(pos).y + sprite.height / 2; var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0; // handle the 4 diagonally flipped states. @@ -814,10 +805,10 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ sprite.rotation = 270; else if (flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { sprite.rotation = 90; - sprite.setFlippedX(true); + sprite.setFlippedX(true); } else { sprite.rotation = 270; - sprite.setFlippedX(true); + sprite.setFlippedX(true); } } else { if ((gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { diff --git a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js index ebd532912a..335b888e2d 100644 --- a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js @@ -25,7 +25,7 @@ (function(){ cc.TMXLayer.WebGLRenderCmd = function(renderableObject){ cc.Node.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; + this._needDraw = false; }; var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); diff --git a/cocos2d/transitions/CCTransition.js b/cocos2d/transitions/CCTransition.js index bd10515f29..6796074555 100644 --- a/cocos2d/transitions/CCTransition.js +++ b/cocos2d/transitions/CCTransition.js @@ -899,476 +899,6 @@ cc.TransitionShrinkGrow.create = function (t, scene) { return new cc.TransitionShrinkGrow(t, scene); }; -/** - * Flips the screen horizontally.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = new cc.TransitionFlipX(t,scene,o); - */ -cc.TransitionFlipX = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionFlipX# */{ - /** - * Constructor of TransitionFlipX - * @function - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_RIGHT_OVER; - scene && this.initWithDuration(t, scene, o); - }, - - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - - if (this._orientation === cc.TRANSITION_ORIENTATION_RIGHT_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), cc.show(), - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, 0, 0), - cc.callFunc(this.finish, this) - ); - - outA = cc.sequence( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 0, 0), - cc.hide(), cc.delayTime(this._duration / 2) - ); - - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen horizontally.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new cc.TransitionFlipX(t, scene,o) instead. - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionFlipX} - */ -cc.TransitionFlipX.create = function (t, scene, o) { - return new cc.TransitionFlipX(t, scene, o); -}; - -/** - * Flips the screen vertically.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = new cc.TransitionFlipY(time,scene,0); - */ -cc.TransitionFlipY = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionFlipY# */{ - - /** - * Constructor of TransitionFlipY - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_UP_OVER; - scene && this.initWithDuration(t, scene, o); - }, - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - - if (this._orientation === cc.TRANSITION_ORIENTATION_UP_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), cc.show(), - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, 90, 0), - cc.callFunc(this.finish, this) - ); - outA = cc.sequence( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 90, 0), - cc.hide(), cc.delayTime(this._duration / 2) - ); - - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen vertically.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new cc.TransitionFlipY(t, scene,o) instead. - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionFlipY} - */ -cc.TransitionFlipY.create = function (t, scene, o) { - return new cc.TransitionFlipY(t, scene, o); -}; - -/** - * Flips the screen half horizontally and half vertically.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = cc.TransitionFlipAngular(time,scene,o); - */ -cc.TransitionFlipAngular = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionFlipAngular# */{ - /** - * Constructor of TransitionFlipAngular - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_RIGHT_OVER; - scene && this.initWithDuration(t, scene, o); - }, - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - - if (this._orientation === cc.TRANSITION_ORIENTATION_RIGHT_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), cc.show(), - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, -45, 0), - cc.callFunc(this.finish, this) - ); - outA = cc.sequence( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 45, 0), - cc.hide(), cc.delayTime(this._duration / 2) - ); - - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen half horizontally and half vertically.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new new cc.TransitionFlipAngular(t, scene, o) instead - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionFlipAngular} - */ -cc.TransitionFlipAngular.create = function (t, scene, o) { - return new cc.TransitionFlipAngular(t, scene, o); -}; - -/** - * Flips the screen horizontally doing a zoom out/in
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = new cc.TransitionZoomFlipX(time,scene,o); - */ -cc.TransitionZoomFlipX = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionZoomFlipX# */{ - - /** - * Constructor of TransitionZoomFlipX - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_RIGHT_OVER; - scene && this.initWithDuration(t, scene, o); - }, - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - - if (this._orientation === cc.TRANSITION_ORIENTATION_RIGHT_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, 0, 0), - cc.scaleTo(this._duration / 2, 1), cc.show()), - cc.callFunc(this.finish, this) - ); - outA = cc.sequence( - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 0, 0), - cc.scaleTo(this._duration / 2, 0.5)), - cc.hide(), - cc.delayTime(this._duration / 2) - ); - - this._inScene.scale = 0.5; - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen horizontally doing a zoom out/in
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new new cc.TransitionZoomFlipX(t, scene, o) instead - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionZoomFlipX} - */ -cc.TransitionZoomFlipX.create = function (t, scene, o) { - return new cc.TransitionZoomFlipX(t, scene, o); -}; - -/** - * Flips the screen vertically doing a little zooming out/in
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = new cc.TransitionZoomFlipY(t,scene,o); - */ -cc.TransitionZoomFlipY = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionZoomFlipY# */{ - - /** - * Constructor of TransitionZoomFlipY - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_UP_OVER; - scene && this.initWithDuration(t, scene, o); - }, - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - - if (this._orientation === cc.TRANSITION_ORIENTATION_UP_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, 90, 0), - cc.scaleTo(this._duration / 2, 1), cc.show()), - cc.callFunc(this.finish, this)); - - outA = cc.sequence( - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 90, 0), - cc.scaleTo(this._duration / 2, 0.5)), - cc.hide(), cc.delayTime(this._duration / 2)); - - this._inScene.scale = 0.5; - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen vertically doing a little zooming out/in
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new new cc.TransitionZoomFlipY(t, scene, o) instead - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionZoomFlipY} - */ -cc.TransitionZoomFlipY.create = function (t, scene, o) { - return new cc.TransitionZoomFlipY(t, scene, o); -}; - -/** - * Flips the screen half horizontally and half vertically doing a little zooming out/in.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @class - * @extends cc.TransitionSceneOriented - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @example - * var trans = new cc.TransitionZoomFlipAngular(time,scene,o); - */ -cc.TransitionZoomFlipAngular = cc.TransitionSceneOriented.extend(/** @lends cc.TransitionZoomFlipAngular# */{ - - /** - * Constructor of TransitionZoomFlipAngular - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - */ - ctor:function (t, scene, o) { - cc.TransitionSceneOriented.prototype.ctor.call(this); - if(o == null) - o = cc.TRANSITION_ORIENTATION_RIGHT_OVER; - scene && this.initWithDuration(t, scene, o); - }, - /** - * custom on enter - */ - onEnter:function () { - cc.TransitionScene.prototype.onEnter.call(this); - - var inA, outA; - this._inScene.visible = false; - - var inDeltaZ, inAngleZ, outDeltaZ, outAngleZ; - if (this._orientation === cc.TRANSITION_ORIENTATION_RIGHT_OVER) { - inDeltaZ = 90; - inAngleZ = 270; - outDeltaZ = 90; - outAngleZ = 0; - } else { - inDeltaZ = -90; - inAngleZ = 90; - outDeltaZ = -90; - outAngleZ = 0; - } - - inA = cc.sequence( - cc.delayTime(this._duration / 2), - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, inAngleZ, inDeltaZ, -45, 0), - cc.scaleTo(this._duration / 2, 1), cc.show()), - cc.show(), - cc.callFunc(this.finish, this)); - outA = cc.sequence( - cc.spawn( - cc.orbitCamera(this._duration / 2, 1, 0, outAngleZ, outDeltaZ, 45, 0), - cc.scaleTo(this._duration / 2, 0.5)), - cc.hide(), cc.delayTime(this._duration / 2)); - - this._inScene.scale = 0.5; - this._inScene.runAction(inA); - this._outScene.runAction(outA); - } -}); - -/** - * Flips the screen half horizontally and half vertically doing a little zooming out/in.
- * The front face is the outgoing scene and the back face is the incoming scene. - * @deprecated since v3.0,please use new new cc.TransitionZoomFlipAngular(t, scene, o) instead - * @param {Number} t time in seconds - * @param {cc.Scene} scene - * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o - * @return {cc.TransitionZoomFlipAngular} - */ -cc.TransitionZoomFlipAngular.create = function (t, scene, o) { - return new cc.TransitionZoomFlipAngular(t, scene, o); -}; - /** * Fade out the outgoing scene and then fade in the incoming scene. * @class diff --git a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js index ceb2ba680e..4cc744fd00 100644 --- a/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js +++ b/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js @@ -85,12 +85,14 @@ if(node._scale9Enabled) { var locRenderers = node._renderers; var protectChildLen = locRenderers.length; + var flags = cc.Node._dirtyFlags; for(var j=0; j < protectChildLen; j++) { var pchild = locRenderers[j]; if(pchild) { pchild._vertexZ = parentCmd._node._vertexZ; var tempCmd = pchild._renderCmd; tempCmd.transform(this, true); + tempCmd._dirtyFlag = tempCmd._dirtyFlag & flags.transformDirty ^ tempCmd._dirtyFlag; } else { break; diff --git a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js index d755cb87b1..17541d6010 100644 --- a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js +++ b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js @@ -28,6 +28,7 @@ cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; + this._parentCmd = null; this._realAnchorPointInPoints = new cc.Point(0,0); }; @@ -35,14 +36,9 @@ cc.inject(ccs.Armature.RenderCmd, proto); proto.constructor = ccs.Armature.WebGLRenderCmd; - proto.rendering = function (ctx, dontChangeMatrix) { - var node = this._node; - - if(!dontChangeMatrix){ - cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); - cc.kmGLPushMatrix(); - cc.kmGLLoadMatrix(this._stackMatrix); - } + proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) { + var node = this._node, cmd; + var parentCmd = this._parentCmd || this; var locChildren = node._children; var alphaPremultiplied = cc.BlendFunc.ALPHA_PREMULTIPLIED, alphaNonPremultipled = cc.BlendFunc.ALPHA_NON_PREMULTIPLIED; @@ -52,44 +48,63 @@ var selNode = selBone.getDisplayRenderNode(); if (null === selNode) continue; + cmd = selNode._renderCmd; switch (selBone.getDisplayRenderNodeType()) { case ccs.DISPLAY_TYPE_SPRITE: if (selNode instanceof ccs.Skin) { selNode.setShaderProgram(this._shaderProgram); - this._updateColorAndOpacity(selNode._renderCmd, selBone); //because skin didn't call visit() - selNode.updateTransform(); + this._updateColorAndOpacity(cmd, selBone); //because skin didn't call visit() + cmd.transform(parentCmd); var func = selBone.getBlendFunc(); if (func.src !== alphaPremultiplied.src || func.dst !== alphaPremultiplied.dst) selNode.setBlendFunc(selBone.getBlendFunc()); else { - if ((node._blendFunc.src === alphaPremultiplied.src && node._blendFunc.dst === alphaPremultiplied.dst) - && !selNode.getTexture().hasPremultipliedAlpha()) + if (node._blendFunc.src === alphaPremultiplied.src && + node._blendFunc.dst === alphaPremultiplied.dst && + !selNode.getTexture().hasPremultipliedAlpha()) { selNode.setBlendFunc(alphaNonPremultipled); - else + } + else { selNode.setBlendFunc(node._blendFunc); + } } - selNode._renderCmd.rendering(ctx); + // Support batch for Armature skin + cc.renderer._uploadBufferData(cmd); } break; case ccs.DISPLAY_TYPE_ARMATURE: selNode.setShaderProgram(this._shaderProgram); - selNode._renderCmd.rendering(ctx, true); - break; + cmd._parentCmd = this; + // Continue rendering in default default: - selNode._renderCmd.transform(); - selNode._renderCmd.rendering(ctx); + if (cmd.uploadData) { + cc.renderer._uploadBufferData(cmd); + } + else { + // Finish previous batch + cc.renderer._batchRendering(); + cmd.transform(this); + cmd.rendering(cc._renderContext); + } break; } } else if (selBone instanceof cc.Node) { selBone.setShaderProgram(this._shaderProgram); - selBone._renderCmd.transform(); - if(selBone._renderCmd.rendering) - selBone._renderCmd.rendering(ctx); + cmd = selBone._renderCmd; + cmd.transform(this); + if (cmd.uploadData) { + cc.renderer._uploadBufferData(cmd); + } + else if (cmd.rendering) { + // Finish previous batch + cc.renderer._batchRendering(); + cmd.rendering(cc._renderContext); + } } } - if(!dontChangeMatrix) - cc.kmGLPopMatrix(); + this._parentCmd = null; + return 0; }; proto.initShaderCache = function(){ @@ -114,53 +129,16 @@ skinRenderCmd._updateColor(); }; - proto.updateChildPosition = function(ctx, dis, selBone, alphaPremultiplied, alphaNonPremultipled){ - var node = this._node; - dis.updateTransform(); - - var func = selBone.getBlendFunc(); - if (func.src !== alphaPremultiplied.src || func.dst !== alphaPremultiplied.dst) - dis.setBlendFunc(selBone.getBlendFunc()); - else { - if ((node._blendFunc.src === alphaPremultiplied.src && node_blendFunc.dst === alphaPremultiplied.dst) - && !dis.getTexture().hasPremultipliedAlpha()) - dis.setBlendFunc(alphaNonPremultipled); - else - dis.setBlendFunc(node._blendFunc); - } - dis.rendering(ctx); - }; - - proto.updateStatus = function () { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - var colorDirty = locFlag & flags.colorDirty, - opacityDirty = locFlag & flags.opacityDirty; - if(colorDirty) - this._updateDisplayColor(); - - if(opacityDirty) - this._updateDisplayOpacity(); - - if(colorDirty || opacityDirty) - this._updateColor(); - - if (locFlag & flags.orderDirty) - this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag; - - //update the transform every visit, don't need dirty flag, - this.transform(this.getParentRenderCmd(), true); - }; - proto.visit = function(parentCmd){ var node = this._node; // quick return if not visible. children won't be drawn. if (!node._visible) return; - var currentStack = cc.current_stack; - currentStack.stack.push(currentStack.top); + parentCmd = parentCmd || this.getParentRenderCmd(); + if (parentCmd) + this._curLevel = parentCmd._curLevel + 1; this.updateStatus(parentCmd); - currentStack.top = this._stackMatrix; node.sortAllChildren(); @@ -196,6 +174,5 @@ } this._dirtyFlag = 0; - currentStack.top = currentStack.stack.pop(); }; })(); \ No newline at end of file diff --git a/extensions/cocostudio/armature/display/CCDisplayFactory.js b/extensions/cocostudio/armature/display/CCDisplayFactory.js index da8f8601df..772bade72c 100644 --- a/extensions/cocostudio/armature/display/CCDisplayFactory.js +++ b/extensions/cocostudio/armature/display/CCDisplayFactory.js @@ -60,15 +60,17 @@ ccs.displayFactory = { }, _helpTransform: {a:1, b:0, c:0, d:1, tx:0, ty:0}, - updateDisplay: function (bone,dt, dirty) { + updateDisplay: function (bone, dt, dirty) { var display = bone.getDisplayRenderNode(); if(!display) return; switch (bone.getDisplayRenderNodeType()) { case ccs.DISPLAY_TYPE_SPRITE: - if (dirty) + if (dirty) { + display._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); display.updateArmatureTransform(); + } break; case ccs.DISPLAY_TYPE_PARTICLE: this.updateParticleDisplay(bone, display, dt); diff --git a/extensions/cocostudio/armature/display/CCSkin.js b/extensions/cocostudio/armature/display/CCSkin.js index 4553cf568b..f391970d25 100644 --- a/extensions/cocostudio/armature/display/CCSkin.js +++ b/extensions/cocostudio/armature/display/CCSkin.js @@ -108,14 +108,6 @@ ccs.Skin = ccs.Sprite.extend(/** @lends ccs.Skin# */{ this.setRotationY(cc.radiansToDegrees(-skinData.skewY)); this.setPosition(skinData.x, skinData.y); - var localTransform = this.getNodeToParentTransform ? this.getNodeToParentTransform() : this.nodeToParentTransform(); - var skinTransform = this._skinTransform; - skinTransform.a = localTransform.a; - skinTransform.b = localTransform.b; - skinTransform.c = localTransform.c; - skinTransform.d = localTransform.d; - skinTransform.tx = localTransform.tx; - skinTransform.ty = localTransform.ty; this.updateArmatureTransform(); }, @@ -131,7 +123,7 @@ ccs.Skin = ccs.Sprite.extend(/** @lends ccs.Skin# */{ * Updates armature skin's transform with skin transform and bone's transform. */ updateArmatureTransform: function () { - this._renderCmd.updateArmatureTransform(); + this._renderCmd.transform(); }, /** diff --git a/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js b/extensions/cocostudio/armature/display/CCSkinRenderCmd.js similarity index 54% rename from extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js rename to extensions/cocostudio/armature/display/CCSkinRenderCmd.js index 83504f8b14..730a57e605 100644 --- a/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js +++ b/extensions/cocostudio/armature/display/CCSkinRenderCmd.js @@ -25,13 +25,40 @@ (function(){ ccs.Skin.RenderCmd = { - updateArmatureTransform: function () { - var node = this._node; - this._transform = cc.affineTransformConcat( - node._skinTransform, - node.bone.getNodeToArmatureTransform() - ); - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag; + transform: function (parentCmd, recursive) { + var node = this._node, + pt = parentCmd ? parentCmd._worldTransform : null, + t = this._transform, + wt = this._worldTransform, + dirty = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty; + + if (dirty || pt) { + this.originTransform(); + cc.affineTransformConcatIn(t, node.bone.getNodeToArmatureTransform()); + this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag; + } + + if (pt) { + wt.a = t.a * pt.a + t.b * pt.c; + wt.b = t.a * pt.b + t.b * pt.d; + wt.c = t.c * pt.a + t.d * pt.c; + wt.d = t.c * pt.b + t.d * pt.d; + wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx; + wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty; + + var lx = node._offsetPosition.x, rx = lx + node._rect.width, + by = node._offsetPosition.y, ty = by + node._rect.height; + + var vertices = this._vertices; + vertices[0].x = lx * wt.a + ty * wt.c + wt.tx; // tl + vertices[0].y = lx * wt.b + ty * wt.d + wt.ty; + vertices[1].x = lx * wt.a + by * wt.c + wt.tx; // bl + vertices[1].y = lx * wt.b + by * wt.d + wt.ty; + vertices[2].x = rx * wt.a + ty * wt.c + wt.tx; // tr + vertices[2].y = rx * wt.b + ty * wt.d + wt.ty; + vertices[3].x = rx * wt.a + by * wt.c + wt.tx; // br + vertices[3].y = rx * wt.b + by * wt.d + wt.ty; + } }, getNodeToWorldTransform: function () { @@ -55,4 +82,12 @@ var proto = ccs.Skin.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); cc.inject(ccs.Skin.RenderCmd, proto); proto.constructor = ccs.Skin.CanvasRenderCmd; + + ccs.Skin.WebGLRenderCmd = function(renderable){ + cc.Sprite.WebGLRenderCmd.call(this, renderable); + }; + + proto = ccs.Skin.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); + cc.inject(ccs.Skin.RenderCmd, proto); + proto.constructor = ccs.Skin.WebGLRenderCmd; })(); diff --git a/extensions/cocostudio/armature/display/CCSkinWebGLRenderCmd.js b/extensions/cocostudio/armature/display/CCSkinWebGLRenderCmd.js deleted file mode 100644 index aa493a6ee9..0000000000 --- a/extensions/cocostudio/armature/display/CCSkinWebGLRenderCmd.js +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - ccs.Skin.WebGLRenderCmd = function(renderable){ - cc.Sprite.WebGLRenderCmd.call(this, renderable); - }; - - var proto = ccs.Skin.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); - cc.inject(ccs.Skin.RenderCmd, proto); - proto.constructor = ccs.Skin.WebGLRenderCmd; - - // The following static properties must be provided for a auto batchable command - proto.vertexBytesPerUnit = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; - proto.bytesPerUnit = proto.vertexBytesPerUnit; - proto.indicesPerUnit = 6; - proto.verticesPerUnit = 4; - proto._supportBatch = true; - - proto.batchShader = null; - - proto.updateTransform = function(){ - var node = this._node; - var locQuad = this._quad; - var vertices = this._vertices; - - if (this._buffer) { - // - // calculate the Quad based on the Affine Matrix - // - var transform = this.getNodeToParentTransform(); //this._transform; - - var buffer = this._float32View, - i, x, y, offset = 0, - row = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT / 16, - parentCmd = this.getParentRenderCmd(), - parentMatrix = (parentCmd ? parentCmd._stackMatrix : cc.current_stack.top), - t4x4 = this._transform4x4, stackMatrix = this._stackMatrix, - mat = t4x4.mat; - - mat[0] = transform.a; - mat[4] = transform.c; - mat[12] = transform.tx; - mat[1] = transform.b; - mat[5] = transform.d; - mat[13] = transform.ty; - cc.kmMat4Multiply(stackMatrix, parentMatrix, t4x4); - mat[14] = node._vertexZ; - - mat = stackMatrix.mat; - - for (i = 0; i < 4; ++i) { - x = vertices[i].x; - y = vertices[i].y; - z = vertices[i].z; - buffer[offset] = x * mat[0] + y * mat[4] + mat[12]; - buffer[offset+1] = x * mat[1] + y * mat[5] + mat[13]; - buffer[offset+2] = mat[14]; - offset += row; - } - // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS - if (node.textureAtlas) { - node.textureAtlas.updateQuad(locQuad, node.textureAtlas.getTotalQuads()); - } - - // Need manually buffer data because it's invoked during rendering - cc._renderContext.bindBuffer(gl.ARRAY_BUFFER, this._buffer.vertexBuffer); - cc._renderContext.bufferSubData(gl.ARRAY_BUFFER, this._bufferOffset, this._float32View); - cc._renderContext.bindBuffer(gl.ARRAY_BUFFER, null); - } - }; -})(); \ No newline at end of file diff --git a/extensions/spine/CCSkeletonWebGLRenderCmd.js b/extensions/spine/CCSkeletonWebGLRenderCmd.js index 51d2184caa..9eb185a204 100644 --- a/extensions/spine/CCSkeletonWebGLRenderCmd.js +++ b/extensions/spine/CCSkeletonWebGLRenderCmd.js @@ -26,8 +26,10 @@ sp.Skeleton.WebGLRenderCmd = function (renderableObject) { cc.Node.WebGLRenderCmd.call(this, renderableObject); this._needDraw = true; - this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR)); + this._matrix = new cc.math.Matrix4(); + this._matrix.identity(); this._tmpQuad = new cc.V3F_C4B_T2F_Quad(); + this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR)); }; var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); @@ -41,8 +43,16 @@ var locBlendFunc = node._blendFunc; var premultiAlpha = node._premultipliedAlpha; + var wt = this._worldTransform; + this._matrix.mat[0] = wt.a; + this._matrix.mat[4] = wt.c; + this._matrix.mat[12] = wt.tx; + this._matrix.mat[1] = wt.b; + this._matrix.mat[5] = wt.d; + this._matrix.mat[13] = wt.ty; + this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); // cc.glBlendFunc(locBlendFunc.src, locBlendFunc.dst); locSkeleton.r = color.r / 255; locSkeleton.g = color.g / 255; @@ -119,9 +129,8 @@ if (node._debugBones || node._debugSlots) { cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); - //cc.kmGLPushMatrixWitMat4(this._stackMatrix); cc.current_stack.stack.push(cc.current_stack.top); - cc.current_stack.top = this._stackMatrix; + cc.current_stack.top = this._matrix; var drawingUtil = cc._drawingUtil; if (node._debugSlots) { diff --git a/moduleConfig.json b/moduleConfig.json index 6527ce8a27..bd179803ab 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -360,8 +360,7 @@ "extensions/cocostudio/armature/display/CCDisplayFactory.js", "extensions/cocostudio/armature/display/CCDisplayManager.js", "extensions/cocostudio/armature/display/CCSkin.js", - "extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js", - "extensions/cocostudio/armature/display/CCSkinWebGLRenderCmd.js", + "extensions/cocostudio/armature/display/CCSkinRenderCmd.js", "extensions/cocostudio/armature/animation/CCProcessBase.js", "extensions/cocostudio/armature/animation/CCArmatureAnimation.js", "extensions/cocostudio/armature/animation/CCTween.js", diff --git a/tools/build.xml b/tools/build.xml index a5a9998872..1c3408f069 100644 --- a/tools/build.xml +++ b/tools/build.xml @@ -253,8 +253,7 @@ - - + From 81b2a6d38c9d6d8c1c0ad401c71d78c9b0c1635c Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 21 Jun 2016 23:45:35 +0800 Subject: [PATCH 14/15] Tilemap new implementation with WebGL renderer --- cocos2d/tilemap/CCTMXLayer.js | 626 ++++++++------------ cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js | 228 ++++++- cocos2d/tilemap/CCTMXTiledMap.js | 1 - cocos2d/tilemap/CCTMXXMLParser.js | 24 +- 4 files changed, 475 insertions(+), 404 deletions(-) diff --git a/cocos2d/tilemap/CCTMXLayer.js b/cocos2d/tilemap/CCTMXLayer.js index 7ab275fcd9..cc9cb6b555 100644 --- a/cocos2d/tilemap/CCTMXLayer.js +++ b/cocos2d/tilemap/CCTMXLayer.js @@ -62,6 +62,10 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ properties: null, layerName: "", + _textures: null, + _texGrids: null, + _spriteTiles: null, + //size of the layer in tiles _layerSize: null, _mapTileSize: null, @@ -93,6 +97,7 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ this._layerSize = cc.size(0, 0); this._mapTileSize = cc.size(0, 0); + this._spriteTiles = {}; if(mapInfo !== undefined) this.initWithTilesetInfo(tilesetInfo, layerInfo, mapInfo); @@ -105,15 +110,115 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ return new cc.TMXLayer.WebGLRenderCmd(this); }, + _fillTextureGrids: function (tileset, texId) { + var tex = this._textures[texId]; + if (!tex.isLoaded()) { + tex.addEventListener("load", function () { + this._fillTextureGrids(tileset, tex); + }, this); + return; + } + if (!tileset.imageSize.width || !tileset.imageSize.height) { + tileset.imageSize.width = tex.width; + tileset.imageSize.height = tex.height; + } + var tw = tileset._tileSize.width, + th = tileset._tileSize.height, + imageW = tex._contentSize.width, + imageH = tex._contentSize.height, + spacing = tileset.spacing, + margin = tileset.margin, + + cols = Math.floor((imageW - margin*2 + spacing) / (tw + spacing)), + rows = Math.floor((imageH - margin*2 + spacing) / (th + spacing)), + count = rows * cols, + + gid = tileset.firstGid, + maxGid = tileset.firstGid + count, + grids = this._texGrids, + grid = null, + override = grids[gid] ? true : false, + + t, l, r, b; + + for (; gid < maxGid; ++gid) { + // Avoid overlapping + if (override && !grids[gid]) { + override = false; + } + if (!override && grids[gid]) { + break; + } + + grid = { + texId: texId, + x: 0, y: 0, width: 0, height: 0, + t: 0, l: 0, r: 0, b: 0 + }; + tileset.rectForGID(gid, grid); + grid.t = grid.y / imageH; + grid.l = grid.x / imageW; + grid.r = (grid.x + grid.width) / imageW; + grid.b = (grid.y + grid.height) / imageH; + grids[gid] = grid; + } + }, + /** - * Sets the untransformed size of the TMXLayer. - * @override - * @param {cc.Size|Number} size The untransformed size of the TMXLayer or The untransformed size's width of the TMXLayer. - * @param {Number} [height] The untransformed size's height of the TMXLayer. + * Initializes a cc.TMXLayer with a tileset info, a layer info and a map info + * @param {cc.TMXTilesetInfo} tilesetInfo + * @param {cc.TMXLayerInfo} layerInfo + * @param {cc.TMXMapInfo} mapInfo + * @return {Boolean} */ - setContentSize:function (size, height) { - cc.Node.prototype.setContentSize.call(this, size, height); - this._renderCmd._updateCacheContext(size, height); + initWithTilesetInfo:function (tilesetInfo, layerInfo, mapInfo) { + var size = layerInfo._layerSize; + var totalNumberOfTiles = parseInt(size.width * size.height); + + // layerInfo + this.layerName = layerInfo.name; + this.tiles = layerInfo._tiles; + this.properties = layerInfo.properties; + this._layerSize = size; + this._minGID = layerInfo._minGID; + this._maxGID = layerInfo._maxGID; + this._opacity = layerInfo._opacity; + + // tilesetInfo + this.tileset = tilesetInfo; + + // mapInfo + this.layerOrientation = mapInfo.orientation; + this._mapTileSize = mapInfo.getTileSize(); + + var tilesets = mapInfo._tilesets; + if (tilesets) { + this._textures = []; + this._texGrids = []; + var i, len = tilesets.length, tileset, tex; + for (i = 0; i < len; ++i) { + tileset = tilesets[i]; + tex = cc.textureCache.addImage(tileset.sourceImage); + this._textures.push(tex); + this._fillTextureGrids(tileset, i); + if (tileset === tilesetInfo) { + this._texture = tex; + } + } + } + + // offset (after layer orientation is set); + var offset = this._calculateLayerOffset(layerInfo.offset); + this.setPosition(cc.pointPixelsToPoints(offset)); + + // Parse cocos2d properties + this._parseInternalProperties(); + + this.setContentSize(cc.sizePixelsToPoints(cc.size(this._layerSize.width * this._mapTileSize.width, + this._layerSize.height * this._mapTileSize.height))); + this._useAutomaticVertexZ = false; + this._vertexZvalue = 0; + return true; }, /** @@ -241,51 +346,28 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ }, /** - * Initializes a cc.TMXLayer with a tileset info, a layer info and a map info - * @param {cc.TMXTilesetInfo} tilesetInfo - * @param {cc.TMXLayerInfo} layerInfo - * @param {cc.TMXMapInfo} mapInfo - * @return {Boolean} + * Return the value for the specific property name + * @param {String} propertyName + * @return {*} */ - initWithTilesetInfo:function (tilesetInfo, layerInfo, mapInfo) { - // XXX: is 35% a good estimate ? - var size = layerInfo._layerSize; - var totalNumberOfTiles = parseInt(size.width * size.height); - var capacity = totalNumberOfTiles * 0.35 + 1; // 35 percent is occupied ? - var texture; - if (tilesetInfo) - texture = cc.textureCache.addImage(tilesetInfo.sourceImage); - - if (this.initWithTexture(texture, capacity)) { - // layerInfo - this.layerName = layerInfo.name; - this._layerSize = size; - this.tiles = layerInfo._tiles; - this._minGID = layerInfo._minGID; - this._maxGID = layerInfo._maxGID; - this._opacity = layerInfo._opacity; - this.properties = layerInfo.properties; - this._contentScaleFactor = cc.director.getContentScaleFactor(); - - // tilesetInfo - this.tileset = tilesetInfo; - - // mapInfo - this._mapTileSize = mapInfo.getTileSize(); - this.layerOrientation = mapInfo.orientation; - - // offset (after layer orientation is set); - var offset = this._calculateLayerOffset(layerInfo.offset); - this.setPosition(cc.pointPixelsToPoints(offset)); - - this._atlasIndexArray = []; - this.setContentSize(cc.sizePixelsToPoints(cc.size(this._layerSize.width * this._mapTileSize.width, - this._layerSize.height * this._mapTileSize.height))); - this._useAutomaticVertexZ = false; - this._vertexZvalue = 0; - return true; - } - return false; + getProperty:function (propertyName) { + return this.properties[propertyName]; + }, + + /** + * Gets the layer name + * @return {String} + */ + getLayerName:function () { + return this.layerName; + }, + + /** + * Set the layer name + * @param {String} layerName + */ + setLayerName:function (layerName) { + this.layerName = layerName; }, /** @@ -294,11 +376,7 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ * If you are going to call layer.getTileGIDAt() then, don't release the map

*/ releaseMap:function () { - if (this.tiles) - this.tiles = null; - - if (this._atlasIndexArray) - this._atlasIndexArray = null; + this._spriteTiles = {}; }, /** @@ -313,41 +391,45 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ * @return {cc.Sprite} */ getTileAt: function (pos, y) { - if(!pos) + if (pos === undefined) { throw new Error("cc.TMXLayer.getTileAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) + } + var x = pos; + if (y === undefined) { + x = pos.x; + y = pos.y; + } + if (x >= this._layerSize.width || y >= this._layerSize.height || x < 0 || y < 0) { throw new Error("cc.TMXLayer.getTileAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ + } + if (!this.tiles) { cc.log("cc.TMXLayer.getTileAt(): TMXLayer: the tiles map has been released"); return null; } - var tile = null, gid = this.getTileGIDAt(pos); + var tile = null, gid = this.getTileGIDAt(x, y); // if GID == 0, then no tile is present - if (gid === 0) + if (gid === 0) { return tile; + } - var z = 0 | (pos.x + pos.y * this._layerSize.width); - tile = this.getChildByTag(z); + var z = 0 | (x + y * this._layerSize.width); + tile = this._spriteTiles[z]; // tile not created yet. create it if (!tile) { - var rect = this.tileset.rectForGID(gid); + var rect = this._texGrids[gid]; + var tex = this._textures[rect.texId]; rect = cc.rectPixelsToPoints(rect); - tile = new cc.Sprite(); - tile.initWithTexture(this.texture, rect); - tile.batchNode = this; - tile.setPosition(this.getPositionAt(pos)); - tile.vertexZ = this._vertexZForPos(pos); - tile.anchorX = 0; - tile.anchorY = 0; - tile.opacity = this._opacity; + tile = new cc.Sprite(tex, rect); + tile.setPosition(this.getPositionAt(x, y)); + var vertexZ = this._vertexZForPos(x, y); + tile.setVertexZ(vertexZ); + tile.setAnchorPoint(0, 0); + tile.setOpacity(this._opacity); - var indexForZ = this._atlasIndexForExistantZ(z); - this.addSpriteWithoutQuad(tile, indexForZ, z); + this.addChild(tile, vertexZ, z); } return tile; }, @@ -361,18 +443,23 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ * @return {Number} */ getTileGIDAt:function (pos, y) { - if(pos == null) + if (pos === undefined) { throw new Error("cc.TMXLayer.getTileGIDAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) + } + var x = pos; + if (y === undefined) { + x = pos.x; + y = pos.y; + } + if (x >= this._layerSize.width || y >= this._layerSize.height || x < 0 || y < 0) { throw new Error("cc.TMXLayer.getTileGIDAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ + } + if (!this.tiles) { cc.log("cc.TMXLayer.getTileGIDAt(): TMXLayer: the tiles map has been released"); return null; } - var idx = 0 | (pos.x + pos.y * this._layerSize.width); + var idx = 0 | (x + y * this._layerSize.width); // Bits on the far end of the 32-bit global tile ID are used for tile flags var tile = this.tiles[idx]; @@ -381,33 +468,6 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ // XXX: deprecated // tileGIDAt:getTileGIDAt, - /** - * lipped tiles can be changed dynamically - * @param {cc.Point|Number} pos or x - * @param {Number} [y] - * @return {Number} - */ - getTileFlagsAt:function (pos, y) { - if(!pos) - throw new Error("cc.TMXLayer.getTileFlagsAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.getTileFlagsAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.getTileFlagsAt(): TMXLayer: the tiles map has been released"); - return null; - } - - var idx = 0 | (pos.x + pos.y * this._layerSize.width); - // Bits on the far end of the 32-bit global tile ID are used for tile flags - var tile = this.tiles[idx]; - - return (tile & cc.TMX_TILE_FLIPPED_ALL) >>> 0; - }, - // XXX: deprecated - // tileFlagAt:getTileFlagsAt, - /** *

Sets the tile gid (gid = tile global id) at a given tile coordinate.
* The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor . Tileset Mgr +1.
@@ -418,8 +478,9 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ * @param {Number} [flags] */ setTileGID: function(gid, posOrX, flagsOrY, flags) { - if(!posOrX) + if (posOrX === undefined) { throw new Error("cc.TMXLayer.setTileGID(): pos should be non-null"); + } var pos; if (flags !== undefined) { pos = cc.p(posOrX, flagsOrY); @@ -427,19 +488,19 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ pos = posOrX; flags = flagsOrY; } - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) + if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) { throw new Error("cc.TMXLayer.setTileGID(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ + } + if (!this.tiles) { cc.log("cc.TMXLayer.setTileGID(): TMXLayer: the tiles map has been released"); return; } - if(gid !== 0 && gid < this.tileset.firstGid){ + if (gid !== 0 && gid < this.tileset.firstGid) { cc.log( "cc.TMXLayer.setTileGID(): invalid gid:" + gid); return; } flags = flags || 0; - this._setNodeDirtyForCache(); var currentFlags = this.getTileFlagsAt(pos); var currentGID = this.getTileGIDAt(pos); @@ -449,75 +510,101 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ if (gid === 0) this.removeTileAt(pos); else if (currentGID === 0) // empty tile. create a new one - this._insertTileForGID(gidAndFlags, pos); + this._updateTileForGID(gidAndFlags, pos); else { // modifying an existing tile with a non-empty tile var z = pos.x + pos.y * this._layerSize.width; var sprite = this.getChildByTag(z); if (sprite) { - var rect = this.tileset.rectForGID(gid); + var rect = this._texGrids[gid]; + var tex = this._textures[rect.texId]; rect = cc.rectPixelsToPoints(rect); - + sprite.setTexture(tex); sprite.setTextureRect(rect, false); if (flags != null) this._setupTileSprite(sprite, pos, gidAndFlags); this.tiles[z] = gidAndFlags; - } else + } else { this._updateTileForGID(gidAndFlags, pos); + } } } }, + addChild: function (child, localZOrder, tag) { + cc.Node.prototype.addChild.call(this, child, localZOrder, tag); + if (tag !== undefined) { + this._spriteTiles[tag] = child; + child._vertexZ = this._vertexZ + cc.renderer.assignedZStep * tag / this.tiles.length; + // child._renderCmd._needDraw = false; + } + }, + + removeChild: function (child, cleanup) { + if (this._spriteTiles[child.tag]) { + this._spriteTiles[child.tag] = null; + // child._renderCmd._needDraw = true; + } + cc.Node.prototype.removeChild.call(this, child, cleanup); + }, + + /** + * lipped tiles can be changed dynamically + * @param {cc.Point|Number} pos or x + * @param {Number} [y] + * @return {Number} + */ + getTileFlagsAt:function (pos, y) { + if(!pos) + throw new Error("cc.TMXLayer.getTileFlagsAt(): pos should be non-null"); + if(y !== undefined) + pos = cc.p(pos, y); + if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) + throw new Error("cc.TMXLayer.getTileFlagsAt(): invalid position"); + if(!this.tiles){ + cc.log("cc.TMXLayer.getTileFlagsAt(): TMXLayer: the tiles map has been released"); + return null; + } + + var idx = 0 | (pos.x + pos.y * this._layerSize.width); + // Bits on the far end of the 32-bit global tile ID are used for tile flags + var tile = this.tiles[idx]; + + return (tile & cc.TMX_TILE_FLIPPED_ALL) >>> 0; + }, + // XXX: deprecated + // tileFlagAt:getTileFlagsAt, + /** * Removes a tile at given tile coordinate * @param {cc.Point|Number} pos position or x * @param {Number} [y] */ removeTileAt:function (pos, y) { - if(!pos) + if (!pos) { throw new Error("cc.TMXLayer.removeTileAt(): pos should be non-null"); - if(y !== undefined) + } + if (y !== undefined) { pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) + } + if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) { throw new Error("cc.TMXLayer.removeTileAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ + } + if (!this.tiles) { cc.log("cc.TMXLayer.removeTileAt(): TMXLayer: the tiles map has been released"); return; } var gid = this.getTileGIDAt(pos); if (gid !== 0) { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); var z = 0 | (pos.x + pos.y * this._layerSize.width); - var atlasIndex = this._atlasIndexForExistantZ(z); // remove tile from GID map this.tiles[z] = 0; - // remove tile from atlas position array - this._atlasIndexArray.splice(atlasIndex, 1); - // remove it from sprites and/or texture atlas - var sprite = this.getChildByTag(z); - - if (sprite) - cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, true); //this.removeChild(sprite, true); - else { - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) - this.textureAtlas.removeQuadAtIndex(atlasIndex); - - // update possible children - if (this._children) { - var locChildren = this._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - var child = locChildren[i]; - if (child) { - var ai = child.atlasIndex; - if (ai >= atlasIndex) - child.atlasIndex = ai - 1; - } - } - } + var sprite = this._spriteTiles[z]; + if (sprite) { + this.removeChild(sprite, true); } } }, @@ -548,100 +635,6 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ // XXX: Deprecated. For backward compatibility only // positionAt:getPositionAt, - /** - * Return the value for the specific property name - * @param {String} propertyName - * @return {*} - */ - getProperty:function (propertyName) { - return this.properties[propertyName]; - }, - - /** - * Creates the tiles - */ - setupTiles:function () { - // Optimization: quick hack that sets the image size on the tileset - this._renderCmd.initImageSize(); - - // Parse cocos2d properties - this._parseInternalProperties(); - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); - - var locLayerHeight = this._layerSize.height, locLayerWidth = this._layerSize.width; - for (var y = 0; y < locLayerHeight; y++) { - for (var x = 0; x < locLayerWidth; x++) { - var pos = x + locLayerWidth * y; - var gid = this.tiles[pos]; - - // XXX: gid == 0 -. empty tile - if (gid !== 0) { - this._appendTileForGID(gid, cc.p(x, y)); - // Optimization: update min and max GID rendered by the layer - this._minGID = Math.min(gid, this._minGID); - this._maxGID = Math.max(gid, this._maxGID); - } - } - } - - if (!((this._maxGID >= this.tileset.firstGid) && (this._minGID >= this.tileset.firstGid))) { - cc.log("cocos2d:TMX: Only 1 tileset per layer is supported"); - } - }, - - /** - * cc.TMXLayer doesn't support adding a cc.Sprite manually. - * @warning addChild(child); is not supported on cc.TMXLayer. Instead of setTileGID. - * @param {cc.Node} child - * @param {number} zOrder - * @param {number} tag - */ - addChild:function (child, zOrder, tag) { - cc.log("addChild: is not supported on cc.TMXLayer. Instead use setTileGID or tileAt."); - }, - - /** - * Remove child - * @param {cc.Sprite} sprite - * @param {Boolean} cleanup - */ - removeChild:function (sprite, cleanup) { - // allows removing nil objects - if (!sprite) - return; - - if(this._children.indexOf(sprite) === -1){ - cc.log("cc.TMXLayer.removeChild(): Tile does not belong to TMXLayer"); - return; - } - - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); - var atlasIndex = sprite.atlasIndex; - var zz = this._atlasIndexArray[atlasIndex]; - this.tiles[zz] = 0; - this._atlasIndexArray.splice(atlasIndex, 1); - cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, cleanup); - cc.renderer.childrenOrderDirty = true; - }, - - /** - * Gets the layer name - * @return {String} - */ - getLayerName:function () { - return this.layerName; - }, - - /** - * Set the layer name - * @param {String} layerName - */ - setLayerName:function (layerName) { - this.layerName = layerName; - }, - _positionForIsoAt:function (pos) { return cc.p(this._mapTileSize.width / 2 * ( this._layerSize.width + pos.x - pos.y - 1), this._mapTileSize.height / 2 * (( this._layerSize.height * 2 - pos.x - pos.y) - 2)); @@ -676,76 +669,15 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ return ret; }, - _appendTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - var z = 0 | (pos.x + pos.y * this._layerSize.width); - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // optimization: - // The difference between appendTileForGID and insertTileforGID is that append is faster, since - // it appends the tile at the end of the texture atlas - var indexForZ = this._atlasIndexArray.length; - - // don't add it using the "standard" way. - this.insertQuadFromSprite(tile, indexForZ); - - // append should be after addQuadFromSprite since it modifies the quantity values - this._atlasIndexArray.splice(indexForZ, 0, z); - return tile; - }, - - _insertTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - var z = 0 | (pos.x + pos.y * this._layerSize.width); - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // get atlas index - var indexForZ = this._atlasIndexForNewZ(z); - - // Optimization: add the quad without adding a child - this.insertQuadFromSprite(tile, indexForZ); - - // insert it into the local atlasindex array - this._atlasIndexArray.splice(indexForZ, 0, z); - // update possible children - if (this._children) { - var locChildren = this._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - var child = locChildren[i]; - if (child) { - var ai = child.atlasIndex; - if (ai >= indexForZ) - child.atlasIndex = ai + 1; - } - } - } - this.tiles[z] = gid; - return tile; - }, - _updateTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - var locScaleFactor = this._contentScaleFactor; - rect = cc.rect(rect.x / locScaleFactor, rect.y / locScaleFactor, - rect.width / locScaleFactor, rect.height / locScaleFactor); - var z = pos.x + pos.y * this._layerSize.width; - - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // get atlas index - tile.atlasIndex = this._atlasIndexForExistantZ(z); - tile.dirty = true; - tile.updateTransform(); - this.tiles[z] = gid; + if (!this._texGrids[gid]) { + return; + } - return tile; + var idx = 0 | (pos.x + pos.y * this._layerSize.width); + if (idx < this.tiles.length) { + this.tiles[idx] = gid; + } }, //The layer recognizes some special properties, like cc_vertez @@ -761,7 +693,7 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ alphaFuncValue = parseFloat(alphaFuncVal); if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { //todo: need move to WebGL render cmd - this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST); + this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST); // NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison this.shaderProgram.use(); this.shaderProgram.setUniformLocationWith1f(cc.UNIFORM_ALPHA_TEST_VALUE_S, alphaFuncValue); @@ -773,65 +705,59 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ _setupTileSprite:function (sprite, pos, gid) { var z = pos.x + pos.y * this._layerSize.width; - sprite.setPosition(this.getPositionAt(pos)); - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) - sprite.vertexZ = this._vertexZForPos(pos); - else - sprite.tag = z; - - sprite.anchorX = 0; - sprite.anchorY = 0; - sprite.opacity = this._opacity; - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { - sprite.rotation = 0.0; - } - + var posInPixel = this.getPositionAt(pos); + sprite.setPosition(posInPixel); + sprite.setVertexZ(this._vertexZForPos(pos)); + sprite.setAnchorPoint(0, 0); + sprite.setOpacity(this._opacity); sprite.setFlippedX(false); sprite.setFlippedY(false); + sprite.setRotation(0.0); // Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles. if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) { // put the anchor in the middle for ease of rotation. - sprite.anchorX = 0.5; - sprite.anchorY = 0.5; - sprite.x = this.getPositionAt(pos).x + sprite.width / 2; - sprite.y = this.getPositionAt(pos).y + sprite.height / 2; + sprite.setAnchorPoint(0.5, 0.5); + sprite.setPosition(posInPixel.x + sprite.width/2, posInPixel.y + sprite.height/2); var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0; // handle the 4 diagonally flipped states. if (flag === cc.TMX_TILE_HORIZONTAL_FLAG) - sprite.rotation = 90; + sprite.setRotation(90); else if (flag === cc.TMX_TILE_VERTICAL_FLAG) - sprite.rotation = 270; + sprite.setRotation(270); else if (flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { - sprite.rotation = 90; + sprite.setRotation(90); sprite.setFlippedX(true); } else { - sprite.rotation = 270; + sprite.setRotation(270); sprite.setFlippedX(true); } } else { if ((gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { sprite.setFlippedX(true); } - if ((gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0) { sprite.setFlippedY(true); } } }, - _vertexZForPos:function (pos) { + _vertexZForPos:function (x, y) { + if (y === undefined) { + y = x.y; + x = x.x; + } var ret = 0; var maxVal = 0; if (this._useAutomaticVertexZ) { switch (this.layerOrientation) { case cc.TMX_ORIENTATION_ISO: maxVal = this._layerSize.width + this._layerSize.height; - ret = -(maxVal - (pos.x + pos.y)); + ret = -(maxVal - (x + y)); break; case cc.TMX_ORIENTATION_ORTHO: - ret = -(this._layerSize.height - pos.y); + ret = -(this._layerSize.height - y); break; case cc.TMX_ORIENTATION_HEX: cc.log("TMX Hexa zOrder not supported"); @@ -844,39 +770,11 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ ret = this._vertexZvalue; } return ret; - }, - - _atlasIndexForExistantZ:function (z) { - var item; - if (this._atlasIndexArray) { - var locAtlasIndexArray = this._atlasIndexArray; - for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) { - item = locAtlasIndexArray[i]; - if (item === z) - break; - } - } - if(!cc.isNumber(item)) - cc.log("cc.TMXLayer._atlasIndexForExistantZ(): TMX atlas index not found. Shall not happen"); - return i; - }, - - _atlasIndexForNewZ:function (z) { - var locAtlasIndexArray = this._atlasIndexArray; - for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) { - var val = locAtlasIndexArray[i]; - if (z < val) - break; - } - return i; } }); var _p = cc.TMXLayer.prototype; -/** @expose */ -cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture); - // Extended properties /** @expose */ _p.layerWidth; diff --git a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js index 335b888e2d..0568ac8925 100644 --- a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js @@ -25,43 +25,213 @@ (function(){ cc.TMXLayer.WebGLRenderCmd = function(renderableObject){ cc.Node.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = false; + this._needDraw = true; + this._vertices = [ + {x:0, y:0}, + {x:0, y:0}, + {x:0, y:0}, + {x:0, y:0} + ]; + this._color = new Uint32Array(1); + this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST); + + var radian = Math.PI * 90 / 180; + this._sin90 = Math.sin(radian); + this._cos90 = Math.cos(radian); + radian = radian * 3; + this._sin270 = Math.sin(radian); + this._cos270 = Math.cos(radian); }; var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.TMXLayer.WebGLRenderCmd; - proto._updateCacheContext = function(){}; + proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) { + var node = this._node, hasRotation = (node._rotationX || node._rotationY), + layerOrientation = node.layerOrientation, + tiles = node.tiles; + + if (!tiles) { + return 0; + } - proto.initImageSize = function(){ - var node = this._node; - node.tileset.imageSize = node._texture.getContentSizeInPixels(); + var scalex = cc.director._contentScaleFactor * cc.view._scaleX, + scaley = cc.director._contentScaleFactor * cc.view._scaleY, + tilew = node._mapTileSize.width / scalex, + tileh = node._mapTileSize.height / scaley, + extw = node.tileset._tileSize.width / scalex - tilew, + exth = node.tileset._tileSize.height / scaley - tileh, + winw = cc.winSize.width, + winh = cc.winSize.height, + rows = node._layerSize.height, + cols = node._layerSize.width, + grids = node._texGrids, + spTiles = node._spriteTiles, + wt = this._worldTransform, + a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, + ox = -node._contentSize.width * node._anchorPoint.x, + oy = -node._contentSize.height * node._anchorPoint.y, + mapx = ox * a + oy * c + tx, + mapy = ox * b + oy * d + ty; - // By default all the tiles are aliased - // pros: - // - easier to render - // cons: - // - difficult to scale / rotate / etc. - node._texture.setAliasTexParameters(); - }; + var opacity = this._displayedOpacity, + cr = this._displayedColor.r, + cg = this._displayedColor.g, + cb = this._displayedColor.b; + if (node._opacityModifyRGB) { + var ca = opacity / 255; + cr *= ca; + cg *= ca; + cb *= ca; + } + this._color[0] = ((opacity<<24) | (cb<<16) | (cg<<8) | cr); + + // Culling + var startCol = 0, startRow = 0, + maxCol = cols, maxRow = rows; + if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ORTHO) { + startCol = Math.floor(-(mapx - extw * a) / (tilew * a)); + startRow = Math.floor((mapy - exth * d + tileh * rows * d - winh) / (tileh * d)); + maxCol = Math.ceil((winw - mapx + extw * a) / (tilew * a)); + maxRow = rows - Math.floor(-(mapy + exth * d) / (tileh * d)); + // Adjustment + if (startCol < 0) startCol = 0; + if (startRow < 0) startRow = 0; + if (maxCol > cols) maxCol = cols; + if (maxRow > rows) maxRow = rows; + } + + var row, col, + offset = vertexDataOffset, + colOffset = startRow * cols, z, gid, grid, + mask = cc.TMX_TILE_FLIPPED_MASK, + i, top, left, bottom, right, + wa = a, wb = b, wc = c, wd = d, wtx = tx, wty = ty, // world + flagged = false, flippedX = false, flippedY = false, + vertices = this._vertices; + for (row = startRow; row < maxRow; ++row) { + for (col = startCol; col < maxCol; ++col) { + // No more buffer + if (offset + 24 > f32buffer.length) { + cc.renderer._increaseBatchingSize((offset - vertexDataOffset) / 6); + cc.renderer._batchRendering(); + vertexDataOffset = 0; + offset = 0; + } + + z = colOffset + col; + // Skip sprite tiles + if (spTiles[z]) { + continue; + } + + gid = node.tiles[z]; + grid = grids[(gid & mask) >>> 0]; + if (!grid) { + continue; + } + + // Vertices + switch (layerOrientation) { + case cc.TMX_ORIENTATION_ORTHO: + left = col * tilew; + bottom = (rows - row - 1) * tileh; + z = node._vertexZ + cc.renderer.assignedZStep * z / tiles.length; + break; + case cc.TMX_ORIENTATION_ISO: + left = tilew / 2 * ( cols + col - row - 1); + bottom = tileh / 2 * ( rows * 2 - col - row - 2); + z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height; + break; + case cc.TMX_ORIENTATION_HEX: + left = col * tilew * 3 / 4; + bottom = (rows - row - 1) * tileh + ((col % 2 === 1) ? (-tileh / 2) : 0); + z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height; + break; + } + right = left + grid.width * scalex; + top = bottom + grid.height * scaley; + // Rotation and Flip + if (gid > cc.TMX_TILE_DIAGONAL_FLAG) { + flagged = true; + flippedX = (gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0; + flippedY = (gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0; + // if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) { + // var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0; + // // handle the 4 diagonally flipped states. + // var la, lb, lc, ld; + // if (flag === cc.TMX_TILE_HORIZONTAL_FLAG || flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { + // lb = -(lc = this._sin90); + // la = ld = this._cos90; + // } + // else { + // lb = -(lc = this._sin270); + // la = ld = this._cos270; + // } + // left += grid.width * scalex / 2; + // bottom += grid.height * scaley / 2; + // wa = la * a + lb * c; + // wb = la * b + lb * d; + // wc = lc * a + ld * c; + // wd = lc * b + ld * d; + // wtx = a * left + c * bottom + tx; + // wty = d * bottom + ty + b * left; + // right = right - left; + // top = top - bottom; + // left = -right; + // bottom = -top; + // } + } + + vertices[0].x = left * wa + top * wc + wtx; // tl + vertices[0].y = left * wb + top * wd + wty; + vertices[1].x = left * wa + bottom * wc + wtx; // bl + vertices[1].y = left * wb + bottom * wd + wty; + vertices[2].x = right * wa + top * wc + wtx; // tr + vertices[2].y = right * wb + top * wd + wty; + vertices[3].x = right * wa + bottom * wc + wtx; // br + vertices[3].y = right * wb + bottom * wd + wty; + + for (i = 0; i < 4; ++i) { + f32buffer[offset] = vertices[i].x; + f32buffer[offset + 1] = vertices[i].y; + f32buffer[offset + 2] = z; + ui32buffer[offset + 3] = this._color[0]; + switch (i) { + case 0: // tl + f32buffer[offset + 4] = flippedX ? grid.r : grid.l; + f32buffer[offset + 5] = flippedY ? grid.b : grid.t; + break; + case 1: // bl + f32buffer[offset + 4] = flippedX ? grid.r : grid.l; + f32buffer[offset + 5] = flippedY ? grid.t : grid.b; + break; + case 2: // tr + f32buffer[offset + 4] = flippedX ? grid.l : grid.r; + f32buffer[offset + 5] = flippedY ? grid.b : grid.t; + break; + case 3: // br + f32buffer[offset + 4] = flippedX ? grid.l : grid.r; + f32buffer[offset + 5] = flippedY ? grid.t : grid.b; + break; + } - proto._reusedTileWithRect = function(rect){ - var node = this._node; - if (!node._reusedTile) { - node._reusedTile = new cc.Sprite(); - node._reusedTile.initWithTexture(node.texture, rect, false); - node._reusedTile.batchNode = node; - } else { - // XXX HACK: Needed because if "batch node" is nil, - // then the Sprite'squad will be reset - node._reusedTile.batchNode = null; - - // Re-init the sprite - node._reusedTile.setTextureRect(rect, false); - - // restore the batch node - node._reusedTile.batchNode = node; + offset += 6; + } + if (flagged) { + wa = a; + wb = b; + wc = c; + wd = d; + wtx = tx; + wty = ty; + flippedX = false; + flippedY = false; + flagged = false; + } + } + colOffset += cols; } - return node._reusedTile; + return (offset - vertexDataOffset) / 6; }; })(); diff --git a/cocos2d/tilemap/CCTMXTiledMap.js b/cocos2d/tilemap/CCTMXTiledMap.js index 787b62319a..5ca4107ed2 100644 --- a/cocos2d/tilemap/CCTMXTiledMap.js +++ b/cocos2d/tilemap/CCTMXTiledMap.js @@ -414,7 +414,6 @@ cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{ var layer = new cc.TMXLayer(tileset, layerInfo, mapInfo); // tell the layerinfo to release the ownership of the tiles map. layerInfo.ownTiles = false; - layer.setupTiles(); return layer; }, diff --git a/cocos2d/tilemap/CCTMXXMLParser.js b/cocos2d/tilemap/CCTMXXMLParser.js index 5133b09cc5..70509e6802 100644 --- a/cocos2d/tilemap/CCTMXXMLParser.js +++ b/cocos2d/tilemap/CCTMXXMLParser.js @@ -123,7 +123,7 @@ cc.TMXLayerInfo = cc.Class.extend(/** @lends cc.TMXLayerInfo# */{ this.properties = []; this.name = ""; this._layerSize = null; - this._tiles = []; + this._tiles = null; this.visible = true; this._opacity = 0; this.ownTiles = true; @@ -200,8 +200,8 @@ cc.TMXTilesetInfo = cc.Class.extend(/** @lends cc.TMXTilesetInfo# */{ * @param {Number} gid * @return {cc.Rect} */ - rectForGID:function (gid) { - var rect = cc.rect(0, 0, 0, 0); + rectForGID:function (gid, result) { + var rect = result || cc.rect(0, 0, 0, 0); rect.width = this._tileSize.width; rect.height = this._tileSize.height; gid &= cc.TMX_TILE_FLIPPED_MASK; @@ -682,30 +682,31 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{ cc.log("cc.TMXMapInfo.parseXMLFile(): unsupported compression method"); return null; } + var tiles; switch (compression) { case 'gzip': - layer._tiles = cc.unzipBase64AsArray(nodeValue, 4); + tiles = cc.unzipBase64AsArray(nodeValue, 4); break; case 'zlib': var inflator = new Zlib.Inflate(cc.Codec.Base64.decodeAsArray(nodeValue, 1)); - layer._tiles = cc.uint8ArrayToUint32Array(inflator.decompress()); + tiles = cc.uint8ArrayToUint32Array(inflator.decompress()); break; case null: case '': // Uncompressed if (encoding === "base64") - layer._tiles = cc.Codec.Base64.decodeAsArray(nodeValue, 4); + tiles = cc.Codec.Base64.decodeAsArray(nodeValue, 4); else if (encoding === "csv") { - layer._tiles = []; + tiles = []; var csvTiles = nodeValue.split(','); for (var csvIdx = 0; csvIdx < csvTiles.length; csvIdx++) - layer._tiles.push(parseInt(csvTiles[csvIdx])); + tiles.push(parseInt(csvTiles[csvIdx])); } else { //XML format var selDataTiles = data.getElementsByTagName("tile"); - layer._tiles = []; + tiles = []; for (var xmlIdx = 0; xmlIdx < selDataTiles.length; xmlIdx++) - layer._tiles.push(parseInt(selDataTiles[xmlIdx].getAttribute("gid"))); + tiles.push(parseInt(selDataTiles[xmlIdx].getAttribute("gid"))); } break; default: @@ -713,6 +714,9 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{ cc.log("cc.TMXMapInfo.parseXMLFile(): Only base64 and/or gzip/zlib maps are supported"); break; } + if (tiles) { + layer._tiles = new Uint32Array(tiles); + } // The parent element is the last layer var layerProps = selLayer.querySelectorAll("properties > property"); From 00d7ea62f2a2624aa852980194770a1ca95103d7 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 21 Jun 2016 23:45:51 +0800 Subject: [PATCH 15/15] Improve audio engine behavior --- CCBoot.js | 9 +++++++-- cocos2d/audio/CCAudio.js | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CCBoot.js b/CCBoot.js index 135523c47f..4fe8b74ab2 100644 --- a/CCBoot.js +++ b/CCBoot.js @@ -2331,7 +2331,10 @@ cc.game = /** @lends cc.game# */{ if (this._paused) return; this._paused = true; // Pause audio engine - cc.audioEngine && cc.audioEngine._pausePlaying(); + if (cc.audioEngine) { + cc.audioEngine.stopAllEffects(); + cc.audioEngine.pauseMusic(); + } // Pause main loop if (this._intervalId) window.cancelAnimationFrame(this._intervalId); @@ -2345,7 +2348,9 @@ cc.game = /** @lends cc.game# */{ if (!this._paused) return; this._paused = false; // Resume audio engine - cc.audioEngine && cc.audioEngine._resumePlaying(); + if (cc.audioEngine) { + cc.audioEngine.resumeMusic(); + } // Resume main loop this._runMainLoop(); }, diff --git a/cocos2d/audio/CCAudio.js b/cocos2d/audio/CCAudio.js index 00de1364a7..07b2efeec0 100644 --- a/cocos2d/audio/CCAudio.js +++ b/cocos2d/audio/CCAudio.js @@ -810,6 +810,7 @@ cc.Audio.WebAudio.prototype = { for(var i=0; i