Name
ARB_vertex_blend
Name Strings
GL_ARB_vertex_blend
Contact
Evan Hart, NVIDIA (ehart 'at' nvidia.com)
Tom Frisinger, AMD (tom.frisinger 'at' amd.com)
Notice
Copyright (c) 2000-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
Status
Complete. Approved by ARB on September 19, 2000.
Version
Last Modified Date: November 4, 2006
Revision: 1.3
Number
ARB Extension #15
Dependencies
OpenGL 1.0 is required.
This extension is written against the OpenGL 1.2.1 Specification.
Overview
This extension provides the ability to replace the single
modelview transformation with a set of n vertex units. (Where
n is constrained to an implementation defined maximum.) Each
unit has its own modelview transform matrix. For each unit,
there is a current weight associated with the vertex. When
this extension is enabled the vertices are transformed by
the modelview matrices of all of the enabled units. Afterward,
these results are scaled by the weights for the respective
units and then summed to create the eye-space vertex. A
similar procedure is followed for the normals, except they
are transformed by the inverse transpose of the modelview
matrices.
This extension is an orthoganalized version of functionality
already provided by other 3D graphics API's.
IP Status
Unknown, but believed to be none.
Issues
Should an indexed form of matrix addressing be used?
No, this should be added as an additional extension.
Should integer blending weights be allowed?
Yes, this was an over-sight in the original spec. Integer
formats allow for the potential to provide smaller data
types to the API. Integer data types are always mapped
to floats in the same manner as colors.
Should the blending weights be forced to sum to 1?
No, it should be provided as a convenience to developers,
since it is the most common case. Additionally, it should
be noted that even if the weights do not sum to one,
the result of the modelview transformation provides an
eye coordinate whose homogenous coordinate is equivalent
to the homogeneous coordinate after the transformation
had the weights been scaled to sum to one.
Additionally, NORMALIZE should in general be left on to
prevent non-unit normals.
What about projective modelview matrices?
Projective modelview matrices can cause problems with many
other features in GL, so this should not be a problem in
practice. This extension makes no attempts to handle
projective modelview matrices.
Should the set of modelview matrices affect parts of GL other
than vertices?
No, this seems to confuse the operation, and it forces
vertex components to affect setting of GL state.
Some transformations may cause the normals to be transformed in
such a way that they no longer represent the tangent plane to
the surface.
This is a basic property of the math of the technique. In
general with these varying transformations, it is impossible
to maintain the normal as the tangent plane to the surface
without topological information.
Lacking the topological data, the best approximation is to
transform the normals by the inverse transpose of the
blend of the modelview matrices. As the inverse per-vertex
may be computationally impractical, a slightly less accurate
blend of inverse transpose matrices is allowed as the
transformation.
When the less accurate blend is used, the normals will only
be identical to the normals formed by the more correct math
when the blending matrices are pair-wise orthogonal and
the sum of the square of the weights is equal to one.
Should weights be specified as vectors rather than independent
scalars?
Yes, this removes little flexibility and significantly
reduces the call overhead.
New Procedures and Functions
void Weight{bsifd ubusui}vARB(int size, T* weights)
void WeightPointerARB(int size, enum type, sizei stride,
void *pointer)
void VertexBlendARB(int count)
New Tokens
Accepted by the parameters of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
MAX_VERTEX_UNITS_ARB 0x86A4
ACTIVE_VERTEX_UNITS_ARB 0x86A5
Accepted by the parameters of Enable and Disable, by the
parameter of IsEnabled, GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
WEIGHT_SUM_UNITY_ARB 0x86A6
VERTEX_BLEND_ARB 0x86A7
Accepted by the parameter of MatrixMode and by the
parameter of GetBooleanv, GetIntegerv, GetFloatv, and
GetDoublev.
MODELVIEW0_ARB: 0x1700 (alias to MODELVIEW)
MODELVIEW1_ARB: 0x850a
MODELVIEW2_ARB: 0x8722
MODELVIEW3_ARB: 0x8723
MODELVIEW4_ARB: 0x8724
MODELVIEW5_ARB: 0x8725
MODELVIEW6_ARB: 0x8726
MODELVIEW7_ARB: 0x8727
MODELVIEW8_ARB: 0x8728
MODELVIEW9_ARB: 0x8729
MODELVIEW10_ARB: 0x872A
MODELVIEW11_ARB: 0x872B
MODELVIEW12_ARB: 0x872C
MODELVIEW13_ARB: 0x872D
MODELVIEW14_ARB: 0x872E
MODELVIEW15_ARB: 0x872F
MODELVIEW16_ARB: 0x8730
MODELVIEW17_ARB: 0x8731
MODELVIEW18_ARB: 0x8732
MODELVIEW19_ARB: 0x8733
MODELVIEW20_ARB: 0x8734
MODELVIEW21_ARB: 0x8735
MODELVIEW22_ARB: 0x8736
MODELVIEW23_ARB: 0x8737
MODELVIEW24_ARB: 0x8738
MODELVIEW25_ARB: 0x8739
MODELVIEW26_ARB: 0x873A
MODELVIEW27_ARB: 0x873B
MODELVIEW28_ARB: 0x873C
MODELVIEW29_ARB: 0x873D
MODELVIEW30_ARB: 0x873E
MODELVIEW31_ARB: 0x873F
Accepted by the parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
CURRENT_WEIGHT_ARB 0x86A8
Accepted by the parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
WEIGHT_ARRAY_TYPE_ARB 0x86A9
WEIGHT_ARRAY_STRIDE_ARB 0x86AA
WEIGHT_ARRAY_SIZE_ARB 0x86AB
Accepted by the parameter of GetPointerv:
WEIGHT_ARRAY_POINTER_ARB 0x86AC
Accepted by the parameters of EnableClientState and
DisableClientState, by the parameter of IsEnabled,
GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev:
WEIGHT_ARRAY_ARB 0x86AD
Additions to Chapter 2 of the OpenGL 1.2.1 Specification (Operation)
- (2.6, p. 12) Second paragraph changed to:
"Each vertex is specified with two, three, or four
coordinates. In addition, a current normal, current texture
coordinates, current color, and a set of current weights
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. Weights are
used to blend between vertex transformations."
- (2.6.3, p. 19) First paragraph changed to:
"The only GL commands that are allowed within Begin/End
pairs are the commands for specifying vertex coordinates,
vertex color, normal coordinates, texture coordinates, and
weights (Vertex, Color, Index, Normal, TexCoord,
WeightvARB), the ArrayElement command (see section 2.8),
the EvalCoord and EvalPoint commands (see section 5.1),
commands for specifying lighting material parameters
(Material commands; see section 2.13.2), display list
invocation commands (CallList and CallLists; see section
5.4), and the EdgeFlag command. Executing any other GL
command between the execution of Begin and the
corresponding execution of End results in the error
INVALID_OPERATION. Executing Begin after Begin has already
been executed but before an End is executed generates the
INVALID_OPERATION error, as does executing End without a
previous corresponding Begin."
- (2.7, p. 20) Added after the third paragraph:
"The current weights are set using
void Weight{bsifd ubusui}vARB(int size, T* weights);
the floating point values are assigned to the current
weight vector. The first current weights are
replaced with such that:
w[i] = [i]
When WEIGHT_SUM_UNITY_ARB is enabled,
-1
w[] = 1 - SUM [i]
i=0
otherwise the rest of the current weights are set to
0. If is greater than MAX_VERTEX_UNITS_ARB or if
WEIGHT_SUM_UNITY_ARB is enabled and equals
MAX_VERTEX_UNITS_ARB, then the error INVALID_VALUE is
generated. When the values are supplied as byte, short,
int, or their unsigned counterparts, they are converted to
floating-point values as indicated for the corresponding
type in Table 2.6."
- (2.8, p. 21) First paragraph changed to read:
"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 an implementation dependent set of
arrays: one each to store edge flags, texture coordinates,
colors, color indices, normals, vertices, and weights.
The commands
void EdgeFlagPointer( sizei stride, void *pointer);
void TexCoordPointer( int size, enum type, sizei stride,
void *pointer );
void ColorPointer( int size, enum type, sizei stride,
void *pointer );
void IndexPointer( enum type, sizei stride, void
*pointer );
void NormalPointer( enum type, sizei stride, void
*pointer );
void VertexPointer( int size, enum type, sizei stride,
void *pointer );
void WeightPointerARB( int size, enum type,
sizei stride, void *pointer)
describe the locations and organizations of these arrays.
For each command, type specifies the data type of the
values stored in the array. Because edge flags are always
type boolean, EdgeFlagPointer has no type argument. Size,
when present, indicates the number of values per vertex
that are stored in the array. Because normals are always
specified with three values, NormalPointer has no size
argument. Likewise, because color indices, edge flags, and
weights are always specified with a single value,
IndexPointer, and EdgeFlagPointer also have no size
argument. Table 2.4 indicates the allowable values for size
and type (when present). For type the values BYTE, SHORT,
INT, FLOAT, and DOUBLE indicates types byte, short, int,
float, and double, respectively; and the values
UNSIGNED_BYTE, UNSIGNED_SHORT, and UNSIGNED_INT indicate
types ubyte, ushort, and uint, respectively. The error
INVALID_VALUE is generated if size is specified with
a value other than that indicated in the table, or if the
parameter to WeightPointerARB is outside the range
allowed for WeightvARB in section 2.7."
- (2.8, p. 22) Change table 2.4 to read:
Command Sizes Types
------- ----- -----
VertexPointer 2,3,4 short, int, float, double
NormalPointer 3 byte, short, int, float, double
ColorPointer 3,4 byte, ubyte, short, ushort,
int, uint, float, double
IndexPointer 1 ubyte, short, int, float,
double
TexCoordPointer 1,2,3,4 short, int, float, double
EdgeFlagPointer 1 boolean
WeightPointerARB 1 ... byte, ubyte, short, ushort,
MAX_VERTEX_UNITS_ARB int, uint, float, double
- (2.8 p. 23) Change paragraph two to:
"An individual array is enabled or disabled by calling one
of
void EnableClientState( enum array );
void DisableClientState( enum array );
with array set to EDGE_FLAG_ARRAY, TEXTURE_COORD_ARRAY,
COLOR_ARRAY, INDEX_ARRAY, NORMAL_ARRAY, VERTEX_ARRAY, or
WEIGHT_ARRAY_ARB, for the edge flag, texture coordinate,
color, color index, normal, vertex, or weight array,
respectively."
- (2.8 p. 23) Change paragraph three to:
"The ith element of every enabled array is transferred to
the GL by calling
void ArrayElement( int i );
For each enabled array, it is as though the corresponding
command form section 2.7 or 2.6.2 were called with a
pointer to element i. For the vertex array, the
corresponding command is Vertex[size][type]v, where size is
one of [2,3,4], and type is one of [s,i,f,d], corresponding
to array types short, int, float, and double respectively.
The corresponding commands for the edge flag, texture
coordinate, color, color index, normal, and weight arrays
are EdgeFlagv, TexCoord[size][type]v, Color[size][type]v,
Index[type]v, Normal[type]v, and Weight[type]vARB,
respectively. The parameter to WeightvARB is the
current for the weight array. If the vertex array
is enabled, it is as though Vertex[size][type]v is executed
last, after the executions of the other corresponding
commands."
- (2.10 p. 28) Added after the second paragraph:
"Alternatively, the model-view transformation may be
performed by a set of model-view matrices when vertex
blending is enabled. Enabling and disabling of vertex
blending is handled by Enable or Disable with the argument
of VERTEX_BLEND_ARB. When blending is enabled, the vertex
is transformed by multiple model-view transformations.
The number of active transformations applied is set by
void VertexBlendARB(int count)
where count is the number of transformations to blend.
If count is greater than the implementation defined
maximum number of transformations reported in
MAX_VERTEX_UNITS_ARB, then the error
INVALID_VALUE is generated."
- (2.10 p. 29) Add after the second paragraph:
"When vertex blending is enabled, the vertex's eye
coordinates are found as:
(xe) n-1 (xo)
(ye) = SUM w_i * M_i * (yo)
(ze) i=0 (zo)
(we) (wo)
where M_i is the i'th model-view matrix, w_i is the
vertex's associated weight for vertex unit i,
and
n = ACTIVE_VERTEX_UNITS_ARB
"
- (2.10.2 p. 31) Change the first paragraph to:
"The projection matrix and model-view matrices are set
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 MODELVIEWn_ARB. 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, the matrix operations apply to the model-view
matrix; if PROJECTION, then they apply to the projection
matrix; if MODLEVIEWn_ARB, then they apply to the n'th
model-view matrix. MODELVIEW0_ARB is aliased to
MODELVIEW."
- (2.10.2 p. 34) Changed the second paragraph to read:
"There is a stack of matrices for each of the matrix
modes. For MODELVIEWn mode, the stack depth is at least 32
(that is, there is a stack of at least 32 MODELVIEWn
matrices). Additionally, all modelview matrices must
have the same stack depth. ..."
- (2.10.2 p. 34) Changed the third paragraph to read:
"... and a stack of at least 32 4 x 4 matrices with an
associated stack pointer for each MODELVIEWn. ..."
- (2.10.3 p. 35) Added after the third paragraph:
"When vertex blending is enabled, the normal is transformed
to eye space by:
n-1
(nx' ny' nz') = (nx ny nz) Inv ( SUM w_i * Mu_i)
i=0
Alternatively implementations may choose to transform the
normal to eye-space by:
n-1
(nx' ny' nz') = SUM w_i * (nx ny nz) Inv(Mu_i)
i=0
where Mu_i is the upper leftmost 3x3 matrix taken from the
model-view for vertex unit i, w_i is the vertex's
associated weight for vertex unit i, and
n = ACTIVE_VERTEX_UNITS_ARB"
- (2.10.3 p. 36) Added after the second paragraph:
"When vertex blending is enabled, rescaling is applied
within each vertex unit independently. The rescale factor
for each unit is derived from the modelview matrix for that
unit. Normalization is applied to the transformed, blended
normal."
Additions to Chapter 3:
None
Additions to Chapter 4:
None
Additions to Chapter 5:
None
Additions to Chapter 6:
None
Additions to the GLX Specification
None
GLX Protocol
Nine new GL rendering commandsl are added. The following commands
are sent to the server as part of a glXRender request:
WeightbvARB
2 8+n rendering command length
2 220 rendering command opcode
4 INT32 size
1*n INT8 weights
WeightubvARB
2 8+n rendering command length
2 221 rendering command opcode
4 INT32 size
1*n CARD8 weights
WeightsvARB
2 8+2*n rendering command length
2 222 rendering command opcode
4 INT32 size
2*n INT16 weights
WeightusvARB
2 8+2*n rendering command length
2 223 rendering command opcode
4 INT32 size
2*n CARD16 weights
WeightivARB
2 8+4*n rendering command length
2 224 rendering command opcode
4 INT32 size
4*n INT32 weights
WeightuivARB
2 8+4*n rendering command length
2 225 rendering command opcode
4 INT32 size
4*n CARD32 weights
VertexBlendARB
2 8 rendering command length
2 226 rendering command opcode
4 INT32 count
WeightfvARB
2 8+4*n rendering command length
2 227 rendering command opcode
4 INT32 size
4*n FLOAT32 weights
WeightdvARB
2 8+8*n rendering command length
2 228 rendering command opcode
4 INT32 size
8*n FLOAT64 weights
Errors
INVALID_VALUE is generated if the parameter for
WeightvARB or WeightPointerARB is greater than
MAX_VERTEX_UNITS_ARB, or if WEIGHT_SUM_UNITY_ARB is enabled
and is equal to MAX_VERTEX_UNITS_ARB
INVALID_VALUE is generated if the parameter to
VertexBlendARB is greater than MAX_VERTEX_UNITS_ARB or
if is equal to zero.
New State
Modified State in Table 6.5:
Get Value Get Command Type Initial Value Attribute
--------- ----------- ---- ------------- ---------
CURRENT_WEIGHT_ARB GetFloatv Rn n=0 - 1.0 current
n>0 - 0.0
Modified State in Table 6.6:
Get Value Get Command Type Initial Value Attribute
--------- ----------- ---- ------------- ---------
WEIGHT_ARRAY_ARB IsEnabled 1*B False vert-array
WEIGHT_ARRAY_TYPE_ARB GetIntegerv 1*Z2 FLOAT vert-array
WEIGHT_ARRAY_SIZE_ARB GetIntegerv 1*Z+ 0 vert-array
WEIGHT_ARRAY_STRIDE_ARB GetIntegerv 1*Z+ 0 vert-array
WEIGHT_ARRAY_POINTER_ARB GetPointerv 1*Y 0 vert-array
Modified state in Table 6.7:
Get Value Get Command Type Initial Value Attribute
--------- ----------- ---- ------------- ---------
MODELVIEWn_ARB GetFloatv 1*32*xM4 Identity -
ACTIVE_VERTEX_UNITS_ARB GetIntegerv Z+ 1 transform
VERTEX_BLEND_ARB IsEnabled B False transform
enable
Modified state in Table 6.25:
Get Value Get Command Type Minmum Value Attribute
--------- ----------- ---- ------------ ---------
MAX_VERTEX_UNITS_ARB GetIntegerv Z+ 2 -
Additions to Appendix A:
None
Revision History
* 1.0 (October 16, 2000) - initial version
* 1.1 (March 12, 2002) - added GLX protocol for Weight[df]v
* 1.2 (March 21, 2002) - correct Weightdv protocol
* 1.3 (November 4, 2006) - updated contact info after ATI/AMD merger