skia / external / github.com / KhronosGroup / OpenGL-Registry / refs/heads/310-issue / . / extensions / EXT / EXT_vertex_weighting.txt

Name | |

EXT_vertex_weighting | |

Name Strings | |

GL_EXT_vertex_weighting | |

Contact | |

Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com) | |

Notice | |

Copyright NVIDIA Corporation, 1999, 2000. | |

Status | |

Discontinued. | |

NVIDIA no longer supports this extension in driver updates | |

after November 2002. Instead, use either ARB_vertex_program & | |

NV_vertex_program. | |

Version | |

NVIDIA Date: January 3, 2003 | |

$Date$ $Revision$ | |

Number | |

188 | |

Dependencies | |

None | |

Written based on the wording of the OpenGL 1.2 specification but not | |

dependent on it. | |

Overview | |

The intent of this extension is to provide a means for blending | |

geometry based on two slightly differing modelview matrices. | |

The blending is based on a vertex weighting that can change on a | |

per-vertex basis. This provides a primitive form of skinning. | |

A second modelview matrix transform is introduced. When vertex | |

weighting is enabled, the incoming vertex object coordinates are | |

transformed by both the primary and secondary modelview matrices; | |

likewise, the incoming normal coordinates are transformed by the | |

inverses of both the primary and secondary modelview matrices. | |

The resulting two position coordinates and two normal coordinates | |

are blended based on the per-vertex vertex weight and then combined | |

by addition. The transformed, weighted, and combined vertex position | |

and normal are then used by OpenGL as the eye-space position and | |

normal for lighting, texture coordinate, generation, clipping, | |

and further vertex transformation. | |

Issues | |

Should the extension be written to extend to more than two vertex | |

weights and modelview matrices? | |

RESOLUTION: NO. Supports only one vertex weight and two modelview | |

matrices. If more than two is useful, that can be handled with | |

another extension. | |

Should the weighting factor be GLclampf instead of GLfloat? | |

RESOLUTION: GLfloat. Though the value of a weighting factors | |

outside the range of zero to one (and even weights that do not add | |

to one) is dubious, there is no reason to limit the implementation | |

to values between zero and one. | |

Should the weights and modelview matrices be labeled 1 & 2 or 0 & 1? | |

RESOLUTION: 0 & 1. This is consistent with the way lights and | |

texture units are named in OpenGL. Make GL_MODELVIEW0_EXT | |

be an alias for GL_MODELVIEW. Note that the GL_MODELVIEW0_EXT+1 | |

will not be GL_MODELVIEW1_EXT as is the case with GL_LIGHT0 and | |

GL_LIGHT1. | |

Should there be a way to simultaneously Rotate, Translate, Scale, | |

LoadMatrix, MultMatrix, etc. the two modelview matrices together? | |

RESOLUTION: NO. The application must use MatrixMode and repeated | |

calls to keep the matrices in sync if desired. | |

Should the secondary modelview matrix stack be as deep as the primary | |

matrix stack or can they be different sizes? | |

RESOLUTION: Must be the SAME size. This wastes a lot of memory | |

that will be probably never be used (the modelview matrix stack | |

must have at least 32 entries), but memory is cheap. | |

The value returned by MAX_MODELVIEW_STACK_DEPTH applies to both | |

modelview matrices. | |

Should there be any vertex array support for vertex weights. | |

RESOLUTION: YES. | |

Should we have a VertexWeight2fEXT that takes has two weight values? | |

RESOLUTION: NO. The weights are always vw and 1-vw. | |

What is the "correct" way to blend matrices, particularly when wo is | |

not one or the modelview matrix is projective? | |

RESOLUTION: While it may not be 100% correct, the extension blends | |

the vertices based on transforming the object coordinates by | |

both M0 and M1, but the resulting w coordinate comes from simply | |

transforming the object coordinates by M0 and extracting the w. | |

Another option would be to simply blend the two sets of eye | |

coordinates without any special handling of w. This is harder. | |

Another option would be to divide by w before blending the two | |

sets of eye coordinates. This is awkward because if the weight | |

is 1.0 with vertex weighting enabled, the result is not the | |

same as disabling vertex weighting since EYE_LINEAR texgen | |

is based of of the non-perspective corrected eye coordinates. | |

As specified, the normal weighting and combination is performed on | |

unnormalized normals. Would the math work better if the normals | |

were normalized before weighting and combining? | |

RESOLUTION: Vertex weighting of normals is after the | |

GL_RESCALE_NORMAL step and before the GL_NORMALIZE step. | |

As specified, feedback and selection should apply vertex weighting | |

if enabled. Yuck, that would mean that we need software code for | |

vertex weighting. | |

RESOLUTION: YES, it should work with feedback and selection. | |

Sometimes it would be useful to mirror changes in both modelview | |

matrices. For example, the viewing transforms are likely to be | |

different, just the final modeling transforms would be different. | |

Should there be an API support for mirroring transformations into | |

both matrices? | |

RESOLUTION: NO. Such support is likely to complicate the | |

matrix management in the OpenGL. Applications can do a | |

Get matrix from modelview0 and then a LoadMatrix into modelview1 | |

manually if they need to mirror things. | |

I also worry that if we had a mirrored matrix mode, it would | |

double the transform concatenation work if used naively. | |

Many of the changes to the two modelview matrices will be the same. | |

For example, the initial view transform loaded into each will be the | |

same. Should there be a way to "mirror" changes to both modelview | |

matrices? | |

RESOLUTION: NO. Mirroring matrix changes would complicate the | |

driver's management of matrices. Also, I am worried that naive | |

users would mirror all transforms and lead to lots of redundant | |

matrix concatenations. The most efficient way to handle the | |

slight differences between the modelview matrices is simply | |

to GetFloat the primary matrix, LoadMatrix the values in the | |

secondary modelview matrix, and then perform the "extra" transform | |

to the secondary modelview matrix. | |

Ideally, a glCopyMatrix(GLenum src, GLenum dst) type OpenGL | |

command could make this more efficient. There are similiar cases | |

where you want the modelview matrix mirrored in the texture matrix. | |

This is not the extension to solve this minor problem. | |

The post-vertex weighting normal is unlikely to be normalized. | |

Should this extension automatically enable normalization? | |

RESOLUTION: NO. Normalization should operate as specified. | |

The user is responsible for enabling GL_RESCALE_NORMAL or | |

GL_NORMALIZE as needed. | |

You could imagine cases where the application only sent | |

vertex weights of either zero or one and pre-normalized normals | |

so that GL_NORMALIZE would not strictly be required. | |

Note that the vertex weighting of transformed normals occurs | |

BEFORE normalize and AFTER rescaling. See the issue below for | |

why this can make a difference. | |

How does vertex weighting interact with OpenGL 1.2's GL_RESCALE_NORMAL | |

enable? | |

RESOLUTION: Vertex weighting of transformed normals occurs | |

BEFORE normalize and AFTER rescaling. | |

OpenGL 1.2 permits normal rescaling to behave just like normalize | |

and because normalize immediately follows rescaling, enabling | |

rescaling can be implementied by simply always enabling normalize. | |

Vertex weighting changes this. If one or both of the modelview | |

matrices has a non-uniform scale, it may be useful to enable | |

rescaling and normalize and this operates differently than | |

simply enabling normalize. The difference is that rescaling | |

occurs before the normal vertex weighting. | |

An implementation that truly treated rescaling as a normalize | |

would support both a pre-weighting normalize and a post-weighting | |

normalize. Arguably, this is a good thing. | |

For implementations that perform simply rescaling and not a full | |

normalize to implement rescaling, the rescaling factor can be | |

concatenated into each particular inverse modelview matrix. | |

New Procedures and Functions | |

void VertexWeightfEXT(float weight); | |

void VertexWeightfvEXT(float *weight); | |

void VertexWeightPointerEXT(int size, enum type, sizei stride, void *pointer); | |

New Tokens | |

Accepted by the <target> parameter of Enable: | |

VERTEX_WEIGHTING_EXT 0x8509 | |

Accepted by the <mode> parameter of MatrixMode: | |

MODELVIEW0_EXT 0x1700 (alias to MODELVIEW enumerant) | |

MODELVIEW1_EXT 0x850A | |

Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, | |

GetFloatv, and GetDoublev: | |

VERTEX_WEIGHTING_EXT | |

MODELVIEW0_EXT | |

MODELVIEW1_EXT | |

MODELVIEW0_MATRIX_EXT 0x0BA6 (alias to MODELVIEW_MATRIX) | |

MODELVIEW1_MATRIX_EXT 0x8506 | |

CURRENT_VERTEX_WEIGHT_EXT 0x850B | |

VERTEX_WEIGHT_ARRAY_EXT 0x850C | |

VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D | |

VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E | |

VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F | |

MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 (alias to MODELVIEW_STACK_DEPTH) | |

MODELVIEW1_STACK_DEPTH_EXT 0x8502 | |

Accepted by the <pname> parameter of GetPointerv: | |

VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 | |

Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation) | |

-- Section 2.6. 2nd paragraph changed: | |

"Each vertex is specified with two, three, or four coordinates. | |

In addition, a current normal, current texture coordinates, current | |

color, and current vertex weight may be used in processing each | |

vertex." | |

-- Section 2.6. New paragraph after the 3rd paragraph: | |

"A vertex weight is associated with each vertex. When vertex | |

weighting is enabled, this weight is used as a blending factor | |

to blend the position and normals transformed by the primary and | |

secondary modelview matrix transforms. The vertex weighting | |

functionality takes place completely in the "vertex / normal | |

transformation" stage of Figure 2.2." | |

-- Section 2.6.3. First paragraph changed to | |

"The only GL commands that are allowed within any Begin/End pairs are | |

the commands for specifying vertex coordinates, vertex colors, normal | |

coordinates, and texture coordinates (Vertex, Color, VertexWeightEXT, | |

Index, Normal, TexCoord)..." | |

-- Section 2.7. New paragraph after the 4th paragraph: | |

"The current vertex weight is set using | |

void VertexWeightfEXT(float weight); | |

void VertexWeightfvEXT(float *weight); | |

This weight is used when vertex weighting is enabled." | |

-- Section 2.7. The last paragraph changes from | |

"... and one floating-point value to store the current color index." | |

to: | |

"... one floating-point number to store the vertex weight, and one | |

floating-point value to store the current color index." | |

-- Section 2.8. Change 1st paragraph to say: | |

"The client may specify up to seven arrays: one each to store edge | |

flags, texture coordinates, colors, color indices, vertex weights, | |

normals, and vertices. The commands" | |

Add to functions listed following first paragraph: | |

void VertexWeightPointerEXT(int size, enum type, sizei stride, void *pointer); | |

Add to table 2.4 (p. 22): | |

Command Sizes Types | |

---------------------- ----- ----- | |

VertexWeightPointerEXT 1 float | |

Starting with the second paragraph on p. 23, change to add | |

VERTEX_WEIGHT_ARRAY_EXT: | |

"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, VERTEX_ARRAY_WEIGHT_EXT, NORMAL_ARRAY, or VERTEX_ARRAY, | |

for the edge flag, texture coordinate, color, secondary color, | |

color index, normal, or vertex array, respectively. | |

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

from section 2.7 or section 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, secondary color, color index, and normal | |

arrays are EdgeFlagv, TexCoord<size><type>v, Color<size><type>v, | |

Index<type>v, VertexWeightfvEXT, and Normal<type>v, respectively..." | |

Change pseudocode on p. 27 to disable vertex weight array for canned | |

interleaved array formats. After the lines | |

DisableClientState(EDGE_FLAG_ARRAY); | |

DisableClientState(INDEX_ARRAY); | |

insert the line | |

DisableClientState(VERTEX_WEIGHT_ARRAY_EXT); | |

Substitute "seven" for every occurrence of "six" in the final | |

paragraph on p. 27. | |

-- Section 2.10. Change the sentence: | |

"The model-view matrix is applied to these coordinates to yield eye | |

coordinates." | |

to: | |

"The primary modelview matrix is applied to these coordinates to | |

yield eye coordinates. When vertex weighting is enabled, a secondary | |

modelview matrix is also applied to the vertex coordinates, the | |

result of the two modelview transformations are weighted by its | |

respective vertex weighting factor and combined by addition to yield | |

the true eye coordinates. Vertex weighting is enabled or disabled | |

using Enable and Disable (see section 2.10.3) with an argument of | |

VERTEX_WEIGHTING_EXT." | |

Change the 4th paragraph to: | |

"If vertex weighting is disabled and a vertex in object coordinates | |

is given by ( xo yo zo wo )' and the primary model-view matrix is | |

M0, then the vertex's eye coordinates are found as | |

(xe ye ze we)' = M0 (xo yo zo wo)' | |

If vertex weighting is enabled, then the vertex's eye coordinates | |

are found as | |

(xe0 ye0 ze0 we0)' = M0 (xo yo zo wo)' | |

(xe1 ye1 ze1 we1)' = M1 (xo yo zo wo)' | |

(xe,ye,ze)' = vw*(xe0,ye0,ze0)' + (1-vw) * (xe1,ye1,ze1)' | |

we = we0 | |

where M1 is the secondary modelview matrix and vw is the current | |

vertex weight." | |

-- Section 2.10.2 Change the 1st paragraph to say: | |

"The projection matrix and the primary and secondary modelview | |

matrices 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 four pre-defined constants TEXTURE, | |

MODELVIEW0, MODELVIEW1, or PROJECTION (note that MODELVIEW is an | |

alias for MODELVIEW0). TEXTURE is described later. If the current | |

matrix is MODELVIEW0, then matrix operations apply to the primary | |

modelview matrix; if MODELVIEW1, then matrix operations apply to | |

the secondary modelview matrix; if PROJECTION, then they apply to | |

the projection matrix." | |

Change the 9th paragraph to say: | |

"There is a stack of matrices for each of the matrix modes. For the | |

MODELVIEW0 and MODELVIEW1 modes, the stack is at least 32 (that is, | |

there is a stack of at least 32 modelview matrices). ..." | |

Change the last paragraph to say: | |

"The state required to implement transformations consists of a | |

four-valued integer indicating the current matrix mode, a stack of | |

at least two 4x4 matrices for each of PROJECTION and TEXTURE with | |

associated stack pointers, and two stacks of at least 32 4x4 matrices | |

with an associated stack pointer for MODELVIEW0 and MODELVIEW1. | |

Initially, there is only one matrix on each stack, and all matrices | |

are set to the identity. The initial matrix mode is MODELVIEW0." | |

-- Section 2.10.3 Change the 2nd and 7th paragraphs to say: | |

"For a modelview matrix M, the normal for this matrix is transformed | |

to eye coordinates by: | |

(nx' ny' nz' q') = (nx ny nz q) * M^-1 | |

where, if (x y z w)' are the associated vertex coordinates, then | |

/ 0, w= 0 | |

| | |

q = | -(nx ny nz) (x y z)' (2.1) | |

| --------------------, w != 0 | |

\ w | |

Implementations may choose instead to transform (x y z)' to eye | |

coordinates using | |

(nx' ny' nz') = (nx ny nz) * Mu^-1 | |

Where Mu is the upper leftmost 3x3 matrix taken from M. | |

Rescale multiplies the transformed normals by a scale factor | |

( nx" ny" nz" ) = f (nx' ny' nz') | |

If rescaling is disabled, then f = 1. If rescaling is enabled, then | |

f is computed as (mij denotes the matrix element in row i and column j | |

of M^-1, numbering the topmost row of the matrix as row 1 and the leftmost column | |

as column 1 | |

1 | |

f = --------------------------- | |

sqrt(m31^2 + m32^2 + m33^2) | |

Note that if the normals sent to GL were unit length and the model-view | |

matrix uniformly scales space, the rescale make sthe transformed normals | |

unit length. | |

Alternatively, an implementation may chose f as | |

1 | |

f = --------------------------- | |

sqrt(nx'^2 + ny'^2 + nz'^2) | |

recomputing f for each normal. This makes all non-zero length | |

normals unit length regardless of their input length and the nature | |

of the modelview matrix. | |

After rescaling, the final transformed normal used in lighting, nf, | |

depends on whether vertex weighting is enabled or not. | |

When vertex weighting is disabled, nf is computed as | |

nf = m * ( nx"0 ny"0 nz"0 ) | |

where (nx"0 ny"0 nz"0) is the normal transformed as described | |

above using the primary modelview matrix for M. | |

If normalization is enabled m=1. Otherwise | |

1 | |

m = ------------------------------ | |

sqrt(nx"0^2 + ny"0^2 + nz"0^2) | |

However when vertex weighting is enabled, the normal is transformed | |

twice as described above, once by the primary modelview matrix and | |

again by the secondary modelview matrix, weighted using the current | |

per-vertex weight, and normalized. So nf is computed as | |

nf = m * ( nx"w ny"w nz"w ) | |

where nw is the weighting normal computed as | |

nw = vw * ( nx"0 ny"0 nz"0 ) + (1-vw) * (nx"1 ny"1 nz"1) | |

where (nx"0 ny"0 nz"0) is the normal transformed as described | |

above using the primary modelview matrix for M, and (nx"1 ny"1 nz"1) is the | |

normal transformed as described above using the secondary modelview matrix for | |

M, and vw is the current pver-vertex weight." | |

-- Section 2.12. Changes the 3rd paragraph: | |

"The coordinates are treated as if they were specified in a | |

Vertex command. The x, y, z, and w coordinates are transformed | |

by the current primary modelview and perspective matrices. These | |

coordinates, along with current values, are used to generate a | |

color and texture coordinates just as done for a vertex, except | |

that vertex weighting is always treated as if it is disabled." | |

Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization) | |

None | |

Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment Operations | |

and the Framebuffer) | |

None | |

Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions) | |

None | |

Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and State Requests) | |

None | |

Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance) | |

None | |

Additions to the AGL/GLX/WGL Specifications | |

None | |

GLX Protocol | |

A new GL rendering command is added. The following command is sent | |

to the server as part of a glXRender request: | |

VertexWeightfvEXT | |

2 8 rendering command length | |

2 4135 rendering command opcode | |

4 FLOAT32 weight0 | |

To support vertex arrays, the DrawArrays rendering command (sent via | |

a glXRender or glXRenderLarge request) is amended as follows: | |

The list of arrays listed for the third element in the ARRAY_INFO | |

structure is amended to include: | |

0x850c j=1 VERTEX_WEIGHT_ARRAY_EXT | |

The VERTEX_DATA description is amended to include: | |

If the vertex weight array is enabled: | |

ws LISTofBYTE vertex weight array element | |

wp unused, wp=pad(ws) | |

with the following paragraph amended to read: | |

"where ns, cs, is, ts, es, vs, ws is the size of the normal, color, | |

index, texture, edge, vertex, and vertex weight array elements and | |

np, cp, ip, tp, ep, vp, wp is the padding for the normal, color, | |

index, texture, edge, vertex, and vertex weight array elements, | |

respectively." | |

Errors | |

The current vertex weight can be updated at any time. In particular | |

WeightVertexEXT can be called between a call to Begin and the | |

corresponding call to End. | |

INVALID_VALUE is generated if VertexWeightPointerEXT parameter <size> | |

is not 1. | |

INVALID_ENUM is generated if VertexWeightPointerEXT parameter <type> | |

is not FLOAT. | |

INVALID_VALUE is generated if VertexWeightPointerEXT parameter <stride> | |

is negative. | |

New State | |

(table 6.5, p196) | |

Get Value Type Get Command Initial Value Description Sec Attribute | |

--------- ---- ----------- ------------- ----------- --- --------- | |

CURRENT_VERTEX_WEIGHT_EXT F GetFloatv 1 Current 2.8 current | |

vertex weight | |

(table 6.6, p197) | |

Get Value Type Get Command Initial Value Description Sec Attribute | |

--------- ---- ----------- ------------- ----------- --- --------- | |

VERTEX_WEIGHT_ARRAY_EXT B IsEnabled False Vertex weight enable 2.8 vertex-array | |

VERTEX_WEIGHT_ARRAY_SIZE_EXT Z+ GetIntegerv 1 Weights per vertex 2.8 vertex-array | |

VERTEX_WEIGHT_ARRAY_TYPE_EXT Z1 GetIntegerv FLOAT Type of weights 2.8 vertex-array | |

VERTEX_WEIGHT_ARRAY_STRIDE_EXT Z GetIntegerv 0 Stride between weights 2.8 vertex-array | |

VERTEX_WEIGHT_ARRAY_POINTER_EXT Y GetPointerv 0 Pointer to vertex weight array 2.8 vertex-array | |

(table 6.7, p198) | |

Get Value Type Get Command Initial Value Description Sec Attribute | |

--------- ---- ----------- ------------- ----------- ------ --------- | |

MODELVIEW0_MATRIX_EXT 32*xM4 GetFloatv Identity Primary modelview 2.10.2 - | |

stack | |

MODELVIEW1_MATRIX_EXT 32*xM4 GetFloatv Identity Secondary modelview 2.10.2 - | |

stack | |

MODELVIEW0_STACK_DEPTH_EXT Z+ GetIntegerv 1 Primary modelview 2.10.2 - | |

stack depth | |

MODELVIEW1_STACK_DEPTH_EXT Z+ GetIntegerv 1 Secondary modelview 2.10.2 - | |

stack depth | |

MATRIX_MODE Z4 GetIntegerv MODELVIEW0 Current matrix mode 2.10.2 transform | |

VERTEX_WEIGHTING_EXT B IsEnabled False Vertex weighting 2.10.2 transform/enable | |

on/off | |

NOTE: MODELVIEW_MATRIX is an alias for MODELVIEW0_MATRIX_EXT | |

MODELVIEW_STACK_DEPTH is an alias for MODELVIEW0_STACK_DEPTH_EXT | |

New Implementation Dependent State | |

None | |

Revision History | |

12/16/2000 amended to include GLX protocol for vertex arrays | |

5/25/2000 added missing MODELVIEW#_MATRIX_EXT token values | |

1/3/2003 changed status to "discontinued" |