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