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 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 * @property {Boolean} dirty - Indicates whether or not the array buffer of the VBO needs to be updated. 40 * @property {Image} texture - Image texture for cc.TextureAtlas. 41 * @property {Number} capacity - <@readonly> Quantity of quads that can be stored with the current texture atlas size. 42 * @property {Number} totalQuads - <@readonly> Quantity of quads that are going to be drawn. 43 * @property {Array} quads - <@readonly> Quads that are going to be rendered 44 */ 45 cc.TextureAtlas = cc.Class.extend(/** @lends cc.TextureAtlas# */{ 46 dirty: false, 47 texture: null, 48 49 _indices: null, 50 //0: vertex 1: indices 51 _buffersVBO: null, 52 _capacity: 0, 53 54 _quads: null, 55 _quadsArrayBuffer: null, 56 _quadsWebBuffer: null, 57 _quadsReader: null, 58 59 /** 60 * <p>Creates a TextureAtlas with an filename and with an initial capacity for Quads. <br /> 61 * The TextureAtlas capacity can be increased in runtime. </p> 62 * Constructor of cc.TextureAtlas 63 * @param {String|cc.Texture2D} fileName 64 * @param {Number} capacity 65 * @example 66 * 1. 67 * //creates a TextureAtlas with filename 68 * var textureAtlas = new cc.TextureAtlas("res/hello.png", 3); 69 * 2. 70 * //creates a TextureAtlas with texture 71 * var texture = cc.textureCache.addImage("hello.png"); 72 * var textureAtlas = new cc.TextureAtlas(texture, 3); 73 */ 74 ctor: function (fileName, capacity) { 75 this._buffersVBO = []; 76 77 if (typeof(fileName) == "string") { 78 this.initWithFile(fileName, capacity); 79 } 80 else if (fileName instanceof cc.Texture2D) { 81 this.initWithTexture(fileName, capacity); 82 } 83 }, 84 85 /** 86 * Quantity of quads that are going to be drawn. 87 * @return {Number} 88 */ 89 getTotalQuads: function () { 90 //return this._quads.length; 91 return this._totalQuads; 92 }, 93 94 /** 95 * Quantity of quads that can be stored with the current texture atlas size 96 * @return {Number} 97 */ 98 getCapacity: function () { 99 return this._capacity; 100 }, 101 102 /** 103 * Texture of the texture atlas 104 * @return {Image} 105 */ 106 getTexture: function () { 107 return this.texture; 108 }, 109 110 /** 111 * @param {Image} texture 112 */ 113 setTexture: function (texture) { 114 this.texture = texture; 115 }, 116 117 /** 118 * specify if the array buffer of the VBO needs to be updated 119 * @param {Boolean} dirty 120 */ 121 setDirty: function (dirty) { 122 this.dirty = dirty; 123 }, 124 125 /** 126 * whether or not the array buffer of the VBO needs to be updated 127 * @returns {boolean} 128 */ 129 isDirty: function () { 130 return this.dirty; 131 }, 132 133 /** 134 * Quads that are going to be rendered 135 * @return {Array} 136 */ 137 getQuads: function () { 138 return this._quads; 139 }, 140 141 /** 142 * @param {Array} quads 143 */ 144 setQuads: function (quads) { 145 this._quads = quads; 146 //TODO need re-binding 147 }, 148 149 _copyQuadsToTextureAtlas: function (quads, index) { 150 if (!quads) 151 return; 152 153 for (var i = 0; i < quads.length; i++) 154 this._setQuadToArray(quads[i], index + i); 155 }, 156 157 _setQuadToArray: function (quad, index) { 158 var locQuads = this._quads; 159 if (!locQuads[index]) { 160 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); 161 return; 162 } 163 locQuads[index].bl = quad.bl; 164 locQuads[index].br = quad.br; 165 locQuads[index].tl = quad.tl; 166 locQuads[index].tr = quad.tr; 167 }, 168 169 /** 170 * Description 171 * @return {String} 172 */ 173 description: function () { 174 return '<cc.TextureAtlas | totalQuads =' + this._totalQuads + '>'; 175 }, 176 177 _setupIndices: function () { 178 if (this._capacity === 0) 179 return; 180 var locIndices = this._indices, locCapacity = this._capacity; 181 for (var i = 0; i < locCapacity; i++) { 182 if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP) { 183 locIndices[i * 6 + 0] = i * 4 + 0; 184 locIndices[i * 6 + 1] = i * 4 + 0; 185 locIndices[i * 6 + 2] = i * 4 + 2; 186 locIndices[i * 6 + 3] = i * 4 + 1; 187 locIndices[i * 6 + 4] = i * 4 + 3; 188 locIndices[i * 6 + 5] = i * 4 + 3; 189 } else { 190 locIndices[i * 6 + 0] = i * 4 + 0; 191 locIndices[i * 6 + 1] = i * 4 + 1; 192 locIndices[i * 6 + 2] = i * 4 + 2; 193 194 // inverted index. issue #179 195 locIndices[i * 6 + 3] = i * 4 + 3; 196 locIndices[i * 6 + 4] = i * 4 + 2; 197 locIndices[i * 6 + 5] = i * 4 + 1; 198 } 199 } 200 }, 201 202 _setupVBO: function () { 203 var gl = cc._renderContext; 204 //create WebGLBuffer 205 this._buffersVBO[0] = gl.createBuffer(); 206 this._buffersVBO[1] = gl.createBuffer(); 207 208 this._quadsWebBuffer = gl.createBuffer(); 209 this._mapBuffers(); 210 }, 211 212 _mapBuffers: function () { 213 var gl = cc._renderContext; 214 215 gl.bindBuffer(gl.ARRAY_BUFFER, this._quadsWebBuffer); 216 gl.bufferData(gl.ARRAY_BUFFER, this._quadsArrayBuffer, gl.DYNAMIC_DRAW); 217 218 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]); 219 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW); 220 }, 221 222 /** 223 * <p>Initializes a TextureAtlas with a filename and with a certain capacity for Quads.<br /> 224 * The TextureAtlas capacity can be increased in runtime.<br /> 225 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory. </p> 226 * @param {String} file 227 * @param {Number} capacity 228 * @return {Boolean} 229 * @example 230 * //example 231 * var textureAtlas = new cc.TextureAtlas(); 232 * textureAtlas.initWithTexture("hello.png", 3); 233 */ 234 initWithFile: function (file, capacity) { 235 // retained in property 236 var texture = cc.textureCache.addImage(file); 237 if (texture) 238 return this.initWithTexture(texture, capacity); 239 else { 240 cc.log(cc._LogInfos.TextureAtlas_initWithFile, file); 241 return false; 242 } 243 }, 244 245 /** 246 * <p>Initializes a TextureAtlas with a previously initialized Texture2D object, and<br /> 247 * with an initial capacity for Quads.<br /> 248 * The TextureAtlas capacity can be increased in runtime.<br /> 249 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory</p> 250 * @param {Image} texture 251 * @param {Number} capacity 252 * @return {Boolean} 253 * @example 254 * //example 255 * var texture = cc.textureCache.addImage("hello.png"); 256 * var textureAtlas = new cc.TextureAtlas(); 257 * textureAtlas.initWithTexture(texture, 3); 258 */ 259 initWithTexture: function (texture, capacity) { 260 261 cc.assert(texture, cc._LogInfos.TextureAtlas_initWithTexture); 262 263 capacity = 0 | (capacity); 264 this._capacity = capacity; 265 this._totalQuads = 0; 266 267 // retained in property 268 this.texture = texture; 269 270 // Re-initialization is not allowed 271 this._quads = []; 272 this._indices = new Uint16Array(capacity * 6); 273 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 274 this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity); 275 this._quadsReader = new Uint8Array(this._quadsArrayBuffer); 276 277 if (!( this._quads && this._indices) && capacity > 0) 278 return false; 279 280 var locQuads = this._quads; 281 for (var i = 0; i < capacity; i++) 282 locQuads[i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, i * quadSize); 283 284 this._setupIndices(); 285 this._setupVBO(); 286 this.dirty = true; 287 return true; 288 }, 289 290 /** 291 * <p>Updates a Quad (texture, vertex and color) at a certain index <br /> 292 * index must be between 0 and the atlas capacity - 1 </p> 293 * @param {cc.V3F_C4B_T2F_Quad} quad 294 * @param {Number} index 295 */ 296 updateQuad: function (quad, index) { 297 298 cc.assert(quad, cc._LogInfos.TextureAtlas_updateQuad); 299 300 cc.assert(index >= 0 && index < this._capacity, cc._LogInfos.TextureAtlas_updateQuad_2); 301 302 this._totalQuads = Math.max(index + 1, this._totalQuads); 303 this._setQuadToArray(quad, index); 304 this.dirty = true; 305 }, 306 307 /** 308 * <p>Inserts a Quad (texture, vertex and color) at a certain index<br /> 309 * index must be between 0 and the atlas capacity - 1 </p> 310 * @param {cc.V3F_C4B_T2F_Quad} quad 311 * @param {Number} index 312 */ 313 insertQuad: function (quad, index) { 314 315 cc.assert(index < this._capacity, cc._LogInfos.TextureAtlas_insertQuad_2); 316 317 this._totalQuads++; 318 if (this._totalQuads > this._capacity) { 319 cc.log(cc._LogInfos.TextureAtlas_insertQuad); 320 return; 321 } 322 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 323 // issue #575. index can be > totalQuads 324 var remaining = (this._totalQuads - 1) - index; 325 var startOffset = index * quadSize; 326 var moveLength = remaining * quadSize; 327 this._quads[this._totalQuads - 1] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads - 1) * quadSize); 328 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize); 329 330 this._setQuadToArray(quad, index); 331 this.dirty = true; 332 }, 333 334 /** 335 * <p> 336 * Inserts a c array of quads at a given index <br /> 337 * index must be between 0 and the atlas capacity - 1 <br /> 338 * this method doesn't enlarge the array when amount + index > totalQuads <br /> 339 * </p> 340 * @param {Array} quads 341 * @param {Number} index 342 * @param {Number} amount 343 */ 344 insertQuads: function (quads, index, amount) { 345 amount = amount || quads.length; 346 347 cc.assert((index + amount) <= this._capacity, cc._LogInfos.TextureAtlas_insertQuads); 348 349 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 350 this._totalQuads += amount; 351 if (this._totalQuads > this._capacity) { 352 cc.log(cc._LogInfos.TextureAtlas_insertQuad); 353 return; 354 } 355 356 // issue #575. index can be > totalQuads 357 var remaining = (this._totalQuads - 1) - index - amount; 358 var startOffset = index * quadSize; 359 var moveLength = remaining * quadSize; 360 var lastIndex = (this._totalQuads - 1) - amount; 361 362 var i; 363 for (i = 0; i < amount; i++) 364 this._quads[lastIndex + i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads - 1) * quadSize); 365 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize * amount); 366 for (i = 0; i < amount; i++) 367 this._setQuadToArray(quads[i], index + i); 368 369 this.dirty = true; 370 }, 371 372 /** 373 * <p>Removes the quad that is located at a certain index and inserts it at a new index <br /> 374 * This operation is faster than removing and inserting in a quad in 2 different steps</p> 375 * @param {Number} fromIndex 376 * @param {Number} newIndex 377 */ 378 insertQuadFromIndex: function (fromIndex, newIndex) { 379 if (fromIndex === newIndex) 380 return; 381 382 cc.assert(newIndex >= 0 || newIndex < this._totalQuads, cc._LogInfos.TextureAtlas_insertQuadFromIndex); 383 384 cc.assert(fromIndex >= 0 || fromIndex < this._totalQuads, cc._LogInfos.TextureAtlas_insertQuadFromIndex_2); 385 386 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 387 var locQuadsReader = this._quadsReader; 388 var sourceArr = locQuadsReader.subarray(fromIndex * quadSize, quadSize); 389 var startOffset, moveLength; 390 if (fromIndex > newIndex) { 391 startOffset = newIndex * quadSize; 392 moveLength = (fromIndex - newIndex) * quadSize; 393 locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize); 394 locQuadsReader.set(sourceArr, startOffset); 395 } else { 396 startOffset = (fromIndex + 1) * quadSize; 397 moveLength = (newIndex - fromIndex) * quadSize; 398 locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength), startOffset - quadSize); 399 locQuadsReader.set(sourceArr, newIndex * quadSize); 400 } 401 this.dirty = true; 402 }, 403 404 /** 405 * <p>Removes a quad at a given index number.<br /> 406 * The capacity remains the same, but the total number of quads to be drawn is reduced in 1 </p> 407 * @param {Number} index 408 */ 409 removeQuadAtIndex: function (index) { 410 411 cc.assert(index < this._totalQuads, cc._LogInfos.TextureAtlas_removeQuadAtIndex); 412 413 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 414 this._totalQuads--; 415 this._quads.length = this._totalQuads; 416 if (index !== this._totalQuads) { 417 //move data 418 var startOffset = (index + 1) * quadSize; 419 var moveLength = (this._totalQuads - index) * quadSize; 420 this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset - quadSize); 421 } 422 this.dirty = true; 423 }, 424 425 /** 426 * Removes a given number of quads at a given index 427 * @param {Number} index 428 * @param {Number} amount 429 */ 430 removeQuadsAtIndex: function (index, amount) { 431 432 cc.assert(index + amount <= this._totalQuads, cc._LogInfos.TextureAtlas_removeQuadsAtIndex); 433 434 this._totalQuads -= amount; 435 436 if (index !== this._totalQuads) { 437 //move data 438 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 439 var srcOffset = (index + amount) * quadSize; 440 var moveLength = (this._totalQuads - index) * quadSize; 441 var dstOffset = index * quadSize; 442 this._quadsReader.set(this._quadsReader.subarray(srcOffset, srcOffset + moveLength), dstOffset); 443 } 444 this.dirty = true; 445 }, 446 447 /** 448 * <p>Removes all Quads. <br /> 449 * The TextureAtlas capacity remains untouched. No memory is freed.<br /> 450 * The total number of quads to be drawn will be 0</p> 451 */ 452 removeAllQuads: function () { 453 this._quads.length = 0; 454 this._totalQuads = 0; 455 }, 456 457 _setDirty: function (dirty) { 458 this.dirty = dirty; 459 }, 460 461 /** 462 * <p>Resize the capacity of the CCTextureAtlas.<br /> 463 * The new capacity can be lower or higher than the current one<br /> 464 * It returns YES if the resize was successful. <br /> 465 * If it fails to resize the capacity it will return NO with a new capacity of 0. <br /> 466 * no used for js</p> 467 * @param {Number} newCapacity 468 * @return {Boolean} 469 */ 470 resizeCapacity: function (newCapacity) { 471 if (newCapacity == this._capacity) 472 return true; 473 474 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 475 var oldCapacity = this._capacity; 476 // update capacity and totolQuads 477 this._totalQuads = Math.min(this._totalQuads, newCapacity); 478 this._capacity = 0 | newCapacity; 479 var i, capacity = this._capacity, locTotalQuads = this._totalQuads; 480 481 if (this._quads == null) { 482 this._quads = []; 483 this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity); 484 this._quadsReader = new Uint8Array(this._quadsArrayBuffer); 485 for (i = 0; i < capacity; i++) 486 this._quads = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, i * quadSize); 487 } else { 488 var newQuads, newArrayBuffer, quads = this._quads; 489 if (capacity > oldCapacity) { 490 newQuads = []; 491 newArrayBuffer = new ArrayBuffer(quadSize * capacity); 492 for (i = 0; i < locTotalQuads; i++) { 493 newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl, quads[i].bl, quads[i].tr, quads[i].br, 494 newArrayBuffer, i * quadSize); 495 } 496 for (; i < capacity; i++) 497 newQuads[i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, newArrayBuffer, i * quadSize); 498 499 this._quadsReader = new Uint8Array(newArrayBuffer); 500 this._quads = newQuads; 501 this._quadsArrayBuffer = newArrayBuffer; 502 } else { 503 var count = Math.max(locTotalQuads, capacity); 504 newQuads = []; 505 newArrayBuffer = new ArrayBuffer(quadSize * capacity); 506 for (i = 0; i < count; i++) { 507 newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl, quads[i].bl, quads[i].tr, quads[i].br, 508 newArrayBuffer, i * quadSize); 509 } 510 this._quadsReader = new Uint8Array(newArrayBuffer); 511 this._quads = newQuads; 512 this._quadsArrayBuffer = newArrayBuffer; 513 } 514 } 515 516 if (this._indices == null) { 517 this._indices = new Uint16Array(capacity * 6); 518 } else { 519 if (capacity > oldCapacity) { 520 var tempIndices = new Uint16Array(capacity * 6); 521 tempIndices.set(this._indices, 0); 522 this._indices = tempIndices; 523 } else { 524 this._indices = this._indices.subarray(0, capacity * 6); 525 } 526 } 527 528 this._setupIndices(); 529 this._mapBuffers(); 530 this.dirty = true; 531 return true; 532 }, 533 534 /** 535 * Used internally by CCParticleBatchNode <br/> 536 * don't use this unless you know what you're doing 537 * @param {Number} amount 538 */ 539 increaseTotalQuadsWith: function (amount) { 540 this._totalQuads += amount; 541 }, 542 543 /** 544 * Moves an amount of quads from oldIndex at newIndex 545 * @param {Number} oldIndex 546 * @param {Number} amount 547 * @param {Number} newIndex 548 */ 549 moveQuadsFromIndex: function (oldIndex, amount, newIndex) { 550 if (newIndex === undefined) { 551 newIndex = amount; 552 amount = this._totalQuads - oldIndex; 553 554 cc.assert((newIndex + (this._totalQuads - oldIndex)) <= this._capacity, cc._LogInfos.TextureAtlas_moveQuadsFromIndex); 555 556 if (amount === 0) 557 return; 558 } else { 559 560 cc.assert((newIndex + amount) <= this._totalQuads, cc._LogInfos.TextureAtlas_moveQuadsFromIndex_2); 561 562 cc.assert(oldIndex < this._totalQuads, cc._LogInfos.TextureAtlas_moveQuadsFromIndex_3); 563 564 if (oldIndex == newIndex) 565 return; 566 } 567 568 var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 569 var srcOffset = oldIndex * quadSize; 570 var srcLength = amount * quadSize; 571 var locQuadsReader = this._quadsReader; 572 var sourceArr = locQuadsReader.subarray(srcOffset, srcOffset + srcLength); 573 var dstOffset = newIndex * quadSize; 574 var moveLength, moveStart; 575 if (newIndex < oldIndex) { 576 moveLength = (oldIndex - newIndex) * quadSize; 577 moveStart = newIndex * quadSize; 578 locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), moveStart + srcLength) 579 } else { 580 moveLength = (newIndex - oldIndex) * quadSize; 581 moveStart = (oldIndex + amount) * quadSize; 582 locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), srcOffset); 583 } 584 locQuadsReader.set(sourceArr, dstOffset); 585 this.dirty = true; 586 }, 587 588 /** 589 * Ensures that after a realloc quads are still empty <br/> 590 * Used internally by CCParticleBatchNode 591 * @param {Number} index 592 * @param {Number} amount 593 */ 594 fillWithEmptyQuadsFromIndex: function (index, amount) { 595 var count = amount * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT; 596 var clearReader = new Uint8Array(this._quadsArrayBuffer, index * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT, count); 597 for (var i = 0; i < count; i++) 598 clearReader[i] = 0; 599 }, 600 601 // TextureAtlas - Drawing 602 603 /** 604 * Draws all the Atlas's Quads 605 */ 606 drawQuads: function () { 607 this.drawNumberOfQuads(this._totalQuads, 0); 608 }, 609 610 _releaseBuffer: function () { 611 var gl = cc._renderContext; 612 if (this._buffersVBO) { 613 if (this._buffersVBO[0]) 614 gl.deleteBuffer(this._buffersVBO[0]); 615 if (this._buffersVBO[1]) 616 gl.deleteBuffer(this._buffersVBO[1]) 617 } 618 if (this._quadsWebBuffer) 619 gl.deleteBuffer(this._quadsWebBuffer); 620 } 621 }); 622 623 var _p = cc.TextureAtlas.prototype; 624 625 // Extended properties 626 /** @expose */ 627 _p.totalQuads; 628 cc.defineGetterSetter(_p, "totalQuads", _p.getTotalQuads); 629 /** @expose */ 630 _p.capacity; 631 cc.defineGetterSetter(_p, "capacity", _p.getCapacity); 632 /** @expose */ 633 _p.quads; 634 cc.defineGetterSetter(_p, "quads", _p.getQuads, _p.setQuads); 635 636 /** 637 * <p>Creates a TextureAtlas with an filename and with an initial capacity for Quads. <br /> 638 * The TextureAtlas capacity can be increased in runtime. </p> 639 * @deprecated since v3.0, please use new cc.TextureAtlas(fileName, capacity) instead 640 * @param {String|cc.Texture2D} fileName 641 * @param {Number} capacity 642 * @return {cc.TextureAtlas|Null} 643 * @example 644 * 1. 645 * //creates a TextureAtlas with filename 646 * var textureAtlas = cc.TextureAtlas.create("res/hello.png", 3); 647 * 2. 648 * //creates a TextureAtlas with texture 649 * var texture = cc.textureCache.addImage("hello.png"); 650 * var textureAtlas = cc.TextureAtlas.create(texture, 3); 651 */ 652 cc.TextureAtlas.create = function (fileName, capacity) { 653 return new cc.TextureAtlas(fileName, capacity); 654 }; 655 656 /** 657 * @deprecated since v3.0, please use new cc.TextureAtlas(texture) instead 658 * @function 659 */ 660 cc.TextureAtlas.createWithTexture = cc.TextureAtlas.create; 661 662 if (cc._renderType === cc._RENDER_TYPE_WEBGL) { 663 cc.assert(typeof cc._tmp.WebGLTextureAtlas === "function", cc._LogInfos.MissingFile, "TexturesWebGL.js"); 664 cc._tmp.WebGLTextureAtlas(); 665 delete cc._tmp.WebGLTextureAtlas; 666 } 667 668 cc.assert(typeof cc._tmp.PrototypeTextureAtlas === "function", cc._LogInfos.MissingFile, "TexturesPropertyDefine.js"); 669 cc._tmp.PrototypeTextureAtlas(); 670 delete cc._tmp.PrototypeTextureAtlas;