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