1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * <p>A class that implements a Texture Atlas. <br /> 29 * Supported features: <br /> 30 * The atlas file can be a PNG, JPG. <br /> 31 * Quads can be updated in runtime <br /> 32 * Quads can be added in runtime <br /> 33 * Quads can be removed in runtime <br /> 34 * Quads can be re-ordered in runtime <br /> 35 * The TextureAtlas capacity can be increased or decreased in runtime.</p> 36 * @class 37 * @extends cc.Class 38 */ 39 cc.TextureAtlas = cc.Class.extend(/** @lends cc.TextureAtlas# */{ 40 _indices:null, 41 //0: vertex 1: indices 42 _buffersVBO:null, 43 //indicates whether or not the array buffer of the VBO needs to be updated 44 _dirty:false, 45 _capacity:0, 46 _texture:null, 47 48 _quads:null, 49 _quadsArrayBuffer:null, 50 _quadsWebBuffer:null, 51 _quadsReader:null, 52 53 ctor:function () { 54 this._buffersVBO = []; 55 }, 56 57 /** 58 * Quantity of quads that are going to be drawn. 59 * @return {Number} 60 */ 61 getTotalQuads:function () { 62 //return this._quads.length; 63 return this._totalQuads; 64 }, 65 66 /** 67 * Quantity of quads that can be stored with the current texture atlas size 68 * @return {Number} 69 */ 70 getCapacity:function () { 71 return this._capacity; 72 }, 73 74 /** 75 * Texture of the texture atlas 76 * @return {Image} 77 */ 78 getTexture:function () { 79 return this._texture; 80 }, 81 82 /** 83 * @param {Image} texture 84 */ 85 setTexture:function (texture) { 86 this._texture = texture; 87 }, 88 89 /** 90 * specify if the array buffer of the VBO needs to be updated 91 * @param {Boolean} dirty 92 */ 93 setDirty:function (dirty) { 94 this._dirty = dirty; 95 }, 96 97 /** 98 * whether or not the array buffer of the VBO needs to be updated 99 * @returns {boolean} 100 */ 101 isDirty:function () { 102 return this._dirty; 103 }, 104 105 /** 106 * Quads that are going to be rendered 107 * @return {Array} 108 */ 109 getQuads:function () { 110 return this._quads; 111 }, 112 113 /** 114 * @param {Array} quads 115 */ 116 setQuads:function (quads) { 117 this._quads = quads; 118 //TODO need re-binding 119 }, 120 121 _copyQuadsToTextureAtlas:function(quads, index){ 122 if(!quads) 123 return; 124 125 for(var i = 0; i < quads.length ; i++) 126 this._setQuadToArray(quads[i], index + i); 127 }, 128 129 _setQuadToArray: function (quad, index) { 130 var locQuads = this._quads; 131 if (!locQuads[index]) { 132 locQuads[index] = new cc.V3F_C4B_T2F_Quad(quad.tl, quad.bl, quad.tr, quad.br, this._quadsArrayBuffer, index * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT); 133 return; 134 } 135 locQuads[index].bl = quad.bl; 136 locQuads[index].br = quad.br; 137 locQuads[index].tl = quad.tl; 138 locQuads[index].tr = quad.tr; 139 }, 140 141 /** 142 * Description 143 * @return {String} 144 */ 145 description:function () { 146 return '<cc.TextureAtlas | totalQuads =' + this._totalQuads + '>'; 147 }, 148 149 _setupIndices:function () { 150 if (this._capacity === 0) 151 return; 152 var locIndices = this._indices, locCapacity = this._capacity; 153 for (var i = 0; i < locCapacity; i++) { 154 if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP) { 155 locIndices[i * 6 + 0] = i * 4 + 0; 156 locIndices[i * 6 + 1] = i * 4 + 0; 157 locIndices[i * 6 + 2] = i * 4 + 2; 158 locIndices[i * 6 + 3] = i * 4 + 1; 159 locIndices[i * 6 + 4] = i * 4 + 3; 160 locIndices[i * 6 + 5] = i * 4 + 3; 161 } else { 162 locIndices[i * 6 + 0] = i * 4 + 0; 163 locIndices[i * 6 + 1] = i * 4 + 1; 164 locIndices[i * 6 + 2] = i * 4 + 2; 165 166 // inverted index. issue #179 167 locIndices[i * 6 + 3] = i * 4 + 3; 168 locIndices[i * 6 + 4] = i * 4 + 2; 169 locIndices[i * 6 + 5] = i * 4 + 1; 170 } 171 } 172 }, 173 174 _setupVBO:function () { 175 var gl = cc.renderContext; 176 //create WebGLBuffer 177 this._buffersVBO[0] = gl.createBuffer(); 178 this._buffersVBO[1] = gl.createBuffer(); 179 180 this._quadsWebBuffer = gl.createBuffer(); 181 this._mapBuffers(); 182 }, 183 184 _mapBuffers:function () { 185 var gl = cc.renderContext; 186 187 gl.bindBuffer(gl.ARRAY_BUFFER, this._quadsWebBuffer); 188 gl.bufferData(gl.ARRAY_BUFFER, this._quadsArrayBuffer, gl.DYNAMIC_DRAW); 189 190 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]); 191 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 192 193 //cc.CHECK_GL_ERROR_DEBUG(); 194 }, 195 196 /** 197 * <p>Initializes a TextureAtlas with a filename and with a certain capacity for Quads.<br /> 198 * The TextureAtlas capacity can be increased in runtime.<br /> 199 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory. </p> 200 * @param {String} file 201 * @param {Number} capacity 202 * @return {Boolean} 203 * @example 204 * //example 205 * var textureAtlas = new cc.TextureAtlas(); 206 * textureAtlas.initWithTexture("hello.png", 3); 207 */ 208 initWithFile:function (file, capacity) { 209 // retained in property 210 var texture = cc.TextureCache.getInstance().addImage(file); 211 if (texture) 212 return this.initWithTexture(texture, capacity); 213 else { 214 cc.log("cocos2d: Could not open file: " + file); 215 return false; 216 } 217 }, 218 219 /** 220 * <p>Initializes a TextureAtlas with a previously initialized Texture2D object, and<br /> 221 * with an initial capacity for Quads.<br /> 222 * The TextureAtlas capacity can be increased in runtime.<br /> 223 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory</p> 224 * @param {Image} texture 225 * @param {Number} capacity 226 * @return {Boolean} 227 * @example 228 * //example 229 * var texture = cc.TextureCache.getInstance().addImage("hello.png"); 230 * var textureAtlas = new cc.TextureAtlas(); 231 * textureAtlas.initWithTexture(texture, 3); 232 */ 233 initWithTexture:function (texture, capacity) { 234 if(!texture) 235 throw "cc.TextureAtlas.initWithTexture():texture should be non-null"; 236 237 capacity = 0 | (capacity); 238 this._capacity = capacity; 239 this._totalQuads = 0; 240 241 // retained in property 242 this._texture = texture; 243 244 // Re-initialization is not allowed 245 this._quads = []; 246 this._indices = new Uint16Array(capacity * 6); 247 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 248 this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity); 249 this._quadsReader = new Uint8Array(this._quadsArrayBuffer); 250 251 if (!( this._quads && this._indices) && capacity > 0) 252 return false; 253 254 var locQuads = this._quads; 255 for(var i = 0; i< capacity; i++) 256 locQuads[i] =new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, i * quadSize); 257 258 this._setupIndices(); 259 this._setupVBO(); 260 this._dirty = true; 261 return true; 262 }, 263 264 /** 265 * <p>Updates a Quad (texture, vertex and color) at a certain index <br /> 266 * index must be between 0 and the atlas capacity - 1 </p> 267 * @param {cc.V2F_C4B_T2F_Quad} quad 268 * @param {Number} index 269 */ 270 updateQuad:function (quad, index) { 271 if(!quad) 272 throw "cc.TextureAtlas.updateQuad(): quad should be non-null"; 273 if((index < 0) || (index >= this._capacity)) 274 throw "cc.TextureAtlas.updateQuad(): Invalid index"; 275 this._totalQuads = Math.max(index + 1, this._totalQuads); 276 this._setQuadToArray(quad, index); 277 this._dirty = true; 278 }, 279 280 /** 281 * <p>Inserts a Quad (texture, vertex and color) at a certain index<br /> 282 * index must be between 0 and the atlas capacity - 1 </p> 283 * @param {cc.V2F_C4B_T2F_Quad} quad 284 * @param {Number} index 285 */ 286 insertQuad:function (quad, index) { 287 if(index >= this._capacity) 288 throw "cc.TextureAtlas.insertQuad(): Invalid index"; 289 290 this._totalQuads++; 291 if(this._totalQuads > this._capacity) { 292 cc.log("cc.TextureAtlas.insertQuad(): invalid totalQuads"); 293 return; 294 } 295 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 296 // issue #575. index can be > totalQuads 297 var remaining = (this._totalQuads-1) - index; 298 var startOffset = index * quadSize; 299 var moveLength = remaining * quadSize; 300 this._quads[this._totalQuads -1] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads -1) * quadSize); 301 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize); 302 303 this._setQuadToArray(quad, index); 304 this._dirty = true; 305 }, 306 307 /** 308 * <p> 309 * Inserts a c array of quads at a given index <br /> 310 * index must be between 0 and the atlas capacity - 1 <br /> 311 * this method doesn't enlarge the array when amount + index > totalQuads <br /> 312 * </p> 313 * @param {Array} quads 314 * @param {Number} index 315 * @param {Number} amount 316 */ 317 insertQuads:function (quads, index, amount) { 318 amount = amount || quads.length; 319 if((index + amount) > this._capacity) 320 throw "cc.TextureAtlas.insertQuad(): Invalid index + amount"; 321 322 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 323 this._totalQuads += amount; 324 if(this._totalQuads > this._capacity) { 325 cc.log("cc.TextureAtlas.insertQuad(): invalid totalQuads"); 326 return; 327 } 328 329 // issue #575. index can be > totalQuads 330 var remaining = (this._totalQuads-1) - index - amount; 331 var startOffset = index * quadSize; 332 var moveLength = remaining * quadSize; 333 var lastIndex = (this._totalQuads-1) - amount; 334 335 var i; 336 for(i = 0; i < amount;i++) 337 this._quads[lastIndex + i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads -1) * quadSize); 338 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize * amount); 339 for(i = 0; i < amount; i++) 340 this._setQuadToArray(quads[i], index + i); 341 342 this._dirty = true; 343 }, 344 345 /** 346 * <p>Removes the quad that is located at a certain index and inserts it at a new index <br /> 347 * This operation is faster than removing and inserting in a quad in 2 different steps</p> 348 * @param {Number} fromIndex 349 * @param {Number} newIndex 350 */ 351 insertQuadFromIndex:function (fromIndex, newIndex) { 352 if (fromIndex === newIndex) 353 return; 354 355 if(newIndex < 0 && newIndex >= this._totalQuads) 356 throw "cc.TextureAtlas.insertQuadFromIndex(): Invalid newIndex"; 357 if(fromIndex < 0 && fromIndex >= this._totalQuads) 358 throw "cc.TextureAtlas.insertQuadFromIndex(): Invalid fromIndex"; 359 360 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 361 var locQuadsReader = this._quadsReader; 362 var sourceArr = locQuadsReader.subarray(fromIndex * quadSize,quadSize); 363 var startOffset, moveLength; 364 if(fromIndex > newIndex){ 365 startOffset = newIndex * quadSize; 366 moveLength = (fromIndex - newIndex) * quadSize; 367 locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength),startOffset + quadSize); 368 locQuadsReader.set(sourceArr,startOffset); 369 }else{ 370 startOffset = (fromIndex + 1) * quadSize; 371 moveLength = (newIndex - fromIndex) * quadSize; 372 locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength),startOffset - quadSize); 373 locQuadsReader.set(sourceArr, newIndex * quadSize); 374 } 375 this._dirty = true; 376 }, 377 378 /** 379 * <p>Removes a quad at a given index number.<br /> 380 * The capacity remains the same, but the total number of quads to be drawn is reduced in 1 </p> 381 * @param {Number} index 382 */ 383 removeQuadAtIndex:function (index) { 384 if(index >= this._totalQuads) 385 throw "cc.TextureAtlas.removeQuadAtIndex(): Invalid index"; 386 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 387 this._totalQuads--; 388 this._quads.length = this._totalQuads; 389 if(index !== this._totalQuads){ 390 //move data 391 var startOffset = (index + 1) * quadSize; 392 var moveLength = (this._totalQuads - index) * quadSize; 393 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset - quadSize); 394 } 395 this._dirty = true; 396 }, 397 398 removeQuadsAtIndex:function (index, amount) { 399 if(index + amount > this._totalQuads) 400 throw "cc.TextureAtlas.removeQuadsAtIndex(): index + amount out of bounds"; 401 this._totalQuads -= amount; 402 403 if(index !== this._totalQuads){ 404 //move data 405 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 406 var srcOffset = (index + amount) * quadSize; 407 var moveLength = (this._totalQuads - index) * quadSize; 408 var dstOffset = index * quadSize; 409 this._quadsReader.set(this._quadsReader.subarray(srcOffset,srcOffset + moveLength),dstOffset); 410 } 411 this._dirty = true; 412 }, 413 414 /** 415 * <p>Removes all Quads. <br /> 416 * The TextureAtlas capacity remains untouched. No memory is freed.<br /> 417 * The total number of quads to be drawn will be 0</p> 418 */ 419 removeAllQuads:function () { 420 this._quads.length = 0; 421 this._totalQuads = 0; 422 }, 423 424 _setDirty:function(dirty){ 425 this._dirty = dirty; 426 }, 427 428 /** 429 * <p>Resize the capacity of the CCTextureAtlas.<br /> 430 * The new capacity can be lower or higher than the current one<br /> 431 * It returns YES if the resize was successful. <br /> 432 * If it fails to resize the capacity it will return NO with a new capacity of 0. <br /> 433 * no used for js</p> 434 * @param {Number} newCapacity 435 * @return {Boolean} 436 */ 437 resizeCapacity:function (newCapacity) { 438 if (newCapacity == this._capacity) 439 return true; 440 441 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 442 var oldCapacity = this._capacity; 443 // update capacity and totolQuads 444 this._totalQuads = Math.min(this._totalQuads, newCapacity); 445 this._capacity = 0 | newCapacity; 446 var i, capacity = this._capacity, locTotalQuads = this._totalQuads; 447 448 if (this._quads == null) { 449 this._quads = []; 450 this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity); 451 this._quadsReader = new Uint8Array(this._quadsArrayBuffer); 452 for(i = 0; i< capacity; i++) 453 this._quads = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer,i * quadSize); 454 } else { 455 var newQuads, newArrayBuffer, quads = this._quads; 456 if (capacity > oldCapacity) { 457 newQuads = []; 458 newArrayBuffer = new ArrayBuffer(quadSize * capacity); 459 for(i = 0; i < locTotalQuads;i++){ 460 newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl,quads[i].bl,quads[i].tr,quads[i].br, 461 newArrayBuffer,i * quadSize); 462 } 463 for(;i<capacity; i ++) 464 newQuads[i] = new cc.V3F_C4B_T2F_Quad(null,null,null,null, newArrayBuffer,i * quadSize); 465 466 this._quadsReader = new Uint8Array(newArrayBuffer); 467 this._quads = newQuads; 468 this._quadsArrayBuffer = newArrayBuffer; 469 } else { 470 var count = Math.max(locTotalQuads, capacity); 471 newQuads = []; 472 newArrayBuffer = new ArrayBuffer(quadSize * capacity); 473 for(i = 0; i < count;i++){ 474 newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl,quads[i].bl,quads[i].tr,quads[i].br, 475 newArrayBuffer,i * quadSize); 476 } 477 this._quadsReader = new Uint8Array(newArrayBuffer); 478 this._quads = newQuads; 479 this._quadsArrayBuffer = newArrayBuffer; 480 } 481 } 482 483 if (this._indices == null) { 484 this._indices = new Uint16Array(capacity * 6); 485 } else { 486 if (capacity > oldCapacity) { 487 var tempIndices = new Uint16Array(capacity * 6); 488 tempIndices.set(this._indices, 0); 489 this._indices = tempIndices; 490 } else { 491 this._indices = this._indices.subarray(0, capacity * 6); 492 } 493 } 494 495 this._setupIndices(); 496 this._mapBuffers(); 497 this._dirty = true; 498 return true; 499 }, 500 501 /** 502 * Used internally by CCParticleBatchNode <br/> 503 * don't use this unless you know what you're doing 504 * @param {Number} amount 505 */ 506 increaseTotalQuadsWith:function (amount) { 507 this._totalQuads += amount; 508 }, 509 510 /** 511 * Moves an amount of quads from oldIndex at newIndex 512 * @param {Number} oldIndex 513 * @param {Number} amount 514 * @param {Number} newIndex 515 */ 516 moveQuadsFromIndex: function (oldIndex, amount, newIndex) { 517 if (arguments.length == 2) { 518 newIndex = amount; 519 amount = this._totalQuads - oldIndex; 520 if((newIndex + (this._totalQuads - oldIndex)) > this._capacity) 521 throw "cc.TextureAtlas.moveQuadsFromIndex(): move is out of bounds"; 522 if(amount === 0) 523 return; 524 }else{ 525 if((newIndex + amount) > this._totalQuads) 526 throw "cc.TextureAtlas.moveQuadsFromIndex(): Invalid newIndex"; 527 if(oldIndex >= this._totalQuads) 528 throw "cc.TextureAtlas.moveQuadsFromIndex(): Invalid oldIndex"; 529 530 if (oldIndex == newIndex) 531 return; 532 } 533 534 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 535 var srcOffset = oldIndex * quadSize; 536 var srcLength = amount * quadSize; 537 var locQuadsReader = this._quadsReader; 538 var sourceArr = locQuadsReader.subarray(srcOffset, srcOffset + srcLength); 539 var dstOffset = newIndex * quadSize; 540 var moveLength, moveStart; 541 if (newIndex < oldIndex) { 542 moveLength = (oldIndex - newIndex) * quadSize; 543 moveStart = newIndex * quadSize; 544 locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), moveStart + srcLength) 545 } else { 546 moveLength = (newIndex - oldIndex) * quadSize; 547 moveStart = (oldIndex + amount) * quadSize; 548 locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), srcOffset); 549 } 550 locQuadsReader.set(sourceArr, dstOffset); 551 this._dirty = true; 552 }, 553 554 /** 555 * Ensures that after a realloc quads are still empty <br/> 556 * Used internally by CCParticleBatchNode 557 * @param {Number} index 558 * @param {Number} amount 559 */ 560 fillWithEmptyQuadsFromIndex:function (index, amount) { 561 var count = amount * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 562 var clearReader = new Uint8Array(this._quadsArrayBuffer, index * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT, count); 563 for (var i = 0; i < count; i++) 564 clearReader[i] = 0; 565 }, 566 567 // TextureAtlas - Drawing 568 569 /** 570 * <p>Draws n quads from an index (offset). <br /> 571 * n + start can't be greater than the capacity of the atlas</p> 572 * @param {Number} n 573 * @param {Number} start 574 */ 575 drawNumberOfQuads:function (n, start) { 576 start = start || 0; 577 if (0 === n || !this._texture || !this._texture.isLoaded()) 578 return; 579 580 var gl = cc.renderContext; 581 cc.glBindTexture2D(this._texture); 582 583 // 584 // Using VBO without VAO 585 // 586 //vertices 587 //gl.bindBuffer(gl.ARRAY_BUFFER, this._buffersVBO[0]); 588 // XXX: update is done in draw... perhaps it should be done in a timer 589 cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSCOLORTEX); 590 591 gl.bindBuffer(gl.ARRAY_BUFFER, this._quadsWebBuffer); 592 if (this._dirty) 593 gl.bufferData(gl.ARRAY_BUFFER, this._quadsArrayBuffer, gl.DYNAMIC_DRAW); 594 595 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); // vertices 596 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); // colors 597 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); // tex coords 598 599 if (this._dirty) 600 this._dirty = false; 601 602 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]); 603 604 if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP) 605 gl.drawElements(gl.TRIANGLE_STRIP, n * 6, gl.UNSIGNED_SHORT, start * 6 * this._indices.BYTES_PER_ELEMENT); 606 else 607 gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, start * 6 * this._indices.BYTES_PER_ELEMENT); 608 609 cc.g_NumberOfDraws++; 610 //cc.CHECK_GL_ERROR_DEBUG(); 611 }, 612 613 /** 614 * Draws all the Atlas's Quads 615 */ 616 drawQuads:function () { 617 this.drawNumberOfQuads(this._totalQuads, 0); 618 }, 619 620 _releaseBuffer: function () { 621 var gl = cc.renderContext; 622 if (this._buffersVBO) { 623 if (this._buffersVBO[0]) 624 gl.deleteBuffer(this._buffersVBO[0]); 625 if (this._buffersVBO[1]) 626 gl.deleteBuffer(this._buffersVBO[1]) 627 } 628 if (this._quadsWebBuffer) 629 gl.deleteBuffer(this._quadsWebBuffer); 630 } 631 }); 632 633 /** 634 * <p>Creates a TextureAtlas with an filename and with an initial capacity for Quads. <br /> 635 * The TextureAtlas capacity can be increased in runtime. </p> 636 * @param {String} file 637 * @param {Number} capacity 638 * @return {cc.TextureAtlas|Null} 639 * @example 640 * //example 641 * var textureAtlas = cc.TextureAtlas.create("hello.png", 3); 642 */ 643 cc.TextureAtlas.create = function (file, capacity) { 644 var textureAtlas = new cc.TextureAtlas(); 645 if (textureAtlas && textureAtlas.initWithFile(file, capacity)) 646 return textureAtlas; 647 return null; 648 }; 649 650 /** 651 * <p>Creates a TextureAtlas with a previously initialized Texture2D object, and with an initial capacity for n Quads. 652 * The TextureAtlas capacity can be increased in runtime.</p> 653 * @param {Image|cc.Texture2D} texture 654 * @param {Number} capacity 655 * @return {cc.TextureAtlas} 656 * @example 657 * //example 658 * var texture = cc.TextureCache.getInstance().addImage("hello.png"); 659 * var textureAtlas = cc.TextureAtlas.createWithTexture(texture, 3); 660 */ 661 cc.TextureAtlas.createWithTexture = function (texture, capacity) { 662 var textureAtlas = new cc.TextureAtlas(); 663 if (textureAtlas && textureAtlas.initWithTexture(texture, capacity)) 664 return textureAtlas; 665 return null; 666 }; 667