Reading and Drawing Pixel Rectangles
This section describes the reading and drawing processes in
detail. The pixel conversions performed when going from framebuffer to memory
(reading) are similar but not identical to the conversions performed when going
in the opposite direction (drawing), as explained in the following sections.
You may wish to skip this section the first time through, especially if you
do not plan to use the pixel-transfer operations right away.
The Pixel Rectangle Drawing Process
Figure 8-10 and the following list describe the operation of drawing pixels into
the framebuffer.
Figure 8-10 : Drawing Pixels with glDrawPixels()
- If the pixels aren't indices (that is, the format isn't
GL_COLOR_INDEX or GL_STENCIL_INDEX), the first step is to convert the components
to floating-point format if necessary. (See Table 4-1 for the details of the conversion.)
- If the format is GL_LUMINANCE or GL_LUMINANCE_ALPHA, the
luminance element is converted into R, G, and B, by using the luminance value
for each of the R, G, and B components. In GL_LUMINANCE_ALPHA format, the
alpha value becomes the A value. If GL_LUMINANCE is specified, the A value
is set to 1.0.
- Each component (R, G, B, A, or depth) is multiplied by
the appropriate scale, and the appropriate bias is added. For example, the
R component is multiplied by the value corresponding to GL_RED_SCALE and added
to the value corresponding to GL_RED_BIAS.
- If GL_MAP_COLOR is true, each of the R, G, B, and A components
is clamped to the range [0.0,1.0], multiplied by an integer one less than
the table size, truncated, and looked up in the table. (See "Tips for Improving Pixel Drawing Rates"
for more details.)
- Next, the R, G, B, and A components are clamped to [0.0,1.0],
if they weren't already, and converted to fixed-point with as many bits to
the left of the binary point as there are in the corresponding framebuffer
component.
- If you're working with index values (stencil
or color indices), then the values are first converted to fixed-point (if
they were initially floating-point numbers) with some unspecified bits to
the right of the binary point. Indices that were initially fixed-point remain
so, and any bits to the right of the binary point are set to zero.
The resulting index value is then shifted right or left by
the absolute value of GL_INDEX_SHIFT bits; the value is shifted left if GL_INDEX_SHIFT
> 0 and right otherwise. Finally, GL_INDEX_OFFSET is added to the index.
- The next step with indices depends on whether you're using
RGBA mode or color-index mode. In RGBA mode, a color index is converted to
RGBA using the color components specified by GL_PIXEL_MAP_I_TO_R, GL_PIXEL_MAP_I_TO_G,
GL_PIXEL_MAP_I_TO_B, and GL_PIXEL_MAP_I_TO_A. (See "Pixel Mapping"
for details.) Otherwise, if GL_MAP_COLOR is GL_TRUE, a color index is looked
up through the table GL_PIXEL_MAP_I_TO_I. (If GL_MAP_COLOR is GL_FALSE, the
index is unchanged.) If the image is made up of stencil indices rather than
color indices, and if GL_MAP_STENCIL is GL_TRUE, the index is looked up in
the table corresponding to GL_PIXEL_MAP_S_TO_S. If GL_MAP_STENCIL is FALSE,
the stencil index is unchanged.
- Finally, if the indices haven't been converted
to RGBA, the indices are then masked to the number of bits of either the color-index
or stencil buffer, whichever is appropriate.
The Pixel Rectangle Reading Process
Many of the conversions done during the pixel rectangle drawing
process are also done during the pixel rectangle reading process. The pixel
reading process is shown in Figure 8-11 and described in the following list.
Figure 8-11 : Reading Pixels with glReadPixels()
- If the pixels to be read aren't indices (that is, the
format isn't GL_COLOR_INDEX or GL_STENCIL_INDEX), the components are mapped
to [0.0,1.0] - that is, in exactly the opposite way that they are when written.
- Next, the scales and biases are applied to each component.
If GL_MAP_COLOR is GL_TRUE, they're mapped and again clamped to [0.0,1.0].
If luminance is desired instead of RGB, the R, G, and B components are added
(L = R + G + B).
- If the pixels are indices (color or stencil), they're
shifted, offset, and, if GL_MAP_COLOR is GL_TRUE, also mapped.
- If the storage format is either GL_COLOR_INDEX or GL_STENCIL_INDEX,
the pixel indices are masked to the number of bits of the storage type (1,
8, 16, or 32) and packed into memory as previously described.
- If the storage format is one of the component kind (such
as luminance or RGB), the pixels are always mapped by the index-to-RGBA maps.
Then, they're treated as though they had been RGBA pixels in the first place
(including potential conversion to luminance).
- Finally, for both index and component data,
the results are packed into memory according to the GL_PACK* modes set with
glPixelStore*().
The scaling, bias, shift, and offset values are the same as
those used when drawing pixels, so if you're both reading and drawing pixels,
be sure to reset these components to the appropriate values before doing a read
or a draw. Similarly, the various maps must be properly reset if you intend
to use maps for both reading and drawing.
Note: It might seem that luminance is handled incorrectly in both the reading
and drawing operations. For example, luminance is not usually equally dependent
on the R, G, and B components as it may be assumed from both Figure 8-10 and Figure 8-11. If you wanted your luminance to be calculated such that the R component
contributed 30 percent, the G 59 percent, and the B 11 percent, you can set
GL_RED_SCALE to .30, GL_RED_BIAS to 0.0, and so on. The computed L is then .30R
+ .59G + .11B.
|