Open GL Super Bible

Previous Table of Contents Next

The Palette’s Structure

To create a palette, you must first allocate memory for a LOGPALETTE structure. This structure is filled with the information that describes the palette, and then is passed to the Win32 function CreatePalette(). The LOGPALETTE structure is defined as follows:

  typedef struct tagLOGPALETTE { // lgpl 
       WORD         palVersion;
       WORD         palNumEntries;
       PALETTEENTRY palPalEntry[1];

The first two members are the palette header and contain the palette version (always set to 0x300) and the number of color entries (256 for 8-bit modes). Each entry is then defined as a PALETTEENTRY structure that contains the RGB components of the color entry.

The following code allocates space for the logical palette:

LOGPALETTE *pPal;          // Pointer to memory for logical palette
// Allocate space for a logical palette structure plus all the palette
// entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +

Here, nColors specifies the number of colors to place in the palette, which for our purposes is always 256.

Each entry in the palette then is a PALETTEENTRY structure, which is defined as follows:

   typedef struct tagPALETTEENTRY { // pe 
       BYTE peRed;
       BYTE peGreen;
       BYTE peBlue;
       BYTE peFlags;

The peRed, peGreen, and peBlue members specify an 8-bit value that represents the relative intensities of each color component. In this way, each of the 256 palette entries contains a 24-color definition. The peFlags member describes advanced usage of the palette entries. For OpenGL purposes you can just set this to NULL.

In addition to the 3-3-2 palette, Windows can support other 8-bit palettes for doing things such as specifying 200 shades of gray.

The 3-3-2 Palette

Now comes the tricky part. Not only must our 256 palette entries be spread evenly throughout the RGB color cube, but they must be in a certain order. It is this order that enables OpenGL to find the color it needs, or the closest available color in the palette. Remember that in an 8-bit color mode you have 3 bits each for red and green, and 2 bits for blue. This is commonly referred to as a 3-3-2 palette. So our RGB color cube measures 8 by 8 by 3 along the red, green, and blue axes, respectively.

To find the color needed in the palette, an 8-8-8 color reference (the 24-bit color mode setup) is scaled to a 3-3-2 reference. This 8-bit value is then the index into our palette array. The red intensities of 0–7 in the 3-3-2 palette must correspond to the intensities 0–255 in the 8-8-8 palette. Figure 8-14 illustrates how the red, green, and blue components are combined to make the palette index.

When we build the palette, we loop through all values from 0 to 255. We then decompose the index into the red, green, and blue intensities represented by these values (in terms of the 3-3-2 palette). Each component is multiplied by 255 and divided by the maximum value represented, which has the effect of smoothly stepping the intensities from 0 to 7 for red and green, and from 0 to 3 for the blue. Table 8-1 shows some sample palette entries, to demonstrate component calculation.

Table 8-1 A Few Sample Palette Entries for a 3-3-2 Palette

Palette Entry Binary (B G R) Blue Component Green Component Red Component

0 000 000 000000 0 0 0
1 00 000 001 0 0 1*255/7
2 00 000 010 0 0 2*255/7
3 00 000 011 0 0 3*255/7
9 00 001 001 0 1*255/7 1*255/7
10 00 001 010 0 1*255/7 2*255/7
137 10 001 001 2*255/3 1*255/7 1*255/7
138 10 001 010 2*255/7 1*255/7 2*255/3
255 11 111 111 3*255/3 7*255/7 7*255/7

Previous Table of Contents Next