Drawing bitmaps in OpenGL

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.

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.

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.

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.

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

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.

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.

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.

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.

Hi there, this thread matches exactly with what I've been fighting for the last 3 hours.
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:

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