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 /** 29 * <p>A class that implements a Texture Atlas. <br /> 30 * Supported features: <br /> 31 * The atlas file can be a PNG, JPG. <br /> 32 * Quads can be updated in runtime <br /> 33 * Quads can be added in runtime <br /> 34 * Quads can be removed in runtime <br /> 35 * Quads can be re-ordered in runtime <br /> 36 * The TextureAtlas capacity can be increased or decreased in runtime.</p> 37 * @class 38 * @extends cc.Class 39 */ 40 cc.TextureAtlas = cc.Class.extend(/** @lends cc.TextureAtlas# */{ 41 _indices:[], 42 //0: vertex 1: indices 43 _buffersVBO:[0, 1], 44 //indicates whether or not the array buffer of the VBO needs to be updated 45 _dirty:false, 46 _capacity:0, 47 _texture:null, 48 _quads:[], 49 /** 50 * Quantity of quads that are going to be drawn. 51 * @return {Number} 52 */ 53 getTotalQuads:function () { 54 return this._quads.length; 55 }, 56 57 /** 58 * Quantity of quads that can be stored with the current texture atlas size 59 * @return {Number} 60 */ 61 getCapacity:function () { 62 return this._capacity; 63 }, 64 65 /** 66 * Texture of the texture atlas 67 * @return {Image} 68 */ 69 getTexture:function () { 70 return this._texture; 71 }, 72 73 /** 74 * @param {Image} texture 75 */ 76 setTexture:function (texture) { 77 this._texture = texture; 78 }, 79 80 /** 81 * Quads that are going to be rendered 82 * @return {Array} 83 */ 84 getQuads:function () { 85 return this._quads; 86 }, 87 88 /** 89 * @param {Array} quads 90 */ 91 setQuads:function (quads) { 92 this._quads = quads; 93 }, 94 95 /** 96 * Description 97 * @return {String} 98 */ 99 description:function () { 100 return '<CCTextureAtlas | totalQuads =' + this._totalQuads + '>'; 101 }, 102 _initIndices:function () { 103 if (this._capacity == 0) 104 return; 105 106 for (var i = 0; i < this._capacity; i++) { 107 this._indices[i * 6 + 0] = i * 4 + 0; 108 this._indices[i * 6 + 1] = i * 4 + 0; 109 this._indices[i * 6 + 2] = i * 4 + 2; 110 this._indices[i * 6 + 3] = i * 4 + 1; 111 this._indices[i * 6 + 4] = i * 4 + 3; 112 this._indices[i * 6 + 5] = i * 4 + 3; 113 } 114 }, 115 116 /** 117 * <p>Initializes a TextureAtlas with a filename and with a certain capacity for Quads.<br /> 118 * The TextureAtlas capacity can be increased in runtime.<br /> 119 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory. </p> 120 * @param {String} file 121 * @param {Number} capacity 122 * @return {Boolean|Null} 123 * @example 124 * //example 125 * var textureAtlas = new cc.TextureAtlas(); 126 * textureAtlas.initWithTexture("hello.png", 3); 127 */ 128 initWithFile:function (file, capacity) { 129 // retained in property 130 var texture = cc.TextureCache.getInstance().addImage(file); 131 132 if (texture) { 133 return this.initWithTexture(texture, capacity); 134 } else { 135 cc.log("cocos2d: Could not open file: " + file); 136 return null; 137 } 138 }, 139 140 /** 141 * <p>Initializes a TextureAtlas with a previously initialized Texture2D object, and<br /> 142 * with an initial capacity for Quads.<br /> 143 * The TextureAtlas capacity can be increased in runtime.<br /> 144 * WARNING: Do not reinitialize the TextureAtlas because it will leak memory</p> 145 * @param {Image} texture 146 * @param {Number} capacity 147 * @return {Boolean} 148 * @example 149 * //example 150 * var texture = cc.TextureCache.getInstance().addImage("hello.png"); 151 * var textureAtlas = new cc.TextureAtlas(); 152 * textureAtlas.initWithTexture(texture, 3); 153 */ 154 initWithTexture:function (texture, capacity) { 155 cc.Assert(texture != null, "TextureAtlas.initWithTexture():texture should not be null"); 156 this._capacity = capacity; 157 158 // retained in property 159 this._texture = texture; 160 161 // Re-initialization is not allowed 162 cc.Assert(this._quads.length == 0 && this._indices.length == 0, "TextureAtlas.initWithTexture():_quads and _indices should not be null"); 163 164 //TODO init array 165 this._quads = []; 166 this._indices = []; 167 168 if (!( this._quads && this._indices) && this._capacity > 0) { 169 return false; 170 } 171 172 this._dirty = true; 173 this._initIndices(); 174 return true; 175 }, 176 177 /** 178 * <p>Updates a Quad (texture, vertex and color) at a certain index <br /> 179 * index must be between 0 and the atlas capacity - 1 </p> 180 * @param {cc.V2F_C4B_T2F_Quad} quad 181 * @param {Number} index 182 */ 183 updateQuad:function (quad, index) { 184 this._quads[index] = quad; 185 this._dirty = true; 186 }, 187 188 /** 189 * <p>Inserts a Quad (texture, vertex and color) at a certain index<br /> 190 * index must be between 0 and the atlas capacity - 1 </p> 191 * @param {cc.V2F_C4B_T2F_Quad} quad 192 * @param {Number} index 193 */ 194 insertQuad:function (quad, index) { 195 this._quads = cc.ArrayAppendObjectToIndex(this._quads, quad, index); 196 this._dirty = true; 197 }, 198 199 /** 200 * <p>Removes the quad that is located at a certain index and inserts it at a new index <br /> 201 * This operation is faster than removing and inserting in a quad in 2 different steps</p> 202 * @param {Number} fromIndex 203 * @param {Number} newIndex 204 */ 205 insertQuadFromIndex:function (fromIndex, newIndex) { 206 if (fromIndex == newIndex) 207 return; 208 209 var quad = this._quads[fromIndex]; 210 cc.ArrayRemoveObjectAtIndex(this._quads, fromIndex); 211 if (fromIndex > newIndex) { 212 this._quads = cc.ArrayAppendObjectToIndex(this._quads, quad, newIndex); 213 } else { 214 this._quads = cc.ArrayAppendObjectToIndex(this._quads, quad, newIndex - 1); 215 } 216 217 this._dirty = true; 218 }, 219 220 /** 221 * <p>Removes a quad at a given index number.<br /> 222 * The capacity remains the same, but the total number of quads to be drawn is reduced in 1 </p> 223 * @param {Number} index 224 */ 225 removeQuadAtIndex:function (index) { 226 cc.ArrayRemoveObjectAtIndex(this._quads, index); 227 228 this._dirty = true; 229 }, 230 231 /** 232 * <p>Removes all Quads. <br /> 233 * The TextureAtlas capacity remains untouched. No memory is freed.<br /> 234 * The total number of quads to be drawn will be 0</p> 235 */ 236 removeAllQuads:function () { 237 this._quads.length = 0; 238 }, 239 240 /** 241 * <p>Resize the capacity of the CCTextureAtlas.<br /> 242 * The new capacity can be lower or higher than the current one<br /> 243 * It returns YES if the resize was successful. <br /> 244 * If it fails to resize the capacity it will return NO with a new capacity of 0. <br /> 245 * no used for js</p> 246 * @param {Number} newCapacity 247 * @return {Boolean} 248 */ 249 resizeCapacity:function (newCapacity) { 250 if (newCapacity == this._capacity) { 251 return true; 252 } 253 254 this._totalQuads = Math.min(this._totalQuads, newCapacity); 255 this._capacity = newCapacity; 256 257 return true; 258 }, 259 260 /** 261 * <p>Draws n quads from an index (offset). <br /> 262 * n + start can't be greater than the capacity of the atlas</p> 263 * @param {Number} n 264 * @param {Number} start 265 */ 266 drawNumberOfQuads:function (n, start) { 267 if (0 == n) 268 return; 269 }, 270 /** 271 * Draws all the Atlas's Quads 272 */ 273 drawQuads:function () { 274 this.drawNumberOfQuads(this._quads.length, 0); 275 } 276 }); 277 278 /** 279 * <p>Creates a TextureAtlas with an filename and with an initial capacity for Quads. <br /> 280 * The TextureAtlas capacity can be increased in runtime. </p> 281 * @param {String} file 282 * @param {Number} capacity 283 * @return {cc.TextureAtlas|Null} 284 * @example 285 * //example 286 * var textureAtlas = cc.TextureAtlas.create("hello.png", 3); 287 */ 288 cc.TextureAtlas.create = function (file, capacity) { 289 var textureAtlas = new cc.TextureAtlas(); 290 if (textureAtlas && textureAtlas.initWithFile(file, capacity)) { 291 return textureAtlas; 292 } 293 return null; 294 }; 295 296 /** 297 * <p>Creates a TextureAtlas with a previously initialized Texture2D object, and with an initial capacity for n Quads. 298 * The TextureAtlas capacity can be increased in runtime.</p> 299 * @param {Image} texture 300 * @param {Number} capacity 301 * @return {cc.TextureAtlas} 302 * @example 303 * //example 304 * var texture = cc.TextureCache.getInstance().addImage("hello.png"); 305 * var textureAtlas = cc.TextureAtlas.createWithTexture(texture, 3); 306 */ 307 cc.TextureAtlas.createWithTexture = function (texture, capacity) { 308 var textureAtlas = new cc.TextureAtlas(); 309 if (textureAtlas && textureAtlas.initWithTexture(texture, capacity)) { 310 return textureAtlas; 311 } 312 return null; 313 }; 314