|
55 | 55 | * cc.LayerColor's rendering objects of WebGL
|
56 | 56 | */
|
57 | 57 | (function () {
|
| 58 | + var FLOAT_PER_VERTEX = 4; |
| 59 | + |
58 | 60 | cc.LayerColor.WebGLRenderCmd = function (renderable) {
|
59 | 61 | this._layerCmdCtor(renderable);
|
60 | 62 | this._needDraw = true;
|
61 | 63 |
|
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; |
82 | 69 |
|
83 | 70 | this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
|
84 | 71 | };
|
85 | 72 | var proto = cc.LayerColor.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype);
|
86 | 73 | proto.constructor = cc.LayerColor.WebGLRenderCmd;
|
87 | 74 |
|
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; |
116 | 80 | };
|
117 | 81 |
|
118 | 82 | proto.transform = function (parentCmd, recursive) {
|
|
122 | 86 | width = node._contentSize.width,
|
123 | 87 | height = node._contentSize.height;
|
124 | 88 |
|
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; |
136 | 100 | };
|
137 | 101 |
|
138 | 102 | 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; |
141 | 107 | 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]; |
146 | 109 | }
|
147 |
| - this._bindLayerColorsBufferData(); |
| 110 | + this._dataDirty = true; |
148 | 111 | };
|
149 | 112 |
|
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 | + } |
155 | 121 |
|
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); |
160 | 151 | };
|
161 | 152 |
|
162 | 153 | proto.updateBlendFunc = function (blendFunc) {
|
|
167 | 158 | * cc.LayerGradient's rendering objects of WebGL
|
168 | 159 | */
|
169 | 160 | (function () {
|
| 161 | + var FLOAT_PER_VERTEX = 4; |
| 162 | + |
170 | 163 | cc.LayerGradient.WebGLRenderCmd = function (renderable) {
|
171 | 164 | cc.LayerColor.WebGLRenderCmd.call(this, renderable);
|
172 | 165 | this._needDraw = true;
|
|
210 | 203 |
|
211 | 204 | this._clippingRectDirty = true;
|
212 | 205 | 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); |
222 | 208 | }
|
223 | 209 |
|
224 | 210 | //init vertex
|
|
244 | 230 | var sin = Math.sin(angle), cos = Math.cos(angle);
|
245 | 231 | var tx = Math.abs((a.x * cos - a.y * sin) / locAnchor.x), ty = Math.abs((b.x * sin + b.y * cos) / locAnchor.y);
|
246 | 232 | transMat = cc.affineTransformScale(transMat, tx, ty);
|
| 233 | + var pos = this._positionView; |
247 | 234 | for (i = 0; i < stopsLen; i++) {
|
248 | 235 | var stop = stops[i], y = stop.p * contentSize.height;
|
249 | 236 | 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; |
253 | 241 | 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; |
257 | 246 | }
|
258 | 247 |
|
259 |
| - this._bindLayerVerticesBufferData(); |
| 248 | + this._dataDirty = true; |
260 | 249 | };
|
261 | 250 |
|
262 | 251 | proto._updateColor = function () {
|
263 | 252 | var node = this._node, stops = node._colorStops;
|
264 | 253 | if (!stops || stops.length < 2)
|
265 | 254 | return;
|
266 | 255 |
|
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; |
281 | 261 | 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]; |
292 | 269 | }
|
293 |
| - this._bindLayerColorsBufferData(); |
| 270 | + this._dataDirty = true; |
294 | 271 | };
|
295 | 272 |
|
296 | 273 | proto.rendering = function (ctx) {
|
297 | 274 | var context = ctx || cc._renderContext, node = this._node;
|
298 | 275 |
|
| 276 | + if (!this._matrix) { |
| 277 | + this._matrix = new cc.math.Matrix4(); |
| 278 | + this._matrix.identity(); |
| 279 | + } |
| 280 | + |
299 | 281 | //it is too expensive to use stencil to clip, so it use Scissor,
|
300 | 282 | //but it has a bug when layer rotated and layer's content size less than canvas's size.
|
301 | 283 | var clippingRect = this._getClippingRect();
|
|
310 | 292 | this._matrix.mat[5] = wt.d;
|
311 | 293 | this._matrix.mat[13] = wt.ty;
|
312 | 294 |
|
| 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 | + |
313 | 304 | //draw gradient layer
|
314 | 305 | this._shaderProgram.use();
|
315 | 306 | this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
|
316 |
| - context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); |
317 |
| - context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); |
318 | 307 | 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); |
327 | 317 |
|
328 | 318 | context.disable(context.SCISSOR_TEST);
|
329 | 319 | };
|
|
0 commit comments