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