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