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 var cc = cc = cc || {}; 27 28 //CONSTANTS: 29 30 /** @typedef CCTexture2DPixelFormat 31 Possible texture pixel formats 32 */ 33 /* 34 * Support for RGBA_4_4_4_4 and RGBA_5_5_5_1 was copied from: 35 * https://devforums.apple.com/message/37855#37855 by a1studmuffin 36 */ 37 cc.TEXTURE_2D_PIXEL_FORMAT_AUTOMATIC = 0; 38 //! 32-bit texture: RGBA8888 39 cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888 = 1; 40 //! 24-bit texture: RGBA888 41 cc.TEXTURE_2D_PIXEL_FORMAT_RGB888 = 2; 42 //! 16-bit texture without Alpha channel 43 cc.TEXTURE_2D_PIXEL_FORMAT_RGB565 = 3; 44 //! 8-bit textures used as masks 45 cc.TEXTURE_2D_PIXEL_FORMAT_A8 = 4; 46 //! 8-bit intensity texture 47 cc.TEXTURE_2D_PIXEL_FORMAT_I8 = 5; 48 //! 16-bit textures used as masks 49 cc.TEXTURE_2D_PIXEL_FORMAT_AI88 = 6; 50 //! 16-bit textures: RGBA4444 51 cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444 = 7; 52 //! 16-bit textures: RGB5A1 53 cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1 = 8; 54 //! 4-bit PVRTC-compressed texture: PVRTC4 55 cc.TEXTURE_2D_PIXEL_FORMAT_PVRTC4 = 9; 56 //! 2-bit PVRTC-compressed texture: PVRTC2 57 cc.TEXTURE_2D_PIXEL_FORMAT_PVRTC2 = 10; 58 59 //! Default texture format: RGBA8888 60 cc.TEXTURE_2D_PIXEL_FORMAT_DEFAULT = cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888; 61 62 // backward compatibility stuff 63 cc.TEXTURE_2D_PIXEL_FORMAT_AUTOMATIC = cc.TEXTURE_2D_PIXEL_FORMAT_AUTOMATIC; 64 cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888 = cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888; 65 cc.TEXTURE_2D_PIXEL_FORMAT_RGB888 = cc.TEXTURE_2D_PIXEL_FORMAT_RGB888; 66 cc.TEXTURE_2D_PIXEL_FORMAT_RGB565 = cc.TEXTURE_2D_PIXEL_FORMAT_RGB565; 67 cc.TEXTURE_2D_PIXEL_FORMAT_A8 = cc.TEXTURE_2D_PIXEL_FORMAT_A8; 68 cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444 = cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444; 69 cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1 = cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1; 70 cc.TEXTURE_2D_PIXEL_FORMAT_DEFAULT = cc.TEXTURE_2D_PIXEL_FORMAT_DEFAULT; 71 72 73 if (cc.ENABLE_CACHE_TEXTTURE_DATA) { 74 //TODO include CCTextureCache.h 75 } 76 77 // If the image has alpha, you can create RGBA8 (32-bit) or RGBA4 (16-bit) or RGB5A1 (16-bit) 78 // Default is: RGBA8888 (32-bit textures) 79 cc.g_defaultAlphaPixelFormat = cc.TEXTURE_2D_PIXEL_FORMAT_DEFAULT; 80 // By default PVR images are treated as if they don't have the alpha channel premultiplied 81 cc.PVRHaveAlphaPremultiplied_ = false; 82 /** 83 Extension to set the Min / Mag filter 84 */ 85 86 function _ccTexParams(minFilter, magFilter, wrapS, wrapT) { 87 this.minFilter = minFilter; 88 this.magFilter = magFilter; 89 this.wrapS = wrapS; 90 this.wrapT = wrapT; 91 } 92 93 //CLASS INTERFACES: 94 95 /** @brief cc.Texture2D class. 96 * This class allows to easily create OpenGL 2D textures from images, text or raw data. 97 * The created cc.Texture2D object will always have power-of-two dimensions. 98 * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0). 99 * Be aware that the content of the generated textures will be upside-down! 100 */ 101 cc.Texture2D = cc.Class.extend({ 102 // By default PVR images are treated as if they don't have the alpha channel premultiplied 103 _pVRHaveAlphaPremultiplied:null, 104 _pixelFormat:null, 105 _pixelsWide:null, 106 _pixelsHigh:null, 107 _name:null, 108 _contentSize:null, 109 _maxS:null, 110 _maxT:null, 111 _hasPremultipliedAlpha:null, 112 113 /*public:*/ 114 ctor:function () { 115 // implementation CCTexture2D (PVRTC); 116 if (cc.SUPPORT_PVRTC) { 117 /** 118 Extensions to make it easy to create a cc.Texture2D object from a PVRTC file 119 Note that the generated textures don't have their alpha premultiplied - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA). 120 */ 121 /** Initializes a texture from a PVRTC buffer */ 122 this.initWithPVRTCData = function (data, level, bpp, hasAlpha, length, pixelFormat) { 123 if (!(cc.Configuration.getInstance().isSupportsPVRTC())) { 124 cc.log("cocos2d: WARNING: PVRTC images is not supported."); 125 return false; 126 } 127 128 //TODO 129 // glGenTextures(1, this._name); 130 //TODO 131 // glBindTexture(gl.TEXTURE_2D, this._name); 132 133 this.setAntiAliasTexParameters(); 134 135 var format; 136 var size = new cc.GLsizei(); 137 size = length * length * bpp / 8; 138 if (hasAlpha) { 139 format = (bpp == 4) ? gl.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : gl.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; 140 } else { 141 format = (bpp == 4) ? gl.COMPRESSED_RGB_PVRTC_4BPPV1_IMG : gl.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; 142 } 143 if (size < 32) { 144 size = 32; 145 } 146 //TODO 147 // glCompressedTexImage2D(gl.TEXTURE_2D, level, format, length, length, 0, size, data); 148 149 this._contentSize = cc.size(length, length); 150 this._pixelsWide = length; 151 this._pixelsHigh = length; 152 this._maxS = 1.0; 153 this._maxT = 1.0; 154 this._hasPremultipliedAlpha = cc.PVRHaveAlphaPremultiplied_; 155 this._pixelFormat = pixelFormat; 156 157 return true; 158 }; 159 }// cc.SUPPORT_PVRTC 160 }, 161 /** pixel format of the texture */ 162 getPixelFormat:function () { 163 return this._pixelFormat; 164 }, 165 //** width in pixels *// 166 getPixelsWide:function () { 167 return this._pixelsWide; 168 }, 169 //** hight in pixels *// 170 getPixelsHigh:function () { 171 return this._pixelsHigh; 172 }, 173 //** texture name *// 174 getName:function () { 175 return this._name; 176 }, 177 //** content size *// 178 getContentSizeInPixels:function () { 179 var ret = cc.size(0, 0); 180 ret.width = this._contentSize.width / cc.CONTENT_SCALE_FACTOR(); 181 ret.height = this._contentSize.height / cc.CONTENT_SCALE_FACTOR(); 182 183 return ret; 184 }, 185 //** texture max S *// 186 getMaxS:function () { 187 return this._maxS; 188 }, 189 setMaxS:function (maxS) { 190 this._maxS = maxS; 191 }, 192 //** texture max T *// 193 getMaxT:function () { 194 return this._maxT; 195 }, 196 setMaxT:function (maxT) { 197 this._maxT = maxT; 198 }, 199 //** whether or not the texture has their Alpha premultiplied *// 200 getHasPremultipliedAlpha:function () { 201 return this._hasPremultipliedAlpha; 202 }, 203 description:function () { 204 var ret = "<cc.Texture2D | Name = " + this._name + " | Dimensions = " + this._pixelsWide + " x " + this._pixelsHigh 205 + " | Coordinates = (" + this._maxS + ", " + this._maxT + ")>"; 206 return ret; 207 }, 208 /** These functions are needed to create mutable textures */ 209 releaseData:function (data) { 210 cc.free(data); 211 }, 212 keepData:function (data, length) { 213 //The texture data mustn't be saved becuase it isn't a mutable texture. 214 return data; 215 }, 216 217 /** Intializes with a texture2d with data */ 218 initWithData:function (pixelFormat, pixelsWide, pixelsHigh, contentSize) { 219 //TODO 220 // glPixelStorei(gl.UNPACK_ALIGNMENT,1); 221 //TODO 222 // glGenTextures(1, this._name); 223 //TODO 224 // glBindTexture(gl.TEXTURE_2D, this._name); 225 226 this.setAntiAliasTexParameters(); 227 228 // Specify OpenGL texture image 229 230 switch (pixelFormat) { 231 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888: 232 //TODO 233 // glTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); 234 break; 235 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB888: 236 //TODO 237 // glTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.RGB, gl.UNSIGNED_BYTE, data); 238 break; 239 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444: 240 //TODO 241 // glTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, data); 242 break; 243 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1: 244 //TODO 245 // glTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.RGBA, gl.UNSIGNED_SHORT_5_5_5_1, data); 246 break; 247 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB565: 248 //TODO 249 // glTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, data); 250 break; 251 case cc.TEXTURE_2D_PIXEL_FORMAT_AI88: 252 //TODO 253 // glTexImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE_ALPHA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, data); 254 break; 255 case cc.TEXTURE_2D_PIXEL_FORMAT_A8: 256 //TODO 257 // glTexImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, gl.ALPHA, gl.UNSIGNED_BYTE, data); 258 break; 259 default: 260 cc.Assert(0, "NSInternalInconsistencyException"); 261 262 } 263 264 this._contentSize = contentSize; 265 this._pixelsWide = pixelsWide; 266 this._pixelsHigh = pixelsHigh; 267 this._pixelFormat = pixelFormat; 268 this._maxS = contentSize.width / pixelsWide; 269 this._maxT = contentSize.height / pixelsHigh; 270 271 this._hasPremultipliedAlpha = false; 272 273 return true; 274 }, 275 276 /** 277 Drawing extensions to make it easy to draw basic quads using a CCTexture2D object. 278 These functions require gl.TEXTURE_2D and both gl.VERTEX_ARRAY and gl.TEXTURE_COORD_ARRAY client states to be enabled. 279 */ 280 /** draws a texture at a given point */ 281 drawAtPoint:function (point) { 282 var coordinates = [ 283 0.0, this._maxT, 284 this._maxS, this._maxT, 285 0.0, 0.0, 286 this._maxS, 0.0 ]; 287 288 var width = this._pixelsWide * this._maxS, 289 height = this._pixelsHigh * this._maxT; 290 291 var vertices = [ 292 point.x, point.y, 0.0, 293 width + point.x, point.y, 0.0, 294 point.x, height + point.y, 0.0, 295 width + point.x, height + point.y, 0.0 ]; 296 297 //TODO 298 // glBindTexture(gl.TEXTURE_2D, this._name); 299 //TODO 300 // glVertexPointer(3, gl.FLOAT, 0, vertices); 301 //TODO 302 // glTexCoordPointer(2, gl.FLOAT, 0, coordinates); 303 //TODO 304 // glDrawArrays(gl.TRIANGLE_STRIP, 0, 4); 305 }, 306 307 /** draws a texture inside a rect */ 308 drawInRect:function (rect) { 309 var coordinates = [ 310 0.0, this._maxT, 311 this._maxS, this._maxT, 312 0.0, 0.0, 313 this._maxS, 0.0]; 314 315 var vertices = [ rect.origin.x, rect.origin.y, /*0.0,*/ 316 rect.origin.x + rect.size.width, rect.origin.y, /*0.0,*/ 317 rect.origin.x, rect.origin.y + rect.size.height, /*0.0,*/ 318 rect.origin.x + rect.size.width, rect.origin.y + rect.size.height /*0.0*/ ]; 319 320 //TODO 321 // glBindTexture(gl.TEXTURE_2D, this._name); 322 //TODO 323 // glVertexPointer(2, gl.FLOAT, 0, vertices); 324 //TODO 325 // glTexCoordPointer(2, gl.FLOAT, 0, coordinates); 326 //TODO 327 // glDrawArrays(gl.TRIANGLE_STRIP, 0, 4); 328 }, 329 330 /** 331 Extensions to make it easy to create a CCTexture2D object from an image file. 332 Note that RGBA type textures will have their alpha premultiplied - use the blending mode (gl.ONE, gl.ONE_MINUS_SRC_ALPHA). 333 */ 334 /** Initializes a texture from a UIImage object */ 335 initWithImage:function (uiImage) { 336 var POTWide, POTHigh; 337 338 if (uiImage == null) { 339 cc.log("cocos2d: cc.Texture2D. Can't create Texture. UIImage is nil"); 340 return false; 341 } 342 343 var conf = cc.Configuration.getInstance(); 344 345 if (cc.TEXTURE_NPOT_SUPPORT) { 346 if (conf.isSupportsNPOT()) { 347 POTWide = uiImage.getWidth(); 348 POTHigh = uiImage.getHeight(); 349 } 350 } else { 351 POTWide = cc.NextPOT(uiImage.getWidth()); 352 POTHigh = cc.NextPOT(uiImage.getHeight()); 353 } 354 355 356 var maxTextureSize = conf.getMaxTextureSize(); 357 if (POTHigh > maxTextureSize || POTWide > maxTextureSize) { 358 cc.log("cocos2d: WARNING: Image (%u x %u) is bigger than the supported %u x %u", POTWide, POTHigh, maxTextureSize, maxTextureSize); 359 return null; 360 } 361 362 // always load premultiplied images 363 return this._initPremultipliedATextureWithImage(uiImage, POTWide, POTHigh); 364 }, 365 366 /** 367 Extensions to make it easy to create a cc.Texture2D object from a string of text. 368 Note that the generated textures are of type A8 - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA). 369 */ 370 /** Initializes a texture from a string with dimensions, alignment, font name and font size */ 371 initWithString:function (text, dimensions, alignment, fontName, fontSize) { 372 if (arguments.length == 3) { 373 fontName = arguments[1]; 374 fontSize = arguments[2]; 375 dimensions = cc.size(0, 0); 376 alignment = cc.TEXT_ALIGNMENT_CENTER; 377 } 378 if (cc.ENABLE_CACHE_TEXTTURE_DATA) { 379 // cache the texture data 380 cc.VolatileTexture.addStringTexture(this, text, dimensions, alignment, fontName, fontSize); 381 } 382 var image = new cc.Image(); 383 eAlign = new cc.Image.ETextAlign(); 384 eAlign = (cc.TEXT_ALIGNMENT_CENTER == alignment) ? cc.Image.ALIGN_CENTER : (cc.TEXT_ALIGNMENT_LEFT == alignment) ? cc.Image.ALIGN_LEFT : cc.Image.ALIGN_RIGHT; 385 386 if (!image.initWithString(text, dimensions.width, dimensions.height, eAlign, fontName, fontSize)) { 387 return false; 388 } 389 return this.initWithImage(image); 390 }, 391 392 /** Initializes a texture from a PVR file */ 393 initWithPVRFile:function (file) { 394 var ret = false; 395 // nothing to do with cc.Object.init 396 397 var pvr = new cc.TexturePVR; 398 ret = pvr.initWithContentsOfFile(file); 399 400 if (ret) { 401 pvr.setRetainName(true); // don't dealloc texture on release 402 403 this._name = pvr.getName(); 404 this._maxS = 1.0; 405 this._maxT = 1.0; 406 this._pixelsWide = pvr.getWidth(); 407 this._pixelsHigh = pvr.getHeight(); 408 this._contentSize = cc.size(this._pixelsWide, this._pixelsHigh); 409 this._hasPremultipliedAlpha = cc.PVRHaveAlphaPremultiplied_; 410 this._pixelFormat = pvr.getFormat(); 411 412 this.setAntiAliasTexParameters(); 413 } 414 else { 415 cc.log("cocos2d: Couldn't load PVR image %s", file); 416 } 417 418 return ret; 419 }, 420 421 /** sets the min filter, mag filter, wrap s and wrap t texture parameters. 422 If the texture size is NPOT (non power of 2), then in can only use gl.CLAMP_TO_EDGE in gl.TEXTURE_WRAP_{S,T}. 423 @since v0.8 424 */ 425 setTexParameters:function (texParams) { 426 cc.Assert((this._pixelsWide == cc.NextPOT(this._pixelsWide) && this._pixelsHigh == cc.NextPOT(this._pixelsHigh)) || 427 (texParams.wrapS == gl.CLAMP_TO_EDGE && texParams.wrapT == gl.CLAMP_TO_EDGE), 428 "gl.CLAMP_TO_EDGE should be used in NPOT textures"); 429 //TODO 430 // BindTexture( gl.TEXTURE_2D, this.this._name ); 431 //TODO 432 // glTexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texParams.minFilter ); 433 //TODO 434 // glTexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texParams.magFilter ); 435 //TODO 436 // glTexParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texParams.wrapS ); 437 //TODO 438 // glTexParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texParams.wrapT ); 439 }, 440 441 /** sets antialias texture parameters: 442 - gl.TEXTURE_MIN_FILTER = gl.LINEAR 443 - gl.TEXTURE_MAG_FILTER = gl.LINEAR 444 445 @since v0.8 446 */ 447 setAntiAliasTexParameters:function () { 448 var texParams = [ gl.LINEAR, gl.LINEAR, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE ]; 449 this.setTexParameters(texParams); 450 }, 451 452 /** sets alias texture parameters: 453 - gl.TEXTURE_MIN_FILTER = gl.NEAREST 454 - gl.TEXTURE_MAG_FILTER = gl.NEAREST 455 456 @since v0.8 457 */ 458 setAliasTexParameters:function () { 459 var texParams = [ gl.NEAREST, gl.NEAREST, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE ]; 460 this.setTexParameters(texParams); 461 }, 462 463 464 /** Generates mipmap images for the texture. 465 It only works if the texture size is POT (power of 2). 466 @since v0.99.0 467 */ 468 generateMipmap:function () { 469 cc.Assert(this._pixelsWide == cc.NextPOT(this._pixelsWide) && this._pixelsHigh == cc.NextPOT(this._pixelsHigh), "Mimpap texture only works in POT textures"); 470 //TODO 471 // glBindTexture( gl.TEXTURE_2D, this.this._name ); 472 //cc.glGenerateMipmap(gl.TEXTURE_2D); 473 }, 474 475 /** returns the bits-per-pixel of the in-memory OpenGL texture 476 @since v1.0 477 */ 478 bitsPerPixelForFormat:function () { 479 var ret = 0; 480 481 switch (this._pixelFormat) { 482 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888: 483 ret = 32; 484 break; 485 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB565: 486 ret = 16; 487 break; 488 case cc.TEXTURE_2D_PIXEL_FORMAT_A8: 489 ret = 8; 490 break; 491 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444: 492 ret = 16; 493 break; 494 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1: 495 ret = 16; 496 break; 497 case cc.TEXTURE_2D_PIXEL_FORMAT_PVRTC4: 498 ret = 4; 499 break; 500 case cc.TEXTURE_2D_PIXEL_FORMAT_PVRTC2: 501 ret = 2; 502 break; 503 case cc.TEXTURE_2D_PIXEL_FORMAT_I8: 504 ret = 8; 505 break; 506 case cc.TEXTURE_2D_PIXEL_FORMAT_AI88: 507 ret = 16; 508 break; 509 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB888: 510 ret = 24; 511 break; 512 default: 513 ret = -1; 514 cc.Assert(false, "illegal pixel format"); 515 cc.log("bitsPerPixelForFormat: %d, cannot give useful result", this._pixelFormat); 516 break; 517 } 518 return ret; 519 }, 520 521 522 /*private:*/ 523 _initPremultipliedATextureWithImage:function (image, POTWide, POTHigh) { 524 var data = null; 525 var tempData = null; 526 var inPixel32 = null; 527 var outPixel16 = null; 528 var hasAlpha; 529 var imageSize = cc.size(0, 0); 530 var pixelFormat = new cc.Texture2DPixelFormat(); 531 var bpp = new cc.size_t(); 532 hasAlpha = image.hasAlpha(); 533 bpp = image.getBitsPerComponent(); 534 535 // compute pixel format 536 if (hasAlpha) { 537 pixelFormat = cc.g_defaultAlphaPixelFormat; 538 } 539 else { 540 if (bpp >= 8) { 541 pixelFormat = cc.TEXTURE_2D_PIXEL_FORMAT_RGB888; 542 } 543 else { 544 cc.log("cocos2d: cc.Texture2D: Using RGB565 texture since image has no alpha"); 545 pixelFormat = cc.TEXTURE_2D_PIXEL_FORMAT_RGB565; 546 } 547 } 548 549 550 imageSize = cc.size(image.getWidth(), image.getHeight()); 551 552 switch (pixelFormat) { 553 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888: 554 case cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444: 555 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1: 556 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB565: 557 case cc.TEXTURE_2D_PIXEL_FORMAT_A8: 558 tempData = image.getData(); 559 cc.Assert(tempData != null, "null image data."); 560 561 if (image.getWidth() == POTWide && image.getHeight() == POTHigh) { 562 data = new (POTHigh * POTWide * 4); 563 cc.memcpy(data, tempData, POTHigh * POTWide * 4); 564 } 565 else { 566 data = new (POTHigh * POTWide * 4); 567 568 var pPixelData = tempData; 569 var pTargetData = data; 570 571 var imageHeight = image.getHeight(); 572 for (var y = 0; y < imageHeight; ++y) { 573 cc.memcpy(pTargetData + POTWide * 4 * y, pPixelData + (image.getWidth()) * 4 * y, (image.getWidth()) * 4); 574 } 575 } 576 577 break; 578 case cc.TEXTURE_2D_PIXEL_FORMAT_RGB888: 579 tempData = image.getData(); 580 cc.Assert(tempData != null, "null image data."); 581 if (image.getWidth() == POTWide && image.getHeight() == POTHigh) { 582 data = new (POTHigh * POTWide * 3); 583 cc.memcpy(data, tempData, POTHigh * POTWide * 3); 584 } 585 else { 586 data = new (POTHigh * POTWide * 3); 587 588 var pPixelData = tempData; 589 var pTargetData = data; 590 591 var imageHeight = image.getHeight(); 592 for (var y = 0; y < imageHeight; ++y) { 593 cc.memcpy(pTargetData + POTWide * 3 * y, pPixelData + (image.getWidth()) * 3 * y, (image.getWidth()) * 3); 594 } 595 } 596 break; 597 default: 598 cc.Assert(0, "Invalid pixel format"); 599 } 600 601 // Repack the pixel data into the right format 602 603 if (pixelFormat == cc.TEXTURE_2D_PIXEL_FORMAT_RGB565) { 604 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB" 605 tempData = new (POTHigh * POTWide * 2); 606 inPixel32 = data; 607 outPixel16 = tempData; 608 609 var length = POTWide * POTHigh; 610 for (var i = 0; i < length; ++i, ++inPixel32) { 611 outPixel16++; 612 outPixel16 = 613 ((((inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R 614 ((((inPixel32 >> 8) & 0xFF) >> 2) << 5) | // G 615 ((((inPixel32 >> 16) & 0xFF) >> 3) << 0); // B 616 } 617 618 delete data; 619 data = tempData; 620 } 621 else if (pixelFormat == cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444) { 622 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA" 623 tempData = new (POTHigh * POTWide * 2); 624 inPixel32 = data; 625 outPixel16 = tempData; 626 627 var length = POTWide * POTHigh; 628 for (var i = 0; i < length; ++i, ++inPixel32) { 629 outPixel16++; 630 outPixel16 = 631 ((((inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R 632 ((((inPixel32 >> 8) & 0xFF) >> 4) << 8) | // G 633 ((((inPixel32 >> 16) & 0xFF) >> 4) << 4) | // B 634 ((((inPixel32 >> 24) & 0xFF) >> 4) << 0); // A 635 } 636 637 delete data; 638 data = tempData; 639 } 640 else if (pixelFormat == cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1) { 641 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA" 642 tempData = new (POTHigh * POTWide * 2); 643 inPixel32 = data; 644 outPixel16 = tempData; 645 646 var length = POTWide * POTHigh; 647 for (var i = 0; i < length; ++i, ++inPixel32) { 648 outPixel16++; 649 outPixel16 = 650 ((((inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R 651 ((((inPixel32 >> 8) & 0xFF) >> 3) << 6) | // G 652 ((((inPixel32 >> 16) & 0xFF) >> 3) << 1) | // B 653 ((((inPixel32 >> 24) & 0xFF) >> 7) << 0); // A 654 } 655 656 delete data; 657 data = tempData; 658 } 659 else if (pixelFormat == cc.TEXTURE_2D_PIXEL_FORMAT_A8) { 660 // fix me, how to convert to A8 661 pixelFormat = cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888; 662 663 /* 664 * The code can not work, how to convert to A8? 665 * 666 tempData = new unsigned char[POTHigh * POTWide]; 667 inPixel32 = (unsigned int*)data; 668 outPixel8 = tempData; 669 670 unsigned int length = POTWide * POTHigh; 671 for(unsigned int i = 0; i < length; ++i, ++inPixel32) 672 { 673 outPixel8++ = (inPixel32 >> 24) & 0xFF; 674 } 675 676 delete []data; 677 data = tempData; 678 */ 679 } 680 681 if (data) { 682 this.initWithData(data, pixelFormat, POTWide, POTHigh, imageSize); 683 684 // should be after calling super init 685 this._hasPremultipliedAlpha = image.isPremultipliedAlpha(); 686 687 //CGContextRelease(context); 688 delete data; 689 } 690 return true; 691 } 692 }); 693 694 /** sets the default pixel format for UIImagescontains alpha channel. 695 If the UIImage contains alpha channel, then the options are: 696 - generate 32-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888 (default one) 697 - generate 24-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_RGB888 698 - generate 16-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_RGBA4444 699 - generate 16-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_RGB5A1 700 - generate 16-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_RGB565 701 - generate 8-bit textures: cc.TEXTURE_2D_PIXEL_FORMAT_A8 (only use it if you use just 1 color) 702 703 How does it work ? 704 - If the image is an RGBA (with Alpha) then the default pixel format will be used (it can be a 8-bit, 16-bit or 32-bit texture) 705 - If the image is an RGB (without Alpha) then an RGB565 or RGB888 texture will be used (16-bit texture) 706 707 @since v0.8 708 */ 709 cc.Texture2D.setDefaultAlphaPixelFormat = function (format) { 710 cc.g_defaultAlphaPixelFormat = format; 711 }; 712 713 /** returns the alpha pixel format 714 @since v0.8 715 */ 716 cc.Texture2D.defaultAlphaPixelFormat = function () { 717 return cc.g_defaultAlphaPixelFormat; 718 }; 719 720 /** treats (or not) PVR files as if they have alpha premultiplied. 721 Since it is impossible to know at runtime if the PVR images have the alpha channel premultiplied, it is 722 possible load them as if they have (or not) the alpha channel premultiplied. 723 724 By default it is disabled. 725 726 @since v0.99.5 727 */ 728 cc.Texture2D.PVRImagesHavePremultipliedAlpha = function (haveAlphaPremultiplied) { 729 cc.PVRHaveAlphaPremultiplied_ = haveAlphaPremultiplied; 730 }; 731