Evaluators provide a means to use a polynomial or rational polynomial mapping to produce vertex, normal, and texture coordinates, and colors. The values so produced are sent on to further stages of the GL as if they had been provided directly by the client. Transformations, lighting, primitive assembly, rasterization, and per-pixel operations are not affected by the use of evaluators.
Consider the -valued polynomial defined by
with and
the ith Bernstein polynomial of degree n (recall that and ). Each is a control point. The relevant command is
void Map1[fd] ( enum type, T , T , int stride, int order, T points ) ;
type is a symbolic constant indicating the range of the defined polynomial. Its possible values, along with the evaluations that each indicates, are given in Table 5.1. is equal to n + 1; The error INVALID_VALUE is generated if is less than one or greater than MAX_EVAL_ORDER. points is a pointer to a set of n+1 blocks of storage. Each block begins with k single-precision floating-point or double-precision floating-point values, respectively. The rest of the block may be filled with arbitrary data. Table 5.1 indicates how k depends on type and what the k values represent in each case.
Table 5.1: Values specified by the target to Map1 .
Values are given in the order in which they are taken.
stride is the number of single- or double-precision values (as appropriate) in each block of storage. The error INVALID_VALUE results if is less than k. The order of the polynomial, order, is also the number of blocks of storage containing control points.
and give two floating-point values that define the endpoints of the pre-image of the map. When a value is presented for evaluation, the formula used is
The error INVALID_VALUE results if .
Map2 is analogous to Map1 , except that it describes bivariate polynomials of the form
The form of the Map2 command is
void Map2[fd] ( enum target, T , T , int ustride, int uorder, T , T , int vstride, int vorder, T points ) ;
target is a range type selected from the same group as is used for Map1 , except that the string MAP1 is replaced with MAP2. points is a pointer to blocks of storage ( and ; the error INVALID_VALUE is generated if either or is less than one or greater than MAX_EVAL_ORDER). The values comprising are located
values (either single- or double-precision floating-point, as appropriate) past the first value pointed to by points. , , , and define the pre-image rectangle of the map; a domain point is evaluated as
The evaluation of a defined map is enabled or disabled with Enable and Disable using the constant corresponding to the map as described above. The error INVALID_VALUE results if either ustride or vstride is less than k, or if is equal to , or if is equal to .
Figure 5.1 describes map evaluation schematically; an evaluation of enabled maps is effected in one of two ways. The first way is to use
void EvalCoord[12][fd] ( T arg ) ;
void EvalCoord[12][fd]v ( T arg ) ;
EvalCoord1 causes evaluation of the enabled 1-dimensional maps. The argument is the value (or a pointer to the value) that is the domain coordinate, . EvalCoord2 causes evaluation of the enabled 2-dimensional maps. The two values specify the two domain coordinates, and , in that order.
When one of the EvalCoord commands is issued, all currently enabled maps of the indicated dimension are evaluated. Then, for each enabled map, it is as if a corresponding GL command were issued with the resulting coordinates, with one important difference. The difference is that when an evaluation is performed, the GL uses evaluated values instead of current values for those evaluations that are enabled (otherwise, the current values are used). The order of the effective commands is immaterial, except that Vertex (for vertex coordinate evaluation) must be issued last. Use of evaluators has no effect on the current color, normal, or texture coordinates. If ColorMaterial is enabled, evaluated color values affect the result of the lighting equation as if the current color was being modified, but no change is made to the tracking lighting parameters or to the current color.
No command is effectively issued if the corresponding map (of the indicated dimension) is not enabled. If more than one evaluation is enabled for a particular dimension (e.g. MAP1_TEXTURE_COORD_1 and MAP1_TEXTURE_COORD_2), then only the result of the evaluation of the map with the highest number of coordinates is used.
Finally, if either MAP2_VERTEX_3 or MAP2_VERTEX_4 is enabled, then the normal to the surface is computed. Analytic computation, which sometimes yields normals of length zero is one method which may be used. If automatic normal generation is enabled, then this computed normal is used as the normal associated with a generated vertex. Automatic normal generation is controlled with Enable and Disable with symbolic the constant AUTO_NORMAL. If automatic normal generation is disabled, then a corresponding normal map, if enabled, is used to produce a normal. If neither automatic normal generation nor a normal map are enabled, then no normal is sent with a vertex resulting from an evaluation (the effect is that the current normal is used).
For MAP_VERTEX_3, let . For MAP_VERTEX_4, let , where . Then let
Then the generated analytic normal, , is given by .
The second way to carry out evaluations is to use a set of commands that provide for efficient specification of a series of evenly spaced values to be mapped. This method proceeds in two steps. The first step is to define a grid in the domain. This is done using
void MapGrid1[fd] ( int n, T , T ) ;
for a 1-dimensional map or
void MapGrid2[fd] ( int , T , T , int , T , T ) ;
for a 2-dimensional map. In the case of MapGrid1 and describe an interval, while n describes the number of partitions of the interval. The error INVALID_VALUE results if . For MapGrid2 , specifies one two-dimensional point and specifies another. gives the number of partitions between and , and gives the number of partitions between and . If either or , then the error INVALID_VALUE occurs.
Once a grid is defined, an evaluation on a rectangular subset of that grid may be carried out by calling
void EvalMesh1 ( enum mode, int , int ) ;
mode is either POINT or LINE. The effect is the same as performing the following code fragment, with :
where EvalCoord1f or EvalCoord1d is substituted for EvalCoord1 as appropriate. If mode is POINT, then type is POINTS; if mode is LINE, then type is LINE_STRIP. The one requirement is that if either i=0 or i=n, then the value computed from is precisely or , respectively.
The corresponding commands for two-dimensional maps are
void EvalMesh2 ( enum mode, int , int , int , int ) ;
mode must be FILL, LINE, or POINT. When mode is FILL, then these commands are equivalent to the following, with and :
If mode is LINE, then a call to EvalMesh2 is equivalent to
If mode is POINT, then a call to EvalMesh2 is equivalent to
Again, in all three cases, there is the requirement that , , , and .
An evaluation of a single point on the grid may also be carried out:
Calling it is equivalent to the command
with and defined as above.
void EvalPoint2 ( int p, int q ) ;
is equivalent to the command
The state required for evaluators potentially consists of 9 1-dimensional map specifications and 9 2-dimensional map specifications, as well as corresponding flags for each specification indicating which are enabled. Each map specification consists of one or two orders, an appropriately sized array of control points, and a set of two values (for a 1-dimensional map) or four values (for a 2-dimensional map) to describe the domain. The maximum possible order, for either u or v, is implementation dependent (one maximum applies to both u and v), but must be at least 8. Each control point consists of between one and four floating-point values (depending on the type of the map). Initially, all maps have order 1 (making them constant maps). All vertex coordinate maps produce the coordinates (or the appropriate subset); all normal coordinate maps produce ; RGBA maps produce ; color index maps produce 1.0; texture coordinate maps produce ; In the initial state, all maps are disabled. A flag indicates whether or not automatic normal generation is enabled for 2-dimensional maps. In the initial state, automatic normal generation is disabled. Also required are two floating-point values and an integer number of grid divisions for the 1-dimensional grid specification and four floating-point values and two integer grid divisions for the 2-dimensional grid specification. In the initial state, the bounds of the domain interval for 1-D is 0 and , respectively; for 2-D, they are and , respectively. The number of grid divisions is 1 for 1-D and 1 in both directions for 2-D. If any evaluation command is issued when no vertex map is enabled, nothing happens.