1 /****************************************************************************
  2  Copyright (c) 2010-2013 cocos2d-x.org
  3  Copyright (c) 2009      On-Core
  4  Copyright (c) 2008-2010 Ricardo Quesada
  5  Copyright (c) 2011      Zynga Inc.
  6 
  7  http://www.cocos2d-x.org
  8 
  9  Permission is hereby granted, free of charge, to any person obtaining a copy
 10  of this software and associated documentation files (the "Software"), to deal
 11  in the Software without restriction, including without limitation the rights
 12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 13  copies of the Software, and to permit persons to whom the Software is
 14  furnished to do so, subject to the following conditions:
 15 
 16  The above copyright notice and this permission notice shall be included in
 17  all copies or substantial portions of the Software.
 18 
 19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 25  THE SOFTWARE.
 26  ****************************************************************************/
 27 
 28 /**
 29  * Base class for cc.Grid
 30  * @class
 31  * @extends cc.Class
 32  */
 33 cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
 34     _active:false,
 35     _reuseGrid:0,
 36     _gridSize:null,
 37     _texture:null,
 38     _step:null,
 39     _grabber:null,
 40     _isTextureFlipped:false,
 41     _shaderProgram:null,
 42     _directorProjection:0,
 43 
 44     _dirty:false,
 45 
 46     ctor:function () {
 47         this._active=false;
 48         this._reuseGrid=0;
 49         this._gridSize=null;
 50         this._texture=null;
 51         this._step = cc.p(0, 0);
 52         this._grabber=null;
 53         this._isTextureFlipped=false;
 54         this._shaderProgram=null;
 55         this._directorProjection=0;
 56         this._dirty=false;
 57     },
 58 
 59     /**
 60      * whether or not the grid is active
 61      * @return {Boolean}
 62      */
 63     isActive:function () {
 64         return this._active;
 65     },
 66 
 67     /**
 68      * whether or not the grid is active
 69      * @param {Number} active
 70      */
 71     setActive:function (active) {
 72         this._active = active;
 73         if (!active) {
 74             var director = cc.Director.getInstance();
 75             var proj = director.getProjection();
 76             director.setProjection(proj);
 77         }
 78     },
 79 
 80     /**
 81      * get number of times that the grid will be reused
 82      * @return {Number}
 83      */
 84     getReuseGrid:function () {
 85         return this._reuseGrid;
 86     },
 87     /**
 88      * set number of times that the grid will be reused
 89      * @param reuseGrid
 90      */
 91     setReuseGrid:function (reuseGrid) {
 92         this._reuseGrid = reuseGrid;
 93     },
 94 
 95     /**
 96      * get size of the grid
 97      * @return {cc.Size}
 98      */
 99     getGridSize:function () {
100         return cc.size(this._gridSize.width, this._gridSize.height);
101     },
102 
103     /**
104      * set size of the grid
105      * @param {cc.Size} gridSize
106      */
107     setGridSize:function (gridSize) {
108         this._gridSize.width = parseInt(gridSize.width);
109         this._gridSize.height = parseInt(gridSize.height);
110     },
111 
112     /**
113      * get pixels between the grids
114      * @return {cc.Point}
115      */
116     getStep:function () {
117         return cc.p(this._step.x, this._step.y);
118     },
119 
120     /**
121      * set pixels between the grids
122      * @param {cc.Point} step
123      */
124     setStep:function (step) {
125         this._step.x = step.x;
126         this._step.y = step.y;
127     },
128 
129     /**
130      * get wheter or not the texture is flipped
131      * @return {Boolean}
132      */
133     isTextureFlipped:function () {
134         return this._isTextureFlipped;
135     },
136 
137     /**
138      * set wheter or not the texture is flipped
139      * @param {Boolean} flipped
140      */
141     setTextureFlipped:function (flipped) {
142         if (this._isTextureFlipped != flipped) {
143             this._isTextureFlipped = flipped;
144             this.calculateVertexPoints();
145         }
146     },
147 
148     /**
149      *
150      * @param {cc.Size} gridSize
151      * @param {cc.Texture2D} [texture=]
152      * @param {Boolean} [flipped=false]
153      * @returns {boolean}
154      */
155     initWithSize:function (gridSize, texture, flipped) {
156         if (!texture) {
157             var director = cc.Director.getInstance();
158             var winSize = director.getWinSizeInPixels();
159 
160             var POTWide = cc.NextPOT(winSize.width);
161             var POTHigh = cc.NextPOT(winSize.height);
162 
163             var data = new Uint8Array(POTWide * POTHigh * 4);
164             if (!data) {
165                 cc.log("cocos2d: CCGrid: not enough memory.");
166                 return false;
167             }
168 
169             texture = new cc.Texture2D();
170             // we only use rgba8888
171             texture.initWithData(data, cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888, POTWide, POTHigh, winSize);
172             if (!texture) {
173                 cc.log("cocos2d: CCGrid: error creating texture");
174                 return false;
175             }
176         }
177 
178         flipped = flipped || false;
179 
180         this._active = false;
181         this._reuseGrid = 0;
182         this._gridSize = gridSize;
183         this._texture = texture;
184         this._isTextureFlipped = flipped;
185 
186         var texSize = this._texture.getContentSize();
187         this._step.x = texSize.width / gridSize.width;
188         this._step.y = texSize.height / gridSize.height;
189 
190         this._grabber = new cc.Grabber();
191         if (!this._grabber)
192             return false;
193         this._grabber.grab(this._texture);
194         this._shaderProgram = cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_TEXTURE);
195         this.calculateVertexPoints();
196         return true;
197     },
198 
199     beforeDraw:function () {
200         // save projection
201         this._directorProjection = cc.Director.getInstance().getProjection();
202 
203         // 2d projection
204         //    [director setProjection:kCCDirectorProjection2D];
205         this.set2DProjection();
206         this._grabber.beforeRender(this._texture);
207     },
208 
209     afterDraw:function (target) {
210         this._grabber.afterRender(this._texture);
211 
212         // restore projection
213         cc.Director.getInstance().setProjection(this._directorProjection);
214 
215         if (target.getCamera().isDirty()) {
216             var offset = target.getAnchorPointInPoints();
217 
218             //
219             // XXX: Camera should be applied in the AnchorPoint
220             //
221             cc.kmGLTranslatef(offset.x, offset.y, 0);
222             target.getCamera().locate();
223             cc.kmGLTranslatef(-offset.x, -offset.y, 0);
224         }
225 
226         cc.glBindTexture2D(this._texture);
227 
228         // restore projection for default FBO .fixed bug #543 #544
229         //TODO:         CCDirector::sharedDirector().setProjection(CCDirector::sharedDirector().getProjection());
230         //TODO:         CCDirector::sharedDirector().applyOrientation();
231         this.blit();
232     },
233 
234     blit:function () {
235         cc.log("cc.GridBase.blit(): Shall be overridden in subclass.");
236     },
237 
238     reuse:function () {
239         cc.log("cc.GridBase.reuse(): Shall be overridden in subclass.");
240     },
241 
242     calculateVertexPoints:function () {
243         cc.log("cc.GridBase.calculateVertexPoints(): Shall be overridden in subclass.");
244     },
245 
246     set2DProjection:function () {
247         var winSize = cc.Director.getInstance().getWinSizeInPixels();
248 
249         var gl = cc.renderContext;
250         gl.viewport(0, 0, winSize.width , winSize.height);
251         cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
252         cc.kmGLLoadIdentity();
253 
254         var orthoMatrix = new cc.kmMat4();
255         cc.kmMat4OrthographicProjection(orthoMatrix, 0, winSize.width, 0, winSize.height, -1, 1);
256         cc.kmGLMultMatrix(orthoMatrix);
257 
258         cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
259         cc.kmGLLoadIdentity();
260         cc.setProjectionMatrixDirty()
261     }
262 });
263 
264 /**
265  * create one cc.GridBase Object
266  * @param {cc.Size} gridSize
267  * @param {cc.Texture2D} [texture=]
268  * @param {Boolean} [flipped=]
269  * @return {cc.GridBase}
270  */
271 cc.GridBase.create = function (gridSize, texture, flipped) {
272     var gridBase = new cc.GridBase();
273     if (gridBase && gridBase.initWithSize(gridSize, texture, flipped))
274         return gridBase;
275     return null;
276 };
277 
278 /**
279  * cc.Grid3D is a 3D grid implementation. Each vertex has 3 dimensions: x,y,z
280  * @class
281  * @extends cc.GridBase
282  */
283 cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{
284     _texCoordinates:null,
285     _vertices:null,
286     _originalVertices:null,
287     _indices:null,
288 
289     _texCoordinateBuffer:null,
290     _verticesBuffer:null,
291     _indicesBuffer:null,
292 
293     ctor:function () {
294         cc.GridBase.prototype.ctor.call(this);
295         this._texCoordinates=null;
296         this._vertices=null;
297         this._originalVertices=null;
298         this._indices=null;
299 
300         this._texCoordinateBuffer=null;
301         this._verticesBuffer=null;
302         this._indicesBuffer=null;
303     },
304 
305     /**
306      * returns the vertex at a given position
307      * @param {cc.Point} pos
308      * @return {cc.Vertex3F}
309      */
310     vertex:function (pos) {
311         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
312             cc.log("cc.Grid3D.vertex() : Numbers must be integers");
313         var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
314         var locVertices = this._vertices;
315         return new cc.Vertex3F(locVertices[index], locVertices[index + 1], locVertices[index + 2]);
316     },
317 
318     /**
319      * returns the original (non-transformed) vertex at a given position
320      * @param {cc.Point} pos
321      * @return {cc.Vertex3F}
322      */
323     originalVertex:function (pos) {
324         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
325             cc.log("cc.Grid3D.originalVertex() : Numbers must be integers");
326         var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
327         var locOriginalVertices = this._originalVertices;
328         return new cc.Vertex3F(locOriginalVertices[index], locOriginalVertices[index + 1], locOriginalVertices[index + 2]);
329     },
330 
331     /**
332      * sets a new vertex at a given position
333      * @param {cc.Point} pos
334      * @param {cc.Vertex3F} vertex
335      */
336     setVertex:function (pos, vertex) {
337         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
338             cc.log("cc.Grid3D.setVertex() : Numbers must be integers");
339         var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
340         var vertArray = this._vertices;
341         vertArray[index] = vertex.x;
342         vertArray[index + 1] = vertex.y;
343         vertArray[index + 2] = vertex.z;
344         this._dirty = true;
345     },
346 
347     blit:function () {
348         var n = this._gridSize.width * this._gridSize.height;
349         cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
350         this._shaderProgram.use();
351         this._shaderProgram.setUniformsForBuiltins();
352 
353         var gl = cc.renderContext, locDirty = this._dirty;
354         //
355         // Attributes
356         //
357         // position
358         gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
359         if (locDirty)
360             gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
361         gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, 0);
362 
363         // texCoords
364         gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
365         if (locDirty)
366             gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
367         gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, 0);
368 
369         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
370         if (locDirty)
371             gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
372         gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
373         if (locDirty)
374             this._dirty = false;
375         cc.INCREMENT_GL_DRAWS(1);
376     },
377 
378     reuse:function () {
379         if (this._reuseGrid > 0) {
380             var locOriginalVertices = this._originalVertices, locVertices = this._vertices;
381             for (var i = 0, len =  this._vertices.length; i < len; i++)
382                 locOriginalVertices[i] = locVertices[i];
383             --this._reuseGrid;
384         }
385     },
386 
387     calculateVertexPoints:function () {
388         var gl = cc.renderContext;
389 
390         var width = this._texture.getPixelsWide();
391         var height = this._texture.getPixelsHigh();
392         var imageH = this._texture.getContentSizeInPixels().height;
393         var locGridSize = this._gridSize;
394 
395         var numOfPoints = (locGridSize.width + 1) * (locGridSize.height + 1);
396         this._vertices = new Float32Array(numOfPoints * 3);
397         this._texCoordinates = new Float32Array(numOfPoints * 2);
398         this._indices = new Uint16Array(locGridSize.width * locGridSize.height * 6);
399 
400         if(this._verticesBuffer)
401             gl.deleteBuffer(this._verticesBuffer);
402         this._verticesBuffer = gl.createBuffer();
403         if(this._texCoordinateBuffer)
404             gl.deleteBuffer(this._texCoordinateBuffer);
405         this._texCoordinateBuffer = gl.createBuffer();
406         if(this._indicesBuffer)
407             gl.deleteBuffer(this._indicesBuffer);
408         this._indicesBuffer = gl.createBuffer();
409 
410         var x, y, i, locIndices = this._indices, locTexCoordinates = this._texCoordinates;
411         var locIsTextureFlipped = this._isTextureFlipped, locVertices = this._vertices;
412         for (x = 0; x < locGridSize.width; ++x) {
413             for (y = 0; y < locGridSize.height; ++y) {
414                 var idx = (y * locGridSize.width) + x;
415                 var x1 = x * this._step.x;
416                 var x2 = x1 + this._step.x;
417                 var y1 = y * this._step.y;
418                 var y2 = y1 + this._step.y;
419 
420                 var a = (x * (locGridSize.height + 1) + y);
421                 var b = ((x + 1) * (locGridSize.height + 1) + y);
422                 var c = ((x + 1) * (locGridSize.height + 1) + (y + 1));
423                 var d = (x * (locGridSize.height + 1) + (y + 1));
424 
425                 locIndices[idx * 6] = a;
426                 locIndices[idx * 6 + 1] = b;
427                 locIndices[idx * 6 + 2] = d;
428                 locIndices[idx * 6 + 3] = b;
429                 locIndices[idx * 6 + 4] = c;
430                 locIndices[idx * 6 + 5] = d;
431 
432                 var l1 = [a * 3, b * 3, c * 3, d * 3];
433                 var e = {x:x1, y:y1, z:0};   //new cc.Vertex3F(x1, y1, 0);
434                 var f = {x:x2, y:y1, z:0};   //new cc.Vertex3F(x2, y1, 0);
435                 var g = {x:x2, y:y2, z:0};   // new cc.Vertex3F(x2, y2, 0);
436                 var h = {x:x1, y:y2, z:0};   //new cc.Vertex3F(x1, y2, 0);
437 
438                 var l2 = [e, f, g, h];
439                 var tex1 = [a * 2, b * 2, c * 2, d * 2];
440                 var tex2 = [cc.p(x1, y1), cc.p(x2, y1), cc.p(x2, y2), cc.p(x1, y2)];
441                 for (i = 0; i < 4; ++i) {
442                     locVertices[l1[i]] = l2[i].x;
443                     locVertices[l1[i] + 1] = l2[i].y;
444                     locVertices[l1[i] + 2] = l2[i].z;
445                     locTexCoordinates[tex1[i]] = tex2[i].x / width;
446                     if (locIsTextureFlipped)
447                         locTexCoordinates[tex1[i] + 1] = (imageH - tex2[i].y) / height;
448                     else
449                         locTexCoordinates[tex1[i] + 1] = tex2[i].y / height;
450                 }
451             }
452         }
453         this._originalVertices = new Float32Array(this._vertices);
454 
455         gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
456         gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
457         gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
458         gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
459         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
460         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
461         this._dirty = true;
462     }
463 });
464 
465 /**
466  * create one Grid3D object
467  * @param {cc.Size} gridSize
468  * @param {cc.Texture2D} [texture=]
469  * @param {Boolean} [flipped=]
470  * @return {cc.Grid3D}
471  */
472 cc.Grid3D.create = function (gridSize, texture, flipped) {
473     var grid3D = new cc.Grid3D();
474     if (grid3D && grid3D.initWithSize(gridSize, texture, flipped))
475         return grid3D;
476     return null;
477 };
478 
479 /**
480  * cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that   <br/>
481  * the tiles can be separated from the grid.
482  * @class
483  * @extends cc.GridBase
484  */
485 cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{
486     _texCoordinates:null,
487     _vertices:null,
488     _originalVertices:null,
489     _indices:null,
490 
491     _texCoordinateBuffer:null,
492     _verticesBuffer:null,
493     _indicesBuffer:null,
494 
495     ctor:function () {
496         cc.GridBase.prototype.ctor.call(this);
497         this._texCoordinates=null;
498         this._vertices=null;
499         this._originalVertices=null;
500         this._indices=null;
501 
502         this._texCoordinateBuffer=null;
503         this._verticesBuffer=null;
504         this._indicesBuffer=null;
505     },
506 
507     /**
508      * returns the tile at the given position
509      * @param {cc.Point} pos
510      * @return {cc.Quad3}
511      */
512     tile:function (pos) {
513         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
514             cc.log("cc.TiledGrid3D.tile() : Numbers must be integers");
515 
516         var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
517         var locVertices = this._vertices;
518         return new cc.Quad3(new cc.Vertex3F(locVertices[idx], locVertices[idx + 1], locVertices[idx + 2]),
519             new cc.Vertex3F(locVertices[idx + 3], locVertices[idx + 4], locVertices[idx + 5]),
520             new cc.Vertex3F(locVertices[idx + 6 ], locVertices[idx + 7], locVertices[idx + 8]),
521             new cc.Vertex3F(locVertices[idx + 9], locVertices[idx + 10], locVertices[idx + 11]));
522     },
523 
524     /**
525      * returns the original tile (untransformed) at the given position
526      * @param {cc.Point} pos
527      * @return {cc.Quad3}
528      */
529     originalTile:function (pos) {
530         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
531             cc.log("cc.TiledGrid3D.originalTile() : Numbers must be integers");
532 
533         var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
534         var locOriginalVertices = this._originalVertices;
535         return new cc.Quad3(new cc.Vertex3F(locOriginalVertices[idx], locOriginalVertices[idx + 1], locOriginalVertices[idx + 2]),
536             new cc.Vertex3F(locOriginalVertices[idx + 3], locOriginalVertices[idx + 4], locOriginalVertices[idx + 5]),
537             new cc.Vertex3F(locOriginalVertices[idx + 6 ], locOriginalVertices[idx + 7], locOriginalVertices[idx + 8]),
538             new cc.Vertex3F(locOriginalVertices[idx + 9], locOriginalVertices[idx + 10], locOriginalVertices[idx + 11]));
539     },
540 
541     /**
542      * sets a new tile
543      * @param {cc.Point} pos
544      * @param {cc.Quad3} coords
545      */
546     setTile:function (pos, coords) {
547         if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
548             cc.log("cc.TiledGrid3D.setTile() : Numbers must be integers");
549 
550         var idx = (this._gridSize.height * pos.x + pos.y) * 12;
551         var locVertices = this._vertices;
552         locVertices[idx] = coords.bl.x;
553         locVertices[idx + 1] = coords.bl.y;
554         locVertices[idx + 2] = coords.bl.z;
555         locVertices[idx + 3] = coords.br.x;
556         locVertices[idx + 4] = coords.br.y;
557         locVertices[idx + 5] = coords.br.z;
558         locVertices[idx + 6] = coords.tl.x;
559         locVertices[idx + 7] = coords.tl.y;
560         locVertices[idx + 8] = coords.tl.z;
561         locVertices[idx + 9] = coords.tr.x;
562         locVertices[idx + 10] = coords.tr.y;
563         locVertices[idx + 11] = coords.tr.z;
564         this._dirty = true;
565     },
566 
567     blit:function () {
568         var n = this._gridSize.width * this._gridSize.height;
569 
570         this._shaderProgram.use();
571         this._shaderProgram.setUniformsForBuiltins();
572 
573         //
574         // Attributes
575         //
576         var gl = cc.renderContext, locDirty = this._dirty;
577         cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
578 
579         // position
580         gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
581         if (locDirty)
582             gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
583         gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, this._vertices);
584 
585         // texCoords
586         gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
587         if (locDirty)
588             gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
589         gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, this._texCoordinates);
590 
591         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
592         if (locDirty)
593             gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
594         gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
595         if (locDirty)
596             this._dirty = false;
597         cc.INCREMENT_GL_DRAWS(1);
598     },
599 
600     reuse:function () {
601         if (this._reuseGrid > 0) {
602             var locVertices = this._vertices, locOriginalVertices = this._originalVertices;
603             for (var i = 0; i < locVertices.length; i++)
604                 locOriginalVertices[i] = locVertices[i];
605             --this._reuseGrid;
606         }
607     },
608 
609     calculateVertexPoints:function () {
610         var width = this._texture.getPixelsWide();
611         var height = this._texture.getPixelsHigh();
612         var imageH = this._texture.getContentSizeInPixels().height;
613         var locGridSize = this._gridSize;
614 
615         var numQuads = locGridSize.width * locGridSize.height;
616         this._vertices = new Float32Array(numQuads * 12);
617         this._texCoordinates = new Float32Array(numQuads * 8);
618         this._indices = new Uint16Array(numQuads * 6);
619 
620         var gl = cc.renderContext;
621         if(this._verticesBuffer)
622             gl.deleteBuffer(this._verticesBuffer);
623         this._verticesBuffer = gl.createBuffer();
624         if(this._texCoordinateBuffer)
625             gl.deleteBuffer(this._texCoordinateBuffer);
626         this._texCoordinateBuffer = gl.createBuffer();
627         if(this._indicesBuffer)
628             gl.deleteBuffer(this._indicesBuffer);
629         this._indicesBuffer = gl.createBuffer();
630 
631         var x, y, i = 0;
632         var locStep = this._step, locVertices = this._vertices, locTexCoords = this._texCoordinates, locIsTextureFlipped = this._isTextureFlipped;
633         for (x = 0; x < locGridSize.width; x++) {
634             for (y = 0; y < locGridSize.height; y++) {
635                 var x1 = x * locStep.x;
636                 var x2 = x1 + locStep.x;
637                 var y1 = y * locStep.y;
638                 var y2 = y1 + locStep.y;
639 
640                 locVertices[i * 12] = x1;
641                 locVertices[i * 12 + 1] = y1;
642                 locVertices[i * 12 + 2] = 0;
643                 locVertices[i * 12 + 3] = x2;
644                 locVertices[i * 12 + 4] = y1;
645                 locVertices[i * 12 + 5] = 0;
646                 locVertices[i * 12 + 6] = x1;
647                 locVertices[i * 12 + 7] = y2;
648                 locVertices[i * 12 + 8] = 0;
649                 locVertices[i * 12 + 9] = x2;
650                 locVertices[i * 12 + 10] = y2;
651                 locVertices[i * 12 + 11] = 0;
652 
653                 var newY1 = y1;
654                 var newY2 = y2;
655 
656                 if (locIsTextureFlipped) {
657                     newY1 = imageH - y1;
658                     newY2 = imageH - y2;
659                 }
660 
661                 locTexCoords[i * 8] = x1 / width;
662                 locTexCoords[i * 8 + 1] = newY1 / height;
663                 locTexCoords[i * 8 + 2] = x2 / width;
664                 locTexCoords[i * 8 + 3] = newY1 / height;
665                 locTexCoords[i * 8 + 4] = x1 / width;
666                 locTexCoords[i * 8 + 5] = newY2 / height;
667                 locTexCoords[i * 8 + 6] = x2 / width;
668                 locTexCoords[i * 8 + 7] = newY2 / height;
669                 i++;
670             }
671         }
672 
673         var locIndices = this._indices;
674         for (x = 0; x < numQuads; x++) {
675             locIndices[x * 6 + 0] = (x * 4 + 0);
676             locIndices[x * 6 + 1] = (x * 4 + 1);
677             locIndices[x * 6 + 2] = (x * 4 + 2);
678 
679             locIndices[x * 6 + 3] = (x * 4 + 1);
680             locIndices[x * 6 + 4] = (x * 4 + 2);
681             locIndices[x * 6 + 5] = (x * 4 + 3);
682         }
683         this._originalVertices = new Float32Array(this._vertices);
684 
685         gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
686         gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
687         gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
688         gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
689         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
690         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.DYNAMIC_DRAW);
691         this._dirty = true;
692     }
693 });
694 
695 /**
696  * create one TiledGrid3D object
697  * @param {cc.Size} gridSize
698  * @param {cc.Texture2D} [texture=]
699  * @param {Boolean} [flipped=]
700  * @return {cc.TiledGrid3D}
701  */
702 cc.TiledGrid3D.create = function (gridSize, texture, flipped) {
703     var ret = new cc.TiledGrid3D();
704     ret.initWithSize(gridSize, texture, flipped);
705     return ret;
706 };
707