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