Using 24-bit Bitmap Files as OpenGL Images

Environment: Visual C++ 5.0, NT4, Oxygen GMX2000 graphics accelerator

Here is a fairly fast and easy way to use a Windows bitmap file (.bmp file) as a
texture map in OpenGL. The limitation is that it only works with 24-bit bitmaps.
To work with other bitmaps you need to pick apart the pixel values and look them up
in the images color table which is a bit more complicated.

You can load a bitmap using the Windows API function LoadImage.

To load an image from a file use:

        HBITMAP hBmp = (HBITMAP) ::LoadImage (NULL,
                        (LPCTSTR) fileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE |

where filename is the name of the bitmap file. According to the documentation
this doesn’t work on Windows NT but I’m running NT 4.0 and it works fine for me.

To load an image from the resources use:

        HBITMAP hBmp = (HBITMAP) ::LoadImage (AfxGetResourceHandle(),
                        MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0,

where IDB_BITMAP1 is the ID of the bitmap resource.

Note that bitmaps created in the DevStudio resource editor are not 24-bit color.
You’ll need to create your bitmap with some other program (like mspaint).

Once you have a handle to the bitmap you can get information about it with the windows function GetObject. GetObject fills in a BITMAP structure that contains the dimensions, bits per pixel and a pointer to the pixels themselves.

        BITMAP BM;
        ::GetObject (hBmp, sizeof (BM), &BM);

If the bitmap is a 24-bit bitmap then the format that the RGB values stored is not far off from the way OpenGL RGB bitmaps are formed. BM.bmBits points to an array of unsigned chars where each set of 3 bytes represents an BGR value – an RGB value where blue and red are switched. In addition each row of the bitmap must start on a longword boundary so rows are padded with extra bytes at the end to ensure this.

In order for OpenGL to ignore the padding at the end of the rows use:

        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

This is the default setting on most systems.

In order for OpenGL to understand BGR use GL_BGR_EXT instead of GL_RGB in your call to glTexImage2D or gluBuild2DMipmaps:

        gluBuild2DMipmaps( GL_TEXTURE_2D, 3, BM.bmWidth, BM.bmHeight,
                           GL_BGR_EXT, GL_UNSIGNED_BYTE,
                           BM.bmBits );

Note that if you use glTexImage2D instead of gluBuild2DMipmaps you’ll have to scale the
image so that both dimensions are a power of 2.

The sample program uses these routines to load a bitmap and texture map it onto a sphere.
The interesting code is in the LoadTexture method of the view class.

This code has been tested with VisualC++ 5.0, Windows NT with an OxygenGMX2000 graphics


Download demo project – 39 Kb


More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read