oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

A Simple Mac OS X libpng Example with OpenGL
Pages: 1, 2, 3

I tend to be a bit impatient when I experiment with code. Once more, I returned to the internet and looked for readily available source code I could snap my pngLoad function code into. It's the Dr. Frankenstein method of coding; find a dead piece of code you can use and bring it back to life. (Also known as code leveraging, in professional circles.) I stumbled across an excellent tutorial on the internet: "OpenGL Texture Mapping: An Introduction," written by Nate Miller. The source code example is over six years old and uses TGA files (the TARGA file format is used by paint programs) for the original texture map source.

It was time to pimp up this source code and give it some new life with a PNG file loader. Essentially, Nate's source code is a hybrid of the checkerboard-texture-mapping example 9-1 from the book OpenGL Programming. I borrowed a snippet of Nate's code, which sets up the textures and texture vertices, and re-integrated it back into the original example 9-1 source code. Source listing 3, pngDrvr.c, shows the program that demonstrates loading a PNG file.

The C function setupGLTexture is where I leveraged Nate's code to wedge in my PNG loader function. This is what the setupGLTexture code looks like:

int setupGLTexture(char *image, int width, int height, int texName) 
  if (image == NULL)
    return 0;
  printf("(loadTexture) width: %d height: %d\n", width, height); 

  /* create a new texture object
   * and bind it to texname (unsigned integer < 0)
  glBindTexture(GL_TEXTURE_2D, texName);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, 
         GL_RGB, GL_UNSIGNED_BYTE, image);
  return 1;

This C function is called from the OpenGL callback function display() in the pngDrvr.c code.

Building the Example Program

If you have been following along the previous articles, in "Developing in OpenGL Using Makefiles," I develop software in two distinct UNIX environments, Mac OS X (Darwin) and Solaris. To work on OpenGL programming between the two environments, I use makefiles and try to keep the source code as platform-independent as possible.

Here is the makefile for Mac OS X in the UNIX environment.

LIBDIR += -L"/System/Library/Frameworks/OpenGL.framework/Libraries" 

FRAMEWORK = -framework GLUT
FRAMEWORK += -framework OpenGL

CC = g++
LIBRARIES = -lGL -lGLU -lm -lobjc -lstdc++ 
LIBRARIES += -L/sw/lib -lpng -lz

SRCS = pngDrvr.c pngLoad.c
OBJECTS = $(SRCS:.c=.o)
All: pngDrvr
pngDrvr: $(OBJECTS)

I need to point out that the last line of the makefile, with <TAB>$CC, indicates an actual physical tab from the text editor. Make that correction before attempting to compile.

There You Have it!

There are pretty much two types of OpenGL programmers: the gurus, who earn a living from their incredible skill sets, and the rest of us. When I started down this road, I noticed that on various forums, there were postings by people like you and me who were looking for source code on how to do this. I know the guru is out there waving a hand: "Blah. It is all so simple." And now, we all know how easy it is. There just wasn't too much info out there demonstrating how simple this really is. Now that you've been informed, go put some textures on those naked polygons you've been drawing, will ya?

Michael J. Norton is a software engineer at Cisco Systems.

Return to the Mac DevCenter