Best way to deal with loading textures?

Member
Posts: 312
Joined: 2006.10
Post: #1
Hey, I was wondering what is the best way to deal with loading textures API wise? I want to keep this ias portable as possible, though I wouldn't mind writing two versions, one for Mac OS X, and the other for my other targeted platform (PlayStation Portable).

If I went portable, what would I use? libpng?

If I went OS specific, for Mac, could I use Quartz or Cocoa to load the image (preferably Quartz)?

Thanks
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
If you want portable, libpng or libjpeg are the obvious choices, though there's also FreeImage which wraps libpng, libjpeg, libtiff and a few others.

If you want Mac-only, Quartz or ImageIO (nearly the same thing) will do the job, as long as you don't care about 10.3 compatibility. If you want 10.3 compatibility, you'll need to use QuickTime instead.
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #3
All right, thanks Smile
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #4
OSC: Can you clarify the difference between Quartz and ImageIO? I've read over apple docs over and over and I've never once seen a reference to ImageIO. All I see are CG* methods.
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Sage
Posts: 1,199
Joined: 2004.10
Post: #6
bronxbomber92 Wrote:Here ya go: http://developer.apple.com/graphicsimagi...ageio.html

So, the CG* functions are imageio. That's too bad, I was hoping I was missing something. You can't load a 32-bit PNG without getting your color channels pre-multiplied using those methods. This means I can't use a normal/specular map in one texture.

That being said, I just use libPNG. But it sure would be nice if Apple's image loaders would let you get bitmap data unmodified.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
ImageIO is a part of Quartz, basically. It was introduced in 10.4.

There is a new simple API in Quartz that you can call to open any image file, which calls through to ImageIO underneath, or you can use the ImageIO APIs yourself for maximum control.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
TomorrowPlusX Wrote:So, the CG* functions are imageio. That's too bad, I was hoping I was missing something. You can't load a 32-bit PNG without getting your color channels pre-multiplied using those methods. This means I can't use a normal/specular map in one texture.

Not so much true that it couldn't happen (Quartz supports nonpremultiplied images) as that you have no choice (ImageIO doesn't appear to have a flag to premultiply or not when creating the CGImage)...
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #9
TomorrowPlusX Wrote:You can't load a 32-bit PNG without getting your color channels pre-multiplied using those methods.
I've managed it. What I had to do was load the nonpremultiplied RGB channels in with one function call, load the alpha channel with a separate function call, and stitch the bytes together afterward. I don't have the code on me at the moment, but I'll paste it here as soon as I get home...
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #10
ThemsAllTook Wrote:I'll paste it here as soon as I get home...
...and here it is:

Code:
CGImageSourceRef imageSource;
  CGImageRef image;
  CGContextRef bitmapRenderContext;
  unsigned char * pixels;
  unsigned char * alphaChannel;
  int pixelIndex;
  
  imageSource = CGImageSourceCreateWithURL((CFURLRef) [NSURL fileURLWithPath: filePath], NULL);
  if (imageSource == NULL) {
    [self release];
    return nil;
  }
  
  image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
  CFRelease(imageSource);
  if (image == NULL) {
    [self release];
    return nil;
  }
  
  width = CGImageGetWidth(image);
  height = CGImageGetHeight(image);
  pixels = (unsigned char *) malloc(4 * width * height);
  
  bitmapRenderContext = CGBitmapContextCreate(pixels,
                                              width,
                                              height,
                                              8,
                                              width * 4,
                                              CGColorSpaceCreateDeviceRGB(),
                                              kCGImageAlphaNoneSkipLast);
  CGContextDrawImage(bitmapRenderContext, (CGRect) {{0, 0}, {width, height}}, image);
  CGContextRelease(bitmapRenderContext);
  
  alphaChannel = (unsigned char *) calloc(width, height);
  bitmapRenderContext = CGBitmapContextCreate(alphaChannel,
                                              width,
                                              height,
                                              8,
                                              width,
                                              NULL,
                                              kCGImageAlphaOnly);
  CGContextDrawImage(bitmapRenderContext, (CGRect) {{0, 0}, {width, height}}, image);
  CGContextRelease(bitmapRenderContext);
  
  for (pixelIndex = 0; pixelIndex < (width * height); pixelIndex++) {
    pixels[(pixelIndex * 4) + 0] = ((pixels[(pixelIndex * 4) + 0] * (alphaChannel[pixelIndex] + 1)) >> 8);
    pixels[(pixelIndex * 4) + 1] = ((pixels[(pixelIndex * 4) + 1] * (alphaChannel[pixelIndex] + 1)) >> 8);
    pixels[(pixelIndex * 4) + 2] = ((pixels[(pixelIndex * 4) + 2] * (alphaChannel[pixelIndex] + 1)) >> 8);
    pixels[(pixelIndex * 4) + 3] = alphaChannel[pixelIndex];
  }
  free(alphaChannel);
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #11
Hey, that's brilliant! I'm going to give it a stab, since I feel "icky" bloating my framework with libPNG.

Thanks!

EDIT: I think it's amusing you're manually pre-multiplying at the end. Rasp
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #12
Interestingly, even with your manual pre-multiplication code removed, I'm seeing pre-multiplication halos on alpha transparent PNGs.

It's neat code, nonetheless.
Quote this message in a reply
socisub
Unregistered
 
Post: #13
I just disovered this from GLSLShowpiece at developers.apple.com. Look for NSBitmapImageRep *LoadImage(NSString *path, int shouldFlipVertical) function. It even works for a png with alpha!

Code:
NSImage *image = [[NSImage alloc] initWithContentsOfFile: aPath];
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
unsigned char *data = [bitmap bitmapData];
Quote this message in a reply
tigakub
Unregistered
 
Post: #14
Why is NSBitmapImageRep not recommended? Doesn't it just call down to Quartz?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #15
NSBitmapImageRep is fine if you create it yourself with the initializer that takes about 17 parameters, because that way you know that you have the data in a format that's useful for OpenGL.

No other way of creating an NSBitmapImageRep makes any such guarantee. The image could be planar; could have alpha or not; could have 8- 16- or 32-bit channels, could have floating-point channels, etc. Even detecting whether the image is useful for OpenGL and deciding how to pass the data in is not easy, and when it's not, what do you do then? There's no way to blit from an NSBitmapImageRep of useless format to one of known good format...

You must also not assume that just because it returns a good format for your particular image on your particular OS/hardware combination, that it will return the same format for that image on every OS/hardware combination. People who did that got bit with the 10.3-10.4 transition when Apple changed the formats NSBitmapImageRep preferred to use. They will change their minds again.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Loading and using textures with alpha in OpenGL with Cocoa corporatenewt 4 5,961 Dec 8, 2007 02:06 PM
Last Post: Malarkey
  loading textures - cocoa openGL mDmarco 20 9,283 Aug 28, 2007 08:48 PM
Last Post: OneSadCookie
  libpng loading junk at bottom of my OpenGL textures...? BinarySpike 6 5,947 Apr 19, 2007 12:20 PM
Last Post: BinarySpike
  Loading textures from bitmaps tehqin 5 3,886 Feb 26, 2007 01:58 AM
Last Post: unknown
  Split: Loading textures dave05 5 3,894 Jun 3, 2005 09:33 PM
Last Post: Fenris