Open GL Super Bible

Previous Table of Contents Next


Mipmapped Textures

So far, we’ve dealt exclusively with single-texture images. That is, whenever we draw a textured polygon, the polygon is painted with a single 1D or 2D image. This is fine for some scenes, but animated displays often need various levels of detail depending on the distance from the viewer. For example, when walking through a virtual room, you might want a high-resolution image of a picture close up, but only the outline at a distance.

OpenGL supports textures with multiple images, called mipmapped textures. Mipmapping selects the texture image closest to the screen resolution for a polygon. Loading mipmapped textures takes slightly longer than standard textures, but the visual results are impressive. In addition, mipmapped textures can improve display performance by reducing the need for GL_LINEAR image filters.


What Does the 'Mip’ in 'Mipmapped’ Mean?:  
'mip’ is latin for 'many’. 'Mipmapping’ means 'many images’.

Mipmapped textures are defined by providing a specific level parameter for each image. For the ROY-G-BIV texture in the previous example, you would use the following:

static unsigned char roygbiv_image0[16][3];
static unsigned char roygbiv_image1[8][3];
static unsigned char roygbiv_image2[4][3];
static unsigned char roygbiv_image3[2][3];
static unsigned char roygbiv_image4[1][3];
glNewList(RainbowTexture = glGenLists(1), GL_COMPILE);
  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,
                  GL_NEAREST_MIPMAP_LINEAR);

  glTexImage1D(GL_TEXTURE_1D, 0, 3, 16, 0, GL_RGB, GL_UNSIGNED_BYTE,
               roygbiv_image0);
  glTexImage1D(GL_TEXTURE_1D, 1, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE,
               roygbiv_image1);
  glTexImage1D(GL_TEXTURE_1D, 2, 3, 4, 0, GL_RGB, GL_UNSIGNED_BYTE,
               roygbiv_image2);
  glTexImage1D(GL_TEXTURE_1D, 3, 3, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
               roygbiv_image3);
  glTexImage1D(GL_TEXTURE_1D, 4, 3, 1, 0, GL_RGB, GL_UNSIGNED_BYTE,
               roygbiv_image4);
glEndList();

The image levels are specified in the first parameter to glTexImage1D(). The level 0 image is your primary, highest-resolution image for the texture. The level 1 image is half the size of the primary image, and so forth. When drawing polygons with a mipmapped texture, you need to use one of the minification filters (GL_TEXTURE_MIN_FILTER) in Table 12-3.

Table 12-3 Minification Filters

Filter Description

GL_NEAREST_MIPMAP_NEAREST Use the image nearest to the screen (polygon) resolution. Use the GL_NEAREST filter when texturing with this image.
GL_NEAREST_MIPMAP_LINEAR Use the image nearest to the screen (polygon) resolution. Use the GL_LINEAR filter when texturing with this image.
GL_LINEAR_MIPMAP_NEAREST Linearly interpolate between the two images nearest to the screen (polygon) resolution. Use the GL_NEAREST filter when texturing with this image.
GL_LINEAR_MIPMAP_LINEAR Linearly interpolate between the two images nearest to the screen (polygon) resolution. Use the GL_LINEAR filter when texturing with this image.

The GL_LINEAR_MIPMAP_NEAREST and GL_LINEAR_MIPMAP_LINEAR filters can be very expensive in terms of display performance. GL_NEAREST_MIPMAP_NEAREST is roughly equivalent to GL_NEAREST in performance, but generally produces much better results. Mipmap images are chosen by comparing the size of the polygon as it will be drawn on the screen, to the sizes of the mipmap images.

To make your life a bit easier, the OpenGL utility library (GLU32.LIB) provides two functions that automatically generate mipmapped images based on a single, high-resolution texture. In the following code, the gluBuild1DMipmaps and gluBuild2DMipmaps functions take the place of glTexImage1D and glTexImage2D:

/* 1D texture */
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,
                GL_NEAREST_MIPMAP_LINEAR);
gluBuild1DMipmaps(GL_TEXTURE_1D, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE,
                  roygbiv_image);

/* 2D texture */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                GL_NEAREST_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, info->bmiHeader.biWidth,
                  info->bmiHeader.biHeight, 0, GL_RGB,
                  GL_UNSIGNED_BYTE, rgb);

Because the gluBuild1DMipmaps and gluBuild2DMipmaps functions create images from one image, the appearance of some textured images may not be accurate. It’s like drawing text characters at different sizes—scaling the bitmaps doesn’t always generate good-looking results! When you run into this sort of problem, generate your mipmap images manually.

A Terrain Viewing Program

Our project for this chapter is a terrain viewing program that takes advantage of some of the texture-mapping features we have discussed. With this program, we’ll want to accomplish the following:

  View textured terrain scenes
  Edit the terrain interactively in 3D
  Fly through the terrain
  Print the current scene
  Save the current scene to a .BMP file

The entire terrain program is listed at the end of this chapter, just before the Reference Section. A copy of the program is in the CH12 source directory on your CD-ROM. Double-click on the TEXSCENE.EXE program icon to try it out!

Defining the Terrain

To keep things simple, we’ll define our terrain as a grid of elevation points with a texture attribute such as “this is water” or “this is a mountain.” Each point in the grid will also have an associated lighting normal to add realism.

#define TERRAIN_SIZE 21

int     TerrainType[TERRAIN_SIZE][TERRAIN_SIZE];
GLfloat TerrainHeight[TERRAIN_SIZE][TERRAIN_SIZE];
GLfloat TerrainNormal[TERRAIN_SIZE][TERRAIN_SIZE][3];

Here the TerrainType array contains the type of terrain at each point and is assigned one of the following control IDs from our user-interface resource file:

IDC_GRASS Grasslands
IDC_WATER Water
IDC_TREES Trees/woodland
IDC_ROCKS Rocks/cliffs
IDC_MOUNTAINS Mountains


Previous Table of Contents Next