The Color Combine Unit
Note: Control of high level rendering functions is managed by three functions,
c = f * a + b 
where
void grColorCombine( 
                     GrCombineFunction_t func,
                     GrCombineFactor_t   factor,
                     GrCombineLocal_t    local,
                     GrCombineOther_t    other,
                     FxBool              invert
                   )
Fourteen combining functions are defined in the GrCombineFunction_t enumerated type;
one is selected with func, the first argument to grColorCombine().

Table 5.1 gives the symbolic names and formulas for each color combine function.

The f variable in the combining formulas is defined by factor, the second argument to grColorCombine(). The choices for this scale factor are given in Table 5.2. Note that alpha values from the texture combine unit (atexture) or specified by grAlphaCombine() arguments (alocal and aother) appear in some of the scale factors.
 


 
Table 5.1 Configuring the color combine unit.

The first argument to grColorCombine(),

  • func, specifies the color combine function; its value is chosen from among the symbols list in the left hand column of the table below. The right hand column gives the combining function that corresponds to each symbolic name.
  • f is a scale factor and is defined by the factor argument to grColorCombine().
  • clocal and cother are specified by the third and fourth arguments.
  • Some of the formulas specify an alpha value, alocal, that is defined in the grAlphaCombine() function described in the next chapter.
  • color combine function computed color
    GR_COMBINE_FUNCTION_ZERO 0
    GR_COMBINE_FUNCTION_LOCAL clocal
    GR_COMBINE_FUNCTION_LOCAL_ALPHA alocal
    GR_COMBINE_FUNCTION_SCALE_OTHER f * cother
    GR_COMBINE_FUNCTION_BLEND_OTHER
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
    f * cother + clocal
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA f * cother + alocal
    GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL f * (cother – clocal)
    GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL

    GR_COMBINE_FUNCTION_BLEND

    f*(cother –clocal) +clocal
        =
    f*cother+(1 – f)*clocal
    GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ALPHA f*(cother – clocal)+alocal
    GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL

    GR_COMBINE_FUNCTION_BLEND_LOCAL

    f * (– clocal) + clocal
        =
    (1 – f) * clocal
    GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL f * (– clocal) + alocal


    Table 5.2 The color combine function scale factor.
    The second argument to grColorCombine(), factor, specifies a scale factor, called f in the formulas delineated in Table 5.1; its value is chosen from among the symbols list in the left hand column of the table below. The right hand column gives the scale factor that corresponds to each symbolic name. clocal is specified by the third argument to grColorCombine(), alocal and aotherare defined in the grAlphaCombine() function described in the next chapter, and atexture comes from the texture combine unit, described in Chapter 9.
    combine factor scale factor (f)
    GR_COMBINE_FACTOR_NONE unspecified
    GR_COMBINE_FACTOR_ZERO 0
    GR_COMBINE_FACTOR_LOCAL clocal / 255
    GR_COMBINE_FACTOR_OTHER_ALPHA aother / 255
    GR_COMBINE_FACTOR_LOCAL_ALPHA alocal / 255
    GR_COMBINE_FACTOR_TEXTURE_ALPHA  atexture / 255
    GR_COMBINE_FACTOR_ONE 1
    GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 1 – clocal / 255
    GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 1 – aother / 255
    GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 1 – alocal / 255
    GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 1 – atexture/255
    The third and fourth arguments to grColorCombine() set values for the clocal and cother variables that appear in the combining functions; the choices are shown in Table 5.3 . Iterated colors are computed by iterating the colors specified in GrVertex structures passed to drawing functions. The texture color comes from the texture combine unit (see Chapter 9), and the constant color is set by grConstantColorValue() (described earlier in this chapter).

    The func formula computes the red, green, and blue color components. The result of the computation is clamped to [0..255] and may be bit-wise inverted, based on the final argument to grColorCombine(), invert.
    Inverting the bits in a color component c is the same as computing (1.0 – c) for floating point values in the range [0..1] or (255 – c) for 8-bit values in the range [0..255].


    Table 5.3 Choosing local and other colors for the color combine unit.
    The third and fourth arguments to grColorCombine(), local and other, specify the sources for the clocal and cother values that appear in the color combine formulas delineated in Table 5.1; their values are chosen from among the symbols in the tables below. Iterated colors are computed by iterating the colors specified in GrVertex structures passed to drawing functions. The texture color comes from the texture combine unit, and the constant color is set by grConstantColorValue().
     
    local combine source local color (clocal)
    GR_COMBINE_LOCAL_NONE unspecified color
    GR_COMBINE_LOCAL_ITERATED iterated vertex color (Gouraud shading)
    GR_COMBINE_LOCAL_CONSTANT constant color 
     
    other combine source other color (cother)
    GR_COMBINE_OTHER_NONE unspecified color
    GR_COMBINE_OTHER_ITERATED  iterated vertex color (Gouraud shading)
    GR_COMBINE_OTHER_TEXTURE color from texture map
    GR_COMBINE_OTHER_CONSTANT constant color
    The color combine unit computes the source color for the remainder of the rendering pipeline. The default color combine mode is
    grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
                   GR_COMBINE_FACTOR_ONE,
                   GR_COMBINE_LOCAL_ITERATED,
                   GR_COMBINE_OTHER_ITERATED,
                   FXFALSE
                  )


    A series of examples follows.

    Example 5.1 Drawing a constant color triangle.
    The code segment below draws a teal colored triangle by setting the constant color and directing the color combine unit to use it as cother.

     

    GrVertex a, b, c; 

    /* set color to teal (assumes ARGB format) */ 
    grConstantColorValue( (100<<8) + 150 ); 

    /* configure color combine unit for constant color */ 
    grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
                   GR_COMBINE_FACTOR_ONE,
                   GR_COMBINE_LOCAL_NONE,
                   GR_COMBINE_OTHER_CONSTANT,
                   FXFALSE); 

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c); 

    The code segment below will produce the same result as the one above, but it points clocal to the constant color.

    GrVertex a, b, c;

    /* set color to teal (assumes ARGB format) */ 
    grConstantColorValue( (100<<8) + 150);

    /* configure color combine unit for constant color */
    grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
                   GR_COMBINE_FACTOR_NONE,
                   GR_COMBINE_LOCAL_CONSTANT,
                   GR_COMBINE_OTHER_NONE,
                   FXFALSE); 

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);
     

     
    Example 5.2 Drawing a flat shaded triangle.
    The code segment below draws a flat-shaded triangle using the color for vertex A. It sets the constant color to the vertex color and proceeds as is in the previous example.

    GrVertex A, B, C; 

    /* set constant color to color of vertex A (assumes ARGB format) */ grConstantColorValue((((int)A.a)<<24)||
                         (((int)A.r)<<16)||
                          ((int)A.g)<<8)||(int) A.b); 

    /* configure color combine unit for constant color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_LOCAL, 
    GR_COMBINE_FACTOR_NONE, 
    GR_COMBINE_LOCAL_CONSTANT, 
    GR_COMBINE_OTHER_NONE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&A, &B, &C);

    Alternatively, you could set the colors of all three vertices to the colors in Vertex A and proceed as in the next example.

    GrVertex A, B, C;

    /* set all vertices to same color */ 
    B.a = C.a = A.a; 
    B.r = C.r = A.r; 
    B.g = C.g = A.g; 
    B.b = C.b = A.b; 

    /* configure color combine unit for iterated colors */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_LOCAL, 
    GR_COMBINE_FACTOR_NONE, 
    GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_NONE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */
    grDrawTriangle(&A, &B, &C);
     

    Example 5.3 Drawing a smooth shaded triangle.
    In this example, a Gouraud shaded triangle will be drawn, with the color blending smoothly from vertex to vertex. The hardware automatically iterates the colors to achieve the smooth shading. The color combine unit is configured with clocal set to the iterated color components.
    GrVertex a, b, c; 

    /* configure color combine unit for iterated color */
    grColorCombine(
    GR_COMBINE_FUNCTION_LOCAL, 
    GR_COMBINE_FACTOR_NONE, 
    GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_NONE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);

    Alternatively, cother can be directed at the iterated color components. 

    GrVertex a, b, c;

    /* configure color combine unit for iterated color */
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, 
    GR_COMBINE_LOCAL_NONE, 
    GR_COMBINE_OTHER_ITERATED, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);
     

    Example 5.4 Drawing a flat-shaded textured triangle.
    The following code produces a textured flat shaded triangle using the constant color.
    GrVertex a, b, c; 

    /* set color to teal (assumes ARGB format) */ 
    grConstantColorValue( (100<<8) + 150); 

    /* configure color combine unit for iterated color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, 
    GR_COMBINE_LOCAL_CONSTANT, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);

    Example 5.5 Drawing a smooth-shaded textured triangle.
    This example configures the color combine unit for a smoothly shaded textured triangle by directing clocal to the iterated color and cother to the output from the texture combine unit.
    GrVertex a, b, c; 

    /* configure color combine unit for iterated color */
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, 
    GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);

     
    Example 5.6 Drawing a smooth shaded triangle with specular lighting.
    Specular lighting is modelled as the sum of the texture color and the iterated color.
    GrVertex a, b, c;

    /* configure color combine unit for iterated color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, 
    GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);

     
    Example 5.7 Drawing a smooth shaded textured triangle with specular highlights.
    By using the alpha component to model monochrome specular highlights, you can produce shiny, textured, smooth-shaded triangles ((texture RGB * iterated RGB) + iterated a). [for a read alpha]
     
     
    GrVertex a, b, c;

    /* configure color combine unit for iterated color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, GR_COMBINE_FACTOR_LOCAL, 
    GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);
     

    Example 5.8 Drawing a smooth shaded triangle with monochrome diffuse and colored specular lighting.
    Alternatively, monochrome diffuse lighting and colored specular lighting can be produced by using the alpha component to model monochrome diffuse lighting and iterated RGB to model colored specular lighting
    ((texture RGB * iterated a) + iterated RGB ). Iterated alpha is chosen to be either alocal or aother with a call to grAlphaCombine() that is not shown here. In the first code segment, iterated alpha is assumed to be available as alocal.

    GrVertex a, b, c;

    /* configure color combine unit for iterated color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_LOCAL_ALPHA, GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);

    Alternatively, iterated alpha can be specified for aother in grAlphaCombine(). In that case the following grColorCombine() configuration is needed.

    GrVertex a, b, c;

    /* configure color combine unit for iterated color */ 
    grColorCombine(
    GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_OTHER_ALPHA, GR_COMBINE_LOCAL_ITERATED, 
    GR_COMBINE_OTHER_TEXTURE, FXFALSE);

    /* assumes that some co-ordinates have been assigned to a, b, and c */ 
    grDrawTriangle(&a, &b, &c);


    Other Color Combine Options

    The routine grAlphaControlsITRGBLighting() can be used to specify that if the high order bit of atexture is 1, then the constant color set by grConstantColorValue() is used instead of the iterated RGB values. This is useful if a portion of a texture is to appear to be illuminated from behind the surface, instead of by an external light source.

    void grAlphaControlsITRGBLighting( FxBool enable ) 
    When enabled, the normal color combine controls for local color (clocal) are overridden, and the most significant bit of texture alpha (atexture) selects between iterated vertex RGB and the constant color set by grConstantColorValue().
    By default, this alpha controlled lighting mode is disabled. Table 5.4 shows how clocal is determined.

    Table 5.4 Overriding the local color when the high order bit of atexture is set.
    You can get hybrid effect between smooth and flat shading by using grAlphaControlsITRGBLighting() to enable a technique whereby the high order bit of atexture is used to switch clocal between iterated RGB and the constant color. The state table below shows how the clocal value is determined.
    when enabled  and the high order bit of atextureis the local color clocal will be
    FXTRUE 0 iterated RGB
    FXTRUE 1 grConstantColorValue()
    FXFALSE 0 set by grColorCombine()
    FXFALSE 1 set by grColorCombine()
    Some possible uses for this mode are self-lit texels and specular paint. If a texture contains texels that represent self luminous areas, such as windows, then multiplicative lighting can be disabled for these texels as follows. This applies lighting to the texture. When a texel’s alpha is 1, the texture color will be multiplied by the Glide constant color that was previously set to white, so no lighting is applied.

    If the color combine unit is configured to add iterated RGB to a texture for the purpose of a specular highlight, then texture alpha can be used as specular paint.
    In this example, the Glide constant color is set to black and iterated RGB iterates the specular lighting. Where a texel’s alpha is 0, the texture color will be added to iterated RGB and specular lighting is applied to the texture. Where a texel’s alpha is 1, the texture color will be added to the Glide constant color that was previously set to black, so no lighting is applied. The result is that the alpha channel in the texture controls where specular lighting is applied to the texture and specularity can be painted onto the texture in the alpha channel.

    Chapter 5                                                                       Next : Gamma Correction