|
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