Open GL Super Bible

Previous Table of Contents Next


Color Index Mode

OpenGL also supports the alternative color index mode. In this mode, you specify a color for drawing operations by specifying an index into an array of colors, rather than as an RGB triplet.

You cannot use color index mode and RGBA color mode together. This means if you use color index mode on a true-color device (or near true-color, such as a 16-bit color card), you won’t have access to all the available colors. Under some implementations, the color index palette can be up to 4,096 entries long. The Microsoft implementation however, only supports 256 entries.

You can use color index mode to do contour mapping in which some function of the surface returns an index into the palette. It is somewhat faster than RGBA, and the limitations of the 3-3-2 palette do not exist. For example, if you need 200 shades of gray, you can have them. However, some of the lighting effects discussed in the next chapter are not available under color index mode either.

Why Use Color Index Mode?

There are really very few good reasons to use color index mode. Typically, this mode is used to get more control over the palette. You can also do palette animation, but only on devices that support palettes (8-bit display cards). This doesn’t mean you can’t use color index mode on these devices; it only means there is no corresponding hardware palette with which you can perform animation. Palette animation occurs when you change the entries in the palette, which causes a corresponding change in all screen pixels having that palette index. This can produce color cycling for some special effects.

Another reason to use color index mode is for applications that use color to indicate a third dimension—to indicate the pressure at certain spatialregions, for instance. You can also use this mode for false color images that do not require an organized palette. Finally, color index mode can be somewhat faster in 8-bit color modes because only one color channel (as opposed to three, one each for red, green, and blue) needs to be manipulated instead of three.

In addition to limiting the color selection, color index mode does not support some of OpenGL’s other special effects—including many lighting effects and shading, fog, anti-aliasing, and alpha blending. Generally, it is better to use RGBA mode.

As mentioned, the most significant advantage of using color index mode is for more palette control on 8-bit display devices. The 3-3-2 palette limits your color choices, and if you want 200 shades of red to do really smooth shading on an 8-bit display, you are out of luck. In color index mode, however, the palette entries range from darkest to lightest colors. You can separate the palette into as many or as few bands as you like. The INDEX sample program displays a triangle shaded from black to bright red (see Figure 8-15). This shading is not possible in 8-bit color mode using at 3-3-2 palette.


Figure 8-15  Output from INDEX showing over 200 shades of red for smooth shading

Using Color Index Mode

To specify color index mode, all you need to do is set the iPixelType member of the PIXELFORMATDESCRIPTOR to PFD_TYPE_COLORINDEX. First, though, you need to create a palette. With color index mode, the palette is specific to the application. For our INDEX sample program, we want a palette consisting only of shades of red to do very smooth shading in an 8-bit color mode. Listing 8-6 is the code to create this palette.

Listing 8-6 Code to create a palette consisting only of shades of red

// Creates a color ramp from black to bright red

HPALETTE GetRedPalette(HDC hDC)

   {

   HPALETTE hRetPal = NULL;      // Handle to palette to be created

   LOGPALETTE *pPal;             // Pointer to memory for logical palette

   int i;                             // Counting 
variable // Allocate space for a logical palette structure plus
all the palette
   //
   entries pPal =             
                       
                                   
 
           
 
 
  {LOGPALETTE*)malloc(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY));

// Fill in palette header
pPal->palVersion = 0x300;// Windows 3.0
pPal->palNumEntries = 256;// table size
  
   
// Loop through all the palette entries, creating a graduated red
// palette containing only shades of red
for(i = 10; i < 246; i++)
        {
        pPal->palPalEntry[i].peRed = i;// Red intensity from 0 to 255
        pPal->palPalEntry[i].peGreen = 0;
        pPal->palPalEntry[i].peBlue = 0;
        pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
        } 
   
// Create the palette
hRetPal = CreatePalette(pPal); 
 
// Go ahead and select and realize the palette for this device context
SelectPalette(hDC,hRetPal,FALSE);
RealizePalette(hDC); 
 
// Free the memory used for the logical palette structure
free(pPal); 
 
// Return the handle to the new palette
return hRetPal;
}

Notice that this code always returns a palette. No check is made to see if the pixel format required a palette. This is because you can use color index mode even in the high-color modes. All of the other code concerning palette realization remains unaffected.

Show the Triangle

Now the code to render the triangle sets the color of the triangle’s apex to color index 0, which is the darkest entry in the palette with 0 intensity (black). The color for the bottom two corners is set to palette index 255, the brightest shade of red. With smooth shading enabled, this code (Listing 8-7) produces the triangle seen in Figure 8-15.

Listing 8-7 Code to render the shaded triangle in the INDEX program

void RenderScene(void)
   {
   // Clear the window with current clearing color
   glClear(GL_COLOR_BUFFER_BIT); 
 
   // Enable smooth shading
   glShadeModel(GL_SMOOTH); 
 
   // Draw the triangle
   glBegin(GL_TRIANGLES);
           // Darkest Red Apex (black)
           glIndexi(0);
           glVertex3f(0.0f,200.0f,0.0f); 
 
           // Brightest red bottom corners
           glIndexi(255);
           glVertex3f(200.0f,-70.0f,0.0f);
           glVertex3f(-200.0f, -70.0f, 0.0f);
   glEnd(); 
 
   // Flush drawing commands
   glFlush();
   }


Previous Table of Contents Next