Skip to content

Commit 1fe74d3

Browse files
author
pandamicro
committed
Improve Layer webgl rendering
1 parent 086cb20 commit 1fe74d3

File tree

1 file changed

+116
-126
lines changed

1 file changed

+116
-126
lines changed

cocos2d/core/layers/CCLayerWebGLRenderCmd.js

Lines changed: 116 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -55,64 +55,28 @@
5555
* cc.LayerColor's rendering objects of WebGL
5656
*/
5757
(function () {
58+
var FLOAT_PER_VERTEX = 4;
59+
5860
cc.LayerColor.WebGLRenderCmd = function (renderable) {
5961
this._layerCmdCtor(renderable);
6062
this._needDraw = true;
6163

62-
this._matrix = new cc.math.Matrix4();
63-
this._matrix.identity();
64-
65-
//
66-
var _t = this;
67-
_t._squareVerticesAB = new ArrayBuffer(48);
68-
_t._squareColorsAB = new ArrayBuffer(16);
69-
70-
var locSquareVerticesAB = _t._squareVerticesAB, locSquareColorsAB = _t._squareColorsAB;
71-
var locVertex3FLen = cc.Vertex3F.BYTES_PER_ELEMENT, locColorLen = cc._WebGLColor.BYTES_PER_ELEMENT;
72-
_t._squareVertices = [new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, 0),
73-
new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen),
74-
new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * 2),
75-
new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * 3)];
76-
_t._squareColors = [new cc._WebGLColor(0, 0, 0, 255, locSquareColorsAB, 0),
77-
new cc._WebGLColor(0, 0, 0, 255, locSquareColorsAB, locColorLen),
78-
new cc._WebGLColor(0, 0, 0, 255, locSquareColorsAB, locColorLen * 2),
79-
new cc._WebGLColor(0, 0, 0, 255, locSquareColorsAB, locColorLen * 3)];
80-
_t._verticesFloat32Buffer = cc._renderContext.createBuffer();
81-
_t._colorsUint8Buffer = cc._renderContext.createBuffer();
64+
this._matrix = null;
65+
66+
this.initData(4);
67+
this._color = new Uint32Array(1);
68+
this._vertexBuffer = null;
8269

8370
this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
8471
};
8572
var proto = cc.LayerColor.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype);
8673
proto.constructor = cc.LayerColor.WebGLRenderCmd;
8774

88-
proto.rendering = function (ctx) {
89-
var context = ctx || cc._renderContext;
90-
var node = this._node;
91-
92-
var wt = this._worldTransform;
93-
this._matrix.mat[0] = wt.a;
94-
this._matrix.mat[4] = wt.c;
95-
this._matrix.mat[12] = wt.tx;
96-
this._matrix.mat[1] = wt.b;
97-
this._matrix.mat[5] = wt.d;
98-
this._matrix.mat[13] = wt.ty;
99-
100-
this._shaderProgram.use();
101-
this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
102-
context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
103-
context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
104-
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
105-
106-
//
107-
// Attributes
108-
//
109-
context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer);
110-
context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, context.FLOAT, false, 0, 0);
111-
112-
context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer);
113-
context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0);
114-
115-
context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length);
75+
proto.initData = function (vertexCount) {
76+
this._data = new ArrayBuffer(16 * vertexCount);
77+
this._positionView = new Float32Array(this._data);
78+
this._colorView = new Uint32Array(this._data);
79+
this._dataDirty = true;
11680
};
11781

11882
proto.transform = function (parentCmd, recursive) {
@@ -122,41 +86,68 @@
12286
width = node._contentSize.width,
12387
height = node._contentSize.height;
12488

125-
var locSquareVertices = this._squareVertices;
126-
locSquareVertices[1].x = width;
127-
locSquareVertices[2].y = height;
128-
locSquareVertices[3].x = width;
129-
locSquareVertices[3].y = height;
130-
locSquareVertices[0].z =
131-
locSquareVertices[1].z =
132-
locSquareVertices[2].z =
133-
locSquareVertices[3].z = node._vertexZ;
134-
135-
this._bindLayerVerticesBufferData();
89+
var pos = this._positionView;
90+
pos[FLOAT_PER_VERTEX] = width; // br.x
91+
pos[FLOAT_PER_VERTEX * 2 + 1] = height; // tl.y
92+
pos[FLOAT_PER_VERTEX * 3] = width; // tr.x
93+
pos[FLOAT_PER_VERTEX * 3 + 1] = height; // tr.y
94+
pos[2].z =
95+
pos[FLOAT_PER_VERTEX + 2] =
96+
pos[FLOAT_PER_VERTEX * 2 + 2] =
97+
pos[FLOAT_PER_VERTEX * 3 + 2] = node._vertexZ;
98+
99+
this._dataDirty = true;
136100
};
137101

138102
proto._updateColor = function () {
139-
var locDisplayedColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity,
140-
locSquareColors = this._squareColors;
103+
var color = this._displayedColor;
104+
this._color[0] = ((this._displayedOpacity << 24) | (color.b << 16) | (color.g << 8) | color.r);
105+
106+
var colors = this._colorView;
141107
for (var i = 0; i < 4; i++) {
142-
locSquareColors[i].r = locDisplayedColor.r;
143-
locSquareColors[i].g = locDisplayedColor.g;
144-
locSquareColors[i].b = locDisplayedColor.b;
145-
locSquareColors[i].a = locDisplayedOpacity;
108+
colors[i * FLOAT_PER_VERTEX + 3] = this._color[0];
146109
}
147-
this._bindLayerColorsBufferData();
110+
this._dataDirty = true;
148111
};
149112

150-
proto._bindLayerVerticesBufferData = function () {
151-
var glContext = cc._renderContext;
152-
glContext.bindBuffer(glContext.ARRAY_BUFFER, this._verticesFloat32Buffer);
153-
glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB, glContext.DYNAMIC_DRAW);
154-
};
113+
proto.rendering = function (ctx) {
114+
var gl = ctx || cc._renderContext;
115+
var node = this._node;
116+
117+
if (!this._matrix) {
118+
this._matrix = new cc.math.Matrix4();
119+
this._matrix.identity();
120+
}
155121

156-
proto._bindLayerColorsBufferData = function () {
157-
var glContext = cc._renderContext;
158-
glContext.bindBuffer(glContext.ARRAY_BUFFER, this._colorsUint8Buffer);
159-
glContext.bufferData(glContext.ARRAY_BUFFER, this._squareColorsAB, glContext.STATIC_DRAW);
122+
var wt = this._worldTransform;
123+
this._matrix.mat[0] = wt.a;
124+
this._matrix.mat[4] = wt.c;
125+
this._matrix.mat[12] = wt.tx;
126+
this._matrix.mat[1] = wt.b;
127+
this._matrix.mat[5] = wt.d;
128+
this._matrix.mat[13] = wt.ty;
129+
130+
if (this._dataDirty) {
131+
if (!this._vertexBuffer) {
132+
this._vertexBuffer = gl.createBuffer();
133+
}
134+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
135+
gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
136+
this._dataDirty = false;
137+
}
138+
139+
this._shaderProgram.use();
140+
this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
141+
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
142+
143+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
144+
gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
145+
gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
146+
147+
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
148+
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
149+
150+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
160151
};
161152

162153
proto.updateBlendFunc = function (blendFunc) {
@@ -167,6 +158,8 @@
167158
* cc.LayerGradient's rendering objects of WebGL
168159
*/
169160
(function () {
161+
var FLOAT_PER_VERTEX = 4;
162+
170163
cc.LayerGradient.WebGLRenderCmd = function (renderable) {
171164
cc.LayerColor.WebGLRenderCmd.call(this, renderable);
172165
this._needDraw = true;
@@ -210,15 +203,8 @@
210203

211204
this._clippingRectDirty = true;
212205
var i, stopsLen = stops.length, verticesLen = stopsLen * 2, contentSize = node._contentSize;
213-
var locVertices = this._squareVertices;
214-
if (locVertices.length < verticesLen) {
215-
this._squareVerticesAB = new ArrayBuffer(verticesLen * 12);
216-
locVertices.length = 0;
217-
var locSquareVerticesAB = this._squareVerticesAB;
218-
var locVertex3FLen = cc.Vertex3F.BYTES_PER_ELEMENT;
219-
for (i = 0; i < verticesLen; i++) {
220-
locVertices.push(new cc.Vertex3F(0, 0, 0, locSquareVerticesAB, locVertex3FLen * i));
221-
}
206+
if (this._positionView.length / FLOAT_PER_VERTEX < verticesLen) {
207+
this.initData(verticesLen);
222208
}
223209

224210
//init vertex
@@ -244,58 +230,54 @@
244230
var sin = Math.sin(angle), cos = Math.cos(angle);
245231
var tx = Math.abs((a.x * cos - a.y * sin) / locAnchor.x), ty = Math.abs((b.x * sin + b.y * cos) / locAnchor.y);
246232
transMat = cc.affineTransformScale(transMat, tx, ty);
233+
var pos = this._positionView;
247234
for (i = 0; i < stopsLen; i++) {
248235
var stop = stops[i], y = stop.p * contentSize.height;
249236
var p0 = cc.pointApplyAffineTransform(-locAnchor.x, y - locAnchor.y, transMat);
250-
locVertices[i * 2].x = p0.x;
251-
locVertices[i * 2].y = p0.y;
252-
locVertices[i * 2].z = node._vertexZ;
237+
var offset = i * 2 * FLOAT_PER_VERTEX;
238+
pos[offset] = p0.x;
239+
pos[offset + 1] = p0.y;
240+
pos[offset + 2] = node._vertexZ;
253241
var p1 = cc.pointApplyAffineTransform(contentSize.width - locAnchor.x, y - locAnchor.y, transMat);
254-
locVertices[i * 2 + 1].x = p1.x;
255-
locVertices[i * 2 + 1].y = p1.y;
256-
locVertices[i * 2 + 1].z = node._vertexZ;
242+
offset += FLOAT_PER_VERTEX;
243+
pos[offset] = p1.x;
244+
pos[offset + 1] = p1.y;
245+
pos[offset + 2] = node._vertexZ;
257246
}
258247

259-
this._bindLayerVerticesBufferData();
248+
this._dataDirty = true;
260249
};
261250

262251
proto._updateColor = function () {
263252
var node = this._node, stops = node._colorStops;
264253
if (!stops || stops.length < 2)
265254
return;
266255

267-
//init color
268-
var i, stopsLen = stops.length;
269-
var locColors = this._squareColors, verticesLen = stopsLen * 2;
270-
if (locColors.length < verticesLen) {
271-
this._squareColorsAB = new ArrayBuffer(verticesLen * 4);
272-
locColors.length = 0;
273-
var locSquareColorsAB = this._squareColorsAB;
274-
var locColorLen = cc._WebGLColor.BYTES_PER_ELEMENT;
275-
for (i = 0; i < verticesLen; i++) {
276-
locColors.push(new cc._WebGLColor(0, 0, 0, 255, locSquareColorsAB, locColorLen * i));
277-
}
278-
}
279-
280-
var opacityf = this._displayedOpacity / 255.0; //, displayColor = this._displayedColor;
256+
var stopsLen = stops.length,
257+
stopColor,
258+
offset,
259+
colors = this._colorView,
260+
opacityf = this._displayedOpacity / 255;
281261
for (i = 0; i < stopsLen; i++) {
282-
var stopColor = stops[i].color, locSquareColor0 = locColors[i * 2], locSquareColor1 = locColors[i * 2 + 1];
283-
locSquareColor0.r = stopColor.r;
284-
locSquareColor0.g = stopColor.g;
285-
locSquareColor0.b = stopColor.b;
286-
locSquareColor0.a = stopColor.a * opacityf;
287-
288-
locSquareColor1.r = stopColor.r;
289-
locSquareColor1.g = stopColor.g;
290-
locSquareColor1.b = stopColor.b;
291-
locSquareColor1.a = stopColor.a * opacityf;
262+
stopColor = stops[i].color;
263+
this._color[0] = ((stopColor.a*opacityf) << 24) | (stopColor.b << 16) | (stopColor.g << 8) | stopColor.r;
264+
265+
offset = i * 2 * FLOAT_PER_VERTEX;
266+
colors[offset + 3] = this._color[0];
267+
offset += FLOAT_PER_VERTEX;
268+
colors[offset + 3] = this._color[0];
292269
}
293-
this._bindLayerColorsBufferData();
270+
this._dataDirty = true;
294271
};
295272

296273
proto.rendering = function (ctx) {
297274
var context = ctx || cc._renderContext, node = this._node;
298275

276+
if (!this._matrix) {
277+
this._matrix = new cc.math.Matrix4();
278+
this._matrix.identity();
279+
}
280+
299281
//it is too expensive to use stencil to clip, so it use Scissor,
300282
//but it has a bug when layer rotated and layer's content size less than canvas's size.
301283
var clippingRect = this._getClippingRect();
@@ -310,20 +292,28 @@
310292
this._matrix.mat[5] = wt.d;
311293
this._matrix.mat[13] = wt.ty;
312294

295+
if (this._dataDirty) {
296+
if (!this._vertexBuffer) {
297+
this._vertexBuffer = gl.createBuffer();
298+
}
299+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
300+
gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
301+
this._dataDirty = false;
302+
}
303+
313304
//draw gradient layer
314305
this._shaderProgram.use();
315306
this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
316-
context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
317-
context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
318307
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
319-
//
320-
// Attributes
321-
//
322-
context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer);
323-
context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, context.FLOAT, false, 0, 0);
324-
context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer);
325-
context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0);
326-
context.drawArrays(context.TRIANGLE_STRIP, 0, this._squareVertices.length);
308+
309+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
310+
gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
311+
gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
312+
313+
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
314+
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
315+
316+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
327317

328318
context.disable(context.SCISSOR_TEST);
329319
};

0 commit comments

Comments
 (0)