Understanding pixel format in cocos2d v0.7.3

Since cocos2d v0.7.3, you can specify the texture’s pixel format of your PNG/TIFF/BMP/GIF images.
The texture’s pixel format is the way the image is stored in GPU memory.

Possible pixel formats:

  • RGBA8888 (32-bit) (kTexture2DPixelFormat_RGBA8888)
  • RGBA4444 (16-bit) (kTexture2DPixelFormat_RGBA4444)
  • RGB5_A1 (16-bit)(kTexture2DPixelFormat_RGB5A1)
  • RGB565 (16-bit) (kTexture2DPixelFormat_RGB565)

RGBA8888:

  • 8 bits are assigned to the red channel, 8 bits to the green channel, 8 bits to the blue channel and 8 bits to the alpha channel.
  • Use this pixel format when you need the maximum possible quality for your image.
  • But it will consume the double of memory compared to 16-bit textures. Memory is a precious resource on the iPhone
  • Usually it is also slower to render.
  • Useful for: background image of your intro scene, and for images with lots of gradient colors

RGBA4444:

  • 4 bits are assigned to the red channel, 4 bits to the green channel, 4 bits to the blue channel, and 4 bits to the alpha channel
  • It gives you good quality in all channels, good speed, good memory consumption.
  • Useful for: sprites that have different values of transparency

RGB5A1:

  • 5 bits are assigned to the red channel, 5 bits to the green channel, 5 bits to the blue channel, and only 1 bit to the alpha channel
  • It gives you good quality in RGB channels but poor quality on the A channel. It also gives you good speed and good memory consumption.
  • Useful for: sprites that have transparent parts, but the transparency is either On or Off

RGB565:

  • 5 bits are assigned to the red channel, 6 bits to the green channel, and 5 bits to the blue channel. It has no alpha channel support
  • It gives you the best possible quality for 16-bit textures, but without alpha channel support.
  • Useful for: background images in your game.

The default pixel format in v0.7.3 is RGBA8888.

How to use it:

// Set the pixel format before loading the image
// RGBA 8888 image (32-bit
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];
Sprite *sprite1 = [Sprite spriteWithFile:@"test-rgba1.png"];
 
// Set the pixel format before loading the image
// RGBA 4444 image (16-bit)
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Sprite *sprite2 = [Sprite spriteWithFile:@"test-rgba2.png"];
 
// Set the pixel format before loading the image
// RGB5A1 image (16-bit)
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGB5A1];
Sprite *sprite3 = [Sprite spriteWithFile:@"test-rgba3.png"];
 
// Set the pixel format before loading the image
// RGB565 image (16-bit)
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGB565];
Sprite *sprite4 = [Sprite spriteWithFile:@"test-rgba4.png"];
 
// restore the default pixel format
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_Default];

FAQ:

  • Q: Can I use this technique for PVRTC images ?
  • A: No, PVRTC images have their own format. PVRTC images are faster and they consume less memory since they are either 2-bit or 4-bit textures but the quality is not that great.
  • Q: If I use 16-bit textures, will my game load faster ?
  • A: The texture pixel format has nothing to do with the loading times of your game. The Pixel Format is how the image is stored in the GPU memory. If you want faster loading times you should reduce the size of your .PNG/GIF/TIFF/TMP image file.
  • Q: Should I use RGB565 for the images that are compressed by XCode ?
  • A: When XCode compresses the PNG images, it will create a compressed PNG image that has it’s alpha channel premultiplied in the RGB channels. The PNG format is RGB565, but you should NOT confuse a PNG format with a texture pixel format. A PNG image is understood by Photoshop and cocos2d, but the GPU knows nothing about PNG images. The PNG images need to be converted into a Texture (the format understood by the GPU). The answer is: it depends on what you want. The Image (PNG,GIF,TIFF,BMP) format is independent of the Texture format.
  • Q: If I create a PNG/BMP/TIFF/GIF image without alpha channel, can I change the texture pixel format ?
  • A: If your PNG/BMP/TIFF/GIF image has no alpha channel (premultiplied or not), then the pixel format that will be used for the texture is RGB565. It can’t be changed using the API but you can change by modifying the Texture2D.m file
  • Q: Can I change the pixel format once the texture was created.
  • A: No. Once the Texture was created you can’t modify the pixel format. But you can create new textures from the same image using different pixel formats. Just remember to remove the image from the TextureMgr!

15 Responses to “Understanding pixel format in cocos2d v0.7.3”


  • Very helpful dude.

  • Riq, thanks for taking the time to explain this. The pixel format stuff and how it affects alpha channels is confusing to a newcomer like myself–I really appreciated the FAQ section.

    If anyone else wants a really great explanation of what happens when Xcode optimizes PNGs with stuff like premultiplied alpha channels, I highly recommend this great tutorial by Jeff Lamarch: http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html

  • Thanks a lot for this, Riq.

  • hmm.. I try to use RGBA4444 for my PNG 8/16-bit sprites with alpha channel but I get images with another pixels instead of transparent and half-transparent areas. What am I doing wrong?

  • @antwerp: could you post your code / images somewhere ?

  • Oh, I meaned 0.7.3 of course, not 0.7.2!

  • something strange with my comments. Sorry if I append several times one comment. Here is the message that I can’t send in comments: http://www.patosin.ru/temp/png-alpha/comment.html

  • @antwerp: v0.8 already supports blend function per objects.

  • @riq: I try to append my sprites into SpriteTest demo from cocos2d-iphone-0.8-rc2 package. Here are the sources:

    Sprite *background=[Sprite spriteWithFile:@"todelete.png"];
    [background setPosition:CGPointMake(240,160)];
    [self addChild:background];

    [Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];

    Sprite *test=[Sprite spriteWithFile:@"circle.png"];
    [test setPosition:CGPointMake(240,240)];
    [self addChild:test];

    But I got the previous results – transparent red circle have black gradient instead of red-blue gradient (compare http://www.patosin.ru/temp/png-alpha/simulator.png and http://www.patosin.ru/temp/png-alpha/photoshop.png). May be I’m doing something wrong?

    Thank you.

    By the way – I have the same problems with my other images too in areas with antialiasing effect. If it is need I can post them too.

  • Did you try using RGBA8, instead of RGBA4 ?

    eg:
    [Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];

  • @riq: yes, I tried and had the same result :( May be something wrong with image? I saved it with Photoshop CS3 with RGB colors and tried to change the option 8bits/channel to 16bits/channel.

    I made another test image: http://www.patosin.ru/temp/png-alpha/hi.png. Here is how it looks in photoshop with another layer: http://www.patosin.ru/temp/png-alpha/hi-photoshop.png and here http://www.patosin.ru/temp/png-alpha/hi-simulator.png how it looks in iPhone Simulator with iPhone SDK v3.0. This is background that I used: http://www.patosin.ru/temp/png-alpha/todelete.png

    As you can see in sample I append this image into the SpriteTest to be sure that I do not change any settings. So at that moment my -(void)onEnter method for SpriteManual class looks like this:

    -(void) onEnter
    {
    [super onEnter];

    tamara.scaleX = 2.5f;
    tamara.scaleY = -1.0f;
    tamara.position = ccp(100,70);
    tamara.opacity = 128;

    grossini.rotation = 120;
    grossini.opacity = 128;
    grossini.position = ccp(240,160);
    grossini.color = ccc3( 255,0,0);

    Sprite *background=[Sprite spriteWithFile:@"todelete.png"];
    [background setPosition:CGPointMake(240,160)];
    [self addChild:background];

    [Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];

    Sprite *lighting=[Sprite spriteWithFile:@"hi.png"];
    [lighting setPosition:CGPointMake(140,160)];
    [self addChild:lighting];
    }

    Thanks..

  • If you run on it on the device (not simulator), what do you see ?

    Please, also read this post:
    http://www.cocos2d-iphone.org/forum/topic/824

    PS: I agree that on the simulator it should look different, but please, test on also on the device.

  • Yeah! It looks perfect on real device without any additional [Texture2D setDefaultAlphaPixelFormat:… and with using RGB 8bits/Channel !! Thank you, riq!

  • Sorry, but I’m not very technical – I’m a designer. I was wondering if you have encounter this problem with png’s in Cocos 2d… I’m designing a game, and we are using Cocos 2d – and my images look georgous before they enter Cocos 2D. The iPhone Application shows colors and images a bit washed out. Is it because the png’s are in the wrong bit 8, 16, 24 or something else I’m missing.

  • @Raven: it’s most likely the iPhone’s display. Especially first generation wash out the colors. For example, true red (255,0,0) looks rather dark and a bit brown-ish. There’s nothing you can do about it other than optimizing your colors for the average iPhone display. Ever handheld game developer has this sort of problem, eg. the classic Gameboy Color used to be unable to display certain color tones very well either.

Leave a Reply




Social Widgets powered by AB-WebLog.com.