diff --git a/CCBoot.js b/CCBoot.js
index 251b2c5fdd..66ffd6c2d3 100644
--- a/CCBoot.js
+++ b/CCBoot.js
@@ -1826,6 +1826,7 @@ var _initSys = function () {
}
}
catch (e) {}
+ tmpCanvas = null;
}
/**
@@ -1936,6 +1937,9 @@ var _initSys = function () {
};
_initSys();
+_tmpCanvas1 = null;
+_tmpCanvas2 = null;
+
//to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
cc.log = cc.warn = cc.error = cc.assert = function () {
};
@@ -2068,7 +2072,7 @@ cc.initEngine = function (config, cb) {
document.body ? _load(config) : cc._addEventListener(window, 'load', _windowLoaded, false);
_engineInitCalled = true;
-}
+};
})();
//+++++++++++++++++++++++++Engine initialization function end+++++++++++++++++++++++++++++
@@ -2592,12 +2596,10 @@ cc.game = /** @lends cc.game# */{
if (this._renderContext) {
cc.renderer = cc.rendererWebGL;
win.gl = this._renderContext; // global variable declared in CCMacro.js
+ cc.renderer.initQuadIndexBuffer();
cc.shaderCache._init();
cc._drawingUtil = new cc.DrawingPrimitiveWebGL(this._renderContext);
cc.textureCache._initializingRenderer();
- // cc.glExt = {};
- // cc.glExt.instanced_arrays = gl.getExtension("ANGLE_instanced_arrays");
- // cc.glExt.element_uint = gl.getExtension("OES_element_index_uint");
} else {
cc.renderer = cc.rendererCanvas;
this._renderContext = cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js
index 4e1756e9ad..a67f9e4c5d 100644
--- a/cocos2d/core/labelttf/CCLabelTTF.js
+++ b/cocos2d/core/labelttf/CCLabelTTF.js
@@ -291,7 +291,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
if (a.r != null && a.g != null && a.b != null && a.a != null) {
this._enableShadow(a, b, c);
} else {
- this._enableShadowNoneColor(a, b, c, d)
+ this._enableShadowNoneColor(a, b, c, d);
}
},
diff --git a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
index a8e0c304a3..d66ea3081c 100644
--- a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
+++ b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
@@ -211,7 +211,7 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
context.setTransform(1, 0, 0, 1, locStatus.contextTransform.x, locStatus.contextTransform.y);
var xOffset = locStatus.xOffset;
var yOffsetArray = locStatus.OffsetYArray;
- this.drawLabels(context, xOffset, yOffsetArray)
+ this.drawLabels(context, xOffset, yOffsetArray);
};
proto._checkWarp = function (strArr, i, maxWidth) {
@@ -350,7 +350,7 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
context.fillText(line, xOffset, yOffsetArray[i]);
}
cc.g_NumberOfDraws++;
- }
+ };
})();
(function(){
diff --git a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
index 7ae79ca588..42ac328cc8 100644
--- a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
+++ b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
@@ -97,7 +97,7 @@
for(var i = 0, len = children.length; i < len; i++)
children[i]._renderCmd._setCachedParent(this);
- if (!this._bakeSprite){
+ if (!this._bakeSprite) {
this._bakeSprite = new cc.BakeSprite();
this._bakeSprite.setAnchorPoint(0,0);
}
diff --git a/cocos2d/core/platform/CCMacro.js b/cocos2d/core/platform/CCMacro.js
index bcb4e63b1d..11e610b1ee 100644
--- a/cocos2d/core/platform/CCMacro.js
+++ b/cocos2d/core/platform/CCMacro.js
@@ -562,26 +562,6 @@ cc.VERTEX_ATTRIB_COLOR = 1;
* @type {Number}
*/
cc.VERTEX_ATTRIB_TEX_COORDS = 2;
-/**
- * @constant
- * @type {Number}
- */
-cc.VERTEX_ATTRIB_MVMAT0 = 3;
-/**
- * @constant
- * @type {Number}
- */
-cc.VERTEX_ATTRIB_MVMAT1 = 4;
-/**
- * @constant
- * @type {Number}
- */
-cc.VERTEX_ATTRIB_MVMAT2 = 5;
-/**
- * @constant
- * @type {Number}
- */
-cc.VERTEX_ATTRIB_MVMAT3 = 6;
/**
* @constant
* @type {Number}
@@ -650,12 +630,17 @@ cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest"
* @constant
* @type {String}
*/
-cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED = "ShaderPositionTextureColorAlphaTestBatched";
+cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST = "ShaderSpritePositionTextureColorAlphaTest";
/**
* @constant
* @type {String}
*/
cc.SHADER_POSITION_COLOR = "ShaderPositionColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_COLOR = "ShaderSpritePositionColor";
/**
* @constant
* @type {String}
diff --git a/cocos2d/core/renderer/GlobalVertexBuffer.js b/cocos2d/core/renderer/GlobalVertexBuffer.js
new file mode 100644
index 0000000000..935c161846
--- /dev/null
+++ b/cocos2d/core/renderer/GlobalVertexBuffer.js
@@ -0,0 +1,138 @@
+/****************************************************************************
+ Copyright (c) 2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var GlobalVertexBuffer = (function () {
+
+var VERTICES_SIZE = 888;
+
+var GlobalVertexBuffer = function (gl) {
+ // WebGL buffer
+ this.gl = gl;
+ this.vertexBuffer = gl.createBuffer();
+
+ this.size = VERTICES_SIZE;
+ this.byteLength = VERTICES_SIZE * 4 * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+
+ // buffer data and views
+ this.data = new ArrayBuffer(this.byteLength);
+ this.dataArray = new Float32Array(this.data);
+
+ // Init buffer data
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this.byteLength, gl.DYNAMIC_DRAW);
+
+ this._dirty = false;
+ this._spaces = {
+ 0: this.byteLength
+ };
+};
+GlobalVertexBuffer.prototype = {
+ constructor: GlobalVertexBuffer,
+
+ allocBuffer: function (offset, size) {
+ var space = this._spaces[offset];
+ if (space && space >= size) {
+ // Remove the space
+ delete this._spaces[offset];
+ if (space > size) {
+ var newOffset = offset + size;
+ this._spaces[newOffset] = space - size;
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+
+ requestBuffer: function (size) {
+ var key, offset, available;
+ for (key in this._spaces) {
+ offset = parseInt(key);
+ available = this._spaces[key];
+ if (available >= size && this.allocBuffer(offset, size)) {
+ return {
+ buffer: this,
+ offset: offset,
+ size: size
+ };
+ }
+ }
+ return null;
+ },
+
+ freeBuffer: function (offset, size) {
+ var spaces = this._spaces;
+ var i, key, end;
+ // Merge with previous space
+ for (key in spaces) {
+ i = parseInt(key);
+ if (i > offset) {
+ break;
+ }
+ if (i + spaces[key] >= offset) {
+ size = size + offset - i;
+ offset = i;
+ break;
+ }
+ }
+
+ end = offset + size;
+ // Merge with next space
+ if (this._spaces[end]) {
+ size += this._spaces[end];
+ delete this._spaces[end];
+ }
+
+ this._spaces[offset] = size;
+ },
+
+ setDirty: function () {
+ this._dirty = true;
+ },
+
+ update: function () {
+ if (this._dirty) {
+ this.gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ // Note: Can memorize different dirty zones and update them separately, maybe faster
+ this.gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.dataArray);
+ this._dirty = false;
+ }
+ },
+
+ destroy: function () {
+ this.gl.deleteBuffer(this.vertexBuffer);
+
+ this.data = null;
+ this.positions = null;
+ this.colors = null;
+ this.texCoords = null;
+
+ this.vertexBuffer = null;
+ }
+};
+
+return GlobalVertexBuffer;
+
+})();
\ No newline at end of file
diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js
index cfb88374d2..4f09548a6c 100644
--- a/cocos2d/core/renderer/RendererWebGL.js
+++ b/cocos2d/core/renderer/RendererWebGL.js
@@ -36,8 +36,10 @@ var CACHING_BUFFER = true;
var ACTIVATE_AUTO_BATCH = true;
// Internal variables
+ // Global vertex buffers, shared by sprites
+var _gbuffers = [],
// Batching general informations
-var _batchedInfo = {
+ _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
@@ -71,6 +73,7 @@ function updateQuadIndexBuffer (numQuads) {
if (!_quadIndexBuffer.buffer) {
return;
}
+ var gl = cc._renderContext;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _quadIndexBuffer.buffer);
var indices = new Uint16Array(numQuads * 6);
@@ -85,13 +88,14 @@ function updateQuadIndexBuffer (numQuads) {
currentQuad += 4;
}
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+ _quadIndexBuffer.maxQuads = numQuads;
}
// 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 = gl.createBuffer();
+ _quadIndexBuffer.buffer = cc._renderContext.createBuffer();
}
if (_quadIndexBuffer.maxQuads < numQuads) {
@@ -101,20 +105,19 @@ function getQuadIndexBuffer (numQuads) {
return _quadIndexBuffer.buffer;
}
-function createVirtualBuffer (buffer, vertexOffset, matrixOrigin, matrixOffset, totalBufferSize, count, data) {
- data = data || new Uint32Array(totalBufferSize / 4);
+function createVirtualBuffer (buffer, vertexOffset, totalBufferSize, count, data) {
+ data = data || new Float32Array(totalBufferSize / 4);
+ var uint32View = new Uint32Array(data.buffer);
var vBuf = {
// The object contains real WebGL buffers, it's created or retrieved via getBatchBuffer
buffer: buffer,
- // The vertex data array (Uint32Array)
- dataArray: data,
+ // The vertex data array (Float32Array)
+ float32View: data,
+ // Uint32 view
+ uint32View: uint32View,
// The start offset in the vertex buffer, in bytes
vertexOffset: vertexOffset,
- // The offset of all matrix data, in bytes
- matrixOrigin: matrixOrigin,
- // The start offset after the origin of matrix data in the vertex buffer, in bytes
- matrixOffset: matrixOffset,
- // Total vertex array buffer size, including vertex data and matrix data, in bytes
+ // Total vertex array buffer size, including vertex data, in bytes
totalBufferSize: totalBufferSize,
// Render command count
count: count
@@ -136,6 +139,35 @@ return {
_currentID: 0,
_clearColor: cc.color(), //background color,default BLACK
+ initQuadIndexBuffer: function () {
+ 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;
+ },
+
getRenderCmd: function (renderableObject) {
//TODO Add renderCmd pool here
return renderableObject._createRenderCmd();
@@ -365,6 +397,8 @@ return {
for (; i < end; ++i) {
_prevRenderCmds[i]._vBuffer = null;
}
+ // keeping i correct, it should run through all elements
+ i--;
continue;
}
}
@@ -379,14 +413,14 @@ return {
cmd1 = _prevRenderCmds[i];
newBuf = createVirtualBuffer(currBuf.buffer,
cmd1._vertexOffset,
- currBuf.matrixOrigin,
- cmd1._matrixOffset,
currBuf.totalBufferSize,
count,
- currBuf.dataArray);
+ currBuf.float32View);
for (; i < end; ++i) {
_prevRenderCmds[i]._vBuffer = newBuf;
}
+ // keeping i correct, it should run through all elements
+ i--;
}
}
}
@@ -435,28 +469,27 @@ return {
}
// Forward check
- var matrixBuffer, martixOrigin;
+ var vertexBuffer;
for (; last < length; ++last) {
cmd = renderCmds[last];
if (vbuffer !== cmd._vBuffer) {
break;
}
- // Lazy update transform matrix in buffer
- if (cmd._savedDirtyFlag) {
- if (!matrixBuffer) {
+ // Lazy update vertex in buffer
+ if (cmd._bufferDirty) {
+ if (!vertexBuffer) {
// Bind buffer
- matrixBuffer = vbuffer;
- martixOrigin = matrixBuffer.matrixOrigin / 4;
- gl.bindBuffer(gl.ARRAY_BUFFER, matrixBuffer.buffer.arrayBuffer);
+ vertexBuffer = vbuffer;
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.buffer.arrayBuffer);
}
- cmd.batchVertexBuffer(matrixBuffer.dataArray, cmd._vertexOffset, martixOrigin, cmd._matrixOffset);
- cmd._savedDirtyFlag = false;
+ cmd.batchVertexBuffer(vertexBuffer.float32View, vertexBuffer.uint32View, cmd._vertexOffset);
+ cmd._bufferDirty = false;
}
}
// Send last buffer to WebGLBuffer
- if (matrixBuffer) {
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, matrixBuffer.dataArray);
+ if (vertexBuffer) {
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertexBuffer.float32View);
}
var size = last - first;
@@ -493,7 +526,6 @@ return {
if (!_batchedInfo.texture)
return 0;
- var matrixOrigin = cmd.vertexBytesPerUnit;
var totalBufferSize = cmd.bytesPerUnit;
// Forward search and collect batch informations
@@ -513,7 +545,6 @@ return {
break;
}
else {
- matrixOrigin += cmd.vertexBytesPerUnit;
totalBufferSize += cmd.bytesPerUnit;
}
++last;
@@ -530,18 +561,14 @@ return {
// Create a virtual buffer
var vbuffer = createVirtualBuffer(buffer,
- 0,
- matrixOrigin,
0,
totalBufferSize,
count);
_currentBuffer = vbuffer;
- var uploadBuffer = vbuffer.dataArray;
+ var uploadBuffer = vbuffer.float32View;
- //all of the divisions by 4 are just because we work with uint32arrays instead of uint8 arrays so all indexes need to be shortened by the factor of 4
- var totalVertexData = matrixOrigin / 4;
+ //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;
- var matrixDataOffset = 0;
// Bind vertex data buffer
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer.buffer.arrayBuffer);
@@ -550,19 +577,17 @@ return {
var i;
for (i = first; i < last; ++i) {
cmd = renderCmds[i];
- cmd.batchVertexBuffer(uploadBuffer, vertexDataOffset, totalVertexData, matrixDataOffset);
+ cmd.batchVertexBuffer(uploadBuffer, vbuffer.uint32View, vertexDataOffset);
if (CACHING_BUFFER) {
cmd._vBuffer = vbuffer;
cmd._vertexOffset = vertexDataOffset;
- cmd._matrixOffset = matrixDataOffset;
}
if (cmd._savedDirtyFlag) {
cmd._savedDirtyFlag = false;
}
vertexDataOffset += cmd.vertexBytesPerUnit / 4;
- matrixDataOffset += cmd.matrixBytesPerUnit / 4;
}
// Submit vertex data in one bufferSubData call
@@ -599,23 +624,11 @@ return {
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 24, vertexOffset);
gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 24, vertexOffset + 12);
gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 24, vertexOffset + 16);
-
- var i;
- var matrixOffset = _currentBuffer.matrixOrigin + _currentBuffer.matrixOffset;
- // Enable matrix vertex attribs row by row (vec4 * 4)
- for (i = 0; i < 4; ++i) {
- gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_MVMAT0 + i);
- gl.vertexAttribPointer(cc.VERTEX_ATTRIB_MVMAT0 + i, 4, gl.FLOAT, false, bytesPerRow * 4, matrixOffset + bytesPerRow * i); //stride is one row
- }
var elemBuffer = getQuadIndexBuffer(count);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer);
gl.drawElements(gl.TRIANGLES, count * 6, gl.UNSIGNED_SHORT, 0);
- for (i = 0; i < 4; ++i) {
- gl.disableVertexAttribArray(cc.VERTEX_ATTRIB_MVMAT0 + i);
- }
-
cc.g_NumberOfDraws++;
},
@@ -628,12 +641,17 @@ 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();
}
- for (i = 0, len = locCmds.length; i < len; i++) {
+ for (i = 0, len = locCmds.length; i < len; ++i) {
cmd = locCmds[i];
next = locCmds[i+1];
diff --git a/cocos2d/core/sprites/CCSprite.js b/cocos2d/core/sprites/CCSprite.js
index c38a2f3788..dc4b35a637 100644
--- a/cocos2d/core/sprites/CCSprite.js
+++ b/cocos2d/core/sprites/CCSprite.js
@@ -132,6 +132,20 @@ 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}
@@ -711,7 +725,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
if(_t.texture)
_t.texture.removeEventListener("load", _t);
texture.addEventListener("load", _t._renderCmd._textureLoadedCallback, _t);
- _t.texture = texture;
+ _t.setTexture(texture);
return true;
}
diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
index 7b977e7ba0..65f1370119 100644
--- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
+++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
@@ -24,24 +24,47 @@
//Sprite's WebGL render command
(function() {
- var matrixByteSize = 4 * 4 * 4; //4 rows of 4 floats, 4 bytes each
+
+ var _resetPointers = true;
cc.Sprite.WebGLRenderCmd = function (renderable) {
cc.Node.WebGLRenderCmd.call(this, renderable);
this._needDraw = true;
- this._quad = new cc.V3F_C4B_T2F_Quad();
- this._quadBufferView = new Uint32Array(this._quad.arrayBuffer);
- this._quadWebBuffer = cc._renderContext.createBuffer();
- this._quadDirty = true;
+ this._vertices = [
+ {x: 0, y: 0, z: 0},
+ {x: 0, y: 0, z: 0},
+ {x: 0, y: 0, z: 0},
+ {x: 0, y: 0, z: 0}
+ ];
+ 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;
- this._matrixOffset = 0;
if (!proto.batchShader) {
- proto.batchShader = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED);
+ proto.batchShader = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
}
};
@@ -50,8 +73,7 @@
// The following static properties must be provided for a auto batchable command
proto.vertexBytesPerUnit = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
- proto.matrixBytesPerUnit = matrixByteSize * 4;
- proto.bytesPerUnit = proto.vertexBytesPerUnit + proto.matrixBytesPerUnit;
+ proto.bytesPerUnit = proto.vertexBytesPerUnit;
proto.indicesPerUnit = 6;
proto.verticesPerUnit = 4;
proto._supportBatch = true;
@@ -65,6 +87,33 @@
info.shader = this.batchShader;
};
+ 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._bufferDirty = true;
+ this._buffer.setDirty();
+ }
+ };
+
+ 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){
@@ -112,12 +161,14 @@
};
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._quadDirty = true;
+ this._bufferDirty = true;
+ this._buffer.setDirty();
};
proto._resetForBatchNode = function () {
@@ -126,12 +177,15 @@
var y1 = node._offsetPosition.y;
var x2 = x1 + node._rect.width;
var y2 = y1 + node._rect.height;
- var locQuad = this._quad;
- locQuad.bl.vertices = {x: x1, y: y1, z: 0};
- locQuad.br.vertices = {x: x2, y: y1, z: 0};
- locQuad.tl.vertices = {x: x1, y: y2, z: 0};
- locQuad.tr.vertices = {x: x2, y: y2, z: 0};
- this._quadDirty = true;
+ 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 () {
@@ -165,7 +219,6 @@
// by default use "Self Render".
// if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
this.setBatchNode(this._batchNode);
- renderCmd._quadDirty = true;
this.dispatchEvent("load");
};
@@ -174,16 +227,16 @@
needConvert = true;
if (needConvert)
rect = cc.rectPointsToPixels(rect);
- var node = this._node;
+ var node = this._node, locQuad = this._quad;
var tex = node._batchNode ? node.textureAtlas.texture : node._texture;
- if (!tex)
+ if (!tex || !locQuad)
return;
var atlasWidth = tex.pixelsWidth;
var atlasHeight = tex.pixelsHeight;
- var left, right, top, bottom, tempSwap, locQuad = this._quad;
+ var left, right, top, bottom, tempSwap;
if (node._rectRotated) {
if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
left = (2 * rect.x + 1) / (2 * atlasWidth);
@@ -251,11 +304,34 @@
locQuad.tr.texCoords.u = right;
locQuad.tr.texCoords.v = top;
}
- this._quadDirty = true;
+ this._bufferDirty = true;
+ this._buffer.setDirty();
};
- proto.transform = function(parentCmd, recursive){
+ proto.transform = function (parentCmd, recursive) {
cc.Node.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive);
+
+ 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;
+ 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;
+ }
+
+ this._bufferDirty = true;
+ this._buffer.setDirty();
+ }
+
this._dirty = true; //use for batching
this._savedDirtyFlag = true;
};
@@ -272,10 +348,13 @@
color4.b *= locDisplayedOpacity / 255.0;
}
var locQuad = this._quad;
- locQuad.bl.colors = color4;
- locQuad.br.colors = color4;
- locQuad.tl.colors = color4;
- locQuad.tr.colors = color4;
+ 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) {
@@ -287,7 +366,7 @@
this._dirty = true;
}
}
- this._quadDirty = true;
+ this._bufferDirty = true;
};
proto._updateBlendFunc = function () {
@@ -320,7 +399,7 @@
cc.log(cc._LogInfos.Sprite_setTexture);
return;
}
- }else{
+ } else {
if(node._texture !== texture){
node._textureLoaded = texture ? texture._textureLoaded : false;
node._texture = texture;
@@ -329,10 +408,9 @@
}
if (texture)
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
else
- this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
-
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_COLOR);
};
proto.updateTransform = function () { //called only at batching.
@@ -445,7 +523,7 @@
proto.rendering = function (ctx) {
var node = this._node, locTexture = node._texture;
- if ((locTexture && (!locTexture._textureLoaded || !node._rect.width || !node._rect.height)) || !this._displayedOpacity)
+ if (!this._buffer || (locTexture && (!locTexture._textureLoaded || !node._rect.width || !node._rect.height)) || !this._displayedOpacity)
return;
var gl = ctx || cc._renderContext;
@@ -455,40 +533,42 @@
if (locTexture) {
if (locTexture._textureLoaded) {
program.use();
- program._setUniformForMVPMatrixWithMat4(this._stackMatrix);
+ program._updateProjectionUniform();
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
//optimize performance for javascript
- cc.glBindTexture2DN(0, locTexture); // = cc.glBindTexture2D(locTexture);
- cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
- if (this._quadDirty) {
- gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.DYNAMIC_DRAW);
- this._quadDirty = false;
+ 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) {
+ cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
+ 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.vertexAttribPointer(0, 3, gl.FLOAT, false, 24, 0); //cc.VERTEX_ATTRIB_POSITION
- gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 24, 12); //cc.VERTEX_ATTRIB_COLOR
- gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 24, 16); //cc.VERTEX_ATTRIB_TEX_COORDS
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ gl.drawArrays(gl.TRIANGLE_STRIP, this._bufferOffset / (this.vertexBytesPerUnit/4), 4);
}
} else {
program.use();
program._setUniformForMVPMatrixWithMat4(this._stackMatrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
- cc.glBindTexture2D(null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._buffer.vertexBuffer);
+ // if (this._bufferDirty) {
+ // gl.bufferSubData(gl.ARRAY_BUFFER, this._bufferOffset, this._float32View);
+ // this._bufferDirty = false;
+ // }
cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer);
- if (this._quadDirty) {
- gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.STATIC_DRAW);
- this._quadDirty = false;
- }
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, 0, 4);
+ gl.drawArrays(gl.TRIANGLE_STRIP, this._bufferOffset / (this.vertexBytesPerUnit/4), 4);
+ _resetPointers = true;
}
cc.g_NumberOfDraws++;
@@ -502,12 +582,12 @@
if (cc.SPRITE_DEBUG_DRAW === 1 || node._showNode) {
// draw bounding box
- var locQuad = this._quad;
+ var vertices = this._vertices;
var verticesG1 = [
- cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y),
- cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y),
- cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y),
- cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y)
+ 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) {
@@ -521,37 +601,20 @@
cc.current_stack.top = cc.current_stack.stack.pop();
};
- proto.batchVertexBuffer = function (buffer, vertexDataOffset, totalVertexData, matrixDataOffset) {
- // buffer is a Uint32 view typed array, not necessarily the same view with render command vertex data,
- // but it's ok, it's just for copy data easier
-
+ proto.batchVertexBuffer = function (f32buffer, int32buffer, vertexDataOffset) {
// Fill in vertex data with quad information (4 vertices for sprite)
- var vertexData = this._quadBufferView;
- var i, len = vertexData.length;
+ var float32Data = this._float32View;
+ var uint32Data = this._uint32View;
+ var i, len = float32Data.length, colorId = 3;
for (i = 0; i < len; ++i) {
- buffer[vertexDataOffset + i] = vertexData[i];
- }
-
- // Fill in matrix data, matrix data is also wrapped into a Uint32 view,
- // you may see strange big values, but it's also ok.
- var matrixData = new Uint32Array(this._stackMatrix.mat.buffer);
- len = matrixData.length;
-
- // We need four matrix data into the buffer, one for each vertex.
- // Otherwise the shader won't work
- var base = totalVertexData + matrixDataOffset;
- var matrixDataSize = matrixByteSize / 4;
- var offset0 = base;
- var offset1 = offset0 + matrixDataSize;
- var offset2 = offset1 + matrixDataSize;
- var offset3 = offset2 + matrixDataSize;
-
- for (i = 0; i < len; ++i) {
- var val = matrixData[i];
- buffer[offset0 + i] = val;
- buffer[offset1 + i] = val;
- buffer[offset2 + i] = val;
- buffer[offset3 + i] = val;
+ if (i === colorId) {
+ int32buffer[vertexDataOffset + i] = uint32Data[i];
+ // 6 data per index
+ colorId += 6;
+ }
+ else {
+ f32buffer[vertexDataOffset + i] = float32Data[i];
+ }
}
};
})();
\ No newline at end of file
diff --git a/cocos2d/shaders/CCGLStateCache.js b/cocos2d/shaders/CCGLStateCache.js
index 1cf4dc2e9e..307157ffbe 100644
--- a/cocos2d/shaders/CCGLStateCache.js
+++ b/cocos2d/shaders/CCGLStateCache.js
@@ -39,6 +39,25 @@ if (cc.ENABLE_GL_STATE_CACHE) {
cc._GLServerState = 0;
if(cc.TEXTURE_ATLAS_USE_VAO)
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;
+ return false;
+ }
+ else {
+ return true;
+ }
+ };
}
// GL State Cache functions
@@ -81,7 +100,7 @@ cc.glUseProgram = function (program) {
if(!cc.ENABLE_GL_STATE_CACHE){
cc.glUseProgram = function (program) {
cc._renderContext.useProgram(program);
- }
+ };
}
/**
@@ -150,9 +169,9 @@ cc.glBlendFuncForParticle = function(sfactor, dfactor) {
}
};
-if(!cc.ENABLE_GL_STATE_CACHE){
+if (!cc.ENABLE_GL_STATE_CACHE) {
cc.glBlendFunc = cc.setBlending;
-};
+}
/**
* Resets the blending mode back to the cached state in case you used glBlendFuncSeparate() or glBlendEquation().
@@ -196,8 +215,6 @@ cc.glEnableVertexAttribs = function (flags) {
if (enablePosition !== cc._vertexAttribPosition) {
if (enablePosition)
ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
- else
- ctx.disableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
cc._vertexAttribPosition = enablePosition;
}
diff --git a/cocos2d/shaders/CCShaderCache.js b/cocos2d/shaders/CCShaderCache.js
index 0fb30350b5..49b786d171 100644
--- a/cocos2d/shaders/CCShaderCache.js
+++ b/cocos2d/shaders/CCShaderCache.js
@@ -84,7 +84,13 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
* @constant
* @type {Number}
*/
- TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED: 8,
+ TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST: 8,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_SPRITE_POSITION_COLOR: 9,
/**
* @public
* @constant
@@ -114,18 +120,22 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
break;
- case this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED:
- program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT_BATCHED, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
+ case this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
- program.addAttribute(cc.ATTRIBUTE_NAME_MVMAT, cc.VERTEX_ATTRIB_MVMAT0);
break;
case this.TYPE_POSITION_COLOR:
program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
break;
+ case this.TYPE_SPRITE_POSITION_COLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ break;
case this.TYPE_POSITION_TEXTURE:
program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_VERT, cc.SHADER_POSITION_TEXTURE_FRAG);
program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
@@ -179,11 +189,11 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
this._programs[cc.SHADER_POSITION_TEXTURECOLORALPHATEST] = program;
this._programs["ShaderPositionTextureColorAlphaTest"] = program;
- // Position Texture Color alpha batched test
+ // Position Texture Color alpha with position precalculated
program = new cc.GLProgram();
- this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED);
- this._programs[cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED] = program;
- this._programs["ShaderPositionTextureColorAlphaTestBatched"] = program;
+ this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST);
+ this._programs[cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST] = program;
+ this._programs["ShaderSpritePositionTextureColorAlphaTest"] = program;
//
// Position, Color shader
@@ -193,6 +203,14 @@ cc.shaderCache = /** @lends cc.shaderCache# */{
this._programs[cc.SHADER_POSITION_COLOR] = program;
this._programs["ShaderPositionColor"] = program;
+ //
+ // Position, Color shader with position precalculated
+ //
+ program = new cc.GLProgram();
+ this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_COLOR);
+ this._programs[cc.SHADER_SPRITE_POSITION_COLOR] = program;
+ this._programs["ShaderSpritePositionColor"] = program;
+
//
// Position Texture shader
//
diff --git a/cocos2d/shaders/CCShaders.js b/cocos2d/shaders/CCShaders.js
index 0668304525..d0c38c60e7 100644
--- a/cocos2d/shaders/CCShaders.js
+++ b/cocos2d/shaders/CCShaders.js
@@ -76,11 +76,20 @@ cc.SHADER_POSITION_COLOR_VERT =
+ "varying lowp vec4 v_fragmentColor;\n"
+ "void main()\n"
+ "{\n"
- //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ " v_fragmentColor = a_color; \n"
+ "}";
+cc.SHADER_SPRITE_POSITION_COLOR_VERT =
+ "attribute vec4 a_position;\n"
+ + "attribute vec4 a_color;\n"
+ + "varying lowp vec4 v_fragmentColor;\n"
+ + "void main()\n"
+ + "{\n"
+ + " gl_Position = CC_PMatrix * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + "}";
+
// --------------------- Shader_PositionColorLengthTexture Shader source------------------------
/**
* @constant
@@ -234,7 +243,6 @@ cc.SHADER_POSITION_TEXTURE_COLOR_VERT =
+ "varying mediump vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
- //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ " v_fragmentColor = a_color; \n"
+ " v_texCoord = a_texCoord; \n"
@@ -260,20 +268,16 @@ cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG =
+ " gl_FragColor = texColor * v_fragmentColor; \n"
+ "}";
-//-----------------------Shader_PositionTextureColorVertBatchedTest_frag Shader Source----------------------------
-// Auto batch implementation inspired from @Heishe 's PR
-// Ref: https://github.com/cocos2d/cocos2d-html5/pull/3248
-cc.SHADER_POSITION_TEXTURE_COLOR_VERT_BATCHED =
+//-----------------------Shader_PositionSpriteTextureColorVertTest_frag Shader Source----------------------------
+cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT =
"attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "attribute vec4 a_color; \n"
- + "attribute mat4 a_mvMatrix;"
+ "varying lowp vec4 v_fragmentColor; \n"
+ "varying mediump vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
- //+ " gl_Position = CC_MVPMatrix * a_position; \n"
- + " gl_Position = (CC_PMatrix * a_mvMatrix) * a_position; \n"
+ + " gl_Position = CC_PMatrix * a_position; \n"
+ " v_fragmentColor = a_color; \n"
+ " v_texCoord = a_texCoord; \n"
+ "}";
diff --git a/moduleConfig.json b/moduleConfig.json
index 96371dd66c..b0498b41be 100644
--- a/moduleConfig.json
+++ b/moduleConfig.json
@@ -74,6 +74,7 @@
"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",
diff --git a/tools/build.xml b/tools/build.xml
index 7077802358..f1251f6159 100644
--- a/tools/build.xml
+++ b/tools/build.xml
@@ -41,6 +41,7 @@
+
@@ -336,6 +337,7 @@
+