Texture Combiners
In Chapter 6, "More on Colors and Materials," you learned how to use the blending equation to control the way color fragments were blended together when multiple layers of geometry were drawn in the color buffer (typically back to front). OpenGL's texture combiners allow the same sort of control (only better) for the way multiple texture fragments are combined. By default, you can simply choose one of the texture environment modes (GL_DECAL, GL_REPLACE, GL_MODULATE, or GL_ADD) for each texture unit, and the results of each texture application are then added to the next texture unit. These texture environments were covered in Chapter 8.
Texture combiners add a new texture environment, GL_COMBINE, that allows you to explicitly set the way texture fragments from each texture unit are combined. To use texture combiners, you call glTexEnv in the following manner:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
Texture combiners are controlled entirely through the glTexEnv function. Next, you need to select which texture combiner function you want to use. The combiner function selector, which can be either GL_COMBINE_RGB or GL_COMBINE_ALPHA, becomes the second argument to the glTexEnv function. The third argument becomes the texture environment function that you want to employ (for either RGB or alpha values). These functions are listed in Table 9.4. For example, to select the GL_REPLACE combiner for RGB values, you would call the following function:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
This combiner does little more than duplicate the normal GL_REPLACE texture environment.
Table 9.4. Texture Combiner Functions
Constant |
Function |
GL_REPLACE |
Arg0 |
GL_MODULATE |
Arg0 * Arg1 |
GL_ADD |
Arg0 + Arg1 |
GL_ADD_SIGNED |
Arg0 + Arg1 - 0.5 |
GL_INTERPOLATE |
(Arg0 * Arg2) + (Arg1 * (1 - Arg2)) |
GL_SUBTRACT |
Arg0 - Arg1 |
GL_DOT3_RGB/GL_DOT3_RGBA |
4*((Arg0r - 0.5) * (Arg1r - 0.5) + (Arg0g - 0.5) * (Arg1g - 0.5) + (Arg0b - 0.5) * (Arg1b - 0.5)) |
The values of Arg0 - Arg2 are from source and operand values set with more calls to glTexEnv. The values GL_SOURCEx_RGB and GL_SOURCEx_ALPHA are used to specify the RGB or alpha combiner function arguments, where x is 0, 1, or 2. The values for these sources are given in Table 9.5.
Table 9.5. Texture Combiner Sources
Constant |
Description |
GL_TEXTURE |
The texture bound to the current active texture unit |
GL_TEXTUREx |
The texture bound to texture unit x |
GL_CONSTANT |
The color (or alpha) value set by the texture environment variable GL_TEXTURE_ENV_COLOR |
GL_PRIMARY_COLOR |
The color (or alpha) value coming from the original geometry fragment |
GL_PREVIOUS |
The color (or alpha) value resulting from the previous texture unit's texture environment |
For example, to select the texture from texture unit 0 for Arg0, you would make the following function call:
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
You also have some additional control over what values are used from a given source for each argument. To set these operands, you use the constant GL_OPERANDx_RGB or GL_OPERANDx_ALPHA, where x is 0, 1, or 2. The valid operands and their meanings are given in Table 9.6.
Table 9.6. Texture Combiner Operands
Constant |
Meaning |
GL_SRC_COLOR |
The color values from the source. This may not be used with GL_OPERANDx_ALPHA. |
GL_ONE_MINUS_SRC_COLOR |
One's complement (1-value) of the color values from the source. This may not be used with GL_OPERANDx_ALPHA. |
GL_SRC_ALPHA |
The alpha values of the source. |
GL_ONE_MINUS_SRC_ALPHA |
One's complement (1-value) of the alpha values from the source. |
For example, if you have two textures loaded on the first two texture units, and you want to multiply the color values from both textures during the texture application, you would set it up as shown here:
// Tell OpenGL you want to use texture combiners glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); // Tell OpenGL which combiner you want to use (GL_MODULATE for RGB values) glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // Tell OpenGL to use texture unit 0's color values for Arg0 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); // Tell OpenGL to use texture unit 1's color values for Arg1 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1); glTexenvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
Finally, with texture combiners, you can also specify a constant RGB or alpha scaling factor. The default parameters for these are as shown here:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0f); glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);
Texture combiners add a lot of flexibility to legacy OpenGL implementations. For ultimate control over how texture layers can be combined, we will later turn to shaders.