Loading Textures in OpenGL using libpng

Moderator
Posts: 508
Joined: 2002.09
Post: #1
I found an interesting article that shows how you can read a PNG file with libpng and use it as an OpenGL texture. I'm gonna give it a try on my upcoming game.

Here's the link: http://www.macdevcenter.com/pub/a/mac/20...tml?page=2

"When you dream, there are no rules..."
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
I believe it'll just crash for anything other than a 24-bit true-color PNG. Feel free to try it, but make sure you test it with 32-bit PNGs, 8-bit indexed PNGs, etc.

This code
http://onesadcookie.com/svn/repos/RubyGa...urce/png.c
should be safe, though it's perhaps a little more complex than you generally want.
Quote this message in a reply
djohnson
Unregistered
 
Post: #3
Does anyone have a simple tutorial that shows how to tie this all together? I have done the following, but only see a white quad...

init stuff
Code:
Image image = load_png_image( filename, 1, 0, 3);
glGenTextures( 1, &texName );
NSLog(@"(loadTexture) width: %d height: %d color type: %d bit depth: %d", image.width, image.height, image.color_type, image.bit_depth);

glBindTexture( GL_TEXTURE_2D, texName );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, &image.data);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
That will show the correct width, height, color type, and bit depth, so I know that libpng is loading the png file.

Here is the draw function:
Code:
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texName );

glBegin( GL_QUADS );
    glTexCoord2f (0.0f,0.0f);
    glVertex2f( -0.5, -0.5 );
    glTexCoord2f (1.0f,0.0f);
    glVertex2f( 0.5, -0.5 );
    glTexCoord2f (1.0f,1.0f);
    glVertex2f( 0.5, 0.5 );
    glTexCoord2f (0.0f,1.0f);
    glVertex2f( -0.5, 0.5 );
glEnd();

glDisable( GL_TEXTURE_2D );

It will draw a quad at the correct spot just as it should. However, it will NOT display the texture. I have tried using glIsTexture(texName) and it always shows GL_FALSE. Any ideas?

edit: I know textures are working b/c my text is displaying correctly and it is formed from text->textures.

update: After further inspection, it seems that the function, load_png_image, is not correctly loading the data for the image. When I get back to work tomorrow, I will see if I can figure out what is going on with the data part of the Image struct. OSC, since it is your code, any specific ideas on why it would be returning the width, height, bit_depth, color_type, but not the data?
Quote this message in a reply
djohnson
Unregistered
 
Post: #4
Each day brings me one step closer to figuring this out...

Code:
NSData *data = [NSData dataWithContentsOfFile:@"/location_to_my_files/texture.png"];
NSBitmapImageRep *imageRep = [ NSBitmapImageRep imageRepWithData:data ];
GLuint samples = [imageRep samplesPerPixel];

Image image = load_png_image( filename, 1, 1, (int)samples+1);

This, when added to the Nehe Lesson 6 tutorial, produces a very nice .png textured quad to appear on my screen. However, the exact same code will not work in my project. I figured I was creating the OpenGLView incorrectly, but it is setup the same. I will continue to work on my base code and see why it is not work. Thanks for the png code OSC.
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #5
You either use libpng or NSBitmapImageRep, not both, that's just asking for trouble. If you use NSBitmap, which is not recommended, you don't need to call libpng to load the png file as an openGL texture.

"When you dream, there are no rules..."
Quote this message in a reply
djohnson
Unregistered
 
Post: #6
Yeah, I am just using libpng now. I was only using some old bitmap code to see why my quad wasnt being textured.

Guess what? After waking up, I noticed I was calling my setup code before the OpenGL context was active. Wacko
Quote this message in a reply
Moderator
Posts: 1,562
Joined: 2003.10
Post: #7
Taxxodium Wrote:If you use NSBitmap, which is not recommended
I've recently discovered a 100% safe way to use NSBitmapImageRep:
Code:
unsigned char * NSBitmapImageRepToRGBAPixelArray(NSBitmapImageRep * bitmap, int targetWidth, int targetHeight) {
  unsigned char * pixels;
  NSBitmapImageRep * bitmap2;
  NSGraphicsContext * context;
  
  pixels = (unsigned char *) malloc(BYTES_PER_PIXEL * targetWidth * targetHeight);
  bitmap2 = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &pixels
                                      pixelsWide: targetWidth
                                      pixelsHigh: targetHeight
                                      bitsPerSample: 8
                                      samplesPerPixel: 4
                                      hasAlpha: YES
                                      isPlanar: NO
                                      colorSpaceName: NSDeviceRGBColorSpace
                                      bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
                                      bytesPerRow: (targetWidth * BYTES_PER_PIXEL)
                                      bitsPerPixel: (BYTES_PER_PIXEL * 8)];
  
  context = [NSGraphicsContext graphicsContextWithBitmapImageRep: bitmap2];
  [NSGraphicsContext saveGraphicsState];
  [NSGraphicsContext setCurrentContext: context];
  [bitmap drawInRect: NSMakeRect(0, 0, targetWidth, targetHeight)];
  [NSGraphicsContext restoreGraphicsState];
  
  [bitmap2 release];
  
  return pixels;
}
This function transforms an arbitrary NSBitmapImageRep into an RGBA pixel array, or any other format you specify in the call to initWithBitmapDataPlanes: pixelsWide: pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmap​Format:bytesPerRow:bitsPerPixel:.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Of course, that copies the image data behind the scenes, which is inefficient, and should probably be avoided if at all possible...
Quote this message in a reply
Moderator
Posts: 1,562
Joined: 2003.10
Post: #9
Yes, there's of course a tradeoff between speed and certainty of your image format. I suppose you could check the NSBitmapImageRep's format before calling that function, and if it's already in a usable state, use its bitmapData directly. I have no idea how often that would be the case, though.
Quote this message in a reply
glMatt
Unregistered
 
Post: #10
Code:
- (void)loadTextures
{
    NSBundle *mainBundle;                
    NSString *path_image;
    NSImage *image;
    NSBitmapImageRep *bitmap_image_rep;
    NSRect image_rect;
    int texture_format;    
    
    mainBundle = [NSBundle mainBundle];
    path_image = [mainBundle pathForResource:@"checkerboard" ofType:@"png"];    
    image = [[NSImage alloc] initWithContentsOfFile:path_image];
    NSSize imgsize = [image size];
    [image setFlipped:YES];

    image_rect = NSMakeRect(0, 0, imgsize.width, imgsize.height);
    [image lockFocus];
    bitmap_image_rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:image_rect];
    [image unlockFocus];
        
    if ([bitmap_image_rep bitsPerPixel] < 32)  {
        texture_format = GL_RGB;
    }  else  {
        texture_format = GL_RGBA;
    }

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    
    glTexImage2D(GL_TEXTURE_2D, 0, texture_format, imgsize.width, imgsize.height, 0,
                 texture_format, GL_UNSIGNED_BYTE, [bitmap_image_rep bitmapData]);

    [mainBundle release];
    [image release];                
    [bitmap_image_rep release];
}

Wouldn't know if this is what you are looking for...
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Texture Loading Cocoa/OpenGL ultitech 1 7,188 Jan 31, 2011 12:51 PM
Last Post: mk12
  OpenGL Model and Texture loading mikey 8 7,511 Jun 6, 2009 08:50 AM
Last Post: unknown
  Problems with fink installed libpng at runtime flash 2 2,639 May 7, 2006 02:10 PM
Last Post: flash
  Linker error when using libPNG TomorrowPlusX 4 4,930 Nov 18, 2004 02:19 PM
Last Post: TomorrowPlusX