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 * @param {cc.Size} gridSize 277 * @param {cc.Texture2D} [texture=] 278 * @param {Boolean} [flipped=] 279 * @return {cc.GridBase} 280 */ 281 cc.GridBase.create = function (gridSize, texture, flipped) { 282 return new cc.GridBase(gridSize, texture, flipped); 283 }; 284 285 /** 286 * cc.Grid3D is a 3D grid implementation. Each vertex has 3 dimensions: x,y,z 287 * @class 288 * @extends cc.GridBase 289 */ 290 cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{ 291 _texCoordinates:null, 292 _vertices:null, 293 _originalVertices:null, 294 _indices:null, 295 296 _texCoordinateBuffer:null, 297 _verticesBuffer:null, 298 _indicesBuffer:null, 299 300 /** 301 * create one Grid3D object 302 * Constructor of cc.Grid3D 303 * @param {cc.Size} gridSize 304 * @param {cc.Texture2D} [texture=] 305 * @param {Boolean} [flipped=] 306 */ 307 ctor:function (gridSize, texture, flipped) { 308 cc.GridBase.prototype.ctor.call(this); 309 this._texCoordinates=null; 310 this._vertices=null; 311 this._originalVertices=null; 312 this._indices=null; 313 314 this._texCoordinateBuffer=null; 315 this._verticesBuffer=null; 316 this._indicesBuffer=null; 317 318 if(gridSize !== undefined) 319 this.initWithSize(gridSize, texture, flipped); 320 }, 321 322 /** 323 * returns the vertex at a given position 324 * @param {cc.Point} pos 325 * @return {cc.Vertex3F} 326 */ 327 vertex:function (pos) { 328 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 329 cc.log("cc.Grid3D.vertex() : Numbers must be integers"); 330 var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3); 331 var locVertices = this._vertices; 332 return new cc.Vertex3F(locVertices[index], locVertices[index + 1], locVertices[index + 2]); 333 }, 334 335 /** 336 * returns the original (non-transformed) vertex at a given position 337 * @param {cc.Point} pos 338 * @return {cc.Vertex3F} 339 */ 340 originalVertex:function (pos) { 341 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 342 cc.log("cc.Grid3D.originalVertex() : Numbers must be integers"); 343 var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3); 344 var locOriginalVertices = this._originalVertices; 345 return new cc.Vertex3F(locOriginalVertices[index], locOriginalVertices[index + 1], locOriginalVertices[index + 2]); 346 }, 347 348 /** 349 * sets a new vertex at a given position 350 * @param {cc.Point} pos 351 * @param {cc.Vertex3F} vertex 352 */ 353 setVertex:function (pos, vertex) { 354 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 355 cc.log("cc.Grid3D.setVertex() : Numbers must be integers"); 356 var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3); 357 var vertArray = this._vertices; 358 vertArray[index] = vertex.x; 359 vertArray[index + 1] = vertex.y; 360 vertArray[index + 2] = vertex.z; 361 this._dirty = true; 362 }, 363 364 blit:function () { 365 var n = this._gridSize.width * this._gridSize.height; 366 cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS); 367 this._shaderProgram.use(); 368 this._shaderProgram.setUniformsForBuiltins(); 369 370 var gl = cc._renderContext, locDirty = this._dirty; 371 // 372 // Attributes 373 // 374 // position 375 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 376 if (locDirty) 377 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 378 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, 0); 379 380 // texCoords 381 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 382 if (locDirty) 383 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 384 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, 0); 385 386 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 387 if (locDirty) 388 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 389 gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0); 390 if (locDirty) 391 this._dirty = false; 392 cc.incrementGLDraws(1); 393 }, 394 395 reuse:function () { 396 if (this._reuseGrid > 0) { 397 var locOriginalVertices = this._originalVertices, locVertices = this._vertices; 398 for (var i = 0, len = this._vertices.length; i < len; i++) 399 locOriginalVertices[i] = locVertices[i]; 400 --this._reuseGrid; 401 } 402 }, 403 404 calculateVertexPoints:function () { 405 var gl = cc._renderContext; 406 407 var width = this._texture.pixelsWidth; 408 var height = this._texture.pixelsHeight; 409 var imageH = this._texture.getContentSizeInPixels().height; 410 var locGridSize = this._gridSize; 411 412 var numOfPoints = (locGridSize.width + 1) * (locGridSize.height + 1); 413 this._vertices = new Float32Array(numOfPoints * 3); 414 this._texCoordinates = new Float32Array(numOfPoints * 2); 415 this._indices = new Uint16Array(locGridSize.width * locGridSize.height * 6); 416 417 if(this._verticesBuffer) 418 gl.deleteBuffer(this._verticesBuffer); 419 this._verticesBuffer = gl.createBuffer(); 420 if(this._texCoordinateBuffer) 421 gl.deleteBuffer(this._texCoordinateBuffer); 422 this._texCoordinateBuffer = gl.createBuffer(); 423 if(this._indicesBuffer) 424 gl.deleteBuffer(this._indicesBuffer); 425 this._indicesBuffer = gl.createBuffer(); 426 427 var x, y, i, locIndices = this._indices, locTexCoordinates = this._texCoordinates; 428 var locIsTextureFlipped = this._isTextureFlipped, locVertices = this._vertices; 429 for (x = 0; x < locGridSize.width; ++x) { 430 for (y = 0; y < locGridSize.height; ++y) { 431 var idx = (y * locGridSize.width) + x; 432 var x1 = x * this._step.x; 433 var x2 = x1 + this._step.x; 434 var y1 = y * this._step.y; 435 var y2 = y1 + this._step.y; 436 437 var a = (x * (locGridSize.height + 1) + y); 438 var b = ((x + 1) * (locGridSize.height + 1) + y); 439 var c = ((x + 1) * (locGridSize.height + 1) + (y + 1)); 440 var d = (x * (locGridSize.height + 1) + (y + 1)); 441 442 locIndices[idx * 6] = a; 443 locIndices[idx * 6 + 1] = b; 444 locIndices[idx * 6 + 2] = d; 445 locIndices[idx * 6 + 3] = b; 446 locIndices[idx * 6 + 4] = c; 447 locIndices[idx * 6 + 5] = d; 448 449 var l1 = [a * 3, b * 3, c * 3, d * 3]; 450 var e = {x:x1, y:y1, z:0}; //new cc.Vertex3F(x1, y1, 0); 451 var f = {x:x2, y:y1, z:0}; //new cc.Vertex3F(x2, y1, 0); 452 var g = {x:x2, y:y2, z:0}; // new cc.Vertex3F(x2, y2, 0); 453 var h = {x:x1, y:y2, z:0}; //new cc.Vertex3F(x1, y2, 0); 454 455 var l2 = [e, f, g, h]; 456 var tex1 = [a * 2, b * 2, c * 2, d * 2]; 457 var tex2 = [cc.p(x1, y1), cc.p(x2, y1), cc.p(x2, y2), cc.p(x1, y2)]; 458 for (i = 0; i < 4; ++i) { 459 locVertices[l1[i]] = l2[i].x; 460 locVertices[l1[i] + 1] = l2[i].y; 461 locVertices[l1[i] + 2] = l2[i].z; 462 locTexCoordinates[tex1[i]] = tex2[i].x / width; 463 if (locIsTextureFlipped) 464 locTexCoordinates[tex1[i] + 1] = (imageH - tex2[i].y) / height; 465 else 466 locTexCoordinates[tex1[i] + 1] = tex2[i].y / height; 467 } 468 } 469 } 470 this._originalVertices = new Float32Array(this._vertices); 471 472 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 473 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 474 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 475 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 476 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 477 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 478 this._dirty = true; 479 } 480 }); 481 482 /** 483 * create one Grid3D object 484 * @param {cc.Size} gridSize 485 * @param {cc.Texture2D} [texture=] 486 * @param {Boolean} [flipped=] 487 * @return {cc.Grid3D} 488 */ 489 cc.Grid3D.create = function (gridSize, texture, flipped) { 490 return new cc.Grid3D(gridSize, texture, flipped); 491 }; 492 493 /** 494 * cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that <br/> 495 * the tiles can be separated from the grid. 496 * @class 497 * @extends cc.GridBase 498 */ 499 cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{ 500 _texCoordinates:null, 501 _vertices:null, 502 _originalVertices:null, 503 _indices:null, 504 505 _texCoordinateBuffer:null, 506 _verticesBuffer:null, 507 _indicesBuffer:null, 508 509 /** 510 * create one TiledGrid3D object 511 * Constructor of cc.TiledGrid3D 512 * @param {cc.Size} gridSize 513 * @param {cc.Texture2D} [texture=] 514 * @param {Boolean} [flipped=] 515 */ 516 ctor:function (gridSize, texture, flipped) { 517 cc.GridBase.prototype.ctor.call(this); 518 this._texCoordinates=null; 519 this._vertices=null; 520 this._originalVertices=null; 521 this._indices=null; 522 523 this._texCoordinateBuffer=null; 524 this._verticesBuffer=null; 525 this._indicesBuffer=null; 526 527 if(gridSize !== undefined) 528 this.initWithSize(gridSize, texture, flipped); 529 }, 530 531 /** 532 * returns the tile at the given position 533 * @param {cc.Point} pos 534 * @return {cc.Quad3} 535 */ 536 tile:function (pos) { 537 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 538 cc.log("cc.TiledGrid3D.tile() : Numbers must be integers"); 539 540 var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3; 541 var locVertices = this._vertices; 542 return new cc.Quad3(new cc.Vertex3F(locVertices[idx], locVertices[idx + 1], locVertices[idx + 2]), 543 new cc.Vertex3F(locVertices[idx + 3], locVertices[idx + 4], locVertices[idx + 5]), 544 new cc.Vertex3F(locVertices[idx + 6 ], locVertices[idx + 7], locVertices[idx + 8]), 545 new cc.Vertex3F(locVertices[idx + 9], locVertices[idx + 10], locVertices[idx + 11])); 546 }, 547 548 /** 549 * returns the original tile (untransformed) at the given position 550 * @param {cc.Point} pos 551 * @return {cc.Quad3} 552 */ 553 originalTile:function (pos) { 554 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 555 cc.log("cc.TiledGrid3D.originalTile() : Numbers must be integers"); 556 557 var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3; 558 var locOriginalVertices = this._originalVertices; 559 return new cc.Quad3(new cc.Vertex3F(locOriginalVertices[idx], locOriginalVertices[idx + 1], locOriginalVertices[idx + 2]), 560 new cc.Vertex3F(locOriginalVertices[idx + 3], locOriginalVertices[idx + 4], locOriginalVertices[idx + 5]), 561 new cc.Vertex3F(locOriginalVertices[idx + 6 ], locOriginalVertices[idx + 7], locOriginalVertices[idx + 8]), 562 new cc.Vertex3F(locOriginalVertices[idx + 9], locOriginalVertices[idx + 10], locOriginalVertices[idx + 11])); 563 }, 564 565 /** 566 * sets a new tile 567 * @param {cc.Point} pos 568 * @param {cc.Quad3} coords 569 */ 570 setTile:function (pos, coords) { 571 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 572 cc.log("cc.TiledGrid3D.setTile() : Numbers must be integers"); 573 574 var idx = (this._gridSize.height * pos.x + pos.y) * 12; 575 var locVertices = this._vertices; 576 locVertices[idx] = coords.bl.x; 577 locVertices[idx + 1] = coords.bl.y; 578 locVertices[idx + 2] = coords.bl.z; 579 locVertices[idx + 3] = coords.br.x; 580 locVertices[idx + 4] = coords.br.y; 581 locVertices[idx + 5] = coords.br.z; 582 locVertices[idx + 6] = coords.tl.x; 583 locVertices[idx + 7] = coords.tl.y; 584 locVertices[idx + 8] = coords.tl.z; 585 locVertices[idx + 9] = coords.tr.x; 586 locVertices[idx + 10] = coords.tr.y; 587 locVertices[idx + 11] = coords.tr.z; 588 this._dirty = true; 589 }, 590 591 blit:function () { 592 var n = this._gridSize.width * this._gridSize.height; 593 594 this._shaderProgram.use(); 595 this._shaderProgram.setUniformsForBuiltins(); 596 597 // 598 // Attributes 599 // 600 var gl = cc._renderContext, locDirty = this._dirty; 601 cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS); 602 603 // position 604 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 605 if (locDirty) 606 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 607 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, this._vertices); 608 609 // texCoords 610 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 611 if (locDirty) 612 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 613 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, this._texCoordinates); 614 615 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 616 if (locDirty) 617 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 618 gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0); 619 if (locDirty) 620 this._dirty = false; 621 cc.incrementGLDraws(1); 622 }, 623 624 reuse:function () { 625 if (this._reuseGrid > 0) { 626 var locVertices = this._vertices, locOriginalVertices = this._originalVertices; 627 for (var i = 0; i < locVertices.length; i++) 628 locOriginalVertices[i] = locVertices[i]; 629 --this._reuseGrid; 630 } 631 }, 632 633 calculateVertexPoints:function () { 634 var width = this._texture.pixelsWidth; 635 var height = this._texture.pixelsHeight; 636 var imageH = this._texture.getContentSizeInPixels().height; 637 var locGridSize = this._gridSize; 638 639 var numQuads = locGridSize.width * locGridSize.height; 640 this._vertices = new Float32Array(numQuads * 12); 641 this._texCoordinates = new Float32Array(numQuads * 8); 642 this._indices = new Uint16Array(numQuads * 6); 643 644 var gl = cc._renderContext; 645 if(this._verticesBuffer) 646 gl.deleteBuffer(this._verticesBuffer); 647 this._verticesBuffer = gl.createBuffer(); 648 if(this._texCoordinateBuffer) 649 gl.deleteBuffer(this._texCoordinateBuffer); 650 this._texCoordinateBuffer = gl.createBuffer(); 651 if(this._indicesBuffer) 652 gl.deleteBuffer(this._indicesBuffer); 653 this._indicesBuffer = gl.createBuffer(); 654 655 var x, y, i = 0; 656 var locStep = this._step, locVertices = this._vertices, locTexCoords = this._texCoordinates, locIsTextureFlipped = this._isTextureFlipped; 657 for (x = 0; x < locGridSize.width; x++) { 658 for (y = 0; y < locGridSize.height; y++) { 659 var x1 = x * locStep.x; 660 var x2 = x1 + locStep.x; 661 var y1 = y * locStep.y; 662 var y2 = y1 + locStep.y; 663 664 locVertices[i * 12] = x1; 665 locVertices[i * 12 + 1] = y1; 666 locVertices[i * 12 + 2] = 0; 667 locVertices[i * 12 + 3] = x2; 668 locVertices[i * 12 + 4] = y1; 669 locVertices[i * 12 + 5] = 0; 670 locVertices[i * 12 + 6] = x1; 671 locVertices[i * 12 + 7] = y2; 672 locVertices[i * 12 + 8] = 0; 673 locVertices[i * 12 + 9] = x2; 674 locVertices[i * 12 + 10] = y2; 675 locVertices[i * 12 + 11] = 0; 676 677 var newY1 = y1; 678 var newY2 = y2; 679 680 if (locIsTextureFlipped) { 681 newY1 = imageH - y1; 682 newY2 = imageH - y2; 683 } 684 685 locTexCoords[i * 8] = x1 / width; 686 locTexCoords[i * 8 + 1] = newY1 / height; 687 locTexCoords[i * 8 + 2] = x2 / width; 688 locTexCoords[i * 8 + 3] = newY1 / height; 689 locTexCoords[i * 8 + 4] = x1 / width; 690 locTexCoords[i * 8 + 5] = newY2 / height; 691 locTexCoords[i * 8 + 6] = x2 / width; 692 locTexCoords[i * 8 + 7] = newY2 / height; 693 i++; 694 } 695 } 696 697 var locIndices = this._indices; 698 for (x = 0; x < numQuads; x++) { 699 locIndices[x * 6 + 0] = (x * 4 + 0); 700 locIndices[x * 6 + 1] = (x * 4 + 1); 701 locIndices[x * 6 + 2] = (x * 4 + 2); 702 703 locIndices[x * 6 + 3] = (x * 4 + 1); 704 locIndices[x * 6 + 4] = (x * 4 + 2); 705 locIndices[x * 6 + 5] = (x * 4 + 3); 706 } 707 this._originalVertices = new Float32Array(this._vertices); 708 709 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 710 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 711 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 712 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 713 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 714 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.DYNAMIC_DRAW); 715 this._dirty = true; 716 } 717 }); 718 719 /** 720 * create one TiledGrid3D object 721 * @param {cc.Size} gridSize 722 * @param {cc.Texture2D} [texture=] 723 * @param {Boolean} [flipped=] 724 * @return {cc.TiledGrid3D} 725 */ 726 cc.TiledGrid3D.create = function (gridSize, texture, flipped) { 727 return new cc.TiledGrid3D(gridSize, texture, flipped); 728 }; 729