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 this._shaderProgram.use(); 456 //this._shaderProgram.setUniformsForBuiltins(); 457 this._shaderProgram._setUniformForMVPMatrixWithMat4(target._renderCmd._stackMatrix); 458 459 var gl = cc._renderContext, locDirty = this._dirty; 460 461 gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); 462 gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); 463 // 464 // Attributes 465 // 466 // position 467 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 468 if (locDirty) 469 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 470 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, 0); 471 472 // texCoords 473 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 474 if (locDirty) 475 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 476 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, 0); 477 478 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 479 if (locDirty) 480 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 481 gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0); 482 if (locDirty) 483 this._dirty = false; 484 cc.incrementGLDraws(1); 485 }, 486 487 reuse:function () { 488 if (this._reuseGrid > 0) { 489 var locOriginalVertices = this._originalVertices, locVertices = this._vertices; 490 for (var i = 0, len = this._vertices.length; i < len; i++) 491 locOriginalVertices[i] = locVertices[i]; 492 --this._reuseGrid; 493 } 494 }, 495 496 calculateVertexPoints:function () { 497 var gl = cc._renderContext; 498 499 var width = this._texture.pixelsWidth; 500 var height = this._texture.pixelsHeight; 501 var imageH = this._texture.getContentSizeInPixels().height; 502 var locGridSize = this._gridSize; 503 504 var numOfPoints = (locGridSize.width + 1) * (locGridSize.height + 1); 505 this._vertices = new Float32Array(numOfPoints * 3); 506 this._texCoordinates = new Float32Array(numOfPoints * 2); 507 this._indices = new Uint16Array(locGridSize.width * locGridSize.height * 6); 508 509 if(this._verticesBuffer) 510 gl.deleteBuffer(this._verticesBuffer); 511 this._verticesBuffer = gl.createBuffer(); 512 if(this._texCoordinateBuffer) 513 gl.deleteBuffer(this._texCoordinateBuffer); 514 this._texCoordinateBuffer = gl.createBuffer(); 515 if(this._indicesBuffer) 516 gl.deleteBuffer(this._indicesBuffer); 517 this._indicesBuffer = gl.createBuffer(); 518 519 var x, y, i, locIndices = this._indices, locTexCoordinates = this._texCoordinates; 520 var locIsTextureFlipped = this._isTextureFlipped, locVertices = this._vertices; 521 for (x = 0; x < locGridSize.width; ++x) { 522 for (y = 0; y < locGridSize.height; ++y) { 523 var idx = (y * locGridSize.width) + x; 524 var x1 = x * this._step.x + this._gridRect.x; 525 var x2 = x1 + this._step.x; 526 var y1 = y * this._step.y + this._gridRect.y; 527 var y2 = y1 + this._step.y; 528 529 var a = (x * (locGridSize.height + 1) + y); 530 var b = ((x + 1) * (locGridSize.height + 1) + y); 531 var c = ((x + 1) * (locGridSize.height + 1) + (y + 1)); 532 var d = (x * (locGridSize.height + 1) + (y + 1)); 533 534 locIndices[idx * 6] = a; 535 locIndices[idx * 6 + 1] = b; 536 locIndices[idx * 6 + 2] = d; 537 locIndices[idx * 6 + 3] = b; 538 locIndices[idx * 6 + 4] = c; 539 locIndices[idx * 6 + 5] = d; 540 541 var l1 = [a * 3, b * 3, c * 3, d * 3]; 542 var e = {x:x1, y:y1, z:0}; //new cc.Vertex3F(x1, y1, 0); 543 var f = {x:x2, y:y1, z:0}; //new cc.Vertex3F(x2, y1, 0); 544 var g = {x:x2, y:y2, z:0}; // new cc.Vertex3F(x2, y2, 0); 545 var h = {x:x1, y:y2, z:0}; //new cc.Vertex3F(x1, y2, 0); 546 547 var l2 = [e, f, g, h]; 548 var tex1 = [a * 2, b * 2, c * 2, d * 2]; 549 var tex2 = [cc.p(x1, y1), cc.p(x2, y1), cc.p(x2, y2), cc.p(x1, y2)]; 550 for (i = 0; i < 4; ++i) { 551 locVertices[l1[i]] = l2[i].x; 552 locVertices[l1[i] + 1] = l2[i].y; 553 locVertices[l1[i] + 2] = l2[i].z; 554 locTexCoordinates[tex1[i]] = tex2[i].x / width; 555 if (locIsTextureFlipped) 556 locTexCoordinates[tex1[i] + 1] = (imageH - tex2[i].y) / height; 557 else 558 locTexCoordinates[tex1[i] + 1] = tex2[i].y / height; 559 } 560 } 561 } 562 this._originalVertices = new Float32Array(this._vertices); 563 564 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 565 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 566 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 567 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 568 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 569 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 570 this._dirty = true; 571 }, 572 573 setNeedDepthTestForBlit: function(needDepthTest){ 574 this._needDepthTestForBlit = needDepthTest; 575 }, 576 577 getNeedDepthTestForBlit: function(){ 578 return this._needDepthTestForBlit; 579 } 580 }); 581 582 /** 583 * create one Grid3D object 584 * @deprecated 585 * @param {cc.Size} gridSize 586 * @param {cc.Texture2D} [texture=] 587 * @param {Boolean} [flipped=] 588 * @return {cc.Grid3D} 589 */ 590 cc.Grid3D.create = function (gridSize, texture, flipped) { 591 return new cc.Grid3D(gridSize, texture, flipped); 592 }; 593 594 /** 595 * cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that <br/> 596 * the tiles can be separated from the grid. 597 * @class 598 * @extends cc.GridBase 599 */ 600 cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{ 601 _texCoordinates:null, 602 _vertices:null, 603 _originalVertices:null, 604 _indices:null, 605 606 _texCoordinateBuffer:null, 607 _verticesBuffer:null, 608 _indicesBuffer:null, 609 610 /** 611 * create one TiledGrid3D object 612 * Constructor of cc.TiledGrid3D 613 * @param {cc.Size} gridSize 614 * @param {cc.Texture2D} [texture=] 615 * @param {Boolean} [flipped=] 616 */ 617 ctor:function (gridSize, texture, flipped, rect) { 618 cc.GridBase.prototype.ctor.call(this); 619 this._texCoordinates=null; 620 this._vertices=null; 621 this._originalVertices=null; 622 this._indices=null; 623 624 this._texCoordinateBuffer=null; 625 this._verticesBuffer=null; 626 this._indicesBuffer=null; 627 628 if(gridSize !== undefined) 629 this.initWithSize(gridSize, texture, flipped, rect); 630 }, 631 632 /** 633 * returns the tile at the given position <br/> 634 * It will be deprecated in future, please use getTile instead. 635 * @param {cc.Point} pos 636 * @return {cc.Quad3} 637 */ 638 tile:function (pos) { 639 return this.getTile(pos); 640 }, 641 642 /** 643 * returns the tile at the given position 644 * @param {cc.Point} pos 645 * @return {cc.Quad3} 646 */ 647 getTile: function(pos){ 648 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 649 cc.log("cc.TiledGrid3D.tile() : Numbers must be integers"); 650 651 var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3; 652 var locVertices = this._vertices; 653 return new cc.Quad3(new cc.Vertex3F(locVertices[idx], locVertices[idx + 1], locVertices[idx + 2]), 654 new cc.Vertex3F(locVertices[idx + 3], locVertices[idx + 4], locVertices[idx + 5]), 655 new cc.Vertex3F(locVertices[idx + 6 ], locVertices[idx + 7], locVertices[idx + 8]), 656 new cc.Vertex3F(locVertices[idx + 9], locVertices[idx + 10], locVertices[idx + 11])); 657 }, 658 659 /** 660 * returns the original tile (untransformed) at the given position 661 * @param {cc.Point} pos 662 * @return {cc.Quad3} 663 */ 664 getOriginalTile:function (pos) { 665 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 666 cc.log("cc.TiledGrid3D.originalTile() : Numbers must be integers"); 667 668 var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3; 669 var locOriginalVertices = this._originalVertices; 670 return new cc.Quad3(new cc.Vertex3F(locOriginalVertices[idx], locOriginalVertices[idx + 1], locOriginalVertices[idx + 2]), 671 new cc.Vertex3F(locOriginalVertices[idx + 3], locOriginalVertices[idx + 4], locOriginalVertices[idx + 5]), 672 new cc.Vertex3F(locOriginalVertices[idx + 6 ], locOriginalVertices[idx + 7], locOriginalVertices[idx + 8]), 673 new cc.Vertex3F(locOriginalVertices[idx + 9], locOriginalVertices[idx + 10], locOriginalVertices[idx + 11])); 674 }, 675 676 /** 677 * returns the original tile (untransformed) at the given position. <br/> 678 * It will be deprecated in future, please use getOriginalTile instead. 679 * @param {cc.Point} pos 680 * @return {cc.Quad3} 681 */ 682 originalTile: function(pos) { 683 return this.getOriginalTile(pos); 684 }, 685 686 /** 687 * sets a new tile 688 * @param {cc.Point} pos 689 * @param {cc.Quad3} coords 690 */ 691 setTile:function (pos, coords) { 692 if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y)) 693 cc.log("cc.TiledGrid3D.setTile() : Numbers must be integers"); 694 695 var idx = (this._gridSize.height * pos.x + pos.y) * 12; 696 var locVertices = this._vertices; 697 locVertices[idx] = coords.bl.x; 698 locVertices[idx + 1] = coords.bl.y; 699 locVertices[idx + 2] = coords.bl.z; 700 locVertices[idx + 3] = coords.br.x; 701 locVertices[idx + 4] = coords.br.y; 702 locVertices[idx + 5] = coords.br.z; 703 locVertices[idx + 6] = coords.tl.x; 704 locVertices[idx + 7] = coords.tl.y; 705 locVertices[idx + 8] = coords.tl.z; 706 locVertices[idx + 9] = coords.tr.x; 707 locVertices[idx + 10] = coords.tr.y; 708 locVertices[idx + 11] = coords.tr.z; 709 this._dirty = true; 710 }, 711 712 blit: function (target) { 713 var n = this._gridSize.width * this._gridSize.height; 714 715 this._shaderProgram.use(); 716 this._shaderProgram._setUniformForMVPMatrixWithMat4(target._renderCmd._stackMatrix); 717 //this._shaderProgram.setUniformsForBuiltins(); 718 719 // 720 // Attributes 721 // 722 var gl = cc._renderContext, locDirty = this._dirty; 723 gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); 724 gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); 725 726 // position 727 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 728 if (locDirty) 729 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 730 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, this._vertices); 731 732 // texCoords 733 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 734 if (locDirty) 735 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 736 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, this._texCoordinates); 737 738 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 739 if (locDirty) 740 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 741 gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0); 742 if (locDirty) 743 this._dirty = false; 744 cc.incrementGLDraws(1); 745 }, 746 747 reuse:function () { 748 if (this._reuseGrid > 0) { 749 var locVertices = this._vertices, locOriginalVertices = this._originalVertices; 750 for (var i = 0; i < locVertices.length; i++) 751 locOriginalVertices[i] = locVertices[i]; 752 --this._reuseGrid; 753 } 754 }, 755 756 calculateVertexPoints:function () { 757 var width = this._texture.pixelsWidth; 758 var height = this._texture.pixelsHeight; 759 var imageH = this._texture.getContentSizeInPixels().height; 760 var locGridSize = this._gridSize; 761 762 var numQuads = locGridSize.width * locGridSize.height; 763 this._vertices = new Float32Array(numQuads * 12); 764 this._texCoordinates = new Float32Array(numQuads * 8); 765 this._indices = new Uint16Array(numQuads * 6); 766 767 var gl = cc._renderContext; 768 if(this._verticesBuffer) 769 gl.deleteBuffer(this._verticesBuffer); 770 this._verticesBuffer = gl.createBuffer(); 771 if(this._texCoordinateBuffer) 772 gl.deleteBuffer(this._texCoordinateBuffer); 773 this._texCoordinateBuffer = gl.createBuffer(); 774 if(this._indicesBuffer) 775 gl.deleteBuffer(this._indicesBuffer); 776 this._indicesBuffer = gl.createBuffer(); 777 778 var x, y, i = 0; 779 var locStep = this._step, locVertices = this._vertices, locTexCoords = this._texCoordinates, locIsTextureFlipped = this._isTextureFlipped; 780 for (x = 0; x < locGridSize.width; x++) { 781 for (y = 0; y < locGridSize.height; y++) { 782 var x1 = x * locStep.x; 783 var x2 = x1 + locStep.x; 784 var y1 = y * locStep.y; 785 var y2 = y1 + locStep.y; 786 787 locVertices[i * 12] = x1; 788 locVertices[i * 12 + 1] = y1; 789 locVertices[i * 12 + 2] = 0; 790 locVertices[i * 12 + 3] = x2; 791 locVertices[i * 12 + 4] = y1; 792 locVertices[i * 12 + 5] = 0; 793 locVertices[i * 12 + 6] = x1; 794 locVertices[i * 12 + 7] = y2; 795 locVertices[i * 12 + 8] = 0; 796 locVertices[i * 12 + 9] = x2; 797 locVertices[i * 12 + 10] = y2; 798 locVertices[i * 12 + 11] = 0; 799 800 var newY1 = y1; 801 var newY2 = y2; 802 803 if (locIsTextureFlipped) { 804 newY1 = imageH - y1; 805 newY2 = imageH - y2; 806 } 807 808 locTexCoords[i * 8] = x1 / width; 809 locTexCoords[i * 8 + 1] = newY1 / height; 810 locTexCoords[i * 8 + 2] = x2 / width; 811 locTexCoords[i * 8 + 3] = newY1 / height; 812 locTexCoords[i * 8 + 4] = x1 / width; 813 locTexCoords[i * 8 + 5] = newY2 / height; 814 locTexCoords[i * 8 + 6] = x2 / width; 815 locTexCoords[i * 8 + 7] = newY2 / height; 816 i++; 817 } 818 } 819 820 var locIndices = this._indices; 821 for (x = 0; x < numQuads; x++) { 822 locIndices[x * 6 + 0] = (x * 4 + 0); 823 locIndices[x * 6 + 1] = (x * 4 + 1); 824 locIndices[x * 6 + 2] = (x * 4 + 2); 825 826 locIndices[x * 6 + 3] = (x * 4 + 1); 827 locIndices[x * 6 + 4] = (x * 4 + 2); 828 locIndices[x * 6 + 5] = (x * 4 + 3); 829 } 830 this._originalVertices = new Float32Array(this._vertices); 831 832 gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer); 833 gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW); 834 gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer); 835 gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW); 836 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer); 837 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.DYNAMIC_DRAW); 838 this._dirty = true; 839 } 840 }); 841 842 /** 843 * create one TiledGrid3D object 844 * @deprecated since v3.0, please use new cc.TiledGrid3D(gridSize, texture, flipped) instead 845 * @param {cc.Size} gridSize 846 * @param {cc.Texture2D} [texture=] 847 * @param {Boolean} [flipped=] 848 * @return {cc.TiledGrid3D} 849 */ 850 cc.TiledGrid3D.create = function (gridSize, texture, flipped) { 851 return new cc.TiledGrid3D(gridSize, texture, flipped); 852 }; 853