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 **i**th 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*,

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*,

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.

Sat Mar 29 02:23:21 PST 1997