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