blob: 75e0faf2c8ce9e6d23b81ece0d4db4583819086e [file] [log] [blame]
Name
ARB_vertex_program
Name Strings
GL_ARB_vertex_program
Contributors
Kurt Akeley
Allen Akin
Ben Ashbaugh
Bob Beretta
John Carmack
Matt Craighead
Ken Dyke
Steve Glanville
Michael Gold
Evan Hart
Mark Kilgard
Bill Licea-Kane
Barthold Lichtenbelt
Erik Lindholm
Benj Lipchak
Bill Mark
James McCombe
Jeremy Morris
Brian Paul
Bimal Poddar
Thomas Roell
Jeremy Sandmel
Jon Paul Schelter
Geoff Stahl
John Stauffer
Nick Triantos
Contact
Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
Notice
Copyright (c) 2002-2013 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
https://www.khronos.org/registry/OpenGL/docs/update_policy.php
IP Status
NVIDIA claims to own intellectual property related to this extension, and
has signed an ARB Contributor License agreement licensing this
intellectual property.
Microsoft claims to own intellectual property related to this extension.
Status
Complete. Approved by ARB on June 18, 2002
Version
Last Modified Date: 07/25/07
Revision: 46
Number
ARB Extension #26
Dependencies
Written based on the wording of the OpenGL 1.3 specification and requires
OpenGL 1.3.
ARB_vertex_blend and EXT_vertex_weighting affect the definition of this
extension.
ARB_matrix_palette affects the definition of this extension.
ARB_point_parameters and EXT_point_parameters affect the definition of
this extension.
EXT_secondary_color affects the definition of this extension.
EXT_fog_coord affects the definition of this extension.
ARB_transpose_matrix affects the definition of this extension.
NV_vertex_program interacts with this extension.
EXT_vertex_shader interacts with this extension.
Overview
Unextended OpenGL mandates a certain set of configurable per-vertex
computations defining vertex transformation, texture coordinate generation
and transformation, and lighting. Several extensions have added further
per-vertex computations to OpenGL. For example, extensions have defined
new texture coordinate generation modes (ARB_texture_cube_map,
NV_texgen_reflection, NV_texgen_emboss), new vertex transformation modes
(ARB_vertex_blend, EXT_vertex_weighting), new lighting modes (OpenGL 1.2's
separate specular and rescale normal functionality), several modes for fog
distance generation (NV_fog_distance), and eye-distance point size
attenuation (EXT/ARB_point_parameters).
Each such extension adds a small set of relatively inflexible
per-vertex computations.
This inflexibility is in contrast to the typical flexibility provided by
the underlying programmable floating point engines (whether micro-coded
vertex engines, DSPs, or CPUs) that are traditionally used to implement
OpenGL's per-vertex computations. The purpose of this extension is to
expose to the OpenGL application writer a significant degree of per-vertex
programmability for computing vertex parameters.
For the purposes of discussing this extension, a vertex program is a
sequence of floating-point 4-component vector operations that determines
how a set of program parameters (defined outside of OpenGL's Begin/End
pair) and an input set of per-vertex parameters are transformed to a set
of per-vertex result parameters.
The per-vertex computations for standard OpenGL given a particular set of
lighting and texture coordinate generation modes (along with any state for
extensions defining per-vertex computations) is, in essence, a vertex
program. However, the sequence of operations is defined implicitly by the
current OpenGL state settings rather than defined explicitly as a sequence
of instructions.
This extension provides an explicit mechanism for defining vertex program
instruction sequences for application-defined vertex programs. In order
to define such vertex programs, this extension defines a vertex
programming model including a floating-point 4-component vector
instruction set and a relatively large set of floating-point 4-component
registers.
The extension's vertex programming model is designed for efficient
hardware implementation and to support a wide variety of vertex programs.
By design, the entire set of existing vertex programs defined by existing
OpenGL per-vertex computation extensions can be implemented using the
extension's vertex programming model.
Issues
(1) What should this extension be called?
RESOLVED: ARB_vertex_program. DirectX 8 refers to its similar
functionality as "vertex shaders". This is a confusing term because
shaders are usually assumed to operate at the fragment or pixel level,
not the vertex level.
Conceptually, what the extension defines is an application-defined
program (admittedly limited by its sequential execution model) for
processing vertices so the "vertex program" term is more accurate.
Some of the API machinery in this extension for describing programs
should be useful for extending other OpenGL operations with programs
(though other types of programs may look very different from vertex
programs).
(2) What terms are important to this specification?
vertex program mode - When vertex program mode is enabled, vertices are
transformed by an application-defined vertex program.
conventional GL vertex transform mode - When vertex program mode is
disabled (or the extension is not supported), vertices are transformed
by GL's conventional texgen, lighting, and transform state.
vertex program - An application-defined program used to transform
vertices when vertex program mode is enabled.
program target - A type or class of program. This extension supports
the VERTEX_PROGRAM_ARB target. Future extensions may add other program
targets.
program object - An object maintained internal to OpenGL that
encapsulates a program and a set of associated state. Operations
performed on program objects include loading a program, binding,
generating program object names, querying state, and deleting.
program name - Each program object has an associated unsigned integer,
called the program name. Applications refer to a program object using
the program name.
current program - Each program target may have a current program object.
For vertex programs, the current program is executed whenever a vertex
is specified when vertex program mode is enabled.
default program - Each program target has a default program object,
referred to using a program name of zero. The current program for each
program target is initially the default program for that target.
program execution environment - A set of resources, instructions, and
semantic rules used to execute a program. Each program target may
support one or more execution environment -- new execution environments
may provide new instructions, resources, or execution rules. Program
strings must specify the execution environment that should be used to
execute the program.
program options - An optional feature that modifies the rules of the
execution environment. Vertex programs specify the options that they
require at the beginning of the program.
vertex attribute - GL state associated with vertices that can vary per
vertex.
conventional vertex attributes - Per-vertex attributes used in
conventional GL vertex transform mode, including colors, normals,
texture coordinate sets.
generic vertex attributes - An array of 16+ 4-component vectors added by
this extension. Generic vertex attributes can be used by vertex
programs but are unused in conventional GL vertex transform mode.
program parameter - A set of constants that are available for vertex
programs to use during their execution. Program parameters include
program environment parameters, program local parameters, conventional
GL state, and program constants.
program environment parameter - A set of 96+ 4-component vectors
belonging to the GL context that can be used as constants during the
execution of any vertex program.
program local parameter - A set of 96+ 4-component vectors belonging to
a vertex program object that can be used as constants during the
execution of the corresponding vertex program. Program local parameters
can not be used by any other vertex programs.
program constants - Constants declared in the text of a program may be
used during the execution of that program.
program temporaries - A set of 12+ 4-component vectors to hold temporary
results that can be read or written during the execution of a vertex
program.
program address registers - A set of 1+ 1-component integer vectors that
can be used to perform variable indirect accesses to program parameter
arrays during the execution of a vertex program. Address registers are
specified as vectors to allow for future extensions supporting multiple
address register components.
program results - A set of 4-component vectors to hold the final results
of a vertex program. The program results correspond closely to the set
of vertex attributes used during primitive assembly and rasterization.
program variables - Variable names used to identify a specific vertex
attribute, program parameter, temporary, address register, or result.
program binding - A program statement that declares a variable and
associates it with a specific vertex attribute, program parameter, or
program result.
implicit binding - When an executable instruction refers to a specific
vertex attribute, program parameter, program result, or constant by
name, without using an explicit program binding statement. When such
values are encountered, an implicit binding to an anonymous variable
name is created.
program invocation - The act of implicitly or explicitly kicking off
program execution. Vertex programs are invoked automatically when
vertex program mode is enabled and vertices are received. Vertex
programs are also invoked automatically when the current raster position
is specified.
(3) What part of OpenGL do vertex programs specifically bypass?
Vertex programs bypass the following OpenGL functionality:
- The modelview and projection matrix vertex transformations.
- Vertex weighting/blending (ARB_vertex_blend).
- Normal transformation, rescaling, and normalization.
- Color material.
- Per-vertex lighting.
- Texture coordinate generation and texture matrix transformations.
- Per-vertex point size computations in ARB/EXT_point_parameters
- Per-vertex fog coordinate computations in EXT_fog_coord and
NV_fog_distance.
- Client-defined clip planes.
- The normalization of AUTO_NORMAL evaluated normals
- All of the above, when computing the current raster position.
Operations not subsumed by vertex programs
- Clipping to the view frustum.
- Perspective divide (division by w).
- The viewport transformation.
- The depth range transformation.
- Front and back color selection (for two-sided lighting and
coloring).
- Clamping the primary and secondary colors to [0,1].
- Primitive assembly and subsequent operations.
- Evaluators (except the AUTO_NORMAL normalization).
(5) This extension adds a set of generic vertex attributes to the existing
conventional attributes. The sum of the number of generic and
conventional attributes supported on a given platform may exceed the total
number of per-vertex attributes supported in hardware. How should this
situation be handled?
RESOLVED: Implementations may alias conventional and generic vertex
attributes, where pairs of conventional and generic vertex attributes
share the same storage. Such aliasing will effectively reduce the
number of vertex attributes a hardware platforms. While implementations
may alias attributes, that behavior is not required. To accommodate both
behaviors, changing a generic vertex attribute leaves the corresponding
conventional attribute undefined, and vice versa.
This undefined behavior is a compromise between the existing
EXT_vertex_shader extension (which does not permit aliasing) and the
NV_vertex_program extension (which requires aliasing). The mapping
between generic and conventional vertex attributes is found in Table X.1
below. This mapping is taken from the NV_vertex_program specification
and generalized to define behavior for >8 texture coordinate sets.
Applications that mix conventional and generic vertex attributes in a
single rendering pass should be careful to avoid using attributes that
may alias. To limit inadvertent use of such attributes, loading a
vertex program that used a pair of attributes that may alias is
guaranteed to fail. Applications requiring a small number of generic
vertex attributes can always safely use generic attributes 6 and 7, and
any supported attributes corresponding to unused or unsupported texture
units. For example, if an implementation supports only four texture
units, generic attributes 12 through 15 can always be used safely.
(6) Should there be a "VertexAttribs" entry point to specify multiple
vertex attributes in one immediate mode call.
RESOLVED: No. Not providing such functionality serves to reduce the
already large number of required immediate mode entry points. A
"VertexAttribs" command would improve the efficiency of vertex attribute
transfer, but vertex arrays or display lists should still be better.
(7) Should a full complement of data types (signed and unsigned bytes,
shorts, and ints, as well as floats and doubles) be supported for vertex
attributes? Should fixed-point data types be supported in both normalized
(map the range to [0,1] or [-1,1]) and unnormalized form?
RESOLVED: For vertex arrays, all data type combinations are supported.
For immediate mode, a smaller subset is supported, to limit the number
of immediate-mode entry points added by this extension. In fully
general form, 112 immediate-mode entry points (4 sizes x 2
vector/non-vector x 14 data types) would be required.
Immediate mode support is available for non-normalized shorts, floats,
and doubles for all component counts. Additionally, immediate mode
support is available for 4-component vectors of all data types
(normalized and unnormalized).
Note also that in immediate mode, the "N" qualifier in function names
like VertexAttrib4Nub will be used to indicate that fixed-point data
should be normalized.
(8) How should applications indicate that fixed-point generic vertex
attribute array components should be converted to [-1,+1] or [0,1] ranges?
RESOLVED: The function VertexAttribPointerARB takes a boolean argument
<normalized> that indicates whether fixed-point array data should be
normalized to [-1,+1] or [0,1].
One alternate approach would have been to extend to set of enumerants to
include values such as NORMALIZED_UNSIGNED_BYTE_ARB. Adding such
enumerants in some sense implies that UNSIGNED_BYTE is not normalized,
even though it usually is.
(9) In unextended OpenGL, calling Vertex() specifies a vertex and causes
vertex transformation operations to be performed on the vertex. Should
there be an equivalent method to specify a vertex using generic vertex
attributes? If so, how should this be accomplished?
RESOLVED: Setting generic vertex attribute zero will always specify a
vertex. Vertex*(...) and VertexAttrib*(0,...) are specified to be
equivalent, whether or not vertex program mode is enabled. Allowing
generic vertex attribute zero to specify a vertex allows applications to
write vertex programs that use only generic attributes; otherwise,
applications would have had to use Vertex() to provoke vertex
processing.
(10) How is this extension different from previous vertex program
extensions, such as EXT_vertex_shader or NV_vertex_program? What pitfalls
are there in porting vertex programs to/from this extension?
RESOLVED: See "Interactions with NV_vertex_program" and "Interactions
with EXT_vertex_shader" sections near the end of this specification.
(11) Should program parameter variables bound to GL state be updated
automatically after the bound state changes? If so, when?
RESOLVED: Yes. Such variables are updated automatically prior to the
next vertex program invocation with no application intervention
required. A proposal to reduce the burden by requiring a manual "update
state" step was considered and rejected.
(12) How should this specification handle variable bindings to Material
state? Material is allowed inside a Begin/End, so material properties are
technically per-vertex state.
RESOLVED: Materials can be bound only as program parameters. Changes
to material properties inside a Begin/End will leave the bindings
undefined until the subsequent End command. At that point, all material
property bindings are guaranteed to be updated, and any material
property changes up to the next Begin command are guaranteed to take
effect immediately.
Supporting per-vertex material properties places additional pressure on
the number of per-vertex bindings an implementation can support, which
was already a problem. See issue (5).
In practice, material properties are usually not changed in this manner.
Applications needing to change material properties inside a Begin/End in
vertex program mode can work around this limitation by storing the color
in a conventional or generic vertex attribute and modifying the vertex
program accordingly.
(13) What semantic restrictions, if any, should be imposed on binding the
same GL state to multiple variables? The grammar permits such bindings,
but allowing this behavior means that single state updates must update
multiple variables.
RESOLVED: Cases where a single state update necessarily requires
updating multiple variables are disallowed. The only restriction
resulting from this decision is that a single state variable can not be
bound more than once in the collection of arrays that are accessed using
relative addressing (at run time). The driver can and will coalesce all
other bindings accessed only at fixed offsets into a single binding.
This restriction and a little driver work allows the same state variable
to be used multiple times without requiring that a single state change
update multiple variables.
(14) What semantic restrictions, if any, should be imposed on using
multiple vertex attributes or program parameters in the same instruction?
RESOLVED: None. If the underlying hardware implementation does not
support reads of multiple attributes or program parameters, the driver
may need to transparently insert additional instructions and/or consume
temporaries to perform the operation.
(15) How and when should related state be combined into a single program
parameter binding? Additionally, should any values derived from core GL
state be exposed, too?
RESOLVED: Related state should be combined when possible, as long as
the binding name remains somewhat sensible. Additionally, certain
pre-computed state items useful for performance reasons are also
exposed. In particular, the following GL state combinations are
supported:
* Light attenuation constants and the spot light exponent are combined
into a single vector called "state.light[n].attenuation" (spot
lights can attenuate the lit result).
* Spot light direction and cutoff angle cosine are called
"state.light[n].spot.direction" (cutoff is directional information).
Binding the cutoff angle itself is pretty useless, so the cosine is
used.
* A pre-computed half angle for lighting with infinite lights and an
infinite viewer is provided and called "state.light[n].half".
* Pre-computed products of ambient, diffuse, and specular light colors
with the corresponding front or back material colors are supported,
and are called "state.lightprod[n].<face>.<property>".
* Exponential fog density, linear fog start and end parameters, as
well as the pre-computed reciprocal of (end-start) are combined into
one vector called "state.fog.params".
* The core point size, minimum and maximum size clamps
(ARB_point_parameters), and multisample fade size threshold
(ARB_point_parameters) are combined into a single vector called
"state.point.size".
* Precomputed transpose, inverse, and inverse transpose matrices are
supported for each base matrix type.
(16) Should the initial values of temporaries and results be undefined?
RESOLVED: Since the underlying hardware differs, it was decided to
leave these values uninitalized. There are a few issues related to this
behavior that programs should keep in mind:
* Since any results not written by the program are undefined, programs
should write to all result registers that are needed during
rasterization.
* In particular, the initial vertex position result is undefined, and
will remain undefined if not written by a program. To achieve
proper results, vertex programs should be careful to write to all
four components of the vertex position. Otherwise, primitives may
be completely clipped or produce undefined results during
rasterization. There is no semantic requirement that programs must
write a transformed vertex position, so erroneous programs will load
succesfully, but will produce undefined (and probably useless)
results. Such a semantic requirement may be impossible to enforce
in future language versions that support run-time branching.
* Since vertex programs may be executed when the raster position is
set, any attributes not written by the program will result in
undefined state in the current raster position. Programs should
write to all result registers that would be used when rasterizing
pixel primitives using the current raster position.
* If conventional OpenGL texture mapping operations are performed, a
program should always write to the "w" coordinate of any texture
coordinates result registers it needs to use. Conventional OpenGL
texture accesses always use projective texture coordinates (e.g.,
s/q, t/q, r/q), even though q is almost always 1.0. An undefined q
coordinate (coming from the "w" component of the result register)
may produce undefined coordinates on the texture lookup.
(17) Should vertex programs be required to have a header token and an end
token?
RESOLVED: Yes. The header token for this extension is named
"!!ARBvp1.0". The ARB may standardize future language versions which
would be expected to have tokens like "!!ARBvp2.0". Vertex programs
must end with the "END" token.
The initial header token reminds the programmer what type of program
they are writing. If vertex programs are ever read from disk files, the
header token can be used to specifically identify vertex programs. The
initial header tokens will also make it easier for programmers to
distinguish between multiple types of vertex programs and between vertex
programs and another future type of programs.
We expect that programs may be generated by concatenation of program
fragments. The "END" token will hopefully reduce bugs due to specifying
an incorrectly concatenated program.
(18) Should ProgramStringARB take a <program> specifier? Should
ProgramLocalParameterARB and GetProgramLocalParameterARB take a <program>
specifier? How about GetProgramivARB and GetProgramStringARB?
RESOLVED: No to all. Instead, these calls are specified to always
query or modify the currently bound program object. Using bound objects
allows GL implementations to avoid locking and name lookup overhead on
each such call.
This behavior does imply that applications loading a sequence of program
objects must bind each in turn.
(19) Should relative addressing be performed using an address register
(load up an integer register) or by taking a floating-point scalar?
RESOLVED: Address register. It would not be a good idea to support
both syntaxes simultaneously, since using a floating-point scalar may
consume the only available address register in the process. The current
address register syntax can be easily extended to allow for multiple
integer registers and/or enable other integer operations in a later
extension.
Using a floating-point index may require an extra instruction on some
architectures, and would require optimization work to eliminate
redundant loads. Using a floating-point index may consume one of a
small number of temporary registers. On the other hand, for
implementations without a dedicated address register, it may be
necessary to dedicate a general-purpose register (or register component)
to hold the address register contents.
(20) How should user-defined clipping be supported in this specification?
RESOLVED: User-defined clipping is not supported in standard vertex
program mode. User-defined clipping support will be provided for
programs that use the "position invariant" option, where all vertex
transformation operations are performed by the fixed-function pipeline.
It is expected that future vertex program extensions or a future
language standard may provide more powerful user clipping functionality.
The options considered were:
(1) Not at all. Does not work for applications requiring user clipping.
User clipping could be supported through a language extension.
(2) Support only through the "position_invariant" option, where vertex
transformation is performed by the fixed-function pipeline.
(3) Support by using the fixed-function pipeline to generate eye
coordinates and perform user clipping as specified for conventional
transformation. May not work properly if the vertex transformation
doesn't match the standard "multiply by modelview and projection
matrices" model.
(4) Project existing fixed-function clip planes into clip coordinates
and perform the clip test in clip space. The clip planes would be
transformed by the inverse of the projection matrix, which will not
work if the projection matrix is singular.
(5) Provide a 4-component "user clip coordinate" result that can be
bound by a vertex program. User clipping is performed as in
unextended OpenGL, using the "user clip coordinate" in place of the
non-existant eye coordinates. This approach allows an application
to do user clipping in any coordinate system. Clipping would not be
independent of primitive tesselation as in the conventional
pipeline. Additionally, the implicit transformation of specified
clip planes by the modelview matrix may be undesirable (e.g.,
clipping in object coordinates).
(6) Provide one or more "clip plane distance" results that can be bound
by a vertex program. For conventional clipping applications, vertex
programs would compute the dot products normally computed by
fixed-function hardware. Additionally, this method would enable
additional unconventional clipping effects. Primitives would be
clipped to the portion whose interpolated clip distances are greater
than or equal to zero. This approach has the same issues as (5).
(21) How should future vertex program opcodes be named?
RESOLVED: Three-character names are recommended for brevity. Three
character names are not a hard-and-fast requirement; extra characters
may be needed for clarity or to disambiguate instructions.
(22) Should anything be said about the precision used for carrying out the
instructions?
RESOLVED: Not much; precision will vary across platforms. The minimum
precision requirements (1 part in 10^5 or roughly 17 bits) are spelled
out in section 2.1.1. In practice, implementations will generally
provide precision comparable to that obtained using single precision
floats. Documenting exact precision across implementations is
difficult. Additionally, it is difficult to spell out precision
requirements for "compound" operations such as DP4.
(23) Should this extension support evaluator maps for generic vertex
attributes? If so, what attribute sizes should be supported? Note that
such maps are not supported at all for texture units except zero.
RESOLVED: No. Evaluator support has not been consistently extended in
previous extensions. For example, neither ARB_multitexture nor OpenGL
1.3 provide support for evaluators for texture units other than unit
zero. Adding evaluators for generic attributes involves a large amount
of new state and complexity, particularly if evaluators should be
supported in general form (1, 2, 3, and 4 components, all supported data
type).
(25) The number of generic vertex attributes is implementation-dependent
and is at least 16. Each generic vertex attribute has a vertex array
enable. Should two new entry points be provided to accept an arbitrary
attribute number, or should we reserve a range of enumerants that is
"large enough"?
RESOLVED: Yes. EnableVertexAttribArrayARB and
DisableVertexAttribArrayARB. This allows the number of vertex
attributes to be unbounded, instead of using a limited range.
(26) What limits should be imposed on the constants that can be added to
or subtracted from the address register for relative addressing? Negative
offsets are sometimes useful for shifting down in an array.
RESOLVED: -64 to +63 should be sufficient for the time being. Offset
sizes are limited to allow offsets to be baked into device-dependent
instruction encodings.
(28) What level of precision should be guaranteed for the EXP and LOG
instructions? And for the EX2 and LG2 instructions?
RESOLVED: The low precision EXP and LOG instructions should give at
least 10 bits (2^-11 maximum relative error). No specific treatment
will be added for EX2/LG2, implying that the computations should at
least meet the minimal floating-point precision required by the spec.
(29) Should incremental program compilation be supported?
RESOLVED: No. Applications can compile programs just as easily using
string concatenation.
(30) Should the execution environment be identified by the program itself
or as an additional "language" parameter to ProgramStringARB?
RESOLVED: Programs should identify their execution environment in the
header. The header (plus any specified options) make it clear what kind
of program is being defined.
(31) Should this extension provide support for character sets other than
7-bit ASCII?
RESOLVED: Provide a <format> argument to ProgramStringARB to allow for
future extensions. Only ASCII will be supported by this extension;
additional character sets or encodings could be supported using separate
extensions.
(32) Support for "program object" functionality may be applicable to
future program targets. Should this functionality be factored out into a
separate extension?
RESOLVED: No, such separation is not necessary. This extension was
designed to allow to easily accommodate future program target types. It
would be straightforward to put program object functionality into a
separate extension, but the functionality provided by that extension
would be of no value by itself.
(33) Should program residency management be supported?
RESOLVED: No. This functionality can be supported in a separate
extension if desired. If may be desirable to address residency
management in a more general form, where an application may desire a
diverse set of objects (textures, programs) to be resident at once.
(34) Should program object management APIs (GenProgramsARB,
DeleteProgramsARB) work like texture objects or display lists?
RESOLVED: Texture objects.
Both approaches have their merits. Pluses for the display list model
include: no need to keep around multiple indices if you want to
allocate a group of object, contiguous indices may fall out on
implementations that share one block allocator for textures and display
lists. Pluses for the texture object model: non-contiguous indices may
be more optimizable -- new objects can be mapped to empty blocks in a
hash table to avoid collisions with existing objects, separate indices
are more compatible with a future handle-based object paradigm, and a
larger base of extensions using this model. Note that display list
allocations needed to be contiguous to support CallLists, but no such
requirement for texture or program objects exists for programs.
(35) Should there be support for a program object zero? With texture
objects, texture object zero is "special" because it is the default
texture object for each target type. Is there something like this for
program objects?
RESOLVED: Yes. Like texture objects, there should be a separate
program object zero for each program type. This allows applications to
use vertex programs without needing to generate and manage program
objects.
With texture objects, an object zero was needed for backward
compatibility with pre-OpenGL 1.1 applications. There is no such
requirement here, but providing an object zero nicely matches the
familiar texture object model.
(36) How should this extension provide feedback on why a program failed to
load?
RESOLVED: Two queries are provided. Calling GetIntegerv() with
PROGRAM_ERROR_POSITION_ARB provides the offset of an offending
instruction in the program string. An error position of -1 indicates
that a program loaded successfully. Calling GetString() with
PROGRAM_ERROR_STRING_ARB returns an implementation-dependent error
string explaining the reason for the failure. The error string can be
queried even on successful program loads to check for warning messages.
The error string may be kept in a static buffer managed by the GL
implementation. Implementations may reuse the same buffer on subsequent
calls to ProgramStringARB, so returned error strings are guaranteed to
be valid only until the next such call.
(37) How does ARB_vertex_blend's WEIGHT_SUM_UNITY_ARB mode interact with
this extension? This mode allows an application to specify N-1 weights,
and have the Nth weight computed by the GL.
RESOLVED: The ARB_vertex_blend spec (as of May, 2002) specifies that
the nth weight is automatically computed by the GL and is effectively
current state. In practice, ARB_vertex_blend implementations compute
the nth weight on the fly in the fixed-function transformation pipeline,
implying that the ARB_vertex_blend spec may require a fix. For the
purposes of this extension, the WEIGHT_SUM_UNITY_ARB enable is ignored
in vertex program mode. Applications performing a vertex weighting
operation in a vertex program are free to compute the extra weight in
the program.
(38) Should program environment parameters be pushed and popped?
RESOLVED: No. There is no need to push and pop this large set of
state, much like pixel maps. Adding a new attribute bit would have
complicated logistics (would the bit be included in ALL_ATTRIB_BITS?).
Having program local parameters provides a method for making localized
changes to certain state simply by switching programs.
(39) How should this extension interact with color material?
RESOLVED: When color material is enabled, any bindings of material
colors that track the current color should be updated when the current
color is updated. In this specification, material properties can be
bound only as program parameters, and any changes to the material
properties inside a Begin/End leave the bindings undefined until the
next End command. Similarly, any indirect changes to the material
properties (through ColorMaterial) will have a similar effect.
Several other options were considered here. One option was to support
per-vertex material property bindings and have programs that reference
tracked material properties should get the current color. This could be
handled either by broadcasting the current color to multiple vertex
attributes, or recompiling the vertex program so that references to a
tracked material property are redirected to the vertex color. Both such
solutions are somewhat complex. A second option would be to ignore the
COLOR_MATERIAL enable and instead use an "old" material color. This
breaks the standard color material model. Implementations can and often
do defer such updates (making an "old" color available), some conditions
may cause an implementation to update of material state at odd times.
(41) What about when the execution environment involves support for other
extensions? In particular, the execution environment subsumes some
functionality from EXT/ARB_point_parameters, EXT_fog_coord,
EXT_secondary_color, and ARB_multitexture.
RESOLVED: This extension assumes support for functionality that
includes a fog coordinate, secondary color, per-vertex point sizes, and
multiple texture coordinates (at least to the extent that it exposes >1
texture coordinate). All of these extensions are supported fairly
widely. On some platforms, some of this functionality may require
software fallbacks.
(42) How does PointSize work with vertex programs?
RESOLVED: If VERTEX_PROGRAM_POINT_SIZE_ARB is disabled, the size of
points is determined by the PointSize state and is not attenuated, even
if EXT_point_parameters is supported. If enabled, the point size is the
point size result value, and is clamped to implementation-dependent
point size limits during point rasterization.
(43) What do we say about the alpha component of the secondary color?
RESOLVED: The alpha component of the secondary color has generally been
treated as zero. This extension specifies that only the R, G, and B
components are added in the color sum operation, making the alpha
component of the secondary color irrelevant. Other downstream
extensions may allow applications to make use of this component.
(44) How are edge flags handled?
RESOLVED: Edge flags are passed through without the ability to be
modified by a vertex program. Applications are free to send edge flags
when vertex program mode is enabled.
(45) Should programs be C-style null-terminated strings?
RESOLVED: No. Programs should be specified as an array of GLubyte with
an explicit length parameter. OpenGL has no precedent for passing
null-terminated strings into the API (though GetString returns
null-terminated strings). Null-terminated strings may be problematic
for some programming languages.
(46) Should all existing OpenGL transform functionality and extensions be
implementable as vertex programs?
RESOLVED: Yes. Vertex programs should be a complete superset of what
you can do with OpenGL 1.2 and existing vertex transform extensions. To
implement EXT_point_parameters, the VERTEX_PROGRAM_POINT_SIZE_ARB enable
is introduced. To implement two-sided lighting, the
VERTEX_PROGRAM_TWO_SIDE_ARB enable is introduced. To implement color
material, applications should refer to the per-vertex color attribute in
their vertex programs.
(47) Should there be a plural version of ProgramEnvParameter and
ProgramLocalParameter, which would set multiple parameters in a single
call?
RESOLVED: No; not necessary.
(48) Can the currently bound vertex program object be deleted or reloaded?
RESOLVED: Yes. When ProgramStringARB is called to reload a program
object, subsequent program executions will use the new program. When
DeleteProgramsARB deletes a currently bound program object, object zero
becomes the new current program object.
(49) What happens if you transform vertices in vertex program mode, but
the current program object does not contain a valid vertex program?
RESOLVED: Begin will fail with an INVALID_OPERATION error if the
currently bound vertex program object does not have a valid program.
The same applies to RasterPos and any command (Rect, DrawArrays,
DrawElements) that implies a Begin.
Because Vertex is ignored outside of a Begin/End pair (without
generating an error) it is impossible to provoke a vertex program if the
current vertex program object is nonexistent or invalid. Other
per-vertex parameters (for examples those set by Color, Normal, and
VertexAttrib*ARB when the attribute number is not zero) are allowed
since they are legal outside of a Begin/End.
(50) Discussing matrices is confusing because of row-major versus
column-major issues. Can you give an example of how a matrix is bound?
RESOLVED: Assume program matrix zero were loaded with the following
code:
// When loaded, the first row is "1, 2, 3, 4", because of column-major
// (OpenGL spec) vs. row-major (C) differences.
GLfloat matrix[16] = { 1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
4, 8, 12, 16 };
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(matrix);
Then in the program
!!ARBvp1.0
PARAM mat1[4] = { state.matrix.program[0] };
PARAM mat2[4] = { state.matrix.program[0].transpose };
mat1[0] would have (1,2,3,4), mat1[3] would have (13,14,15,16), mat2[0]
would have (1,5,9,13), and mat2[3] would have (4,8,12,16).
(51) Should the new vertex program-related enables push/pop with
ENABLE_BIT?
RESOLVED: Yes. Pushing and popping enable bits is easy.
(52) Should all the vertex attribute state push/pop with CURRENT_BIT?
RESOLVED: Yes.
(53) Should all the vertex attrib vertex array state push/pop with
CLIENT_VERTEX_ARRAY_BIT?
RESOLVED: Yes.
(55) Should we generate an INVALID_VALUE operation if updating a vertex
attribute greater than MAX_VERTEX_ATTRIBS_ARB?
RESOLVED: Yes. The other option would be to leave the behavior
undefined, as with MultiTexCoord() functions. An implementation could
mask or modulo the vertex attribute index with MAX_VERTEX_ATTRIB_ARB if
it were a power of two. This error check will be a minor performance
issue with VertexAttrib*ARB() and VertexAttribArrayARB() calls. There
will be no per-vertex overhead when using vertex arrays or display
lists.
(56) Should writes to program environment or local parameters during a
vertex program be supported?
RESOLVED. No. Writes to program parameter registers from within a
vertex program would require the execution of vertex programs to be
serialized with respect to each other. This would create a severe
implementation penalty for pipelined or parallel vertex program
execution implementations.
(58) Should program objects be shared among rendering contexts in the same
manner as display lists and texture objects?
RESOLVED: Yes.
(60) Should there be a MatrixMode or ActiveTexture-style selector for
vertex attributes?
RESOLVED: No. While this would reduce the number of enumerants used by
this extensions, it would create programming a hassle in lots of cases.
Consider having to change the vertex attribute mode to enable a set of
vertex arrays.
(61) How should queries of vertex attribute arrays work?
RESOLVED: Add new get commands. Using the existing calls would require
adding 6 sets of 16+ enumerants for current state and vertex attribute
array state. That's too many new enumerants. Instead, add
GetVertexAttribARB and GetVertexAttribPointervARB. GetVertexAttribARB
will be used to query vertex attribute array state and the current
values of the generic vertex attributes. Get and GetPointerv will not
return vertex attribute array state and pointers.
(63) What should be said about rendering invariances?
RESOLVED: See the Appendix A additions below.
The justification for the two rules cited is to support multi-pass
rendering when using vertex programs. Different rendering passes will
likely use different programs so there must be some means of
guaranteeing that two different programs can generate particular
identical vertex results between different passes.
In practice, this does limit the type of vertex program implementations
that are possible.
For example, consider a limited hardware implementation of vertex
programs that uses a different floating-point implementation than the
CPU's floating-point implementation. If the limited hardware
implementation can only run small vertex programs (say the hardware
provides on 4 temporary registers instead of the required 12), the
implementation is incorrect and non-conformant if programs that only
require 4 temporary registers use the vertex program hardware, but
programs that require more than 4 temporary registers are implemented by
the CPU.
This is a very important practical requirement. Consider a multi-pass
rendering algorithm where one pass uses a vertex program that uses only
4 temporary registers, but a different pass uses a vertex program that
uses 5 temporary registers. If two programs have instruction sequences
that given the same input state compute identical resulting vertex
positions, the multi-pass algorithm should generate identically
positioned primitives for each pass. But given the non-conformant
vertex program implementation described above, this could not be
guaranteed.
This does not mean that schemes for splitting vertex program
implementations between dedicated hardware and CPUs are impossible. If
the CPU and dedicated vertex program hardware used IDENTICAL
floating-point implementations and therefore generated exactly identical
results, the above described could work.
While these invariance rules are vital for vertex programs operating
correctly for multi-pass algorithms, there is no requirement that
conventional OpenGL vertex transform mode will be invariant with vertex
program mode. A multi-pass algorithm should not assume that one pass
using vertex program mode and another pass using conventional GL vertex
transform mode will generate identically positioned primitives.
Consider that while the conventional OpenGL vertex program mode is
repeatable with itself, the exact procedure used to transform vertices
is not specified nor is the procedure's precision specified. The GL
specification indicates that vertex coordinates are transformed by the
modelview matrix and then transformed by the projection matrix. Some
implementations may perform this sequence of transformations exactly,
but other implementations may transform vertex coordinates by the
composite of the modelview and projection matrices (one matrix transform
instead of two matrix transforms in sequence). Given this
implementation flexibility, there is no way for a vertex program author
to exactly duplicate the precise computations used by the conventional
OpenGL vertex transform mode.
The guidance to OpenGL application programs is clear. If you are going
to implement multi-pass rendering algorithms that require certain
invariances between the multiple passes, choose either vertex program
mode or the conventional OpenGL vertex transform mode for your rendering
passes, but do not mix the two modes.
(64) Should there be a way to guarantee position invariance with respect
to conventional vertex transformation?
RESOLVED: Yes. The "OPTION ARB_position_invariant" program option
addresses this issue. This program option will be available on all
implementations of this extension.
John Carmack advocated the need for this.
(65) Why must RCP of 1.0 always be 1.0?
RESOLVED: This is important for 3D graphics so that non-projective
textures and orthogonal projections work as expected. Basically when q
or w is 1.0, things should work as expected. Stronger requirements such
as "RCP of -1.0 must always be -1.0" are encouraged, but there is no
compelling reason to state such requirements explicitly as is the case
for "RCP of 1.0 must always be 1.0".
(66) What happens when the source scalar value for the ARL instruction is
an extremely large positive or negative floating-point value? Is there a
problem mapping the value to a constrained integer range?
RESOLVED: In this extension, address registers are only useful for
relative addressing. The range of offsets that can be added to an
address register is limited (-64 to +63) and the set of valid array
indices is also limited to MAX_PROGRAM_PARAMETERS_ARB. So, the set of
floating-point values that needs to be handled properly is
well-constrained.
(67) How do you perform a 3-component normalize in three instructions?
RESOLVED: As follows.
DP3 result.w, vector, vector; # result.w = nx^2+ny^2+nz^2
RSQ result.w, result.w; # result.w = 1/sqrt(nx^2+ny^2+nz^2)
MUL result.xyz, result.w, vector;
(69) How do you compute the determinant of a 3x3 matrix in three
instructions?
RESOLVED: As follows.
#
# Determinant of | vec0.x vec0.y vec0.z | into result.
# | vec1.x vec1.y vec1.z |
# | vec2.x vec2.y vec2.z |
#
MUL result, vec1.zxyw, vec2.yzxw;
MAD result, vec1.yzxw, vec2.zxyw, -result;
DP3 result, vec0, result;
(70) How do you transform a vertex position by a 4x4 matrix and then
perform a homogeneous divide?
RESOLVED: As follows.
ATTRIB pos = vertex.position;
TEMP result, temp;
PARAM mat[4] = { state.matrix.modelview };
DP4 result.w, pos, mat[3];
DP4 result.x, pos, mat[0];
DP4 result.y, pos, mat[1];
DP4 result.z, pos, mat[2];
RCP temp.w, result.w;
MUL result, result, temp.w;
(71) How do you perform a vector weighting of two vectors using a single
weight?
RESOLVED: As follows.
# result = a * vec0 + (1-a) * vec1
# = vec1 + a * (vec0 - vec1)
SUB result, vec0, vec1;
MAD result, a, result, vec1;
(72) How do you reduce a value to some fundamental period such as 2*PI?
RESOLVED: As follows.
# result = 2*PI * fraction(in/(2*PI))
# piVec = (1/(2*PI), 2*PI, 0, 0)
PARAM piVec = { 0.159154943, 6.283185307, 0, 0 };
MUL result, in, piVec.x;
EXP result, result.x;
MUL result, result.y, piVec.y;
(73) How do you implement a simple ambient, specular, and diffuse infinite
lighting computation with a single light and an eye-space normal?
RESOLVED: As follows.
!!ARBvp1.0
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
PARAM mvinv[4] = { state.matrix.modelview.invtrans };
PARAM mvp[4] = { state.matrix.mvp };
PARAM lightDir = state.light[0].position;
PARAM halfDir = state.light[0].half;
PARAM specExp = state.material.shininess;
PARAM ambientCol = state.lightprod[0].ambient;
PARAM diffuseCol = state.lightprod[0].diffuse;
PARAM specularCol = state.lightprod[0].specular;
TEMP xfNormal, temp, dots;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
# Transform the vertex to clip coordinates.
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Transform the normal to eye coordinates.
DP3 xfNormal.x, mvinv[0], iNormal;
DP3 xfNormal.y, mvinv[1], iNormal;
DP3 xfNormal.z, mvinv[2], iNormal;
# Compute diffuse and specular dot products and use LIT to compute
# lighting coefficients.
DP3 dots.x, xfNormal, lightDir;
DP3 dots.y, xfNormal, halfDir;
MOV dots.w, specExp.x;
LIT dots, dots;
# Accumulate color contributions.
MAD temp, dots.y, diffuseCol, ambientCol;
MAD oColor.xyz, dots.z, specularCol, temp;
MOV oColor.w, diffuseCol.w;
END
(75) Can you perturb transformed vertex positions with a vertex program?
RESOLVED: Yes. Here is an example that performs an object-space
diffuse lighting computations and perturbs the vertex position based on
this lighting result. Do not take this example too seriously.
!!ARBvp1.0
#
# Program environment parameters:
# c[0].xyz = normalized light direction in object-space
#
# outputs diffuse illumination for color and perturbed position
#
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
PARAM mvp[4] = { state.matrix.mvp };
PARAM lightDir = program.env[0];
PARAM diffuseCol = { 1, 1, 0, 1 };
TEMP temp;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
DP3 temp, lightDir, iNormal;
MUL oColor.xyz, temp, diffuseCol;
MAX temp, temp, 0; # clamp dot product to zero
MUL temp, temp, iNormal; # align in direction of normal
MUL temp, temp, 0.125; # scale displacement by 1/8
SUB temp, temp, iPos; # perturb
DP4 oPos.x, mvp[0], temp; # xform using perturbed position
DP4 oPos.y, mvp[1], temp;
DP4 oPos.z, mvp[2], temp;
DP4 oPos.w, mvp[3], temp;
END
(76) Should this extension provide any method for updating program
parameters in a program itself?
RESOLVED: No. NV_vertex_program provided a special mechanism to do
this using a "vertex state program" manually executed by calling
ExecuteProgramNV. This capability has not proven itself particularly
useful to date.
(78) Should there be a different ProgramStringARB call for every distinct
program target? Arguably, 1D, 2D, and 3D textures each have their own
TexImage command for specifying their image data.
RESOLVED: No. All program objects can/should be loaded with
ProgramStringARB. We expect the string to be a sufficient to express
any kind of programmability.
Moreover, the 1D, 2D, and 3D TexImage commands describe the image being
specified as opposed to the texture target being updated. With cube map
textures, there are six face texture targets that use the TexImage2D
command but not with the TEXTURE_2D target.
(79) This extension introduces a collection of new matrices for use by
vertex programs (and possibly other programs as well). What should these
matrices be called?
RESOLVED: Program matrices. These matrices are referred to as
"tracking matrices" in NV_vertex_program, but the functionality is
equivalent.
(80) With ARB_vertex_blend and EXT_vertex_weighting, there are multiple
modelview matrices. This extension provides a single "MVP" matrix,
defined to be the product of modelview matrix 0 and the projection
matrices. Should this extension instead provide one MVP matrix per
modelview matrix?
RESOLVED: No. Providing multiple MVP matrices allows applications to
do N transformations into clip space and then one weighting operation,
instead of N transformations into eye space, a weighting operation, and
then a single transformation into clip space. This would potentially
save instructions, but this optimization would be of no value if the
program did any other operations that required eye coordinates.
Note also that the MVP transformations are likely general 4x4 matrix
multiplies (4 DP4 instructions per transform). On the other hand,
object and eye coordinates are often 3D coordinates with a constant W of
1.0. So each transformation to eye coordinates may require only 3 DP4
instructions, in which case the comparison may be 4N instructions (clip
weighting) vs. 3N+4 (eye weighting).
(81) Should variable declarations be allowed to be anywhere within the
program body, or should they instead be required to be done at the
beginning of the program? Should the possibility of branching in a future
standard affect this resolution?
RESOLVED: Declarations will be allowed anywhere in the program text;
the only ordering requirement is that the declaration of a variable must
precede its use in the program text. Requiring up-front variable
declarations may require multiple passes for applications that build
programs on the fly.
While declarations can appear anywhere in the program body, they are not
executable statements. Any corresponding bindings (including constant
initializations) are resolved before the program executes. The bindings
will be resolved even if a program were to "branch around" a
declaration.
(82) Should address register variables be treated as vectors? If so,
should a variable number of components (up to four) be supported by this
extension?
RESOLVED: In the future, four-component address vectors may be
supported, and vector notation is used for forward compatibility. Using
this notation makes address registers consistent with all the other
vector data types in this extension. However, support for more than one
usable component will be left for future extensions, but could be added
via a program option or in a new language revision (e.g., !!ARBvp2.0).
(83) Should program local parameters be logically connected to the program
string or the program object?
RESOLVED: Program local parameters are properties of a program object.
Their values persist even after a new program is loaded into the object.
This model does allow applications to recompile the program in a given
object based on certain rendering settings without having to
re-initialize any state stored in the object.
(84) Should this extension provide a method to specify "anonymous" program
local parameters and query an index into the program parameter array.
RESOLVED: No. It would be nice to declare a variable in a program such
as
PARAM foo = program.local; # note no index in the array
after which an application could query the location of "foo" in the
program local parameter array. However, given that local parameters
persist even across program loads, it would be difficult to specify what
program local parameter "foo" would be assigned to.
(85) EXT_vertex_weighting provides a single vertex blend weight.
ARB_vertex_blend generalizes this concept to a weight vector. Both pieces
of state are specified separately, and could be thought of as distinct.
Should distinct bindings be provided in this extension?
RESOLVED: No. No current implementation supports both extensions, but
the vendors involved in this standardization process agree that the
state should not be considered distinct. If an implementation supported
both extensions, the APIs would modify the same state.
(86) Should this extension provide functionality for variable aliasing?
If so, how should it be specified and what types of variables can be
aliasesed?
RESOLVED: Yes, for all variable types. The syntax is a simple text
replacement:
ALIAS a = b;
This functionality allows applications to "share" variables, and thereby
exceed implementation-dependent limits on the number of variable
declarations. This may be particularly significant for temporaries,
where the limit on the number of variables may be fairly low.
(87) How do you determine whether a given program option is supported by
the GL implementation?
RESOLVED: Program options may be introduced in OpenGL extensions and
may be added to future OpenGL specifications. An option will be
supported if and only if (1) the corresponding OpenGL extension appears
in the implementation-dependent EXTENSIONS string or (2) the option is
documented in the OpenGL specification version corresponding to the
implementation's VERSION string.
The ARB_position_invariant option is provided by this extension, and
will always be available (provided this extension is supported).
(88) What's the deal with binding the alpha component of light colors, fog
colors, and material colors (other than diffuse)? They don't do anything,
right?
RESOLVED: The GL state for these different colors includes alpha
components, which will be returned by queries. However, in the
conventional OpenGL pipeline, most of these alpha components are
effectively ignored. However, since they are present in the GL state,
they will be exposed in bindings. What is done with these alpha values
in program mode is completely up to the vertex program.
Vertex programs need to be careful to ensure that the alpha component is
computed correctly when evaluating lighting equations. When
accumulating light contributions, it may be necessary to use write masks
to disable writes to the alpha component.
(89) The LOG instruction takes the logarithm of the absolute value of its
operand while the LG2 instruction takes the logarithm of the operand
itself. In LG2, the logarithm of negative numbers is undefined.
RESOLVED: The LOG instruction is present for (1) compatibility with
NV_vertex_program and DirectX 8 languages and (2) because it may
outperform LG2 on some platforms. For compatibility, it is defined to
behave identically to existing languages.
(90) With vertex programs, fog coordinates and point sizes can be computed
on a per-vertex basis. How are the fog coordinates and point sizes
associated with vertices introduced by clipping computed?
RESOLVED: Fog coordinates and point sizes for clipped vertices are
computed by interpolating the computed values at the original vertices
in exactly the same manner as colors and texture coordinates are
interpolated in section 2.13.8 of the OpenGL 1.3 specification.
(91) Vertex programs support only RGBA colors, but do not support color
index inputs or results. What happens if an application uses vertex
programs in color index mode.
RESOLVED: The results of vertex program execution are undefined if the
GL is in color index mode.
(92) Should automatic normalization of evaluated normals (AUTO_NORMAL) be
supported when the GL is in vertex program mode?
RESOLVED: Automatic normalization of normals will be disabled in vertex
program mode. The current vertex program can easily normalize the
normal if required. This can lead to greater efficiency if the vertex
program transforms the normal to another coordinate system such as
eye-space with a transform that preserves vector length. Then a single
normalize after transform is more efficient than normalizing after
evaluation and normalizing again after transform. Conceptually, the
normalize mandated for AUTO_NORMAL in section 5.1 is just one of the
many transformation operations subsumed by vertex programs.
(93) This extension allows applications to name their own variables. What
keywords should be reserved?
RESOLVED: Instruction names and declaration keywords (e.g., PARAM) will
be reserved. Additionally, since attribute, parameter, and result
bindings are allowed in the program text, the binding prefix keywords
"vertex", "state", "program", and "result" are reserved to simplify
parsing. This prevents the need to distinguish between
"vertex.position" ("vertex" as a binding) and "vertex.xyzw" ("vertex" as
a variable).
(94) When counting the number of program parameter bindings, multiple
constant vectors with the same components are counted only once. How is
this determined?
RESOLVED: The implementation does a numerical comparison after the
specified constants are converted to an internal floating-point
representation. Due to floating-point representation limits, such
conversions are not always precise. Constants specified with different
text that are "equivalent" (e.g., "12" and "1.2E+01") are not guaranteed
to resolve to the same value. Additionally, constants that are not
"equivalent" but have only small relative differences (e.g., "200000000"
and "200000001") may end up resolving to the same value. Constants
specified with the same text should always be identical.
(95) What characters are allowed in identifier names?
RESOLVED: Letters ("A"-"Z", "a"-"z"), numbers ("0"-"9"), underscores
("_"), and dollar signs ("$").
(96) How should future programmability extensions interact with this one?
RESOLVED: Future programmability extensions are expected to fall in one
of two classes: (1) extensions that bring programmability to new
sections and (2) extensions the extend existing programmability models.
The former class should introduce a new program target; the latter class
would extend the functionality of an existing target.
Recommendations for extensions introducing new program targets include:
* Re-use and reference the functionality specified in this extension
(or in a future OpenGL specification incorporating this extension)
as much as possible, to maintain a consistent model.
* Provide a program header allowing for easy identification and
versioning of programs for the new target.
Recommendations for extensions modifying existing program targets
include:
* The option mechanism (section 2.14.4.5) should be used to provide
minor modifications to the program language.
* The program header/version string (section 2.14.2) should be used to
provide major modifications to the language, or potentially to
provide a commonly used collection of options. Program header
string changes should be multi-vendor extensions as much as
possible.
* For portability, programs should not be allowed to use extended
language features without specifying the corresponding program
options or program header.
New Procedures and Functions
void VertexAttrib1sARB(uint index, short x);
void VertexAttrib1fARB(uint index, float x);
void VertexAttrib1dARB(uint index, double x);
void VertexAttrib2sARB(uint index, short x, short y);
void VertexAttrib2fARB(uint index, float x, float y);
void VertexAttrib2dARB(uint index, double x, double y);
void VertexAttrib3sARB(uint index, short x, short y, short z);
void VertexAttrib3fARB(uint index, float x, float y, float z);
void VertexAttrib3dARB(uint index, double x, double y, double z);
void VertexAttrib4sARB(uint index, short x, short y, short z, short w);
void VertexAttrib4fARB(uint index, float x, float y, float z, float w);
void VertexAttrib4dARB(uint index, double x, double y, double z, double w);
void VertexAttrib4NubARB(uint index, ubyte x, ubyte y, ubyte z, ubyte w);
void VertexAttrib1svARB(uint index, const short *v);
void VertexAttrib1fvARB(uint index, const float *v);
void VertexAttrib1dvARB(uint index, const double *v);
void VertexAttrib2svARB(uint index, const short *v);
void VertexAttrib2fvARB(uint index, const float *v);
void VertexAttrib2dvARB(uint index, const double *v);
void VertexAttrib3svARB(uint index, const short *v);
void VertexAttrib3fvARB(uint index, const float *v);
void VertexAttrib3dvARB(uint index, const double *v);
void VertexAttrib4bvARB(uint index, const byte *v);
void VertexAttrib4svARB(uint index, const short *v);
void VertexAttrib4ivARB(uint index, const int *v);
void VertexAttrib4ubvARB(uint index, const ubyte *v);
void VertexAttrib4usvARB(uint index, const ushort *v);
void VertexAttrib4uivARB(uint index, const uint *v);
void VertexAttrib4fvARB(uint index, const float *v);
void VertexAttrib4dvARB(uint index, const double *v);
void VertexAttrib4NbvARB(uint index, const byte *v);
void VertexAttrib4NsvARB(uint index, const short *v);
void VertexAttrib4NivARB(uint index, const int *v);
void VertexAttrib4NubvARB(uint index, const ubyte *v);
void VertexAttrib4NusvARB(uint index, const ushort *v);
void VertexAttrib4NuivARB(uint index, const uint *v);
void VertexAttribPointerARB(uint index, int size, enum type,
boolean normalized, sizei stride,
const void *pointer);
void EnableVertexAttribArrayARB(uint index);
void DisableVertexAttribArrayARB(uint index);
void ProgramStringARB(enum target, enum format, sizei len,
const void *string);
void BindProgramARB(enum target, uint program);
void DeleteProgramsARB(sizei n, const uint *programs);
void GenProgramsARB(sizei n, uint *programs);
void ProgramEnvParameter4dARB(enum target, uint index,
double x, double y, double z, double w);
void ProgramEnvParameter4dvARB(enum target, uint index,
const double *params);
void ProgramEnvParameter4fARB(enum target, uint index,
float x, float y, float z, float w);
void ProgramEnvParameter4fvARB(enum target, uint index,
const float *params);
void ProgramLocalParameter4dARB(enum target, uint index,
double x, double y, double z, double w);
void ProgramLocalParameter4dvARB(enum target, uint index,
const double *params);
void ProgramLocalParameter4fARB(enum target, uint index,
float x, float y, float z, float w);
void ProgramLocalParameter4fvARB(enum target, uint index,
const float *params);
void GetProgramEnvParameterdvARB(enum target, uint index,
double *params);
void GetProgramEnvParameterfvARB(enum target, uint index,
float *params);
void GetProgramLocalParameterdvARB(enum target, uint index,
double *params);
void GetProgramLocalParameterfvARB(enum target, uint index,
float *params);
void GetProgramivARB(enum target, enum pname, int *params);
void GetProgramStringARB(enum target, enum pname, void *string);
void GetVertexAttribdvARB(uint index, enum pname, double *params);
void GetVertexAttribfvARB(uint index, enum pname, float *params);
void GetVertexAttribivARB(uint index, enum pname, int *params);
void GetVertexAttribPointervARB(uint index, enum pname, void **pointer);
boolean IsProgramARB(uint program);
New Tokens
Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, by the
<pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev,
and by the <target> parameter of ProgramStringARB, BindProgramARB,
ProgramEnvParameter4[df][v]ARB, ProgramLocalParameter4[df][v]ARB,
GetProgramEnvParameter[df]vARB, GetProgramLocalParameter[df]vARB,
GetProgramivARB, and GetProgramStringARB.
VERTEX_PROGRAM_ARB 0x8620
Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, and by
the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and
GetDoublev:
VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
COLOR_SUM_ARB 0x8458
Accepted by the <format> parameter of ProgramStringARB:
PROGRAM_FORMAT_ASCII_ARB 0x8875
Accepted by the <pname> parameter of GetVertexAttrib[dfi]vARB:
VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
CURRENT_VERTEX_ATTRIB_ARB 0x8626
Accepted by the <pname> parameter of GetVertexAttribPointervARB:
VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
Accepted by the <pname> parameter of GetProgramivARB:
PROGRAM_LENGTH_ARB 0x8627
PROGRAM_FORMAT_ARB 0x8876
PROGRAM_BINDING_ARB 0x8677
PROGRAM_INSTRUCTIONS_ARB 0x88A0
MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
PROGRAM_TEMPORARIES_ARB 0x88A4
MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
PROGRAM_PARAMETERS_ARB 0x88A8
MAX_PROGRAM_PARAMETERS_ARB 0x88A9
PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
PROGRAM_ATTRIBS_ARB 0x88AC
MAX_PROGRAM_ATTRIBS_ARB 0x88AD
PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
Accepted by the <pname> parameter of GetProgramStringARB:
PROGRAM_STRING_ARB 0x8628
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
PROGRAM_ERROR_POSITION_ARB 0x864B
CURRENT_MATRIX_ARB 0x8641
TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
MAX_VERTEX_ATTRIBS_ARB 0x8869
MAX_PROGRAM_MATRICES_ARB 0x862F
MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
Accepted by the <name> parameter of GetString:
PROGRAM_ERROR_STRING_ARB 0x8874
Accepted by the <mode> parameter of MatrixMode:
MATRIX0_ARB 0x88C0
MATRIX1_ARB 0x88C1
MATRIX2_ARB 0x88C2
MATRIX3_ARB 0x88C3
MATRIX4_ARB 0x88C4
MATRIX5_ARB 0x88C5
MATRIX6_ARB 0x88C6
MATRIX7_ARB 0x88C7
MATRIX8_ARB 0x88C8
MATRIX9_ARB 0x88C9
MATRIX10_ARB 0x88CA
MATRIX11_ARB 0x88CB
MATRIX12_ARB 0x88CC
MATRIX13_ARB 0x88CD
MATRIX14_ARB 0x88CE
MATRIX15_ARB 0x88CF
MATRIX16_ARB 0x88D0
MATRIX17_ARB 0x88D1
MATRIX18_ARB 0x88D2
MATRIX19_ARB 0x88D3
MATRIX20_ARB 0x88D4
MATRIX21_ARB 0x88D5
MATRIX22_ARB 0x88D6
MATRIX23_ARB 0x88D7
MATRIX24_ARB 0x88D8
MATRIX25_ARB 0x88D9
MATRIX26_ARB 0x88DA
MATRIX27_ARB 0x88DB
MATRIX28_ARB 0x88DC
MATRIX29_ARB 0x88DD
MATRIX30_ARB 0x88DE
MATRIX31_ARB 0x88DF
Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation)
Modify Section 2.6, Begin/End Paradigm (p. 12)
(modify last paragraph, p. 12) ... In addition, a current normal, a
current color, multiple current texture coordinate sets, and multiple
generic vertex attributes may be used in processing each vertex. Normals
are used by the GL in lighting calculations; the current normal is a
three-dimensional vector that may be set by sending three coordinates that
specify it. Texture coordinates determine how a texture image is mapped
onto a primitive. Multiple sets of texture coordinates may be used to
specify how multiple texture images are mapped onto a primitive. Generic
vertex attributes do not have any specific function but can be used in
vertex program mode (section 2.14) to compute final values for any data
associated with a vertex.
Modify Section 2.6.3, GL Commands within Begin/End (p. 19)
(modify first paragraph of section, p. 19) The only GL commands that are
allowed within any Begin/End pairs are the commands for specifying vertex
coordinates, vertex color, normal coordinates, texture coordinates, and
generic vertex attributes (Vertex, Color, Index, Normal, TexCoord,
VertexAttrib*ARB), ...
Modify Section 2.7, Vertex Specification (p. 19)
(remove the "Finally" from the next-to-last paragraph, p. 20) There are
several ways to set the current color. The GL stores both a current
single-valued color index, and a current four-valued RGBA color. One
(add new paragraph before last paragraph of section, p. 21) Vertex
programs (section 2.14) can access an array of four-component generic
current vertex attributes. The first entry of this array is numbered
zero, and the number of entries in the array is given by the
implementation-dependent constant MAX_VERTEX_ATTRIBS_ARB. The commands
void VertexAttrib{1234}{sfd}ARB(uint index, T coords);
void VertexAttrib{123}{sfd}vARB(uint index, T coords);
void VertexAttrib4{bsifd ubusui}vARB(uint index, T coords);
specify the current vertex attribute numbered <index>, whose components
are named <x>, <y>, <z>, and <w>. The VertexAttrib1ARB family of commands
sets the <x> coordinate to the provided single argument while setting <y>
and <z> to 0 and <w> to 1. Similarly, VertexAttrib2ARB commands set <x>
and <y> to the specified values, <z> to 0 and <w> to 1; VertexAttrib3ARB
commands set <x>, <y>, and <z>, with <w> set to 1, and VertexAttrib4ARB
commands set all four coordinates. The error INVALID_VALUE is generated
if <index> is greater than or equal to MAX_VERTEX_ATTRIBS_ARB.
The commands
void VertexAttrib4NubARB(uint index, T coords);
void VertexAttrib4N{bsi ubusui}vARB(uint index, T coords);
also specify vertex attributes with fixed-point coordinates that are
scaled to the range [0,1] or [-1,1], according to Table 2.6.
Setting generic vertex attribute zero specifies a vertex; the four vertex
coordinates are taken from the values of attribute zero. A Vertex2,
Vertex3, or Vertex4 command is completely equivalent to the corresponding
VertexAttrib command with an index of zero. Setting any other generic
vertex attribute updates the current values of the attribute. There are
no current values for vertex attribute zero.
Implementations may, but do not necessarily, use the same storage for the
current values of generic and certain conventional vertex attributes.
When any generic vertex attribute other than zero is specified, the
current values for the corresponding conventional attribute in Table X.1
become undefined. Additionally, when a conventional vertex attribute is
specified, the current values for the corresponding generic vertex
attribute in Table X.1 become undefined. For example, setting the current
normal will leave generic vertex attribute 2 undefined, and vice versa.
Generic
Attribute Conventional Attribute Conventional Attribute Command
--------- ------------------------ ------------------------------
0 vertex position Vertex
1 vertex weights 0-3 WeightARB, VertexWeightEXT
2 normal Normal
3 primary color Color
4 secondary color SecondaryColorEXT
5 fog coordinate FogCoordEXT
6 - -
7 - -
8 texture coordinate set 0 MultiTexCoord(TEXTURE0, ...)
9 texture coordinate set 1 MultiTexCoord(TEXTURE1, ...)
10 texture coordinate set 2 MultiTexCoord(TEXTURE2, ...)
11 texture coordinate set 3 MultiTexCoord(TEXTURE3, ...)
12 texture coordinate set 4 MultiTexCoord(TEXTURE4, ...)
13 texture coordinate set 5 MultiTexCoord(TEXTURE5, ...)
14 texture coordinate set 6 MultiTexCoord(TEXTURE6, ...)
15 texture coordinate set 7 MultiTexCoord(TEXTURE7, ...)
8+n texture coordinate set n MultiTexCoord(TEXTURE0+n, ...)
Table X.1, Generic and Conventional Vertex Attribute Mappings. For each
row, the current value of the conventional attribute becomes undefined
when the corresponding generic attribute is set, and vice versa.
Attribute zero corresponds to the vertex position and has no current
state.
Setting any conventional vertex attribute not listed in Table X.1
(including vertex weights 4 and above, if supported) will not cause any
generic vertex attribute to become undefined, and such attributes will not
become undefined when any generic vertex attribute is set.
(modify the last paragraph in the section, p.21) The state required to
support vertex specification consists of four floating-point numbers per
texture unit to store the current texture coordinates s, t, r, and q,
three floating-point numbers to store the three coordinates of the current
normal, four floating-point values to store the current RGBA color, one
floating-point value to store the current color index, and
MAX_VERTEX_ATTRIBS_ARB-1 four-component floating-point vectors for generic
vertex attributes. There is no notion of a current vertex, so no state is
devoted to vertex coordinates or vertex attribute zero. The initial
texture coordinates are (S,T,R,Q) = (0,0,0,1) for each texture unit. The
initial current normal has coordinates (0,0,1). The initial RGBA color is
(R,G,B,A) = (1,1,1,1). The initial color index is 1. The initial values
for all generic vertex attributes are undefined.
Modify Section 2.8, Vertex Arrays (p. 21)
(modify first paragraph of section, p.21) The vertex specification
commands described in section 2.7 accept data in almost any format, but
their use requires many command executions to specify even simple
geometry. Vertex data may also be placed into arrays that are stored in
the client's address space. Blocks of data in these arrays may then be
used to specify multiple geometric primitives through the execution of a
single GL command. The client may specify up to 5 plus the values of
MAX_TEXTURE_UNITS and MAX_VERTEX_ATTRIBS_ARB arrays: one each to store
vertex coordinates, edge flags, colors, color indices, normals, one or
more texture coordinate sets, and one or more generic vertex attributes.
The commands
...
void VertexAttribPointerARB(uint index, int size, enum type,
boolean normalized, sizei stride,
const void *pointer);
describe the locations and organizations...
(add after the first paragraph, p.22) The <index> parameter in the
VertexAttribPointer command identifies the generic vertex attribute array
being described. The error INVALID_VALUE is generated if <index> is
greater than or equal to MAX_VERTEX_ATTRIBS_ARB. The <normalized>
parameter in the VertexAttribPointer command identifies whether
fixed-point types should be normalized when converted to floating-point.
If <normalized> is TRUE, fixed-point data are converted as specified in
Table 2.6; otherwise, the fixed-point values are converted directly.
(add after first paragraph, p.23) An individual generic vertex attribute
array is enabled or disabled by calling one of
void EnableVertexAttribArrayARB(uint index);
void DisableVertexAttribArrayARB(uint index);
where <index> identifies the generic vertex attribute array to enable or
disable. The error INVALID_VALUE is generated if <index> is greater than
or equal to MAX_VERTEX_ATTRIBS_ARB.
(modify Table 2.4, p.23)
Normal
Command Sizes ized? Types
---------------------- ------- ------ --------------------------------
VertexPointer 2,3,4 no short, int, float, double
NormalPointer 3 yes byte, short, int, float, double
ColorPointer 3,4 yes byte, ubyte, short, ushort,
int, uint, float, double
IndexPointer 1 no ubyte, short, int, float, double
TexCoordPointer 1,2,3,4 no short, int, float, double
EdgeFlagPointer 1 no boolean
VertexAttribPointerARB 1,2,3,4 flag byte, ubyte, short, ushort,
int, uint, float, double
WeightPointerARB >=1 yes byte, ubyte, short, ushort,
int, uint, float, double
VertexWeightPointerEXT 1 n/a float
SecondaryColor- 3 yes byte, ubyte, short, ushort,
PointerEXT int, uint, float, double
FogCoordPointerEXT 1 n/a float, double
MatrixIndexPointerARB >=1 no ubyte, ushort, uint
Table 2.4: Vertex array sizes (values per vertex) and data types. The
"normalized" column indicates whether fixed-point types are accepted
directly or normalized to [0,1] (for unsigned types) or [-1,1] (for
singed types). For generic vertex attributes, fixed-point data are
normalized if and only if the <normalized> flag is set.
(modify last paragraph, p.23) The command
void ArrayElement(int i);
transfers the ith element of every enabled array to the GL. The effect of
ArrayElement(i) is the same as the effect of the command sequence
if (ARB_vertex_blend vertex weight array enabled) {
Weight[type]vARB(vertex weight array size,
vertex weight array element i);
}
if (EXT_vertex_weighting vertex weight array enabled) {
VertexWeight[type]vARB(vertex weight array element i);
}
if (normal array enabled) {
Normal3[type]v(normal array element i);
}
if (color array enabled) {
Color[size][type]v(color array element i);
}
if (secondary color array enabled) {
SecondaryColor3[type]vEXT(secondary color array element i);
}
if (fog coordinate array enabled) {
FogCoord[type]vEXT(fog coordinate array element i);
}
if (matrix index array enabled) {
MatrixIndex[type]vARB(matrix index array size,
matrix index array element i);
}
for (j = 0; j < textureUnits; j++) {
if (texture coordinate set j array enabled) {
MultiTexCoord[size][type]v(TEXTURE0 + j,
texture coordinate set j
array element i);
}
if (color index array enabled) {
Index[type]v(color index array element i);
}
if (edge flag array enabled) {
EdgeFlagv(edge flag array element i);
}
for (j = 1; j < genericAttributes; j++) {
if (generic vertex attribute j array enabled) {
if (generic vertex attribute j array normalization flag
is set, and type is not FLOAT or DOUBLE) {
VertexAttrib[size]N[type]vARB(j, generic vertex attribute j
array element i);
} else {
VertexAttrib[size][type]vARB(j, generic vertex attribute j
array element i);
}
}
}
if (generic attribute array 0 enabled) {
if (generic vertex attribute j array normalization flag
is set, and type is not FLOAT or DOUBLE) {
VertexAttrib[size]N[type]vARB(0, generic vertex attribute 0
array element i);
} else {
VertexAttrib[size][type]vARB(0, generic vertex attribute 0
array element i);
}
} else if (vertex array enabled) {
Vertex[size][type]vARB(vertex array element i);
}
where <textureUnits> and <genericAttributes> give the number of texture
units and generic vertex attributes supported by the implementation,
respectively. "[size]" and "[type]" correspond to the size and type of
the corresponding array. For generic vertex attributes, it is assumed
that a complete set of vertex attribute commands exists, even though not
all such functions are provided by the GL. Both generic attribute array
zero and the vertex array can specify a vertex if enabled, but only one
such array is used. As described in section 2.7, setting a generic vertex
attributes listed in Table X.1 will leave the corresponding conventional
vertex attribute undefined, and vice versa.
(modify last paragraph of section, p.28) If the number of supported
texture units (the value of MAX TEXTURE UNITS) is m and the number of
supported generic vertex attributes (MAX_VERTEX_ATTRIBS_ARB) is n, then
the client state required to implement vertex arrays consists of 5+m+n
boolean enables, 5+m+n memory pointers, 5+m+n integer stride values, 4+m+n
symbolic constants representing array types, 2+m+n integers representing
values per element, and n boolean normalization flags. In the initial
state, the enable values are each disabled, the memory pointers are each
null, the strides are each zero, the array types are each FLOAT, the
integers representing values per element are each four, and the
normalization flags are disabled..
Modify Section 2.10, Coordinate Transformations (p. 29)
(add new paragraphs) Vertex attributes are transformed before the vertex
is used to generate primitives for rasterization, establish a raster
position, or generate vertices for selection or feedback. The attributes
of each vertex are transformed using one of two vertex transformation
modes. The first mode, described in this and subsequent sections, is GL's
conventional vertex transformation model. The second mode, known as
vertex program mode and described in section 2.14, transforms vertex
attributes as specified in an application-supplied vertex program.
Vertex program mode is enabled and disabled, respectively, by
void Enable(enum target);
and
void Disable(enum target);
with <target> equal to VERTEX_PROGRAM_ARB. When vertex program mode is
enabled, vertices are transformed by the currently bound vertex program as
discussed in section 2.14.
When vertex program mode is disabled, vertices, normals, and texture
coordinates are transformed before their coordinates are used to produce
an image in the framebuffer. We begin with a description of how vertex
coordinates are transformed and how the transformation is controlled in
this case. The discussion that continues through section 2.13 applies
when vertex program mode is disabled.
Modify Section 2.10.2, Matrices (p. 31)
(modify 1st paragraph) The projection matrix and model-view matrix are set
and modified with a variety of commands. The affected matrix is
determined by the current matrix mode. The current matrix mode is set
with
void MatrixMode(enum mode);
which takes one of the pre-defined constants TEXTURE, MODELVIEW, COLOR,
PROJECTION, or MATRIX<i>_ARB as the argument. In the case of
MATRIX<i>_ARB, <i> is an integer between 0 and <n>-1 indicating one of <n>
program matrices where <n> is the value of the implementation defined
constant MAX_PROGRAM_MATRICES_ARB. Such program matrices are described in
section 2.14.6. TEXTURE is described later in section 2.10.2, and COLOR
is described in section 3.6.3. If the current matrix mode is MODELVIEW,
then matrix operations apply to the model-view matrix; if PROJECTION, then
they apply to the projection matrix.
(modify last paragraph of section) The state required to implement
transformations consists of a <n>-value integer indicating the current
matrix mode (where <n> is 4 + the number of supported texture and program
matrices), a stack of at least two 4x4 matrices for each of COLOR,
PROJECTION, and TEXTURE with associated stack pointers, <n> stacks (where
<n> is at least 8) of at least one 4x4 matrix for each MATRIX<i>_ARB with
associated stack pointers, and a stack of at least 32 4x4 matrices with an
associated stack pointer for MODELVIEW. Initially, there is only one
matrix on each stack, and all matrices are set to the identity. The
initial matrix mode is MODELVIEW. The initial value of ACTIVE_TEXTURE is
TEXTURE0.
Modify Section 2.11, Clipping (p. 39)
(add to end of next-to-last paragraph, p. 40) ... User clipping is not
supported in vertex program mode if the current program is not
position-invariant (section 2.14.4.5.1). In this case, client-defined
clip planes are always treated as disabled.
Modify Section 2.12, Current Raster Position (p. 42)
(modify fourth paragraph, p.42) The coordinates are treated as if they
were specified in a Vertex command. If vertex program mode is enabled,
the currently bound vertex program is executed, using the x, y, z, and w
coordinates as the object coordinates of the vertex. Otherwise, the x, y,
z, and w coordinates are transformed by the current model-view and
projection matrices. These coordinates, along with current values, are
used to generate a color and texture coordinates just as is done for a
vertex. The color and texture coordinates produced using either method
replace the color and texture coordinates stored in the current raster
position's associated data. When in vertex program mode, the "x"
component of the fog coordinate result replaces the current raster
distance; otherwise, the distance from the origin of the eye coordinate
system to the vertex as transformed by only the current model-view matrix
replaces the current raster distance. The latter distance can be
approximated (see section 3.10).
Rename and Modify Section 2.13.8, Color and Vertex Data Clipping (p.56)
(modify second paragraph, p.57) Texture coordinates, as well as fog
coordinates and point sizes computed on a per-vertex basis, must also be
clipped when a primitive is clipped. The method is exactly analogous to
that used for color clipping.
Add New Section 2.14 and subsections (p. 57).
Section 2.14, Vertex Programs
The conventional GL vertex transformation model described in sections 2.10
through 2.13 is a configurable but essentially hard-wired sequence of
per-vertex computations based on a canonical set of per-vertex parameters
and vertex transformation related state such as transformation matrices,
lighting parameters, and texture coordinate generation parameters. The
general success and utility of the conventional GL vertex transformation
model reflects its basic correspondence to the typical vertex
transformation requirements of 3D applications.
However when the conventional GL vertex transformation model is not
sufficient, the vertex program mode provides a substantially more flexible
model for vertex transformation. The vertex program mode permits
applications to define their own vertex programs.
A vertex program is a character string that specifies a sequence of
operations to perform. Vertex program instructions are typically
4-component vector operations that operate on per-vertex attributes and
program parameters. Vertex programs execute on a per-vertex basis and
operate on each vertex completely independently from any other vertices.
Vertex programs execute a finite fixed sequence of instructions with no
branching or looping. Vertex programs execute without data hazards so
results computed in one instruction can be used immediately afterwards.
The result of a vertex program is a set of vertex result registers that
becomes the set of transformed vertex attributes used during clipping and
primitive assembly.
Vertex programs are defined to operate only in RGBA mode. The results of
vertex program execution are undefined if the GL is in color index mode.
Section 2.14.1, Program Objects
The GL provides one or more program targets, each identifying a portion of
the GL that can be controlled through application-specified programs. The
program target for vertex programs is VERTEX_PROGRAM_ARB. Each program
target has an associated program object, called the current program
object. Each program target also has a default program object, which is
initially the current program object.
Each program object has an associated program string. The command
ProgramStringARB(enum target, enum format, sizei len,
const void *string);
updates the program string for the current program object for <target>.
<format> describes the format of the program string, which must currently
be PROGRAM_FORMAT_ASCII_ARB. <string> is a pointer to the array of bytes
representing the program string being loaded, which need not be
null-terminated. The length of the array is given by <len>. If <string>
is null-terminated, <len> should not include the terminator.
When a program string is loaded, it is interpreted according to syntactic
and semantic rules corresponding to the program target specified by
<target>. If a program violates the syntactic or semantic restrictions of
the program target, ProgramStringARB generates the error
INVALID_OPERATION.
Additionally, ProgramString will update the program error position
(PROGRAM_ERROR_POSITION_ARB) and error string (PROGRAM_ERROR_STRING_ARB).
If a program fails to load, the value of the program error position is set
to the ubyte offset into the specified program string indicating where the
first program error was detected. If the program fails to load because of
a semantic restriction that is not detected until the program is fully
scanned, the error position is set to the value of <len>. If a program
loads successfully, the error position is set to the value negative one.
The implementation-dependent program error string contains one or more
error or warning messages. If a program loads succesfully, the error
string may either contain warning messages or be empty.
Each program object has an associated array of program local parameters.
The number and type of program local parameters is target- and
implementation-dependent. For vertex programs, program local parameters
are four-component floating-point vectors. The number of vectors is given
by the implementation-dependent constant MAX_PROGRAM_LOCAL_PARAMETERS_ARB,
which must be at least 96. The commands
void ProgramLocalParameter4fARB(enum target, uint index,
float x, float y, float z, float w);
void ProgramLocalParameter4fvARB(enum target, uint index,
const float *params);
void ProgramLocalParameter4dARB(enum target, uint index,
double x, double y, double z, double w);
void ProgramLocalParameter4dvARB(enum target, uint index,
const double *params);
update the values of the program local parameter numbered <index>
belonging to the program object currently bound to <target>. For
ProgramLocalParameter4fARB and ProgramLocalParameter4dARB, the four
components of the parameter are updated with the values of <x>, <y>, <z>,
and <w>, respectively. For ProgramLocalParameter4fvARB and
ProgramLocalParameter4dvARB, the four components of the parameter are
updated with the array of four values pointed to by <params>. The error
INVALID_VALUE is generated if <index> is greater than or equal to the
number of program local parameters supported by <target>.
Additionally, each program target has an associated array of program
environment parameters. Unlike program local parameters, program
environment parameters are shared by all program objects of a given
target. The number and type of program environment parameters is target-
and implementation-dependent. For vertex programs, program environment
parameters are four-component floating-point vectors. The number of
vectors is given by the implementation-dependent constant
MAX_PROGRAM_ENV_PARAMETERS_ARB, which must be at least 96. The commands
void ProgramEnvParameter4fARB(enum target, uint index,
float x, float y, float z, float w);
void ProgramEnvParameter4fvARB(enum target, uint index,
const float *params);
void ProgramEnvParameter4dARB(enum target, uint index,
double x, double y, double z, double w);
void ProgramEnvParameter4dvARB(enum target, uint index,
const double *params);
update the values of the program environment parameter numbered <index>
for the given program target <target>. For ProgramEnvParameter4fARB and
ProgramEnvParameter4dARB, the four components of the parameter are updated
with the values of <x>, <y>, <z>, and <w>, respectively. For
ProgramEnvParameter4fvARB and ProgramEnvParameter4dvARB, the four
components of the parameter are updated with the array of four values
pointed to by <params>. The error INVALID_VALUE is generated if <index>
is greater than or equal to the number of program environment parameters
supported by <target>.
Each program target has a default program object. Additionally, named
program objects can be created and operated upon. The name space for
program objects is the positive integers and is shared by programs of all
targets. The name zero is reserved by the GL.
A named program object is created by binding an unused program object name
to a valid program target. The binding is effected by calling
BindProgramARB(enum target, uint program);
with <target> set to the desired program target and <program> set to the
unused program name. The resulting program object has a program target
given by <target> and is assigned target-specific default values (see
section 2.14.7 for vertex programs). BindProgramARB may also be used to
bind an existing program object to a program target. If <program> is
zero, the default program object for <target> is bound. If <program> is
the name of an existing program object whose associated program target is
<target>, the named program object is bound. The error INVALID_OPERATION
is generated if <program> names an existing program object whose
associated program target is anything other than <target>.
Programs objects are deleted by calling
void DeleteProgramsARB(sizei n, const uint *programs);
<programs> contains <n> names of programs to be deleted. After a program
object is deleted, its name is again unused. If a program object that is
bound to any target is deleted, it is as though BindProgramARB is first
executed with same target and a <program> of zero. Unused names in
<programs> are silently ignored, as is the value zero.
The command
void GenProgramsARB(sizei n, uint *programs);
returns <n> currently unused program names in <programs>. These names are
marked as used, for the purposes of GenProgramsARB only, but objects are
created only when they are first bound using BindProgramARB.
Section 2.14.2, Vertex Program Grammar and Semantic Restrictions
Vertex program strings are specified as an array of ASCII characters
containing the program text. When a vertex program is loaded by a call to
ProgramStringARB, the program string is parsed into a set of tokens
possibly separated by whitespace. Spaces, tabs, newlines, carriage
returns, and comments are considered whitespace. Comments begin with the
character "#" and are terminated by a newline, a carriage return, or the
end of the program array.
The Backus-Naur Form (BNF) grammar below specifies the syntactically valid
sequences for vertex programs. The set of valid tokens can be inferred
from the grammar. The token "" represents an empty string and is used to
indicate optional rules. A program is invalid if it contains any
undefined tokens or characters.
A vertex program is required to begin with the header string "!!ARBvp1.0",
without any preceding whitespace. This string identifies the subsequent
program text as a vertex program (version 1.0) that should be parsed
according to the following grammar and semantic rules. Program string
parsing begins with the character immediately following the header string.
<program> ::= <optionSequence> <statementSequence> "END"
<optionSequence> ::= <optionSequence> <option>
| ""
<option> ::= "OPTION" <identifier> ";"
<statementSequence> ::= <statementSequence> <statement>
| ""
<statement> ::= <instruction> ";"
| <namingStatement> ";"
<instruction> ::= <ARL_instruction>
| <VECTORop_instruction>
| <SCALARop_instruction>
| <BINSCop_instruction>
| <BINop_instruction>
| <TRIop_instruction>
| <SWZ_instruction>
<ARL_instruction> ::= "ARL" <maskedAddrReg> "," <scalarSrcReg>
<VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg>
<VECTORop> ::= "ABS"
| "FLR"
| "FRC"
| "LIT"
| "MOV"
<SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg>
<SCALARop> ::= "EX2"
| "EXP"
| "LG2"
| "LOG"
| "RCP"
| "RSQ"
<BINSCop_instruction> ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> ","
<scalarSrcReg>
<BINSCop> ::= "POW"
<BINop_instruction> ::= <BINop> <maskedDstReg> ","
<swizzleSrcReg> "," <swizzleSrcReg>
<BINop> ::= "ADD"
| "DP3"
| "DP4"
| "DPH"
| "DST"
| "MAX"
| "MIN"
| "MUL"
| "SGE"
| "SLT"
| "SUB"
| "XPD"
<TRIop_instruction> ::= <TRIop> <maskedDstReg> ","
<swizzleSrcReg> "," <swizzleSrcReg> ","
<swizzleSrcReg>
<TRIop> ::= "MAD"
<SWZ_instruction> ::= "SWZ" <maskedDstReg> "," <srcReg> ","
<extendedSwizzle>
<scalarSrcReg> ::= <optionalSign> <srcReg> <scalarSuffix>
<swizzleSrcReg> ::= <optionalSign> <srcReg> <swizzleSuffix>
<maskedDstReg> ::= <dstReg> <optionalMask>
<maskedAddrReg> ::= <addrReg> <addrWriteMask>
<extendedSwizzle> ::= <extSwizComp> "," <extSwizComp> ","
<extSwizComp> "," <extSwizComp>
<extSwizComp> ::= <optionalSign> <extSwizSel>
<extSwizSel> ::= "0"
| "1"
| <component>
<srcReg> ::= <vertexAttribReg>
| <temporaryReg>
| <progParamReg>
<dstReg> ::= <temporaryReg>
| <vertexResultReg>
<vertexAttribReg> ::= <establishedName>
| <vtxAttribBinding>
<temporaryReg> ::= <establishedName>
<progParamReg> ::= <progParamSingle>
| <progParamArray> "[" <progParamArrayMem> "]"
| <paramSingleItemUse>
<progParamSingle> ::= <establishedName>
<progParamArray> ::= <establishedName>
<progParamArrayMem> ::= <progParamArrayAbs>
| <progParamArrayRel>
<progParamArrayAbs> ::= <integer>
<progParamArrayRel> ::= <addrReg> <addrComponent> <addrRegRelOffset>
<addrRegRelOffset> ::= ""
| "+" <addrRegPosOffset>
| "-" <addrRegNegOffset>
<addrRegPosOffset> ::= <integer> from 0 to 63
<addrRegNegOffset> ::= <integer> from 0 to 64
<vertexResultReg> ::= <establishedName>
| <resultBinding>
<addrReg> ::= <establishedName>
<addrComponent> ::= "." "x"
<addrWriteMask> ::= "." "x"
<scalarSuffix> ::= "." <component>
<swizzleSuffix> ::= ""
| "." <component>
| "." <component> <component>
<component> <component>
<component> ::= "x"
| "y"
| "z"
| "w"
<optionalMask> ::= ""
| "." "x"
| "." "y"
| "." "xy"
| "." "z"
| "." "xz"
| "." "yz"
| "." "xyz"
| "." "w"
| "." "xw"
| "." "yw"
| "." "xyw"
| "." "zw"
| "." "xzw"
| "." "yzw"
| "." "xyzw"
<namingStatement> ::= <ATTRIB_statement>
| <PARAM_statement>
| <TEMP_statement>
| <ADDRESS_statement>
| <OUTPUT_statement>
| <ALIAS_statement>
<ATTRIB_statement> ::= "ATTRIB" <establishName> "="
<vtxAttribBinding>
<vtxAttribBinding> ::= "vertex" "." <vtxAttribItem>
<vtxAttribItem> ::= "position"
| "weight" <vtxOptWeightNum>
| "normal"
| "color" <optColorType>
| "fogcoord"
| "texcoord" <optTexCoordNum>
| "matrixindex" "[" <vtxWeightNum> "]"
| "attrib" "[" <vtxAttribNum> "]"
<vtxAttribNum> ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1
<vtxOptWeightNum> ::= ""
| "[" <vtxWeightNum> "]"
<vtxWeightNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1,
must be divisible by four
<PARAM_statement> ::= <PARAM_singleStmt>
| <PARAM_multipleStmt>
<PARAM_singleStmt> ::= "PARAM" <establishName> <paramSingleInit>
<PARAM_multipleStmt> ::= "PARAM" <establishName> "[" <optArraySize> "]"
<paramMultipleInit>
<optArraySize> ::= ""
| <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB
(maximum number of allowed program
parameter bindings)
<paramSingleInit> ::= "=" <paramSingleItemDecl>
<paramMultipleInit> ::= "=" "{" <paramMultInitList> "}"
<paramMultInitList> ::= <paramMultipleItem>
| <paramMultipleItem> "," <paramMultiInitList>
<paramSingleItemDecl> ::= <stateSingleItem>
| <programSingleItem>
| <paramConstDecl>
<paramSingleItemUse> ::= <stateSingleItem>
| <programSingleItem>
| <paramConstUse>
<paramMultipleItem> ::= <stateMultipleItem>
| <programMultipleItem>
| <paramConstDecl>
<stateMultipleItem> ::= <stateSingleItem>
| "state" "." <stateMatrixRows>
<stateSingleItem> ::= "state" "." <stateMaterialItem>
| "state" "." <stateLightItem>
| "state" "." <stateLightModelItem>
| "state" "." <stateLightProdItem>
| "state" "." <stateTexGenItem>
| "state" "." <stateFogItem>
| "state" "." <stateClipPlaneItem>
| "state" "." <statePointItem>
| "state" "." <stateMatrixRow>
<stateMaterialItem> ::= "material" <optFaceType> "." <stateMatProperty>
<stateMatProperty> ::= "ambient"
| "diffuse"
| "specular"
| "emission"
| "shininess"
<stateLightItem> ::= "light" "[" <stateLightNumber> "]" "."
<stateLightProperty>
<stateLightProperty> ::= "ambient"
| "diffuse"
| "specular"
| "position"
| "attenuation"
| "spot" "." <stateSpotProperty>
| "half"
<stateSpotProperty> ::= "direction"
<stateLightModelItem> ::= "lightmodel" <stateLModProperty>
<stateLModProperty> ::= "." "ambient"
| <optFaceType> "." "scenecolor"
<stateLightProdItem> ::= "lightprod" "[" <stateLightNumber> "]"
<optFaceType> "." <stateLProdProperty>
<stateLProdProperty> ::= "ambient"
| "diffuse"
| "specular"
<stateLightNumber> ::= <integer> from 0 to MAX_LIGHTS-1
<stateTexGenItem> ::= "texgen" <optTexCoordNum> "."
<stateTexGenType> "." <stateTexGenCoord>
<stateTexGenType> ::= "eye"
| "object"
<stateTexGenCoord> ::= "s"
| "t"
| "r"
| "q"
<stateFogItem> ::= "fog" "." <stateFogProperty>
<stateFogProperty> ::= "color"
| "params"
<stateClipPlaneItem> ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane"
<stateClipPlaneNum> ::= <integer> from 0 to MAX_CLIP_PLANES-1
<statePointItem> ::= "point" "." <statePointProperty>
<statePointProperty> ::= "size"
| "attenuation"
<stateMatrixRow> ::= <stateMatrixItem> "." "row" "["
<stateMatrixRowNum> "]"
<stateMatrixRows> ::= <stateMatrixItem> <optMatrixRows>
<optMatrixRows> ::= ""
| "." "row" "[" <stateMatrixRowNum> ".."
<stateMatrixRowNum> "]"
<stateMatrixItem> ::= "matrix" "." <stateMatrixName>
<stateOptMatModifier>
<stateOptMatModifier> ::= ""
| "." <stateMatModifier>
<stateMatModifier> ::= "inverse"
| "transpose"
| "invtrans"
<stateMatrixRowNum> ::= <integer> from 0 to 3
<stateMatrixName> ::= "modelview" <stateOptModMatNum>
| "projection"
| "mvp"
| "texture" <optTexCoordNum>
| "palette" "[" <statePaletteMatNum> "]"
| "program" "[" <stateProgramMatNum> "]"
<stateOptModMatNum> ::= ""
| "[" <stateModMatNum> "]"
<stateModMatNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1
<statePaletteMatNum> ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1
<stateProgramMatNum> ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1
<programSingleItem> ::= <progEnvParam>
| <progLocalParam>
<programMultipleItem> ::= <progEnvParams>
| <progLocalParams>
<progEnvParams> ::= "program" "." "env"
"[" <progEnvParamNums> "]"
<progEnvParamNums> ::= <progEnvParamNum>
| <progEnvParamNum> ".." <progEnvParamNum>
<progEnvParam> ::= "program" "." "env"
"[" <progEnvParamNum> "]"
<progLocalParams> ::= "program" "." "local"
"[" <progLocalParamNums> "]"
<progLocalParamNums> ::= <progLocalParamNum>
| <progLocalParamNum> ".." <progLocalParamNum>
<progLocalParam> ::= "program" "." "local"
"[" <progLocalParamNum> "]"
<progEnvParamNum> ::= <integer> from 0 to
MAX_PROGRAM_ENV_PARAMETERS_ARB - 1
<progLocalParamNum> ::= <integer> from 0 to
MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1
<paramConstDecl> ::= <paramConstScalarDecl>
| <paramConstVector>
<paramConstUse> ::= <paramConstScalarUse>
| <paramConstVector>
<paramConstScalarDecl> ::= <signedFloatConstant>
<paramConstScalarUse> ::= <floatConstant>
<paramConstVector> ::= "{" <signedFloatConstant> "}"
| "{" <signedFloatConstant> ","
<signedFloatConstant> "}"
| "{" <signedFloatConstant> ","
<signedFloatConstant> ","
<signedFloatConstant> "}"
| "{" <signedFloatConstant> ","
<signedFloatConstant> ","
<signedFloatConstant> ","
<signedFloatConstant> "}"
<signedFloatConstant> ::= <optionalSign> <floatConstant>
<floatConstant> ::= see text
<optionalSign> ::= ""
| "-"
| "+"
<TEMP_statement> ::= "TEMP" <varNameList>
<ADDRESS_statement> ::= "ADDRESS" <varNameList>
<varNameList> ::= <establishName>
| <establishName> "," <varNameList>
<OUTPUT_statement> ::= "OUTPUT" <establishName> "="
<resultBinding>
<resultBinding> ::= "result" "." "position"
| "result" "." <resultColBinding>
| "result" "." "fogcoord"
| "result" "." "pointsize"
| "result" "." "texcoord" <optTexCoordNum>
<resultColBinding> ::= "color" <optFaceType> <optColorType>
<optFaceType> ::= ""
| "." "front"
| "." "back"
<optColorType> ::= ""
| "." "primary"
| "." "secondary"
<optTexCoordNum> ::= ""
| "[" <texCoordNum> "]"
<texCoordNum> ::= <integer> from 0 to MAX_TEXTURE_UNITS-1
<ALIAS_statement> ::= "ALIAS" <establishName> "="
<establishedName>
<establishName> ::= <identifier>
<establishedName> ::= <identifier>
<identifier> ::= see text
The <integer> rule matches an integer constant. The integer consists
of a sequence of one or more digits ("0" through "9").
The <floatConstant> rule matches a floating-point constant consisting
of an integer part, a decimal point, a fraction part, an "e" or
"E", and an optionally signed integer exponent. The integer and
fraction parts both consist of a sequence of one or more digits ("0"
through "9"). Either the integer part or the fraction parts (not
both) may be missing; either the decimal point or the "e" (or "E")
and the exponent (not both) may be missing.
The <identifier> rule matches a sequence of one or more letters ("A"
through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"),
or dollar signs ("$"); the first character must not be a number. Upper
and lower case letters are considered different (names are
case-sensitive). The following strings are reserved keywords and may not
be used as identifiers:
ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2,
EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT,
PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result,
state, and vertex.
The error INVALID_OPERATION is generated if a vertex program fails to load
because it is not syntactically correct or for one of the semantic
restrictions described in the following sections.
A successfully loaded vertex program is parsed into a sequence of
instructions. Each instruction is identified by its tokenized name. The
operation of these instructions when executed is defined in section
2.14.5. A successfully loaded program string replaces the program string
previously loaded into the specified program object. If the OUT_OF_MEMORY
error is generated by ProgramStringARB, no change is made to the previous
contents of the current program object.
Section 2.14.3, Vertex Program Variables
Vertex programs may access a number of different variables during their
execution. The following sections define the variables that can be
declared and used by a vertex program.
Explicit variable declarations allow a vertex program to establish a
variable name that can be used to refer to a specified resource in
subsequent instructions. A vertex program will fail to load if it
declares the same variable name more than once or if it refers to a
variable name that has not been previously declared in the program string.
Implicit variable declarations allow a vertex program to use the name of
certain available resources by name.
Section 2.14.3.1, Vertex Attributes
Vertex program attribute variables are a set of four-component
floating-point vectors holding the attributes of the vertex being
processed. Vertex attribute variables are read-only during vertex program
execution.
Vertex attribute variables can be declared explicitly using the
<ATTRIB_statement> grammar rule, or implicitly using the
<vtxAttribBinding> grammar rule in an executable instruction.
Each vertex attribute variable is bound to a single item of vertex state
according to the <vtxAttrBinding> grammar rule. The set of GL state that
can be bound to a vertex attribute variable is given in Table X.2. Vertex
attribute variables are initialized at each vertex program invocation with
the current values of the bound state.
Vertex Attribute Binding Components Underlying State
------------------------ ---------- ------------------------------
vertex.position (x,y,z,w) object coordinates
vertex.weight (w,w,w,w) vertex weights 0-3
vertex.weight[n] (w,w,w,w) vertex weights n-n+3
vertex.normal (x,y,z,1) normal
vertex.color (r,g,b,a) primary color
vertex.color.primary (r,g,b,a) primary color
vertex.color.secondary (r,g,b,a) secondary color
vertex.fogcoord (f,0,0,1) fog coordinate
vertex.texcoord (s,t,r,q) texture coordinate, unit 0
vertex.texcoord[n] (s,t,r,q) texture coordinate, unit n
vertex.matrixindex (i,i,i,i) vertex matrix indices 0-3
vertex.matrixindex[n] (i,i,i,i) vertex matrix indices n-n+3
vertex.attrib[n] (x,y,z,w) generic vertex attribute n
Table X.2: Vertex Attribute Bindings. The "Components" column
indicates the mapping of the state in the "Underlying State" column.
Values of "0" or "1" in the "Components" column indicate the constants
0.0 and 1.0, respectively. Bindings containing "[n]" require an integer
value of <n> to select an individual item.
If a vertex attribute binding matches "vertex.position", the "x", "y", "z"
and "w" components of the vertex attribute variable are filled with the
"x", "y", "z", and "w" components, respectively, of the vertex position.
If a vertex attribute binding matches "vertex.normal", the "x", "y", and
"z" components of the vertex attribute variable are filled with the "x",
"y", and "z" components, respectively, of the vertex normal. The "w"
component is filled with 1.
If a vertex attribute binding matches "vertex.color" or
"vertex.color.primary", the "x", "y", "z", and "w" components of the
vertex attribute variable are filled with the "r", "g", "b", and "a"
components, respectively, of the vertex color.
If a vertex attribute binding matches "vertex.color.secondary", the "x",
"y", "z", and "w" components of the vertex attribute variable are filled
with the "r", "g", "b", and "a" components, respectively, of the vertex
secondary color.
If a vertex attribute binding matches "vertex.fogcoord", the "x" component
of the vertex attribute variable is filled with the vertex fog coordinate.
The "y", "z", and "w" coordinates are filled with 0, 0, and 1,
respectively.
If a vertex attribute binding matches "vertex.texcoord" or
"vertex.texcoord[n]", the "x", "y", "z", and "w" components of the vertex
attribute variable are filled with the "s", "t", "r", and "q" components,
respectively, of the vertex texture coordinates for texture unit <n>. If
"[n]" is omitted, texture unit zero is used.
If a vertex attribute binding matches "vertex.weight" or
"vertex.weight[n]", the "x", "y", "z", and "w" components of the vertex
attribute variable are filled with vertex weights <n> through <n>+3,
respectively. If "[n]" is omitted, weights zero through three are used.
For the purposes of this binding, all weights supported by the
implementation but not set by the application are set to zero, including
the extra derived weight corresponding to the fixed-function
WEIGHT_SUM_UNITY_ARB enable. For components whose corresponding weight is
not supported by the implementation (i.e., numbered MAX_VERTEX_UNITS_ARB
or larger), "y" and "z" components are set to 0.0 and "w" components are
set to 1.0. A vertex program will fail to load if a vertex attribute
binding specifies a weight number <n> that is greater than or equal to
MAX_VERTEX_UNITS_ARB or is not divisible by four.
If a vertex attribute binding matches "vertex.matrixindex" or
"vertex.matrixindex[n]", the "x", "y", "z", and "w" components of the
vertex attribute variable are filled with matrix indices <n> through <n>+3
of the vertex, respectively. If "[n]" is omitted, matrix indices zero
through three are used. For components whose corresponding matrix index
is not supported by the implementation (i.e., numbered
MAX_VERTEX_UNITS_ARB or larger), "y", and "z" components are set to 0.0
and "w" components are set to 1.0. A vertex program will fail to load if
an attribute binding specifies a matrix index number <n> that is greater
than or equal MAX_VERTEX_UNITS_ARB or is not divisible by four.
If a vertex attribute binding matches "vertex.attrib[n]", the "x", "y",
"z" and "w" components of the vertex attribute variable are filled with
the "x", "y", "z", and "w" components, respectively, of generic vertex
attribute <n>. Note that "vertex.attrib[0]" and "vertex.position" are
equivalent.
As described in section 2.7, setting a generic vertex attribute may leave
a corresponding conventional vertex attribute undefined, and vice versa.
To prevent inadvertent use of attribute pairs with undefined attributes, a
vertex program will fail to load if it binds both a conventional vertex
attribute and a generic vertex attribute listed in the same row of Table
X.2.1.
Conventional Attribute Binding Generic Attribute Binding
------------------------------ -------------------------
vertex.position vertex.attrib[0]
vertex.weight vertex.attrib[1]
vertex.weight[0] vertex.attrib[1]
vertex.normal vertex.attrib[2]
vertex.color vertex.attrib[3]
vertex.color.primary vertex.attrib[3]
vertex.color.secondary vertex.attrib[4]
vertex.fogcoord vertex.attrib[5]
vertex.texcoord vertex.attrib[8]
vertex.texcoord[0] vertex.attrib[8]
vertex.texcoord[1] vertex.attrib[9]
vertex.texcoord[2] vertex.attrib[10]
vertex.texcoord[3] vertex.attrib[11]
vertex.texcoord[4] vertex.attrib[12]
vertex.texcoord[5] vertex.attrib[13]
vertex.texcoord[6] vertex.attrib[14]
vertex.texcoord[7] vertex.attrib[15]
vertex.texcoord[n] vertex.attrib[8+n]
Table X.2.1: Invalid Vertex Attribute Binding Pairs. Vertex programs
may not bind both attributes listed in any row. The <n> in the last row
matches the number of any valid texture unit.
Section 2.14.3.2, Vertex Program Parameters
Vertex program parameter variables are a set of four-component
floating-point vectors used as constants during vertex program execution.
Vertex program parameters retain their values across vertex program
invocations, although their values can change between invocations due to
GL state changes.
Single program parameter variables and arrays of program parameter
variables can be declared explicitly using the <PARAM_statement> grammar
rule. Single program parameter variables can also be declared implicitly
using the <paramSingleItemUse> grammar rule in an executable instruction.
Each single program parameter variable is bound to a constant vector or to
a GL state vector according to the <paramSingleInit> grammar rule.
Individual items of a program parameter array are bound to constant
vectors or GL state vectors according to the <programMultipleInit> grammar
rule. The set of GL state that can be bound to program parameter
variables are given in Tables X.3.1 through X.3.8.
Constant Bindings
A program parameter variable can be bound to a scalar or vector constant
using the <paramConstDecl> grammar rule (explicit declarations) or the
<paramConstUse> grammar rule (implicit declarations).
If a program parameter binding matches the <paramConstScalarDecl> or
<paramConstScalarUse> grammar rules, the corresponding program parameter
variable is bound to the vector (X,X,X,X), where X is the value of the
specified constant. Note that the <paramConstScalarUse> grammar rule,
used only in implicit declarations, allows only non-negative constants.
This disambiguates cases like "-2", which could conceivably be taken to
mean either the vector "(2,2,2,2)" with all components negated or
"(-2,-2,-2,-2)" without negation. Only the former interpretation is
allowed by the grammar.
If a program parameter binding matches <paramConstVector>, the
corresponding program parameter variable is bound to the vector (X,Y,Z,W),
where X, Y, Z, and W are the values corresponding to the first, second,
third, and fourth match of <signedFloatConstant>. If fewer than four
constants are specified, Y, Z, and W assume the values 0.0, 0.0, and 1.0,
if their respective constants are not specified.
Program parameter variables initialized to constant values can never be
modified.
Program Environment/Local Parameter Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
program.env[a] (x,y,z,w) program environment
parameter a
program.local[a] (x,y,z,w) program local parameter a
program.env[a..b] (x,y,z,w) program environment
parameters a through b
program.local[a..b] (x,y,z,w) program local parameters
a through b
Table X.3.1: Program Environment/Local Parameter Bindings. <a> and <b>
indicate parameter numbers, where <a> must be less than or equal to <b>.
If a program parameter binding matches "program.env[a]" or
"program.local[a]", the four components of the program parameter variable
are filled with the four components of program environment parameter <a>
or program local parameter <a>, respectively.
Additionally, for program parameter array bindings, "program.env[a..b]"
and "program.local[a..b]" are equivalent to specifying program environment
parameters <a> through <b> in order or program local parameters <a>
through <b> in order, respectively. In either case, a program will fail
to load if <a> is greater than <b>.
Material Property Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
state.material.ambient (r,g,b,a) front ambient material color
state.material.diffuse (r,g,b,a) front diffuse material color
state.material.specular (r,g,b,a) front specular material color
state.material.emission (r,g,b,a) front emissive material color
state.material.shininess (s,0,0,1) front material shininess
state.material.front.ambient (r,g,b,a) front ambient material color
state.material.front.diffuse (r,g,b,a) front diffuse material color
state.material.front.specular (r,g,b,a) front specular material color
state.material.front.emission (r,g,b,a) front emissive material color
state.material.front.shininess (s,0,0,1) front material shininess
state.material.back.ambient (r,g,b,a) back ambient material color
state.material.back.diffuse (r,g,b,a) back diffuse material color
state.material.back.specular (r,g,b,a) back specular material color
state.material.back.emission (r,g,b,a) back emissive material color
state.material.back.shininess (s,0,0,1) back material shininess
Table X.3.2: Material Property Bindings. If a material face is not
specified in the binding, the front property is used.
If a program parameter binding matches any of the material properties
listed in Table X.3.2, the program parameter variable is filled according
to the table. For ambient, diffuse, specular, or emissive colors, the
"x", "y", "z", and "w" components are filled with the "r", "g", "b", and
"a" components, respectively, of the corresponding material color. For
material shininess, the "x" component is filled with the material's
specular exponent, and the "y", "z", and "w" components are filled with 0,
0, and 1, respectively. Bindings containing ".back" refer to the back
material; all other bindings refer to the front material.
Material properties can be changed inside a Begin/End pair, either
directly by calling Material, or indirectly through color material.
However, such property changes are not guaranteed to update program
parameter bindings until the following End command. Program parameter
variables bound to material properties changed inside a Begin/End pair are
undefined until the following End command.
Light Property Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
state.light[n].ambient (r,g,b,a) light n ambient color
state.light[n].diffuse (r,g,b,a) light n diffuse color
state.light[n].specular (r,g,b,a) light n specular color
state.light[n].position (x,y,z,w) light n position
state.light[n].attenuation (a,b,c,e) light n attenuation constants
and spot light exponent
state.light[n].spot.direction (x,y,z,c) light n spot direction and
cutoff angle cosine
state.light[n].half (x,y,z,1) light n infinite half-angle
state.lightmodel.ambient (r,g,b,a) light model ambient color
state.lightmodel.scenecolor (r,g,b,a) light model front scene color
state.lightmodel. (r,g,b,a) light model front scene color
front.scenecolor
state.lightmodel. (r,g,b,a) light model back scene color
back.scenecolor
state.lightprod[n].ambient (r,g,b,a) light n / front material
ambient color product
state.lightprod[n].diffuse (r,g,b,a) light n / front material
diffuse color product
state.lightprod[n].specular (r,g,b,a) light n / front material
specular color product
state.lightprod[n]. (r,g,b,a) light n / front material
front.ambient ambient color product
state.lightprod[n]. (r,g,b,a) light n / front material
front.diffuse diffuse color product
state.lightprod[n]. (r,g,b,a) light n / front material
front.specular specular color product
state.lightprod[n]. (r,g,b,a) light n / back material
back.ambient ambient color product
state.lightprod[n]. (r,g,b,a) light n / back material
back.diffuse diffuse color product
state.lightprod[n]. (r,g,b,a) light n / back material
back.specular specular color product
Table X.3.3: Light Property Bindings. <n> indicates a light number.
If a program parameter binding matches "state.light[n].ambient",
"state.light[n].diffuse", or "state.light[n].specular", the "x", "y", "z",
and "w" components of the program parameter variable are filled with the
"r", "g", "b", and "a" components, respectively, of the corresponding
light color.
If a program parameter binding matches "state.light[n].position", the "x",
"y", "z", and "w" components of the program parameter variable are filled
with the "x", "y", "z", and "w" components, respectively, of the light
position.
If a program parameter binding matches "state.light[n].attenuation", the
"x", "y", and "z" components of the program parameter variable are filled
with the constant, linear, and quadratic attenuation parameters of the
specified light, respectively (section 2.13.1). The "w" component of the
program parameter variable is filled with the spot light exponent of the
specified light.
If a program parameter binding matches "state.light[n].spot.direction",
the "x", "y", and "z" components of the program parameter variable are
filled with the "x", "y", and "z" components of the spot light direction
of the specified light, respectively (section 2.13.1). The "w" component
of the program parameter variable is filled with the cosine of the spot
light cutoff angle of the specified light.
If a program parameter binding matches "state.light[n].half", the "x",
"y", and "z" components of the program parameter variable are filled with
the x, y, and z components, respectively, of the normalized infinite
half-angle vector
h_inf = || P + (0, 0, 1) ||.
The "w" component is filled with 1. In the computation of h_inf, P
consists of the x, y, and z coordinates of the normalized vector from the
eye position P_e to the eye-space light position P_pli (section 2.13.1).
h_inf is defined to correspond to the normalized half-angle vector when
using an infinite light (w coordinate of the position is zero) and an
infinite viewer (v_bs is FALSE). For local lights or a local viewer,
h_inf is well-defined but does not match the normalized half-angle vector,
which will vary depending on the vertex position.
If a program parameter binding matches "state.lightmodel.ambient", the
"x", "y", "z", and "w" components of the program parameter variable are
filled with the "r", "g", "b", and "a" components of the light model
ambient color, respectively.
If a program parameter binding matches "state.lightmodel.scenecolor" or
"state.lightmodel.front.scenecolor", the "x", "y", and "z" components of
the program parameter variable are filled with the "r", "g", and "b"
components respectively of the "front scene color"
c_scene = a_cs * a_cm + e_cm,
where a_cs is the light model ambient color, a_cm is the front ambient
material color, and e_cm is the front emissive material color. The "w"
component of the program parameter variable is filled with the alpha
component of the front diffuse material color. If a program parameter
binding matches "state.lightmodel.back.scenecolor", a similar back scene
color, computed using back-facing material properties, is used. The front
and back scene colors match the values that would be assigned to vertices
using conventional lighting if all lights were disabled.
If a program parameter binding matches anything beginning with
"state.lightprod[n]", the "x", "y", and "z" components of the program
parameter variable are filled with the "r", "g", and "b" components,
respectively, of the corresponding light product. The three light product
components are the products of the corresponding color components of the
specified material property and the light color of the specified light
(see Table X.3.3). The "w" component of the program parameter variable is
filled with the alpha component of the specified material property.
Light products depend on material properties, which can be changed inside
a Begin/End pair. Such property changes are not guaranteed to take effect
until the following End command. Program parameter variables bound to
light products whose corresponding material property changes inside a
Begin/End pair are undefined until the following End command.
Texture Coordinate Generation Property Bindings
Binding Components Underlying State
------------------------- ---------- ----------------------------
state.texgen[n].eye.s (a,b,c,d) TexGen eye linear plane
coefficients, s coord, unit n
state.texgen[n].eye.t (a,b,c,d) TexGen eye linear plane
coefficients, t coord, unit n
state.texgen[n].eye.r (a,b,c,d) TexGen eye linear plane
coefficients, r coord, unit n
state.texgen[n].eye.q (a,b,c,d) TexGen eye linear plane
coefficients, q coord, unit n
state.texgen[n].object.s (a,b,c,d) TexGen object linear plane
coefficients, s coord, unit n
state.texgen[n].object.t (a,b,c,d) TexGen object linear plane
coefficients, t coord, unit n
state.texgen[n].object.r (a,b,c,d) TexGen object linear plane
coefficients, r coord, unit n
state.texgen[n].object.q (a,b,c,d) TexGen object linear plane
coefficients, q coord, unit n
Table X.3.4: Texture Coordinate Generation Property Bindings. "[n]" is
optional -- texture unit <n> is used if specified; texture unit 0 is
used otherwise.
If a program parameter binding matches a set of TexGen plane coefficients,
the "x", "y", "z", and "w" components of the program parameter variable
are filled with the coefficients p1, p2, p3, and p4, respectively, for
object linear coefficients, and the coefficents p1', p2', p3', and p4',
respectively, for eye linear coefficients (section 2.10.4).
Fog Property Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
state.fog.color (r,g,b,a) RGB fog color (section 3.10)
state.fog.params (d,s,e,r) fog density, linear start
and end, and 1/(end-start)
(section 3.10)
Table X.3.5: Fog Property Bindings
If a program parameter binding matches "state.fog.color", the "x", "y",
"z", and "w" components of the program parameter variable are filled with
the "r", "g", "b", and "a" components, respectively, of the fog color
(section 3.10).
If a program parameter binding matches "state.fog.params", the "x", "y",
and "z" components of the program parameter variable are filled with the
fog density, linear fog start, and linear fog end parameters (section
3.10), respectively. The "w" component is filled with 1/(end-start),
where end and start are the linear fog end and start parameters,
respectively.
Clip Plane Property Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
state.clip[n].plane (a,b,c,d) clip plane n coefficients
Table X.3.6: Clip Plane Property Bindings. <n> specifies the clip
plane number, and is required.
If a program parameter binding matches "state.clip[n].plane", the "x",
"y", "z", and "w" components of the program parameter variable are filled
with the coefficients p1', p2', p3', and p4', respectively, of clip plane
<n> (section 2.11).
Point Property Bindings
Binding Components Underlying State
----------------------------- ---------- ----------------------------
state.point.size (s,n,x,f) point size, min and max size
clamps, and fade threshold
(section 3.3)
state.point.attenuation (a,b,c,1) point size attenuation consts
Table X.3.7: Point Property Bindings
If a program parameter binding matches "state.point.size", the "x", "y",
"z", and "w" components of the program parameter variable are filled with
the point size, minimum point size, maximum point size, and fade
threshold, respectively (section 3.3).
If a program parameter binding matches "state.point.attenuation", the "x",
"y", and "z" components of the program parameter variable are filled with
the constant, linear, and quadratic point size attenuation parameters (a,
b, and c), respectively (section 3.3). The "w" component is filled with
1.
Matrix Property Bindings
Binding Underlying State
------------------------------------ ---------------------------
* state.matrix.modelview[n] modelview matrix n
state.matrix.projection projection matrix
state.matrix.mvp modelview-projection matrix
* state.matrix.texture[n] texture matrix n
state.matrix.palette[n] modelview palette matrix n
state.matrix.program[n] program matrix n
Table X.3.8: Base Matrix Property Bindings. The "[n]" syntax indicates
a specific matrix number. For modelview and texture matrices, a matrix
number is optional, and matrix zero will be used if the matrix number is
omitted. These base bindings may further be modified by a
inverse/transpose selector and a row selector.
If the beginning of a program parameter binding matches any of the matrix
binding names listed in Table X.3.8, the binding corresponds to a 4x4
matrix. If the parameter binding is followed by ".inverse", ".transpose",
or ".invtrans" (<stateMatModifier> grammar rule), the inverse, transpose,
or transpose of the inverse, respectively, of the matrix specified in
Table X.3.8 is selected. Otherwise, the matrix specified in Table X.3.8
is selected. If the specified matrix is poorly-conditioned (singular or
nearly so), its inverse matrix is undefined. The binding name
"state.matrix.mvp" refers to the product of modelview matrix zero and the
projection matrix, defined as
MVP = P * M0,
where P is the projection matrix and M0 is modelview matrix zero.
If the selected matrix is followed by ".row[<a>]" (matching the
<stateMatrixRow> grammar rule), the "x", "y", "z", and "w" components of
the program parameter variable are filled with the four entries of row <a>
of the selected matrix. In the example,
PARAM m0 = state.matrix.modelview[1].row[0];
PARAM m1 = state.matrix.projection.transpose.row[3];
the variable "m0" is set to the first row (row 0) of modelview matrix 1
and "m1" is set to the last row (row 3) of the transpose of the projection
matrix.
For program parameter array bindings, multiple rows of the selected matrix
can be bound via the <stateMatrixRows> grammar rule. If the selected
matrix binding is followed by ".row[<a>..<b>]", the result is equivalent
to specifying matrix rows <a> through <b>, in order. A program will fail
to load if <a> is greater than <b>. If no row selection is specified
(<optMatrixRows> matches ""), matrix rows 0 through 3 are bound in order.
In the example,
PARAM m2[] = { state.matrix.program[0].row[1..2] };
PARAM m3[] = { state.matrix.program[0].transpose };
the array "m2" has two entries, containing rows 1 and 2 of program matrix
zero, and "m3" has four entries, containing all four rows of the transpose
of program matrix zero.
Program Parameter Arrays
A program parameter array variable can be declared explicitly by matching
the <PARAM_multipleStmt> grammar rule. Programs can optionally specify
the number of individual program parameters in the array, using the
<optArraySize> grammar rule. Program parameter arrays may not be declared
implicity.
Individual parameter variables in a program parameter array are bound to
GL state vectors or constant vectors as specified by the grammar rule
<paramMultInitList>. Each individual parameter in the array is bound in
turn as described above.
The total number of entries in the array is equal to the number of
parameters bound in the initializer list. A vertex program that specifies
an array size (<optArraySize> matches <integer>) that does not match the
number of parameter bindings in the initialization list will fail to load.
Program parameter array variables may be accessed using absolute
addressing by matching the <progParamArrayAbs> grammar rule, or relative
addressing by matching the <progParamArrayRel> grammar rule.
Array accesses using absolute addressing are checked against the limits of
the array. If any vertex program instruction accesses a program parameter
array using absolute addressing with an out-of-range index (greater than
or equal to the size of the array), the vertex program will fail to load.
Individual state vectors can have no more than one unique binding in any
given program. The GL will automatically combine multiple bindings of the
same state vector into a single unique binding, except for the case where
a state vector is bound multiple times in program parameter arrays
accessed using relative addressing. A vertex program will fail to load if
any GL state vector is bound multiple times in a single array accessed
using relative addressing or bound once in two or more arrays accessed
using relative addressing.
Section 2.14.3.3, Vertex Program Temporaries
Vertex program temporary variables are a set of four-component
floating-point vectors used to hold temporary results during vertex
program execution. Temporaries do not persist between program
invocations, and are undefined at the beginning of each vertex program
invocation.
Vertex program temporary variables can be declared explicitly using the
<TEMP_statement> grammar rule. Each such statement can declare one or
more temporaries. Vertex program temporary variables can not be declared
implicitly.
Section 2.14.3.4, Vertex Program Results
Vertex program result variables are a set of four-component floating-point
vectors used to hold the final results of a vertex program. Vertex
program result variables are write-only during vertex program execution.
Vertex program result variables can be declared explicitly using the
<OUTPUT_statement> grammar rule, or implicitly using the <resultBinding>
grammar rule in an executable instruction. Each vertex program result
variable is bound to a transformed vertex attribute used during primitive
assembly and rasterization. The set of vertex program result variable
bindings is given in Table X.4.
Binding Components Description
----------------------------- ---------- ----------------------------
result.position (x,y,z,w) position in clip coordinates
result.color (r,g,b,a) front-facing primary color
result.color.primary (r,g,b,a) front-facing primary color
result.color.secondary (r,g,b,a) front-facing secondary color
result.color.front (r,g,b,a) front-facing primary color
result.color.front.primary (r,g,b,a) front-facing primary color
result.color.front.secondary (r,g,b,a) front-facing secondary color
result.color.back (r,g,b,a) back-facing primary color
result.color.back.primary (r,g,b,a) back-facing primary color
result.color.back.secondary (r,g,b,a) back-facing secondary color
result.fogcoord (f,*,*,*) fog coordinate
result.pointsize (s,*,*,*) point size
result.texcoord (s,t,r,q) texture coordinate, unit 0
result.texcoord[n] (s,t,r,q) texture coordinate, unit n
Table X.4: Vertex Result Variable Bindings. Components labeled "*" are
unused.
If a result variable binding matches "result.position", updates to the
"x", "y", "z", and "w" components of the result variable modify the "x",
"y", "z", and "w" components, respectively, of the transformed vertex's
clip coordinates. Final window coordinates will be generated for the
vertex as described in section 2.14.4.4.
If a result variable binding match begins with "result.color", updates to
the "x", "y", "z", and "w" components of the result variable modify the
"r", "g", "b", and "a" components, respectively, of the corresponding
vertex color attribute in Table X.4. Color bindings that do not specify
"front" or "back" are consided to refer to front-facing colors. Color
bindings that do not specify "primary" or "secondary" are considered to
refer to primary colors.
If a result variable binding matches "result.fogcoord", updates to the "x"
component of the result variable set the transformed vertex's fog
coordinate. Updates to the "y", "z", and "w" components of the result
variable have no effect.
If a result variable binding matches "result.pointsize", updates to the
"x" component of the result variable set the transformed vertex's point
size. Updates to the "y", "z", and "w" components of the result variable
have no effect.
If a result variable binding matches "result.texcoord" or
"result.texcoord[n]", updates to the "x", "y", "z", and "w" components of
the result variable set the "s", "t", "r" and "q" components,
respectively, of the transformed vertex's texture coordinates for texture
unit <n>. If "[n]" is omitted, texture unit zero is selected.
When in vertex program mode, all attributes of a transformed vertex are
undefined at each vertex program invocation. Any results, or even
individual components of results, that are not written to during vertex
program execution remain undefined.
Section 2.14.3.5, Vertex Program Address Registers
Vertex program address register variables are a set of four-component
signed integer vectors where only the "x" component of the address
registers is currently accessible. Address registers are used as indices
when performing relative addressing in program parameter arrays (section
2.14.4.2).
Vertex program address registers can be declared explicitly using the
<ADDRESS_statement> grammar rule. Each such statement can declare one or
more address registers. Vertex program address registers can not be
declared implicitly.
Vertex program address register variables are undefined at each vertex
program invocation. Address registers can be written by the ARL
instruction (section 2.14.5.3), and will be read when a program uses
relative addressing in program parameter arrays.
Section 2.14.3.6, Vertex Program Aliases
Vertex programs can create aliases by matching the <ALIAS_statement>
grammar rule. Aliases allow programs to use multiple variable names to
refer to a single underlying variable. For example, the statement
ALIAS var1 = var0
establishes a variable name named "var1". Subsequent references to "var1"
in the program text are treated as references to "var0". The left hand
side of an ALIAS statement must be a new variable name, and the right hand
side must be an established variable name.
Aliases are not considered variable declarations, so do not count against
the limits on the number of variable declarations allowed in the program
text.
Section 2.14.3.7, Vertex Program Resource Limits
The vertex program execution environment provides implementation-dependent
resource limits on the number of instructions, temporary variable
declarations, vertex attribute bindings, address register declarations,
and program parameter bindings. A program that exceeds any of these
resource limits will fail to load. The resource limits for vertex
programs can be queried by calling GetProgramiv (section 6.1.12) with a
target of VERTEX_PROGRAM_ARB.
The limit on vertex program instructions can be queried with a <pname> of
MAX_PROGRAM_INSTRUCTIONS_ARB, and must be at least 128. Each instruction
in the program (matching the <instruction> grammar rule) counts against
this limit.
The limit on vertex program temporary variable declarations can be queried
with a <pname> of MAX_PROGRAM_TEMPORARIES_ARB, and must be at least 12.
Each temporary declared in the program, using the <TEMP_statement> grammar
rule, counts against this limit. Aliases of declared temporaries do not.
The limit on vertex program attribute bindings can be queried with a
<pname> of MAX_PROGRAM_ATTRIBS_ARB and must be at least 16. Each distinct
vertex attribute bound explicitly or implicitly in the program counts
against this limit; vertex attributes bound multiple times count only
once.
The limit on vertex program address register declarations can be queried
with a <pname> of MAX_PROGRAM_ADDRESS_REGISTERS_ARB, and must be at least
1. Each address register declared in the program, using the
<ADDRESS_statement> grammar rule, counts against this limit.
The limit on vertex program parameter bindings can be queried with a
<pname> of MAX_PROGRAM_PARAMETERS_ARB, and must be at least 96. Each
distinct GL state vector bound explicitly or implicitly in the program
counts against this limit; GL state vectors bound multiple times count
only once. Each constant vector bound to an array accessed using relative
addressing counts against this limit, even if the same constant vector is
bound multiple times or in multiple arrays. Every other constant vector
bound in the program is counted if and only if an identical constant
vector has not already been counted. Two constant vectors are considered
identical if the four component values are numerically equivalent. Recall
that scalar constants bound in a program are treated as vector constants
with the scalar value replicated. In the following code
PARAM arr1[4] = { {1,2,3,4}, {1,2,3,4}, {4,4,4,4}, {5,6,7,8} };
PARAM arr2[3] = { {1,2,3,4}, {5,6,7,8}, {0,1,2,3} };
PARAM x = {4,3,2,1};
PARAM y = {1,2,3,4};
PARAM z = 4;
PARAM r = {4,3,2,1};
assume that arr1 is accessed using relative addressing but arr2 is not.
The four constants in arr1 all count against the limit. Only two other
constants, {0,1,2,3} in arr2, and {4,3,2,1} in x, are counted; the other
constants are identical to constants that had been previously counted.
In addition to the limits described above, the GL provides a similar set
of implementation-dependent native resource limits. These limits,
specified in section 6.1.12, provide guidance as to whether the program is
small enough to use a "native" mode where vertex programs may be executed
with higher performance. The native resource limits and usage counts are
implementation-dependent and may not exactly correspond to limits and
counts described above. In particular, native resource consumption may be
reduced by program optimizations performed by the GL, or increased due to
emulation of non-native instructions. Programs that satisfy the program
resource limits described above, but whose native resource usage exceeds
one or more native resource limits, are guaranteed to load but may execute
suboptimally.
To assist in resource counting, the GL additionally provides GetProgram
queries to determine the resource usage and native resource usage of the
currently bound program, and to determine whether the bound program
exceeds any native resource limit.
Section 2.14.4, Vertex Program Execution Environment
If vertex program mode is enabled, the currently bound vertex program is
executed when a vertex is specified directly through the Vertex command,
indirectly through vertex arrays or evaluators (section 5.1), or when the
current raster position is updated.
If vertex program mode is enabled and the currently bound program object
does not contain a valid vertex program, the error INVALID_OPERATION will
be generated by Begin, RasterPos, and any command that implicitly calls
Begin (e.g., DrawArrays).
Vertex programs execute a sequence of instructions without
branching. Vertex programs begin by executing the first instruction in
the program, and execute instructions in the order specified in the
program until the last instruction is completed.
There are twenty-seven vertex program instructions. The instructions and
their respective input and output parameters are summarized in Table X.5.
Instruction Inputs Output Description
----------- ------ ------ --------------------------------
ABS v v absolute value
ADD v,v v add
ARL s a address register load
DP3 v,v ssss 3-component dot product
DP4 v,v ssss 4-component dot product
DPH v,v ssss homogeneous dot product
DST v,v v distance vector
EX2 s ssss exponential base 2
EXP s v exponential base 2 (approximate)
FLR v v floor
FRC v v fraction
LG2 s ssss logarithm base 2
LIT v v compute light coefficients
LOG s v logarithm base 2 (approximate)
MAD v,v,v v multiply and add
MAX v,v v maximum
MIN v,v v minimum
MOV v v move
MUL v,v v multiply
POW s,s ssss exponentiate
RCP s ssss reciprocal
RSQ s ssss reciprocal square root
SGE v,v v set on greater than or equal
SLT v,v v set on less than
SUB v,v v subtract
SWZ v v extended swizzle
XPD v,v v cross product
Table X.5: Summary of vertex program instructions. "v" indicates a
floating-point vector input or output, "s" indicates a floating-point
scalar input, "ssss" indicates a scalar output replicated across a
4-component result vector, and "a" indicates a single address register
component.
Section 2.14.4.1, Vertex Program Operands
Most vertex program instructions operate on floating-point vectors or
scalars, as indicated by the grammar rules <swizzleSrcReg> and
<scalarSrcReg>, respectively.
Vector and scalar operands can be obtained from vertex attribute, program
parameter, or temporary registers, as indicated by the <srcReg> rule. For
scalar operands, a single vector component is selected by the
<scalarSuffix> rule, where the characters "x", "y", "z", and "w" select
the x, y, z, and w components, respectively, of the vector.
Vector operands can be swizzled according to the <swizzleSuffix> rule. In
its most general form, the <swizzleSuffix> rule matches the pattern
".????" where each question mark is replaced with one of "x", "y", "z", or
"w". For such patterns, the x, y, z, and w components of the operand are
taken from the vector components named by the first, second, third, and
fourth character of the pattern, respectively. For example, if the
swizzle suffix is ".yzzx" and the specified source contains {2,8,9,0}, the
swizzled operand used by the instruction is {8,9,9,2}.
If the <swizzleSuffix> rule matches "", it is treated as though it were
".xyzw". If the <swizzleSuffix> rule matches (ignoring whitespace) ".x",
".y", ".z", or ".w", these are treated the same as ".xxxx", ".yyyy",
".zzzz", and ".wwww" respectively.
Floating-point scalar or vector operands can optionally be negated
according to the <optionalSign> rule in <scalarSrcReg> and
<swizzleSrcReg>. If the <optionalSign> matches "-", each operand or
operand component is negated.
The following pseudo-code spells out the operand generation process. In
the example, "float" is a floating-point scalar type, while "floatVec" is
a four-component vector. "source" refers to the register used for the
operand, matching the <srcReg> rule. "negate" is TRUE if the
<optionalSign> rule in <scalarSrcReg> or <swizzleSrcReg> matches "-" and
FALSE otherwise. The ".c***", ".*c**", ".**c*", ".***c" modifiers refer
to the x, y, z, and w components obtained by the swizzle operation; the
".c" modifier refers to the single component selected for a scalar load.
floatVec VectorLoad(floatVec source)
{
floatVec operand;
operand.x = source.c***;
operand.y = source.*c**;
operand.z = source.**c*;
operand.w = source.***c;
if (negate) {
operand.x = -operand.x;
operand.y = -operand.y;
operand.z = -operand.z;
operand.w = -operand.w;
}
return operand;
}
float ScalarLoad(floatVec source)
{
float operand;
operand = source.c;
if (negate) {
operand = -operand;
}
return operand;
}
Section 2.14.4.2, Vertex Program Parameter Arrays
A vertex program can load a single element of a program parameter array
using either absolute or relative addressing. Program parameter arrays
are accessed when the <progParamArray> rule is matched.
Absolute addressing is used when the <progParamArrayMem> grammar rule
matches <progParamArrayAbs>. When using absolute addressing, the offset
of the selected entry in the array is given by the number matching
<progParamRegNum>.
Relative addressing is used when the <progParamArrayMem> grammar rule
matches <progParamArrayRel>. When using relative addressing, the offset
of the selected entry in the array is computed by adding the address
register component specified by the <addrReg> and <addrComponent> rules to
the positive or negative offset specified by the <addrRegRelOffset> rule.
If <addrRegRelOffset> matches "", no fixed offset is added to the address
register component. If the computed offset is negative or exceeds the
size of the array, the results of the access are undefined, but may not
lead to program or GL termination.
The following pseudo-code spells out the process of loading a program
parameter from an array. "addrReg" refers to the address register
component used for relative addressing, "absolute" is TRUE if the operand
uses absolute addressing and FALSE otherwise. "paramNumber" is the
program parameter number for absolute addressing; "paramOffset" is the
constant program parameter offset for relative addressing. "paramArray"
is the parameter array that matches the <progParamArray> rule.
floatVec ProgramParameterLoad(int addrReg)
{
int index;
if (absolute) {
index = paramNumber;
} else {
index = addrReg + paramOffset
}
return paramArray[index];
}
Relative addressing can only be used for accessing program parameter
arrays.
Section 2.14.4.3, Vertex Program Destination Register Update
Most vertex program instructions write a 4-component result vector to a
single temporary or vertex result register. Writes to individual
components of the destination register are controlled by individual
component write masks specified as part of the instruction.
The component write mask is specified by the <optionalMask> rule found in
the <maskedDstReg> rule. If the optional mask is "", all components are
enabled. Otherwise, the optional mask names the individual components to
enable. The characters "x", "y", "z", and "w" match the x, y, z, and w
components respectively. For example, an optional mask of ".xzw"
indicates that the x, z, and w components should be enabled for writing
but the y component should not. The grammar requires that the destination
register mask components must be listed in "xyzw" order.
Each component of the destination register is updated with the result of
the vertex program instruction if and only if the component is enabled for
writes by the component write mask. Otherwise, the component of the
destination register remains unchanged.
The following pseudocode illustrates the process of writing a result
vector to the destination register. In the pseudocode, "instrmask" refers
to the component write mask given by the <optionalMask> rule. "result"
and "destination" refer to the result vector and the register selected by
<dstReg>, respectively.
void UpdateDestination(floatVec destination, floatVec result)
{
floatVec merged;
// Merge the converted result into the destination register, under
// control of the compile-time write mask.
merged = destination;
if (instrMask.x) {
merged.x = result.x;
}
if (instrMask.y) {
merged.y = result.y;
}
if (instrMask.z) {
merged.z = result.z;
}
if (instrMask.w) {
merged.w = result.w;
}
// Write out the new destination register.
destination = merged;
}
The "ARL" instruction updates the single address register component
similarly; the grammar is designed so that it writes to only the "x"
component of an address register variable.
Section 2.14.4.4, Vertex Program Result Processing
As a vertex program executes, it will write to one or more result
registers that are mapped to transformed vertex attributes. When a vertex
program completes, the transformed vertex attributes are used to generate
primitives.
The clip coordinates written to "result.position" are used to generate
normalized device coordinates and window coordinates for the vertex in the
manner described section 2.10.
Transformed vertices are then assembled into primitives and clipped as
described in section 2.11.
The selection between front-facing and back-facing color attributes
depends on the primitive to which the vertex belongs. If the primitive is
a point or a line segment, or if vertex program two-sided color mode is
disabled, the front-facing colors are always selected. If it is a polygon
and two-sided color mode is enabled, then the selection is performed in
exactly the same way as in two-sided lighting mode (section 2.13.1).
Vertex program two-sided color mode is enabled and disabled by calling
Enable or Disable with the symbolic value VERTEX_PROGRAM_TWO_SIDE_ARB.
Finally, as primitives are assembled, color clamping (section 2.13.6),
flatshading (section 2.13.7), color, attribute clipping (section 2.13.8),
and final color processing (section 2.13.9) operations are applied to the
transformed vertices.
Section 2.14.4.5, Vertex Program Options
The <optionSequence> grammar rule provides a mechanism for programs to
indicate that one or more extended language features are used by the
program. All program options used by the program must be declared at the
beginning of the program string. Each program option specified in a
program string will modify the syntactic or semantic rules used to
interpet the program and the execution environment used to execute the
program. Program options not present in the program string are ignored,
even if they are supported by the GL.
The <identifier> token in the <option> rule must match the name of a
program option supported by the implementation. To avoid option name
conflicts, option identifiers are required to begin with a vendor prefix.
A program will fail to load if it specifies a program option not supported
by the GL.
Vertex program options should confine their semantic changes to the domain
of vertex programs. Support for a vertex program option should not change
the specification and behavior of vertex programs not requesting use of
that option.
2.14.4.5.1, Position-Invariant Vertex Program Option
If a vertex program specifies the "ARB_position_invariant" option, the
program is used to generate all transformed vertex attributes except for
position. Instead, clip coordinates are computed as specified in section
2.10. Additionally, user clipping is performed as described in section
2.11. Use of position-invariant vertex programs should generally
guarantee that the transformed position of a vertex should be the same
whether vertex program mode is enabled or disabled, allowing for correct
mixed multi-pass rendering semantics.
When the position-invariant option is specified in a vertex program,
vertex programs can no longer produced a transformed position. The
<resultBinding> rule is modified to remove "result.position" from the list
of token sequences matching the rule. A semantic restriction is added to
indicate that a vertex program will fail to load if the number of
instructions it contains exceeds the implementation-dependent limit minus
four.
Section 2.14.5, Vertex Program Instruction Set
The following sections describe the set of supported vertex program
instructions. Each section contains pseudocode describing the
instruction. Instructions will have up to three operands, referred to as
"op0", "op1", and "op2". The operands are loaded using the mechanisms
specified in section 2.14.4.1. The variables "tmp", "tmp0", "tmp1", and
"tmp2" describe scalars or vectors used to hold intermediate results in
the instruction. Most instructions will generate a result vector called
"result". The result vector is then written to the destination register
specified in the instruction as described in section 2.14.4.3.
Section 2.14.5.1, ABS: Absolute Value
The ABS instruction performs a component-wise absolute value operation on
the single operand to yield a result vector.
tmp = VectorLoad(op0);
result.x = fabs(tmp.x);
result.y = fabs(tmp.y);
result.z = fabs(tmp.z);
result.w = fabs(tmp.w);
Section 2.14.5.2, ADD: Add
The ADD instruction performs a component-wise add of the two operands to
yield a result vector.
tmp0 = VectorLoad(op0);
tmp1 = VectorLoad(op1);
result.x = tmp0.x + tmp1.x;
result.y = tmp0.y + tmp1.y;
result.z = tmp0.z + tmp1.z;
result.w = tmp0.w + tmp1.w;
The following rules apply to addition:
1. <x> + <y> == <y> + <x>, for all <x> and <y>.
2. <x> + 0.0 == <x>, for all <x>.
Section 2.14.5.3, ARL: Address Register Load
The ARL instruction loads a single scalar operand and performs a floor
operation to generate a signed integer scalar result:
result = floor(ScalarLoad(op0));
The floor operation returns the largest integer less than or equal to the
operand. For example floor(-1.7) = -2.0, floor(+1.0) = +1.0, and
floor(+3.7) = +3.0.
Section 2.14.5.4, DP3: Three-Component Dot Product
The DP3 instruction computes a three-component dot product of the two
operands (using the x, y, and z components) and replicates the dot product
to all four components of the result vector.
tmp0 = VectorLoad(op0);
tmp1 = VectorLoad(op1);
dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +
(tmp0.z * tmp1.z);
result.x = dot;
result.y = dot;
result.z = dot;
result.w = dot;
Section 2.14.5.5, DP4: Four-Component Dot Product
The DP4 instruction computes a four-component dot product of the two
operands and replicates the dot product to all four components of the
result vector.
tmp0 = VectorLoad(op0);
tmp1 = VectorLoad(op1):
dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +
(tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);
result.x = dot;
result.y = dot;
result.z = dot;
result.w = dot;
Section 2.14.5.6, DPH: Homogeneous Dot Product
The DPH instruction computes a three-component dot product of the two
operands (using the x, y, and z components), adds the w component of the
second operand, and replicates the sum to all four components of the
result vector. This is equivalent to a four-component dot product where
the w component of the first operand is forced to 1.0.
tmp0 = VectorLoad(op0);
tmp1 = VectorLoad(op1):
dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +
(tmp0.z * tmp1.z) + tmp1.w;
result.x = dot;
result.y = dot;
result.z = dot;
result.w = dot;
Section 2.14.5.7, DST: Distance Vector
The DST instruction computes a distance vector from two specially-
formatted operands. The first operand should be of the form [NA, d^2,
d^2, NA] and the second operand should be of the form [NA, 1/d, NA, 1/d],
where NA values are not relevant to the calculation and d is a vector
length. If both vectors satisfy these conditions, the result vector will
be of the form [1.0, d, d^2, 1/d].
The exact behavior is specified in the following pseudo-code:
tmp0 = VectorLoad(op0);
tmp1 = VectorLoad(op1);
result.x = 1.0;
result.y = tmp0.y * tmp1.y;
result.z = tmp0.z;
result.w = tmp1.w;
Given an arbitrary vector, d^2 can be obtained using the DP3 instruction
(using the same vector for both operands) and 1/d can be obtained from d^2
using the RSQ instruction.
This distance vector is useful for per-vertex light attenuation
calculations: a DP3 operation using the distance vector and an
attenuation constants vector as operands will yield the attenuation
factor.
Section 2.14.5.8, EX2: Exponential Base 2
The EX2 instruction approximates 2 raised to the power of the scalar
operand and replicates the approximation to all four components of the
result vector.
tmp = ScalarLoad(op0);
result.x = Approx2ToX(tmp);
result.y = Approx2ToX(tmp);
result.z = Approx2ToX(tmp);
result.w = Approx2ToX(tmp);
Section 2.14.5.9, EXP: Exponential Base 2 (approximate)
The EXP instruction computes a rough approximation of 2 raised to the
power of the scalar operand. The approximation is returned in the "z"
component of the result vector. A vertex program can also use the "x" and
"y" components of the result vector to generate a more accurate
approximation by evaluating
result.x * f(result.y),
where f(x) is a user-defined function that approximates 2^x over the
domain [0.0, 1.0). The "w" component of the result vector is always 1.0.
The exact behavior is specified in the following pseudo-code:
tmp = ScalarLoad(op0);
result.x = 2^floor(tmp);
result.y = tmp - floor(tmp);
result.z = RoughApprox2ToX(tmp);
result.w = 1.0;
The approximation function is accurate to at least 10 bits:
| RoughApprox2ToX(x) - 2^x | < 1.0 / 2^11, if 0.0 <= x < 1.0,
and, in general,
| RoughApprox2ToX(x) - 2^x | < (1.0 / 2^11) * (2^floor(x)).
Section 2.14.5.10, FLR: Floor
The FLR instruction performs a component-wise floor operation on the
operand to generate a result vector. The floor of a value is defined as
the largest integer less than or equal to the value. The floor of 2.3 is
2.0; the floor of -3.6 is -4.0.
tmp = VectorLoad(op0);
result.x = floor(tmp.x);
result.y = floor(tmp.y);
result.z = floor(tmp.z);
result.w = floor(tmp.w);
Section 2.14.5.11, FRC: Fraction
The FRC instruction extracts the fractional portion of each component of
the operand to generate a result vector. The fractional portion of a
component is defined as the result after subtracting off the floor of the
component (see FLR), and is always in the range [0.0, 1.0).
For negative values, the fractional portion is NOT the number written to
the right of the decimal point -- the fractional portion of -1.7 is not
0.7 -- it is 0.3. 0.3 is produced by subtracting the floor of -1.7 (-2.0)
from -1.7.
tmp = VectorLoad(op0);
result.x = fraction(tmp.x);
result.y = fraction(tmp.y);
result.z = fraction(tmp.z);
result.w = fraction(tmp.w);
Section 2.14.5.12, LG2: Logarithm Base 2
The LG2 instruction approximates the base 2 logarithm of the scalar
operand and replicates it to all four components of the result vector.
tmp = ScalarLoad(op0);
result.x = ApproxLog2(tmp);
result.y = ApproxLog2(tmp);
result.z = ApproxLog2(tmp);
result.w = ApproxLog2(tmp);
If the scalar operand is zero or negative, the result is undefined.
Section 2.14.5.13, LIT: Light Coefficients
The LIT instruction accelerates per-vertex lighting by computing lighting
coefficients for ambient, diffuse, and specular light contributions. The
"x" component of the single operand is assumed to hold a diffuse dot
product (n dot VP_pli, as in the vertex lighting equations in Section
2.13.1). The "y" component of the operand is assumed to hold a specular
dot product (n dot h_i). The "w" component of the operand is assumed to
hold the specular exponent of the material (s_rm), and is clamped to the
range (-128, +128) exclusive.
The "x" component of the result vector receives the value that should be
multiplied by the ambient light/material product (always 1.0). The "y"
component of the result vector receives the value that should be
multiplied by the diffuse light/material product (n dot VP_pli). The "z"
component of the result vector receives the value that should be
multiplied by the specular light/material product (f_i * (n dot h_i) ^
s_rm). The "w" component of the result is the constant 1.0.
Negative diffuse and specular dot products are clamped to 0.0, as is done
in the standard per-vertex lighting operations. In addition, if the
diffuse dot product is zero or negative, the specular coefficient is
forced to zero.
tmp = VectorLoad(op0);
if (tmp.x < 0) tmp.x = 0;
if (tmp.y < 0) tmp.y = 0;
if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon);
else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon;
result.x = 1.0;
result.y = tmp.x;
result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0;
result.w = 1.0;
The exponentiation approximation function may be defined in terms of the
base 2 exponentiation and logarithm approximation operations in the EXP
and LOG instructions, where
RoughApproxPower(a,b) = RoughApproxExp2(b * RoughApproxLog2(a)).
In particular, the approximation may not be any more accurate than the
underlying EXP and LOG operations.
Also, since