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