iDevGames Forums
Loading Textures in OpenGL using libpng - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Loading Textures in OpenGL using libpng (/thread-4425.html)



Loading Textures in OpenGL using libpng - Taxxodium - Mar 21, 2006 04:28 AM

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/2005/10/14/texture-maps.html?page=2


Loading Textures in OpenGL using libpng - OneSadCookie - Mar 21, 2006 05:09 AM

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/RubyGameCommon/Source/png.c
should be safe, though it's perhaps a little more complex than you generally want.


Loading Textures in OpenGL using libpng - djohnson - Apr 3, 2006 01:13 PM

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?


Loading Textures in OpenGL using libpng - djohnson - Apr 4, 2006 01:08 PM

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.


Loading Textures in OpenGL using libpng - Taxxodium - Apr 4, 2006 01:13 PM

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.


Loading Textures in OpenGL using libpng - djohnson - Apr 4, 2006 01:49 PM

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


Loading Textures in OpenGL using libpng - ThemsAllTook - Apr 4, 2006 04:19 PM

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:.


Loading Textures in OpenGL using libpng - OneSadCookie - Apr 4, 2006 06:03 PM

Of course, that copies the image data behind the scenes, which is inefficient, and should probably be avoided if at all possible...


Loading Textures in OpenGL using libpng - ThemsAllTook - Apr 4, 2006 09:18 PM

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.


Loading Textures in OpenGL using libpng - glMatt - Apr 4, 2006 09:21 PM

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...