Loading Textures in OpenGL using libpng
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
Here's the link: http://www.macdevcenter.com/pub/a/mac/20...tml?page=2
"When you dream, there are no rules..."
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.
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.
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
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:
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?
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);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?
Each day brings me one step closer to figuring this out...
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.
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.
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..."
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.
Guess what? After waking up, I noticed I was calling my setup code before the OpenGL context was active.
Taxxodium Wrote:If you use NSBitmap, which is not recommendedI'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;
}
Of course, that copies the image data behind the scenes, which is inefficient, and should probably be avoided if at all possible...
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.
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...
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Texture Loading Cocoa/OpenGL | ultitech | 1 | 5,676 |
Jan 31, 2011 12:51 PM Last Post: mk12 |
|
| OpenGL Model and Texture loading | mikey | 8 | 5,982 |
Jun 6, 2009 08:50 AM Last Post: unknown |
|
| Problems with fink installed libpng at runtime | flash | 2 | 2,202 |
May 7, 2006 02:10 PM Last Post: flash |
|
| Linker error when using libPNG | TomorrowPlusX | 4 | 3,798 |
Nov 18, 2004 02:19 PM Last Post: TomorrowPlusX |
|

