iDevGames Forums
Drawing bitmaps in OpenGL - Printable Version

+- iDevGames Forums (
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Drawing bitmaps in OpenGL (/thread-3567.html)

Pages: 1 2

Drawing bitmaps in OpenGL - MacGoober - Jan 10, 2007 06:35 AM

I'm going absolutely nuts trying to figure out how to draw an image to the screen through OpenGL. I'm reading the red book and I've spent a great deal of time looking for examples and reading code and yet I can't seem to make it work. Can anyone take a look at this and point me in the right direction? I have a PNG 200x200 pixel image. I'm just trying to code a simple example that will place that PNG ('scarlett.png') onto the screen. I drew a red backdrop just to make sure that the other command were getting flushed properly. File and image reps seem to load fine when checked. But I get no compiling errors, just a big window filled with red.

any help would be **greatly** appreciated

    NSData *raw;
    NSBitmapImageRep *rep;
    raw = nil;
    raw = [NSData dataWithContentsOfFile:@"/Users/matt/Desktop/Projects/Tests/Golden Triangle/scarlett.png"];
    if (raw!=nil)
        rep = [NSBitmapImageRep imageRepWithData: raw];
        glDrawPixels(200,200,GL_RGBA,GL_UNSIGNED_BYTE,[rep bitmapData]);

Drawing bitmaps in OpenGL - unknown - Jan 10, 2007 07:08 AM

Why dont you load the image data into an array then pass it to GL via glTexImage2D then draw a texture mapped quad instead of using drawpixels.

Drawing bitmaps in OpenGL - longjumper - Jan 10, 2007 11:06 AM

NSBitmapImageRep's bitmapData method will not return data suitable for OpenGL's default settings for image data. You can find the functions to change the way OpenGL reads image data, but from everything I've heard, NSBitmapImageRep is not guarenteed to work with OpenGL. Look into libpng or some other image loading library.

And if you plan to go with unknown's route(using the image as a texture), the above applies, and your image's dimensions must also be a power of 2.

Drawing bitmaps in OpenGL - OneSadCookie - Jan 10, 2007 01:04 PM

search the forums for "texture loading" and you'll turn up a QuickTime texture loader and an ImageIO texture loader. If you need cross-platform, there's always libjpeg and libpng, too.

200x200 is a slightly tricky size, being non-power-of-two. You'll either need to draw a sub-area of a 256x256 texture, or use ARB_texture_rectangle, or [implicitly] use OpenGL 2.0/ARB_texture_non_power_of_two, if your video card is recent enough.

Drawing bitmaps in OpenGL - MacGoober - Jan 10, 2007 02:36 PM

Thanks for the pointers, I'll do some more searching and keep at it~

Drawing bitmaps in OpenGL - MacGoober - Jan 10, 2007 02:57 PM

just an FYI for anyone who might want it, here was the code that finally worked. the key was changing the PNG to a 256x256 image file. Although I'm not sure how I'm going to re-do my current game in OpenGL if I have to make all the image files power of 2 sizes. Sad

Anyways this code ended up working fine tho. Apparently also changing the GL_RGBA to GL_RGB was necessary, I thought that my PNG had contained a byte for Alpha but when loaded, apparently it was discarded.

the final thing was that my coordinates were wrong, i changed the raster drawing position to 0,0

with those things done, this seems to work fine:

    NSData *raw;
    NSBitmapImageRep *rep;
    raw = nil;
    raw = [NSData dataWithContentsOfFile:@"/Users/matt/Desktop/Projects/Tests/Golden Triangle/scarlett.png"];
    if (raw!=nil)
        rep = [NSBitmapImageRep imageRepWithData: raw];
        glDrawPixels(256,256,GL_RGB,GL_UNSIGNED_BYTE,[rep bitmapData]);

Drawing bitmaps in OpenGL - akb825 - Jan 10, 2007 03:22 PM

glDrawPixels simply puts the pixels on the framebuffer, and shouldn't be limited to powers of 2. However, the data may have been stored in such a way that it works using NSBitmapImageRep's methods work with OpenGL with those dimensions.

Drawing bitmaps in OpenGL - arekkusu - Jan 10, 2007 03:40 PM

Right. Drawpixels should work with any dimensions as long as all of the pixel state is correct (i.e. you need to query the NSBitmapImageRep to find out how many components it really has and what the rowbytes really are.)

Also RasterPos is transformed by the usual MVP. Use glWindowPos if you want to bypass that.

Drawing bitmaps in OpenGL - akb825 - Jan 10, 2007 03:52 PM

As a note, you may need to use glPixelStorei to set the GL_UNPACK_ALIGNMENT to however NSBitmapImageRep stores it. (and possibly some other parameters as well)

Drawing bitmaps in OpenGL - OneSadCookie - Jan 10, 2007 07:10 PM

Bottom line, you should *not* use NSBitmapImageRep for image loading, unless you create the object yourself with the initializer that takes about 17 arguments, passing sane values for each. There are many pixel formats that NSBitmapImageRep supports that OpenGL does not, and no guarantee on any API about what pixel format it will actually give you.

QuickTime, ImageIO, libpng and libjpeg are all safe. Use one of them instead.

Drawing bitmaps in OpenGL - akb825 - Jan 10, 2007 07:26 PM

I would recommend libpng: it's cross platform, and though it looks daunting at first, it's actually surprisingly simple.

Drawing bitmaps in OpenGL - ThemsAllTook - Jan 11, 2007 07:10 AM

OneSadCookie Wrote:unless you create the object yourself with the initializer that takes about 17 arguments, passing sane values for each
Here's a code snippet that demonstrates a way to do this. It's likely to be slower than loading the image with something that puts it into a known format (because it makes a copy of the image in a potentially different format), but it does the job.
unsigned char * NSBitmapImageRepToRGBAPixelArray(NSBitmapImageRep * bitmap, int targetWidth, int targetHeight) {
  unsigned char * pixels;
  static long systemVersion = 0x0000;
  if (systemVersion == 0x0000) {
    Gestalt(gestaltSystemVersion, &systemVersion);
  pixels = (unsigned char *) malloc(4 * targetWidth * targetHeight);
  if (systemVersion >= 0x1040) {
    NSBitmapImageRep * bitmap2;
    NSGraphicsContext * context;
    bitmap2 = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &pixels
                                        pixelsWide: targetWidth
                                        pixelsHigh: targetHeight
                                        bitsPerSample: 8
                                        samplesPerPixel: 4
                                        hasAlpha: YES
                                        isPlanar: NO
                                        colorSpaceName: NSDeviceRGBColorSpace
                                        bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
                                        bytesPerRow: (targetWidth * 4)
                                        bitsPerPixel: 32];
    context = [NSGraphicsContext graphicsContextWithBitmapImageRep: bitmap2];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext: context];
    [bitmap drawInRect: NSMakeRect(0, 0, targetWidth, targetHeight)];
    [NSGraphicsContext restoreGraphicsState];
    [bitmap2 release];
  } else {
    memcpy(pixels, [bitmap bitmapData], (4 * targetWidth * targetHeight));
  return pixels;
If you don't need pre-10.4 support, you can take out the Gestalt stuff and the else.

Drawing bitmaps in OpenGL - MacGoober - Jan 11, 2007 11:40 AM

Thank you for the info, everyone~

Drawing bitmaps in OpenGL - socisub - Mar 10, 2007 06:17 PM

Hi there, this thread matches exactly with what I've been fighting for the last 3 hours. Mad
As I found a different (and easy) solution I thought it would be worth registering and posting it for the community's sake. ( Hello google users that finished here like me! hope this helps ! )

My findings are that there is a way to keep using PNGs while using NSBitmapImageRep. First you build an NSImage with your png, then build an NSBitmapImageRep with the TIFFRepresentation of that image and then as usual extract the bitmapData. It magically works ! And the best, it preserves the png alpha channel for transparency. No CoreGraphics nor external libraries needed. See my code below:

// aPath is a string url to your png
NSImage *image = [[NSImage alloc] initWithContentsOfFile: aPath];
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
unsigned char *data = [bitmap bitmapData];
[image release];
[bitmap release];

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
      [bitmap size].width, [bitmap size].height, 0,

I found out how to do this by looking at the GLSLShowpiece example at The interesting code is in exhibit.m, look for the method
NSBitmapImageRep *LoadImage(NSString *path, int shouldFlipVertical

Drawing bitmaps in OpenGL - arekkusu - Mar 10, 2007 10:58 PM

This is a bit tricky.

That code will probably work fine for a simple app where you control every image that you're going to open. But try passing it various types of images, and it will crash:

* [bitmap size] is measured in points, while [bitmap pixelsWide] and [bitmap pixelsHigh] are really in pixels. Try opening an image with dpi != 72.

* your client format and type are assuming RGBA, UNSIGNED_BYTE. Try opening an image without alpha, or a greyscale image. You can use [bitmap samplesPerPixel] to figure out how many channels there are, and [bitmap bitmapFormat] to see if it is RGBA or ARGB (which unfortunately, may change for the same image depending which OS version you're on.)

* you're assuming the image is tightly packed, i.e. a 256 pixel wide RGBA image has 1024 bytes per scanline. This isn't always true, sometimes the rows are padded. Use [bitmap bytesPerRow] and GL_PACK_ROW_LENGTH to skip padding.