back  Return to list

GL_EXT_vertex_weighting
homeprevnext Name
  
    EXT_vertex_weighting  
  
homeprevnext Name Strings
  
    GL_EXT_vertex_weighting  
  
homeprevnext Contact
  
    Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)  
  
homeprevnext Notice
  
    Copyright NVIDIA Corporation, 1999, 2000.  
  
homeprevnext Status
  
    Discontinued.  
  
    NVIDIA no longer supports this extension in driver updates  
    after November 2002.  Instead, use either ARB_vertex_program &  
    NV_vertex_program.  
  
homeprevnext Version
  
    NVIDIA Date: January 3, 2003  
    $Date$ $Revision$    
  
homeprevnext Number
  
    188  
  
homeprevnext Dependencies
  
    None  
  
    Written based on the wording of the OpenGL 1.2 specification but not  
    dependent on it.  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext New Procedures and Functions
  
    void VertexWeightfEXT(float weight);  
  
    void VertexWeightfvEXT(float *weight);  
  
    void VertexWeightPointerEXT(int size, enum type, sizei stride, void *pointer);  
  
homeprevnext 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  
  
homeprevnext 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."  
  
homeprevnext Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
  
    None  
  
homeprevnext Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment Operations and the Framebuffer)
  
    None  
  
homeprevnext Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
  
    None  
  
homeprevnext Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and State Requests)
  
    None  
  
homeprevnext Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
  
    None  
  
homeprevnext Additions to the AGL/GLX/WGL Specifications
  
    None  
  
homeprevnext 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."  
  
homeprevnext 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.  
  
homeprevnext 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  
  
homeprevnext New Implementation Dependent State
  
    None  
  
homeprevnext 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"  
    1/3/2003 changed status to "discontinued"  
Valid XHTML 1.1! Valid CSS! Last update: November 14, 2006.
Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1.