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