• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2Name
3
4    EXT_vertex_weighting
5
6Name Strings
7
8    GL_EXT_vertex_weighting
9
10Contact
11
12    Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
13
14Notice
15
16    Copyright NVIDIA Corporation, 1999, 2000.
17
18Status
19
20    Discontinued.
21
22    NVIDIA no longer supports this extension in driver updates
23    after November 2002.  Instead, use either ARB_vertex_program &
24    NV_vertex_program.
25
26Version
27
28    NVIDIA Date: January 3, 2003
29    $Date$ $Revision$
30
31Number
32
33    188
34
35Dependencies
36
37    None
38
39    Written based on the wording of the OpenGL 1.2 specification but not
40    dependent on it.
41
42Overview
43
44    The intent of this extension is to provide a means for blending
45    geometry based on two slightly differing modelview matrices.
46    The blending is based on a vertex weighting that can change on a
47    per-vertex basis.  This provides a primitive form of skinning.
48
49    A second modelview matrix transform is introduced.  When vertex
50    weighting is enabled, the incoming vertex object coordinates are
51    transformed by both the primary and secondary modelview matrices;
52    likewise, the incoming normal coordinates are transformed by the
53    inverses of both the primary and secondary modelview matrices.
54    The resulting two position coordinates and two normal coordinates
55    are blended based on the per-vertex vertex weight and then combined
56    by addition.  The transformed, weighted, and combined vertex position
57    and normal are then used by OpenGL as the eye-space position and
58    normal for lighting, texture coordinate, generation, clipping,
59    and further vertex transformation.
60
61Issues
62
63    Should the extension be written to extend to more than two vertex
64    weights and modelview matrices?
65
66      RESOLUTION: NO.  Supports only one vertex weight and two modelview
67      matrices.  If more than two is useful, that can be handled with
68      another extension.
69
70    Should the weighting factor be GLclampf instead of GLfloat?
71
72      RESOLUTION:  GLfloat.  Though the value of a weighting factors
73      outside the range of zero to one (and even weights that do not add
74      to one) is dubious, there is no reason to limit the implementation
75      to values between zero and one.
76
77    Should the weights and modelview matrices be labeled 1 & 2 or 0 & 1?
78
79      RESOLUTION:  0 & 1.  This is consistent with the way lights and
80      texture units are named in OpenGL.  Make GL_MODELVIEW0_EXT
81      be an alias for GL_MODELVIEW.  Note that the GL_MODELVIEW0_EXT+1
82      will not be GL_MODELVIEW1_EXT as is the case with GL_LIGHT0 and
83      GL_LIGHT1.
84
85    Should there be a way to simultaneously Rotate, Translate, Scale,
86    LoadMatrix, MultMatrix, etc. the two modelview matrices together?
87
88      RESOLUTION:  NO.  The application must use MatrixMode and repeated
89      calls to keep the matrices in sync if desired.
90
91    Should the secondary modelview matrix stack be as deep as the primary
92    matrix stack or can they be different sizes?
93
94      RESOLUTION:  Must be the SAME size.  This wastes a lot of memory
95      that will be probably never be used (the modelview matrix stack
96      must have at least 32 entries), but memory is cheap.
97
98      The value returned by MAX_MODELVIEW_STACK_DEPTH applies to both
99      modelview matrices.
100
101    Should there be any vertex array support for vertex weights.
102
103      RESOLUTION:  YES.
104
105    Should we have a VertexWeight2fEXT that takes has two weight values?
106
107      RESOLUTION:  NO.  The weights are always vw and 1-vw.
108
109    What is the "correct" way to blend matrices, particularly when wo is
110    not one or the modelview matrix is projective?
111
112      RESOLUTION:  While it may not be 100% correct, the extension blends
113      the vertices based on transforming the object coordinates by
114      both M0 and M1, but the resulting w coordinate comes from simply
115      transforming the object coordinates by M0 and extracting the w.
116
117      Another option would be to simply blend the two sets of eye
118      coordinates without any special handling of w.  This is harder.
119
120      Another option would be to divide by w before blending the two
121      sets of eye coordinates.  This is awkward because if the weight
122      is 1.0 with vertex weighting enabled, the result is not the
123      same as disabling vertex weighting since EYE_LINEAR texgen
124      is based of of the non-perspective corrected eye coordinates.
125
126    As specified, the normal weighting and combination is performed on
127    unnormalized normals.  Would the math work better if the normals
128    were normalized before weighting and combining?
129
130      RESOLUTION:  Vertex weighting of normals is after the
131      GL_RESCALE_NORMAL step and before the GL_NORMALIZE step.
132
133    As specified, feedback and selection should apply vertex weighting
134    if enabled.  Yuck, that would mean that we need software code for
135    vertex weighting.
136
137       RESOLUTION:  YES, it should work with feedback and selection.
138
139    Sometimes it would be useful to mirror changes in both modelview
140    matrices.  For example, the viewing transforms are likely to be
141    different, just the final modeling transforms would be different.
142    Should there be an API support for mirroring transformations into
143    both matrices?
144
145      RESOLUTION:  NO.  Such support is likely to complicate the
146      matrix management in the OpenGL.  Applications can do a
147      Get matrix from modelview0 and then a LoadMatrix into modelview1
148      manually if they need to mirror things.
149
150      I also worry that if we had a mirrored matrix mode, it would
151      double the transform concatenation work if used naively.
152
153    Many of the changes to the two modelview matrices will be the same.
154    For example, the initial view transform loaded into each will be the
155    same.  Should there be a way to "mirror" changes to both modelview
156    matrices?
157
158      RESOLUTION:  NO.  Mirroring matrix changes would complicate the
159      driver's management of matrices.  Also, I am worried that naive
160      users would mirror all transforms and lead to lots of redundant
161      matrix concatenations.  The most efficient way to handle the
162      slight differences between the modelview matrices is simply
163      to GetFloat the primary matrix, LoadMatrix the values in the
164      secondary modelview matrix, and then perform the "extra" transform
165      to the secondary modelview matrix.
166
167      Ideally, a glCopyMatrix(GLenum src, GLenum dst) type OpenGL
168      command could make this more efficient.  There are similiar cases
169      where you want the modelview matrix mirrored in the texture matrix.
170      This is not the extension to solve this minor problem.
171
172    The post-vertex weighting normal is unlikely to be normalized.
173    Should this extension automatically enable normalization?
174
175      RESOLUTION:  NO.  Normalization should operate as specified.
176      The user is responsible for enabling GL_RESCALE_NORMAL or
177      GL_NORMALIZE as needed.
178
179      You could imagine cases where the application only sent
180      vertex weights of either zero or one and pre-normalized normals
181      so that GL_NORMALIZE would not strictly be required.
182
183      Note that the vertex weighting of transformed normals occurs
184      BEFORE normalize and AFTER rescaling.  See the issue below for
185      why this can make a difference.
186
187    How does vertex weighting interact with OpenGL 1.2's GL_RESCALE_NORMAL
188    enable?
189
190      RESOLUTION:  Vertex weighting of transformed normals occurs
191      BEFORE normalize and AFTER rescaling.
192
193      OpenGL 1.2 permits normal rescaling to behave just like normalize
194      and because normalize immediately follows rescaling, enabling
195      rescaling can be implementied by simply always enabling normalize.
196
197      Vertex weighting changes this.  If one or both of the modelview
198      matrices has a non-uniform scale, it may be useful to enable
199      rescaling and normalize and this operates differently than
200      simply enabling normalize.  The difference is that rescaling
201      occurs before the normal vertex weighting.
202
203      An implementation that truly treated rescaling as a normalize
204      would support both a pre-weighting normalize and a post-weighting
205      normalize.  Arguably, this is a good thing.
206
207      For implementations that perform simply rescaling and not a full
208      normalize to implement rescaling, the rescaling factor can be
209      concatenated into each particular inverse modelview matrix.
210
211New Procedures and Functions
212
213    void VertexWeightfEXT(float weight);
214
215    void VertexWeightfvEXT(float *weight);
216
217    void VertexWeightPointerEXT(int size, enum type, sizei stride, void *pointer);
218
219New Tokens
220
221    Accepted by the <target> parameter of Enable:
222
223        VERTEX_WEIGHTING_EXT                0x8509
224
225    Accepted by the <mode> parameter of MatrixMode:
226
227        MODELVIEW0_EXT                      0x1700  (alias to MODELVIEW enumerant)
228        MODELVIEW1_EXT                      0x850A
229
230    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
231    GetFloatv, and GetDoublev:
232
233        VERTEX_WEIGHTING_EXT
234        MODELVIEW0_EXT
235        MODELVIEW1_EXT
236        MODELVIEW0_MATRIX_EXT               0x0BA6  (alias to MODELVIEW_MATRIX)
237        MODELVIEW1_MATRIX_EXT               0x8506
238        CURRENT_VERTEX_WEIGHT_EXT           0x850B
239        VERTEX_WEIGHT_ARRAY_EXT             0x850C
240        VERTEX_WEIGHT_ARRAY_SIZE_EXT        0x850D
241        VERTEX_WEIGHT_ARRAY_TYPE_EXT        0x850E
242        VERTEX_WEIGHT_ARRAY_STRIDE_EXT      0x850F
243        MODELVIEW0_STACK_DEPTH_EXT          0x0BA3  (alias to MODELVIEW_STACK_DEPTH)
244        MODELVIEW1_STACK_DEPTH_EXT          0x8502
245
246     Accepted by the <pname> parameter of GetPointerv:
247
248        VERTEX_WEIGHT_ARRAY_POINTER_EXT     0x8510
249
250Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
251
252 --  Section 2.6.  2nd paragraph changed:
253
254     "Each vertex is specified with two, three, or four coordinates.
255     In addition, a current normal, current texture coordinates, current
256     color, and current vertex weight may be used in processing each
257     vertex."
258
259 --  Section 2.6.  New paragraph after the 3rd paragraph:
260
261     "A vertex weight is associated with each vertex.  When vertex
262     weighting is enabled, this weight is used as a blending factor
263     to blend the position and normals transformed by the primary and
264     secondary modelview matrix transforms.  The vertex weighting
265     functionality takes place completely in the "vertex / normal
266     transformation" stage of Figure 2.2."
267
268 --  Section 2.6.3.  First paragraph changed to
269
270     "The only GL commands that are allowed within any Begin/End pairs are
271     the commands for specifying vertex coordinates, vertex colors, normal
272     coordinates, and texture coordinates (Vertex, Color, VertexWeightEXT,
273     Index, Normal, TexCoord)..."
274
275 --  Section 2.7.  New paragraph after the 4th paragraph:
276
277     "The current vertex weight is set using
278
279         void VertexWeightfEXT(float weight);
280         void VertexWeightfvEXT(float *weight);
281
282     This weight is used when vertex weighting is enabled."
283
284 --  Section 2.7.  The last paragraph changes from
285
286     "... and one floating-point value to store the current color index."
287
288     to:
289
290     "... one floating-point number to store the vertex weight, and one
291     floating-point value to store the current color index."
292
293 --  Section 2.8.  Change 1st paragraph to say:
294
295     "The client may specify up to seven arrays: one each to store edge
296     flags, texture coordinates, colors, color indices, vertex weights,
297     normals, and vertices. The commands"
298
299     Add to functions listed following first paragraph:
300
301        void VertexWeightPointerEXT(int size, enum type, sizei stride, void *pointer);
302
303     Add to table 2.4 (p. 22):
304
305        Command                     Sizes   Types
306        ----------------------      -----   -----
307        VertexWeightPointerEXT      1       float
308
309     Starting with the second paragraph on p. 23, change to add
310     VERTEX_WEIGHT_ARRAY_EXT:
311
312     "An individual array is enabled or disabled by calling one of
313
314            void EnableClientState(enum array)
315            void DisableClientState(enum array)
316
317     with array set to EDGE_FLAG_ARRAY, TEXTURE_COORD_ARRAY, COLOR_ARRAY,
318     INDEX_ARRAY, VERTEX_ARRAY_WEIGHT_EXT, NORMAL_ARRAY, or VERTEX_ARRAY,
319     for the edge flag, texture coordinate, color, secondary color,
320     color index, normal, or vertex array, respectively.
321
322     The ith element of every enabled array is transferred to the GL by calling
323
324            void ArrayElement(int i)
325
326     For each enabled array, it is as though the corresponding command
327     from section 2.7 or section 2.6.2 were called with a pointer to
328     element i. For the vertex array, the corresponding command is
329     Vertex<size><type>v, where <size> is one of [2,3,4], and <type> is
330     one of [s,i,f,d], corresponding to array types short, int, float, and
331     double respectively. The corresponding commands for the edge flag,
332     texture coordinate, color, secondary color, color index, and normal
333     arrays are EdgeFlagv, TexCoord<size><type>v, Color<size><type>v,
334     Index<type>v, VertexWeightfvEXT, and Normal<type>v, respectively..."
335
336     Change pseudocode on p. 27 to disable vertex weight array for canned
337     interleaved array formats. After the lines
338
339            DisableClientState(EDGE_FLAG_ARRAY);
340            DisableClientState(INDEX_ARRAY);
341
342     insert the line
343
344            DisableClientState(VERTEX_WEIGHT_ARRAY_EXT);
345
346     Substitute "seven" for every occurrence of "six" in the final
347     paragraph on p. 27.
348
349 --  Section 2.10.  Change the sentence:
350
351    "The model-view matrix is applied to these coordinates to yield eye
352     coordinates."
353
354     to:
355
356     "The primary modelview matrix is applied to these coordinates to
357     yield eye coordinates.  When vertex weighting is enabled, a secondary
358     modelview matrix is also applied to the vertex coordinates, the
359     result of the two modelview transformations are weighted by its
360     respective vertex weighting factor and combined by addition to yield
361     the true eye coordinates.  Vertex weighting is enabled or disabled
362     using Enable and Disable (see section 2.10.3) with an argument of
363     VERTEX_WEIGHTING_EXT."
364
365     Change the 4th paragraph to:
366
367     "If vertex weighting is disabled and a vertex in object coordinates
368     is given by ( xo yo zo wo )' and the primary model-view matrix is
369     M0, then the vertex's eye coordinates are found as
370
371        (xe ye ze we)'  =  M0 (xo yo zo wo)'
372
373     If vertex weighting is enabled, then the vertex's eye coordinates
374     are found as
375
376        (xe0 ye0 ze0 we0)'  =  M0 (xo yo zo wo)'
377
378        (xe1 ye1 ze1 we1)'  =  M1 (xo yo zo wo)'
379
380        (xe,ye,ze)' = vw*(xe0,ye0,ze0)' + (1-vw) * (xe1,ye1,ze1)'
381
382        we = we0
383
384     where M1 is the secondary modelview matrix and vw is the current
385     vertex weight."
386
387 --  Section 2.10.2  Change the 1st paragraph to say:
388
389     "The projection matrix and the primary and secondary modelview
390     matrices are set and modified with a variety of commands. The
391     affected matrix is determined by the current matrix mode. The
392     current matrix mode is set with
393
394        void MatrixMode(enum mode);
395
396     which takes one of the four pre-defined constants TEXTURE,
397     MODELVIEW0, MODELVIEW1, or PROJECTION (note that MODELVIEW is an
398     alias for MODELVIEW0).  TEXTURE is described later.  If the current
399     matrix is MODELVIEW0, then matrix operations apply to the primary
400     modelview matrix; if MODELVIEW1, then matrix operations apply to
401     the secondary modelview matrix; if PROJECTION, then they apply to
402     the projection matrix."
403
404     Change the 9th paragraph to say:
405
406     "There is a stack of matrices for each of the matrix modes.  For the
407     MODELVIEW0 and MODELVIEW1 modes, the stack is at least 32 (that is,
408     there is a stack of at least 32 modelview matrices). ..."
409
410     Change the last paragraph to say:
411
412     "The state required to implement transformations consists of a
413     four-valued integer indicating the current matrix mode, a stack of
414     at least two 4x4 matrices for each of PROJECTION and TEXTURE with
415     associated stack pointers, and two stacks of at least 32 4x4 matrices
416     with an associated stack pointer for MODELVIEW0 and MODELVIEW1.
417     Initially, there is only one matrix on each stack, and all matrices
418     are set to the identity.  The initial matrix mode is MODELVIEW0."
419
420 --  Section 2.10.3  Change the 2nd and 7th paragraphs to say:
421
422     "For a modelview matrix M, the normal for this matrix is transformed
423     to eye coordinates by:
424
425        (nx' ny' nz' q') = (nx ny nz q) * M^-1
426
427     where, if (x y z w)' are the associated vertex coordinates, then
428
429            /  0,                     w= 0
430            |
431        q = |  -(nx ny nz) (x y z)'                        (2.1)
432            |  --------------------,  w != 0
433            \          w
434
435     Implementations may choose instead to transform (x y z)' to eye
436     coordinates using
437
438        (nx' ny' nz') = (nx ny nz) * Mu^-1
439
440     Where Mu is the upper leftmost 3x3 matrix taken from M.
441
442     Rescale multiplies the transformed normals by a scale factor
443
444        ( nx" ny" nz" ) = f (nx' ny' nz')
445
446     If rescaling is disabled, then f = 1.  If rescaling is enabled, then
447     f is computed as (mij denotes the matrix element in row i and column j
448     of M^-1, numbering the topmost row of the matrix as row 1 and the leftmost column
449     as column 1
450
451                                1
452               f =    ---------------------------
453                      sqrt(m31^2 + m32^2 + m33^2)
454
455     Note that if the normals sent to GL were unit length and the model-view
456     matrix uniformly scales space, the rescale make sthe transformed normals
457     unit length.
458
459     Alternatively, an implementation may chose f as
460
461                                 1
462               f =     ---------------------------
463                       sqrt(nx'^2 + ny'^2 + nz'^2)
464
465     recomputing f for each normal.  This makes all non-zero length
466     normals unit length regardless of their input length and the nature
467     of the modelview matrix.
468
469     After rescaling, the final transformed normal used in lighting, nf,
470     depends on whether vertex weighting is enabled or not.
471
472     When vertex weighting is disabled, nf is computed as
473
474            nf = m * ( nx"0  ny"0  nz"0 )
475
476     where (nx"0 ny"0 nz"0) is the normal transformed as described
477     above using the primary modelview matrix for M.
478
479     If normalization is enabled m=1.  Otherwise
480
481                                 1
482               m =     ------------------------------
483                       sqrt(nx"0^2 + ny"0^2 + nz"0^2)
484
485     However when vertex weighting is enabled, the normal is transformed
486     twice as described above, once by the primary modelview matrix and
487     again by the secondary modelview matrix, weighted using the current
488     per-vertex weight, and normalized.  So nf is computed as
489
490            nf = m * ( nx"w  ny"w  nz"w )
491
492     where nw is the weighting normal computed as
493
494            nw = vw * ( nx"0  ny"0  nz"0 ) + (1-vw) * (nx"1 ny"1 nz"1)
495
496     where (nx"0 ny"0 nz"0) is the normal transformed as described
497     above using the primary modelview matrix for M, and (nx"1 ny"1 nz"1) is the
498     normal transformed as described above using the secondary modelview matrix for
499     M, and vw is the current pver-vertex weight."
500
501 --  Section 2.12.  Changes the 3rd paragraph:
502
503     "The coordinates are treated as if they were specified in a
504     Vertex command.  The x, y, z, and w coordinates are transformed
505     by the current primary modelview and perspective matrices. These
506     coordinates, along with current values, are used to generate a
507     color and texture coordinates just as done for a vertex, except
508     that vertex weighting is always treated as if it is disabled."
509
510Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
511
512    None
513
514Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment Operations
515and the Framebuffer)
516
517    None
518
519Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
520
521    None
522
523Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and State Requests)
524
525    None
526
527Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
528
529    None
530
531Additions to the AGL/GLX/WGL Specifications
532
533    None
534
535GLX Protocol
536
537    A new GL rendering command is added. The following command is sent
538    to the server as part of a glXRender request:
539
540        VertexWeightfvEXT
541            2  8        rendering command length
542            2  4135     rendering command opcode
543            4  FLOAT32  weight0
544
545    To support vertex arrays, the DrawArrays rendering command (sent via
546    a glXRender or glXRenderLarge request) is amended as follows:
547
548    The list of arrays listed for the third element in the ARRAY_INFO
549    structure is amended to include:
550
551                0x850c         j=1        VERTEX_WEIGHT_ARRAY_EXT
552
553    The VERTEX_DATA description is amended to include:
554
555       If the vertex weight array is enabled:
556       ws            LISTofBYTE        vertex weight array element
557       wp                              unused, wp=pad(ws)
558
559    with the following paragraph amended to read:
560
561    "where ns, cs, is, ts, es, vs, ws is the size of the normal, color,
562    index, texture, edge, vertex, and vertex weight array elements and
563    np, cp, ip, tp, ep, vp, wp is the padding for the normal, color,
564    index, texture, edge, vertex, and vertex weight array elements,
565    respectively."
566
567Errors
568
569    The current vertex weight can be updated at any time.  In particular
570    WeightVertexEXT can be called between a call to Begin and the
571    corresponding call to End.
572
573    INVALID_VALUE is generated if VertexWeightPointerEXT parameter <size>
574    is not 1.
575
576    INVALID_ENUM is generated if VertexWeightPointerEXT parameter <type>
577    is not FLOAT.
578
579    INVALID_VALUE is generated if VertexWeightPointerEXT parameter <stride>
580    is negative.
581
582New State
583
584(table 6.5, p196)
585Get Value                   Type    Get Command     Initial Value   Description     Sec Attribute
586---------                   ----    -----------     -------------   -----------     --- ---------
587CURRENT_VERTEX_WEIGHT_EXT    F       GetFloatv       1               Current         2.8 current
588                                                                     vertex weight
589
590(table 6.6, p197)
591Get Value                           Type    Get Command     Initial Value   Description                     Sec Attribute
592---------                           ----    -----------     -------------   -----------                     --- ---------
593VERTEX_WEIGHT_ARRAY_EXT              B       IsEnabled       False           Vertex weight enable            2.8 vertex-array
594VERTEX_WEIGHT_ARRAY_SIZE_EXT         Z+      GetIntegerv     1               Weights per vertex              2.8 vertex-array
595VERTEX_WEIGHT_ARRAY_TYPE_EXT         Z1      GetIntegerv     FLOAT           Type of weights                 2.8 vertex-array
596VERTEX_WEIGHT_ARRAY_STRIDE_EXT       Z       GetIntegerv     0               Stride between weights          2.8 vertex-array
597VERTEX_WEIGHT_ARRAY_POINTER_EXT      Y       GetPointerv     0               Pointer to vertex weight array  2.8 vertex-array
598
599(table 6.7, p198)
600Get Value                   Type    Get Command     Initial Value   Description         Sec      Attribute
601---------                   ----    -----------     -------------   -----------         ------   ---------
602MODELVIEW0_MATRIX_EXT       32*xM4  GetFloatv       Identity        Primary modelview    2.10.2   -
603                                                                    stack
604MODELVIEW1_MATRIX_EXT       32*xM4  GetFloatv       Identity        Secondary modelview  2.10.2   -
605                                                                    stack
606MODELVIEW0_STACK_DEPTH_EXT  Z+      GetIntegerv     1               Primary modelview    2.10.2   -
607                                                                    stack depth
608MODELVIEW1_STACK_DEPTH_EXT  Z+      GetIntegerv     1               Secondary modelview  2.10.2   -
609                                                                    stack depth
610MATRIX_MODE                 Z4      GetIntegerv     MODELVIEW0      Current matrix mode  2.10.2   transform
611VERTEX_WEIGHTING_EXT        B       IsEnabled       False           Vertex weighting     2.10.2   transform/enable
612                                                                    on/off
613
614    NOTE:  MODELVIEW_MATRIX is an alias for MODELVIEW0_MATRIX_EXT
615           MODELVIEW_STACK_DEPTH is an alias for MODELVIEW0_STACK_DEPTH_EXT
616
617New Implementation Dependent State
618
619    None
620
621Revision History
622
623    12/16/2000 amended to include GLX protocol for vertex arrays
624    5/25/2000 added missing MODELVIEW#_MATRIX_EXT token values
625    1/3/2003 changed status to "discontinued"
626