summary refs log tree commit diff stats
path: root/libs/cocos2d/CCTexture2D.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/CCTexture2D.m')
-rwxr-xr-xlibs/cocos2d/CCTexture2D.m814
1 files changed, 814 insertions, 0 deletions
diff --git a/libs/cocos2d/CCTexture2D.m b/libs/cocos2d/CCTexture2D.m new file mode 100755 index 0000000..afa64e2 --- /dev/null +++ b/libs/cocos2d/CCTexture2D.m
@@ -0,0 +1,814 @@
1/*
2
3===== IMPORTANT =====
4
5This is sample code demonstrating API, technology or techniques in development.
6Although this sample code has been reviewed for technical accuracy, it is not
7final. Apple is supplying this information to help you plan for the adoption of
8the technologies and programming interfaces described herein. This information
9is subject to change, and software implemented based on this sample code should
10be tested with final operating system software and final documentation. Newer
11versions of this sample code may be provided with future seeds of the API or
12technology. For information about updates to this and other developer
13documentation, view the New & Updated sidebars in subsequent documentationd
14seeds.
15
16=====================
17
18File: Texture2D.m
19Abstract: Creates OpenGL 2D textures from images or text.
20
21Version: 1.6
22
23Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
24("Apple") in consideration of your agreement to the following terms, and your
25use, installation, modification or redistribution of this Apple software
26constitutes acceptance of these terms. If you do not agree with these terms,
27please do not use, install, modify or redistribute this Apple software.
28
29In consideration of your agreement to abide by the following terms, and subject
30to these terms, Apple grants you a personal, non-exclusive license, under
31Apple's copyrights in this original Apple software (the "Apple Software"), to
32use, reproduce, modify and redistribute the Apple Software, with or without
33modifications, in source and/or binary forms; provided that if you redistribute
34the Apple Software in its entirety and without modifications, you must retain
35this notice and the following text and disclaimers in all such redistributions
36of the Apple Software.
37Neither the name, trademarks, service marks or logos of Apple Inc. may be used
38to endorse or promote products derived from the Apple Software without specific
39prior written permission from Apple. Except as expressly stated in this notice,
40no other rights or licenses, express or implied, are granted by Apple herein,
41including but not limited to any patent rights that may be infringed by your
42derivative works or by other works in which the Apple Software may be
43incorporated.
44
45The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
46WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
47WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
49COMBINATION WITH YOUR PRODUCTS.
50
51IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
52CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
53GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
55DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
56CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
57APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58
59Copyright (C) 2008 Apple Inc. All Rights Reserved.
60
61*/
62
63/*
64 * Support for RGBA_4_4_4_4 and RGBA_5_5_5_1 was copied from:
65 * https://devforums.apple.com/message/37855#37855 by a1studmuffin
66 */
67
68
69#import <Availability.h>
70
71#import "Platforms/CCGL.h"
72#import "Platforms/CCNS.h"
73
74
75#import "CCTexture2D.h"
76#import "ccConfig.h"
77#import "ccMacros.h"
78#import "CCConfiguration.h"
79#import "Support/ccUtils.h"
80#import "CCTexturePVR.h"
81
82#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && CC_FONT_LABEL_SUPPORT
83// FontLabel support
84#import "FontManager.h"
85#import "FontLabelStringDrawing.h"
86#endif// CC_FONT_LABEL_SUPPORT
87
88
89// For Labels use 16-bit textures on iPhone 3GS / iPads since A8 textures are very slow
90#if (defined(__ARM_NEON__) || TARGET_IPHONE_SIMULATOR) && CC_USE_LA88_LABELS_ON_NEON_ARCH
91#define USE_TEXT_WITH_A8_TEXTURES 0
92
93#else
94#define USE_TEXT_WITH_A8_TEXTURES 1
95#endif
96
97//CLASS IMPLEMENTATIONS:
98
99
100// If the image has alpha, you can create RGBA8 (32-bit) or RGBA4 (16-bit) or RGB5A1 (16-bit)
101// Default is: RGBA8888 (32-bit textures)
102static CCTexture2DPixelFormat defaultAlphaPixelFormat_ = kCCTexture2DPixelFormat_Default;
103
104#pragma mark -
105#pragma mark CCTexture2D - Main
106
107@implementation CCTexture2D
108
109@synthesize contentSizeInPixels = size_, pixelFormat = format_, pixelsWide = width_, pixelsHigh = height_, name = name_, maxS = maxS_, maxT = maxT_;
110@synthesize hasPremultipliedAlpha = hasPremultipliedAlpha_;
111
112- (id) initWithData:(const void*)data pixelFormat:(CCTexture2DPixelFormat)pixelFormat pixelsWide:(NSUInteger)width pixelsHigh:(NSUInteger)height contentSize:(CGSize)size
113{
114 if((self = [super init])) {
115 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
116 glGenTextures(1, &name_);
117 glBindTexture(GL_TEXTURE_2D, name_);
118
119 [self setAntiAliasTexParameters];
120
121 // Specify OpenGL texture image
122
123 switch(pixelFormat)
124 {
125 case kCCTexture2DPixelFormat_RGBA8888:
126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) width, (GLsizei) height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
127 break;
128 case kCCTexture2DPixelFormat_RGBA4444:
129 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) width, (GLsizei) height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
130 break;
131 case kCCTexture2DPixelFormat_RGB5A1:
132 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) width, (GLsizei) height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, data);
133 break;
134 case kCCTexture2DPixelFormat_RGB565:
135 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei) width, (GLsizei) height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
136 break;
137 case kCCTexture2DPixelFormat_AI88:
138 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, (GLsizei) width, (GLsizei) height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
139 break;
140 case kCCTexture2DPixelFormat_A8:
141 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, (GLsizei) width, (GLsizei) height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
142 break;
143 default:
144 [NSException raise:NSInternalInconsistencyException format:@""];
145
146 }
147
148 size_ = size;
149 width_ = width;
150 height_ = height;
151 format_ = pixelFormat;
152 maxS_ = size.width / (float)width;
153 maxT_ = size.height / (float)height;
154
155 hasPremultipliedAlpha_ = NO;
156 }
157 return self;
158}
159
160- (void) releaseData:(void*)data
161{
162 //Free data
163 free(data);
164}
165
166- (void*) keepData:(void*)data length:(NSUInteger)length
167{
168 //The texture data mustn't be saved becuase it isn't a mutable texture.
169 return data;
170}
171
172- (void) dealloc
173{
174 CCLOGINFO(@"cocos2d: deallocing %@", self);
175 if(name_)
176 glDeleteTextures(1, &name_);
177
178 [super dealloc];
179}
180
181- (NSString*) description
182{
183 return [NSString stringWithFormat:@"<%@ = %08X | Name = %i | Dimensions = %ix%i | Coordinates = (%.2f, %.2f)>", [self class], self, name_, width_, height_, maxS_, maxT_];
184}
185
186-(CGSize) contentSize
187{
188 CGSize ret;
189 ret.width = size_.width / CC_CONTENT_SCALE_FACTOR();
190 ret.height = size_.height / CC_CONTENT_SCALE_FACTOR();
191
192 return ret;
193}
194@end
195
196#pragma mark -
197#pragma mark CCTexture2D - Image
198
199@implementation CCTexture2D (Image)
200#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
201- (id) initWithImage:(UIImage *)uiImage
202#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
203- (id) initWithImage:(CGImageRef)CGImage
204#endif
205{
206 NSUInteger POTWide, POTHigh;
207 CGContextRef context = nil;
208 void* data = nil;;
209 CGColorSpaceRef colorSpace;
210 void* tempData;
211 unsigned int* inPixel32;
212 unsigned short* outPixel16;
213 BOOL hasAlpha;
214 CGImageAlphaInfo info;
215 CGSize imageSize;
216 CCTexture2DPixelFormat pixelFormat;
217
218#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
219 CGImageRef CGImage = uiImage.CGImage;
220#endif
221
222 if(CGImage == NULL) {
223 CCLOG(@"cocos2d: CCTexture2D. Can't create Texture. UIImage is nil");
224 [self release];
225 return nil;
226 }
227
228 CCConfiguration *conf = [CCConfiguration sharedConfiguration];
229
230#if CC_TEXTURE_NPOT_SUPPORT
231 if( [conf supportsNPOT] ) {
232 POTWide = CGImageGetWidth(CGImage);
233 POTHigh = CGImageGetHeight(CGImage);
234
235 } else
236#endif
237 {
238 POTWide = ccNextPOT(CGImageGetWidth(CGImage));
239 POTHigh = ccNextPOT(CGImageGetHeight(CGImage));
240 }
241
242 NSUInteger maxTextureSize = [conf maxTextureSize];
243 if( POTHigh > maxTextureSize || POTWide > maxTextureSize ) {
244 CCLOG(@"cocos2d: WARNING: Image (%lu x %lu) is bigger than the supported %ld x %ld",
245 (long)POTWide, (long)POTHigh,
246 (long)maxTextureSize, (long)maxTextureSize);
247 [self release];
248 return nil;
249 }
250
251 info = CGImageGetAlphaInfo(CGImage);
252 hasAlpha = ((info == kCGImageAlphaPremultipliedLast) || (info == kCGImageAlphaPremultipliedFirst) || (info == kCGImageAlphaLast) || (info == kCGImageAlphaFirst) ? YES : NO);
253
254 size_t bpp = CGImageGetBitsPerComponent(CGImage);
255 colorSpace = CGImageGetColorSpace(CGImage);
256
257 if(colorSpace) {
258 if(hasAlpha || bpp >= 8)
259 pixelFormat = defaultAlphaPixelFormat_;
260 else {
261 CCLOG(@"cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha");
262 pixelFormat = kCCTexture2DPixelFormat_RGB565;
263 }
264 } else {
265 // NOTE: No colorspace means a mask image
266 CCLOG(@"cocos2d: CCTexture2D: Using A8 texture since image is a mask");
267 pixelFormat = kCCTexture2DPixelFormat_A8;
268 }
269
270 imageSize = CGSizeMake(CGImageGetWidth(CGImage), CGImageGetHeight(CGImage));
271
272 // Create the bitmap graphics context
273
274 switch(pixelFormat) {
275 case kCCTexture2DPixelFormat_RGBA8888:
276 case kCCTexture2DPixelFormat_RGBA4444:
277 case kCCTexture2DPixelFormat_RGB5A1:
278 colorSpace = CGColorSpaceCreateDeviceRGB();
279 data = malloc(POTHigh * POTWide * 4);
280 info = hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast;
281// info = kCGImageAlphaPremultipliedLast; // issue #886. This patch breaks BMP images.
282 context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
283 CGColorSpaceRelease(colorSpace);
284 break;
285
286 case kCCTexture2DPixelFormat_RGB565:
287 colorSpace = CGColorSpaceCreateDeviceRGB();
288 data = malloc(POTHigh * POTWide * 4);
289 info = kCGImageAlphaNoneSkipLast;
290 context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
291 CGColorSpaceRelease(colorSpace);
292 break;
293 case kCCTexture2DPixelFormat_A8:
294 data = malloc(POTHigh * POTWide);
295 info = kCGImageAlphaOnly;
296 context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
297 break;
298 default:
299 [NSException raise:NSInternalInconsistencyException format:@"Invalid pixel format"];
300 }
301
302
303 CGContextClearRect(context, CGRectMake(0, 0, POTWide, POTHigh));
304 CGContextTranslateCTM(context, 0, POTHigh - imageSize.height);
305 CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(CGImage), CGImageGetHeight(CGImage)), CGImage);
306
307 // Repack the pixel data into the right format
308
309 if(pixelFormat == kCCTexture2DPixelFormat_RGB565) {
310 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
311 tempData = malloc(POTHigh * POTWide * 2);
312 inPixel32 = (unsigned int*)data;
313 outPixel16 = (unsigned short*)tempData;
314 for(unsigned int i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
315 *outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0);
316 free(data);
317 data = tempData;
318
319 }
320 else if (pixelFormat == kCCTexture2DPixelFormat_RGBA4444) {
321 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
322 tempData = malloc(POTHigh * POTWide * 2);
323 inPixel32 = (unsigned int*)data;
324 outPixel16 = (unsigned short*)tempData;
325 for(unsigned int i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
326 *outPixel16++ =
327 ((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R
328 ((((*inPixel32 >> 8) & 0xFF) >> 4) << 8) | // G
329 ((((*inPixel32 >> 16) & 0xFF) >> 4) << 4) | // B
330 ((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A
331
332
333 free(data);
334 data = tempData;
335
336 }
337 else if (pixelFormat == kCCTexture2DPixelFormat_RGB5A1) {
338 //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
339 tempData = malloc(POTHigh * POTWide * 2);
340 inPixel32 = (unsigned int*)data;
341 outPixel16 = (unsigned short*)tempData;
342 for(unsigned int i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
343 *outPixel16++ =
344 ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R
345 ((((*inPixel32 >> 8) & 0xFF) >> 3) << 6) | // G
346 ((((*inPixel32 >> 16) & 0xFF) >> 3) << 1) | // B
347 ((((*inPixel32 >> 24) & 0xFF) >> 7) << 0); // A
348
349
350 free(data);
351 data = tempData;
352 }
353 self = [self initWithData:data pixelFormat:pixelFormat pixelsWide:POTWide pixelsHigh:POTHigh contentSize:imageSize];
354
355 // should be after calling super init
356 hasPremultipliedAlpha_ = (info == kCGImageAlphaPremultipliedLast || info == kCGImageAlphaPremultipliedFirst);
357
358 CGContextRelease(context);
359 [self releaseData:data];
360
361 return self;
362}
363@end
364
365#pragma mark -
366#pragma mark CCTexture2D - Text
367
368@implementation CCTexture2D (Text)
369
370#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
371
372- (id) initWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(CCTextAlignment)alignment lineBreakMode:(CCLineBreakMode)lineBreakMode font:(id)uifont
373{
374 NSAssert( uifont, @"Invalid font");
375
376 NSUInteger POTWide = ccNextPOT(dimensions.width);
377 NSUInteger POTHigh = ccNextPOT(dimensions.height);
378 unsigned char* data;
379
380 CGContextRef context;
381 CGColorSpaceRef colorSpace;
382
383#if USE_TEXT_WITH_A8_TEXTURES
384 data = calloc(POTHigh, POTWide);
385#else
386 data = calloc(POTHigh, POTWide * 2);
387#endif
388
389 colorSpace = CGColorSpaceCreateDeviceGray();
390 context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, colorSpace, kCGImageAlphaNone);
391 CGColorSpaceRelease(colorSpace);
392
393 if( ! context ) {
394 free(data);
395 [self release];
396 return nil;
397 }
398
399 CGContextSetGrayFillColor(context, 1.0f, 1.0f);
400 CGContextTranslateCTM(context, 0.0f, POTHigh);
401 CGContextScaleCTM(context, 1.0f, -1.0f); //NOTE: NSString draws in UIKit referential i.e. renders upside-down compared to CGBitmapContext referential
402
403 UIGraphicsPushContext(context);
404
405 // normal fonts
406 if( [uifont isKindOfClass:[UIFont class] ] )
407 [string drawInRect:CGRectMake(0, 0, dimensions.width, dimensions.height) withFont:uifont lineBreakMode:lineBreakMode alignment:alignment];
408
409#if CC_FONT_LABEL_SUPPORT
410 else // ZFont class
411 [string drawInRect:CGRectMake(0, 0, dimensions.width, dimensions.height) withZFont:uifont lineBreakMode:lineBreakMode alignment:alignment];
412#endif
413
414 UIGraphicsPopContext();
415
416#if USE_TEXT_WITH_A8_TEXTURES
417 self = [self initWithData:data pixelFormat:kCCTexture2DPixelFormat_A8 pixelsWide:POTWide pixelsHigh:POTHigh contentSize:dimensions];
418
419#else // ! USE_TEXT_WITH_A8_TEXTURES
420 NSUInteger textureSize = POTWide*POTHigh;
421 unsigned short *la88_data = (unsigned short*)data;
422 for(int i = textureSize-1; i>=0; i--) //Convert A8 to AI88
423 la88_data[i] = (data[i] << 8) | 0xff;
424
425 self = [self initWithData:data pixelFormat:kCCTexture2DPixelFormat_AI88 pixelsWide:POTWide pixelsHigh:POTHigh contentSize:dimensions];
426#endif // ! USE_TEXT_WITH_A8_TEXTURES
427
428 CGContextRelease(context);
429 [self releaseData:data];
430
431 return self;
432}
433
434
435
436#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
437
438- (id) initWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(CCTextAlignment)alignment attributedString:(NSAttributedString*)stringWithAttributes
439{
440 NSAssert( stringWithAttributes, @"Invalid stringWithAttributes");
441
442 NSUInteger POTWide = ccNextPOT(dimensions.width);
443 NSUInteger POTHigh = ccNextPOT(dimensions.height);
444 unsigned char* data;
445
446 NSSize realDimensions = [stringWithAttributes size];
447
448 //Alignment
449 float xPadding = 0;
450
451 // Mac crashes if the width or height is 0
452 if( realDimensions.width > 0 && realDimensions.height > 0 ) {
453 switch (alignment) {
454 case CCTextAlignmentLeft: xPadding = 0; break;
455 case CCTextAlignmentCenter: xPadding = (dimensions.width-realDimensions.width)/2.0f; break;
456 case CCTextAlignmentRight: xPadding = dimensions.width-realDimensions.width; break;
457 default: break;
458 }
459
460 //Disable antialias
461 [[NSGraphicsContext currentContext] setShouldAntialias:NO];
462
463 NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(POTWide, POTHigh)];
464 [image lockFocus];
465
466 [stringWithAttributes drawAtPoint:NSMakePoint(xPadding, POTHigh-dimensions.height)]; // draw at offset position
467
468 NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect (0.0f, 0.0f, POTWide, POTHigh)];
469 [image unlockFocus];
470
471 data = (unsigned char*) [bitmap bitmapData]; //Use the same buffer to improve the performance.
472
473 NSUInteger textureSize = POTWide*POTHigh;
474 for(int i = 0; i<textureSize; i++) //Convert RGBA8888 to A8
475 data[i] = data[i*4+3];
476
477 data = [self keepData:data length:textureSize];
478 self = [self initWithData:data pixelFormat:kCCTexture2DPixelFormat_A8 pixelsWide:POTWide pixelsHigh:POTHigh contentSize:dimensions];
479
480 [bitmap release];
481 [image release];
482
483 } else {
484 [self release];
485 return nil;
486 }
487
488 return self;
489}
490#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
491
492- (id) initWithString:(NSString*)string fontName:(NSString*)name fontSize:(CGFloat)size
493{
494 CGSize dim;
495
496#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
497 id font;
498 font = [UIFont fontWithName:name size:size];
499 if( font )
500 dim = [string sizeWithFont:font];
501
502#if CC_FONT_LABEL_SUPPORT
503 if( ! font ){
504 font = [[FontManager sharedManager] zFontWithName:name pointSize:size];
505 if (font)
506 dim = [string sizeWithZFont:font];
507 }
508#endif // CC_FONT_LABEL_SUPPORT
509
510 if( ! font ) {
511 CCLOG(@"cocos2d: Unable to load font %@", name);
512 [self release];
513 return nil;
514 }
515
516 return [self initWithString:string dimensions:dim alignment:CCTextAlignmentCenter lineBreakMode:UILineBreakModeWordWrap font:font];
517
518#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
519 {
520
521 NSFont *font = [[NSFontManager sharedFontManager]
522 fontWithFamily:name
523 traits:NSUnboldFontMask | NSUnitalicFontMask
524 weight:0
525 size:size];
526
527 NSDictionary *dict = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
528
529 NSAttributedString *stringWithAttributes = [[[NSAttributedString alloc] initWithString:string attributes:dict] autorelease];
530
531 dim = NSSizeToCGSize( [stringWithAttributes size] );
532
533 return [self initWithString:string dimensions:dim alignment:CCTextAlignmentCenter attributedString:stringWithAttributes];
534 }
535#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
536
537}
538
539- (id) initWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(CCTextAlignment)alignment fontName:(NSString*)name fontSize:(CGFloat)size
540{
541 return [self initWithString:string dimensions:dimensions alignment:alignment lineBreakMode:CCLineBreakModeWordWrap fontName:name fontSize:size];
542}
543
544- (id) initWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(CCTextAlignment)alignment lineBreakMode:(CCLineBreakMode)lineBreakMode fontName:(NSString*)name fontSize:(CGFloat)size
545{
546#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
547 id uifont = nil;
548
549 uifont = [UIFont fontWithName:name size:size];
550
551#if CC_FONT_LABEL_SUPPORT
552 if( ! uifont )
553 uifont = [[FontManager sharedManager] zFontWithName:name pointSize:size];
554#endif // CC_FONT_LABEL_SUPPORT
555 if( ! uifont ) {
556 CCLOG(@"cocos2d: Texture2d: Invalid Font: %@. Verify the .ttf name", name);
557 [self release];
558 return nil;
559 }
560
561 return [self initWithString:string dimensions:dimensions alignment:alignment lineBreakMode:lineBreakMode font:uifont];
562
563#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
564
565 NSAssert( lineBreakMode == CCLineBreakModeWordWrap, @"CCTexture2D: unsupported line break mode for Mac OS X");
566
567 //String with attributes
568 NSAttributedString *stringWithAttributes =
569 [[[NSAttributedString alloc] initWithString:string
570 attributes:[NSDictionary dictionaryWithObject:[[NSFontManager sharedFontManager]
571 fontWithFamily:name
572 traits:NSUnboldFontMask | NSUnitalicFontMask
573 weight:0
574 size:size]
575 forKey:NSFontAttributeName]
576 ]
577 autorelease];
578
579 return [self initWithString:string dimensions:dimensions alignment:alignment attributedString:stringWithAttributes];
580
581#endif // Mac
582}
583@end
584
585#pragma mark -
586#pragma mark CCTexture2D - PVRSupport
587
588@implementation CCTexture2D (PVRSupport)
589
590// By default PVR images are treated as if they don't have the alpha channel premultiplied
591static BOOL PVRHaveAlphaPremultiplied_ = NO;
592
593#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
594-(id) initWithPVRTCData: (const void*)data level:(int)level bpp:(int)bpp hasAlpha:(BOOL)hasAlpha length:(int)length pixelFormat:(CCTexture2DPixelFormat)pixelFormat
595{
596 // GLint saveName;
597
598 if( ! [[CCConfiguration sharedConfiguration] supportsPVRTC] ) {
599 CCLOG(@"cocos2d: WARNING: PVRTC images is not supported");
600 [self release];
601 return nil;
602 }
603
604 if((self = [super init])) {
605 glGenTextures(1, &name_);
606 glBindTexture(GL_TEXTURE_2D, name_);
607
608 [self setAntiAliasTexParameters];
609
610 GLenum format;
611 GLsizei size = length * length * bpp / 8;
612 if(hasAlpha)
613 format = (bpp == 4) ? GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
614 else
615 format = (bpp == 4) ? GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
616
617 if(size < 32)
618 size = 32;
619
620 glCompressedTexImage2D(GL_TEXTURE_2D, level, format, length, length, 0, size, data);
621
622 size_ = CGSizeMake(length, length);
623 width_ = length;
624 height_ = length;
625 maxS_ = 1.0f;
626 maxT_ = 1.0f;
627 hasPremultipliedAlpha_ = PVRHaveAlphaPremultiplied_;
628 format_ = pixelFormat;
629 }
630 return self;
631}
632#endif // __IPHONE_OS_VERSION_MAX_ALLOWED
633
634-(id) initWithPVRFile: (NSString*) file
635{
636 if( (self = [super init]) ) {
637 CCTexturePVR *pvr = [[CCTexturePVR alloc] initWithContentsOfFile:file];
638 if( pvr ) {
639 pvr.retainName = YES; // don't dealloc texture on release
640
641 name_ = pvr.name; // texture id
642 maxS_ = 1; // only POT texture are supported
643 maxT_ = 1;
644 width_ = pvr.width;
645 height_ = pvr.height;
646 size_ = CGSizeMake(width_, height_);
647 hasPremultipliedAlpha_ = PVRHaveAlphaPremultiplied_;
648 format_ = pvr.format;
649
650 [pvr release];
651
652 [self setAntiAliasTexParameters];
653 } else {
654
655 CCLOG(@"cocos2d: Couldn't load PVR image: %@", file);
656 [self release];
657 return nil;
658 }
659 }
660 return self;
661}
662
663+(void) PVRImagesHavePremultipliedAlpha:(BOOL)haveAlphaPremultiplied
664{
665 PVRHaveAlphaPremultiplied_ = haveAlphaPremultiplied;
666}
667@end
668
669#pragma mark -
670#pragma mark CCTexture2D - Drawing
671
672@implementation CCTexture2D (Drawing)
673
674- (void) drawAtPoint:(CGPoint)point
675{
676 GLfloat coordinates[] = { 0.0f, maxT_,
677 maxS_, maxT_,
678 0.0f, 0.0f,
679 maxS_, 0.0f };
680 GLfloat width = (GLfloat)width_ * maxS_,
681 height = (GLfloat)height_ * maxT_;
682
683 GLfloat vertices[] = { point.x, point.y, 0.0f,
684 width + point.x, point.y, 0.0f,
685 point.x, height + point.y, 0.0f,
686 width + point.x, height + point.y, 0.0f };
687
688 glBindTexture(GL_TEXTURE_2D, name_);
689 glVertexPointer(3, GL_FLOAT, 0, vertices);
690 glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
691 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
692}
693
694
695- (void) drawInRect:(CGRect)rect
696{
697 GLfloat coordinates[] = { 0.0f, maxT_,
698 maxS_, maxT_,
699 0.0f, 0.0f,
700 maxS_, 0.0f };
701 GLfloat vertices[] = { rect.origin.x, rect.origin.y, /*0.0f,*/
702 rect.origin.x + rect.size.width, rect.origin.y, /*0.0f,*/
703 rect.origin.x, rect.origin.y + rect.size.height, /*0.0f,*/
704 rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, /*0.0f*/ };
705
706 glBindTexture(GL_TEXTURE_2D, name_);
707 glVertexPointer(2, GL_FLOAT, 0, vertices);
708 glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
709 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
710}
711
712@end
713
714
715#pragma mark -
716#pragma mark CCTexture2D - GLFilter
717
718//
719// Use to apply MIN/MAG filter
720//
721@implementation CCTexture2D (GLFilter)
722
723-(void) generateMipmap
724{
725 NSAssert( width_ == ccNextPOT(width_) && height_ == ccNextPOT(height_), @"Mimpap texture only works in POT textures");
726 glBindTexture( GL_TEXTURE_2D, name_ );
727 ccglGenerateMipmap(GL_TEXTURE_2D);
728}
729
730-(void) setTexParameters: (ccTexParams*) texParams
731{
732 NSAssert( (width_ == ccNextPOT(width_) && height_ == ccNextPOT(height_)) ||
733 (texParams->wrapS == GL_CLAMP_TO_EDGE && texParams->wrapT == GL_CLAMP_TO_EDGE),
734 @"GL_CLAMP_TO_EDGE should be used in NPOT textures");
735 glBindTexture( GL_TEXTURE_2D, name_ );
736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParams->minFilter );
737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParams->magFilter );
738 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParams->wrapS );
739 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParams->wrapT );
740}
741
742-(void) setAliasTexParameters
743{
744 ccTexParams texParams = { GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
745 [self setTexParameters: &texParams];
746}
747
748-(void) setAntiAliasTexParameters
749{
750 ccTexParams texParams = { GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
751 [self setTexParameters: &texParams];
752}
753@end
754
755
756#pragma mark -
757#pragma mark CCTexture2D - Pixel Format
758
759//
760// Texture options for images that contains alpha
761//
762@implementation CCTexture2D (PixelFormat)
763+(void) setDefaultAlphaPixelFormat:(CCTexture2DPixelFormat)format
764{
765 defaultAlphaPixelFormat_ = format;
766}
767
768+(CCTexture2DPixelFormat) defaultAlphaPixelFormat
769{
770 return defaultAlphaPixelFormat_;
771}
772
773-(NSUInteger) bitsPerPixelForFormat
774{
775 NSUInteger ret=0;
776
777 switch (format_) {
778 case kCCTexture2DPixelFormat_RGBA8888:
779 ret = 32;
780 break;
781 case kCCTexture2DPixelFormat_RGB565:
782 ret = 16;
783 break;
784 case kCCTexture2DPixelFormat_A8:
785 ret = 8;
786 break;
787 case kCCTexture2DPixelFormat_RGBA4444:
788 ret = 16;
789 break;
790 case kCCTexture2DPixelFormat_RGB5A1:
791 ret = 16;
792 break;
793 case kCCTexture2DPixelFormat_PVRTC4:
794 ret = 4;
795 break;
796 case kCCTexture2DPixelFormat_PVRTC2:
797 ret = 2;
798 break;
799 case kCCTexture2DPixelFormat_I8:
800 ret = 8;
801 break;
802 case kCCTexture2DPixelFormat_AI88:
803 ret = 16;
804 break;
805 default:
806 ret = -1;
807 NSAssert1(NO , @"bitsPerPixelForFormat: %ld, unrecognised pixel format", (long)format_);
808 CCLOG(@"bitsPerPixelForFormat: %ld, cannot give useful result", (long)format_);
809 break;
810 }
811 return ret;
812}
813@end
814