back  Return to list

GL_ARB_vertex_program
homeprevnext Name
      
    ARB_vertex_program  
  
homeprevnext Name Strings
  
    GL_ARB_vertex_program  
  
homeprevnext Contributors
  
    Kurt Akeley  
    Allen Akin  
    Ben Ashbaugh  
    Bob Beretta  
    John Carmack  
    Matt Craighead  
    Ken Dyke  
    Steve Glanville  
    Michael Gold  
    Evan Hart  
    Mark Kilgard  
    Bill Licea-Kane  
    Barthold Lichtenbelt  
    Erik Lindholm  
    Benj Lipchak  
    Bill Mark  
    James McCombe  
    Jeremy Morris  
    Brian Paul  
    Bimal Poddar  
    Thomas Roell  
    Jeremy Sandmel  
    Jon Paul Schelter  
    Geoff Stahl  
    John Stauffer  
    Nick Triantos  
  
homeprevnext Contact
  
    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)  
  
homeprevnext IP Status
  
    NVIDIA claims to own intellectual property related to this extension, and  
    has signed an ARB Contributor License agreement licensing this  
    intellectual property.  
  
    Microsoft claims to own intellectual property related to this extension.  
  
homeprevnext Status
  
    Complete. Approved by ARB on June 18, 2002  
  
homeprevnext Version
  
    Last Modified Date:  07/25/07  
    Revision:            46  
  
homeprevnext Number
  
    ARB Extension #26  
  
homeprevnext Dependencies
  
    Written based on the wording of the OpenGL 1.3 specification and requires  
    OpenGL 1.3.  
  
    ARB_vertex_blend and EXT_vertex_weighting affect the definition of this  
    extension.  
  
    ARB_matrix_palette affects the definition of this extension.  
  
    ARB_point_parameters and EXT_point_parameters affect the definition of  
    this extension.  
  
    EXT_secondary_color affects the definition of this extension.  
  
    EXT_fog_coord affects the definition of this extension.  
  
    ARB_transpose_matrix affects the definition of this extension.  
  
    NV_vertex_program interacts with this extension.  
  
    EXT_vertex_shader interacts with this extension.  
  
homeprevnext Overview
  
    Unextended OpenGL mandates a certain set of configurable per-vertex  
    computations defining vertex transformation, texture coordinate generation  
    and transformation, and lighting.  Several extensions have added further  
    per-vertex computations to OpenGL.  For example, extensions have defined  
    new texture coordinate generation modes (ARB_texture_cube_map,  
    NV_texgen_reflection, NV_texgen_emboss), new vertex transformation modes  
    (ARB_vertex_blend, EXT_vertex_weighting), new lighting modes (OpenGL 1.2's  
    separate specular and rescale normal functionality), several modes for fog  
    distance generation (NV_fog_distance), and eye-distance point size  
    attenuation (EXT/ARB_point_parameters).  
  
    Each such extension adds a small set of relatively inflexible  
    per-vertex computations.  
  
    This inflexibility is in contrast to the typical flexibility provided by  
    the underlying programmable floating point engines (whether micro-coded  
    vertex engines, DSPs, or CPUs) that are traditionally used to implement  
    OpenGL's per-vertex computations.  The purpose of this extension is to  
    expose to the OpenGL application writer a significant degree of per-vertex  
    programmability for computing vertex parameters.  
  
    For the purposes of discussing this extension, a vertex program is a  
    sequence of floating-point 4-component vector operations that determines  
    how a set of program parameters (defined outside of OpenGL's Begin/End  
    pair) and an input set of per-vertex parameters are transformed to a set  
    of per-vertex result parameters.  
  
    The per-vertex computations for standard OpenGL given a particular set of  
    lighting and texture coordinate generation modes (along with any state for  
    extensions defining per-vertex computations) is, in essence, a vertex  
    program.  However, the sequence of operations is defined implicitly by the  
    current OpenGL state settings rather than defined explicitly as a sequence  
    of instructions.  
  
    This extension provides an explicit mechanism for defining vertex program  
    instruction sequences for application-defined vertex programs.  In order  
    to define such vertex programs, this extension defines a vertex  
    programming model including a floating-point 4-component vector  
    instruction set and a relatively large set of floating-point 4-component  
    registers.  
  
    The extension's vertex programming model is designed for efficient  
    hardware implementation and to support a wide variety of vertex programs.  
    By design, the entire set of existing vertex programs defined by existing  
    OpenGL per-vertex computation extensions can be implemented using the  
    extension's vertex programming model.  
  
homeprevnext Issues
  
    (1) What should this extension be called?  
  
      RESOLVED:  ARB_vertex_program.  DirectX 8 refers to its similar  
      functionality as "vertex shaders".  This is a confusing term because  
      shaders are usually assumed to operate at the fragment or pixel level,  
      not the vertex level.  
  
      Conceptually, what the extension defines is an application-defined  
      program (admittedly limited by its sequential execution model) for  
      processing vertices so the "vertex program" term is more accurate.  
  
      Some of the API machinery in this extension for describing programs  
      should be useful for extending other OpenGL operations with programs  
      (though other types of programs may look very different from vertex  
      programs).  
  
    (2) What terms are important to this specification?  
  
      vertex program mode - When vertex program mode is enabled, vertices are  
      transformed by an application-defined vertex program.  
  
      conventional GL vertex transform mode - When vertex program mode is  
      disabled (or the extension is not supported), vertices are transformed  
      by GL's conventional texgen, lighting, and transform state.  
  
      vertex program - An application-defined program used to transform  
      vertices when vertex program mode is enabled.  
  
      program target - A type or class of program.  This extension supports  
      the VERTEX_PROGRAM_ARB target.  Future extensions may add other program  
      targets.  
  
      program object - An object maintained internal to OpenGL that  
      encapsulates a program and a set of associated state.  Operations  
      performed on program objects include loading a program, binding,  
      generating program object names, querying state, and deleting.  
  
      program name - Each program object has an associated unsigned integer,  
      called the program name.  Applications refer to a program object using  
      the program name.  
  
      current program - Each program target may have a current program object.  
      For vertex programs, the current program is executed whenever a vertex  
      is specified when vertex program mode is enabled.  
  
      default program - Each program target has a default program object,  
      referred to using a program name of zero.  The current program for each  
      program target is initially the default program for that target.  
  
      program execution environment - A set of resources, instructions, and  
      semantic rules used to execute a program.  Each program target may  
      support one or more execution environment -- new execution environments  
      may provide new instructions, resources, or execution rules.  Program  
      strings must specify the execution environment that should be used to  
      execute the program.  
  
      program options - An optional feature that modifies the rules of the  
      execution environment.  Vertex programs specify the options that they  
      require at the beginning of the program.  
  
      vertex attribute - GL state associated with vertices that can vary per  
      vertex.  
  
      conventional vertex attributes - Per-vertex attributes used in  
      conventional GL vertex transform mode, including colors, normals,  
      texture coordinate sets.  
  
      generic vertex attributes - An array of 16+ 4-component vectors added by  
      this extension.  Generic vertex attributes can be used by vertex  
      programs but are unused in conventional GL vertex transform mode.  
  
      program parameter - A set of constants that are available for vertex  
      programs to use during their execution.  Program parameters include  
      program environment parameters, program local parameters, conventional  
      GL state, and program constants.  
  
      program environment parameter - A set of 96+ 4-component vectors  
      belonging to the GL context that can be used as constants during the  
      execution of any vertex program.  
  
      program local parameter - A set of 96+ 4-component vectors belonging to  
      a vertex program object that can be used as constants during the  
      execution of the corresponding vertex program.  Program local parameters  
      can not be used by any other vertex programs.  
  
      program constants - Constants declared in the text of a program may be  
      used during the execution of that program.  
  
      program temporaries - A set of 12+ 4-component vectors to hold temporary  
      results that can be read or written during the execution of a vertex  
      program.  
  
      program address registers - A set of 1+ 1-component integer vectors that  
      can be used to perform variable indirect accesses to program parameter  
      arrays during the execution of a vertex program.  Address registers are  
      specified as vectors to allow for future extensions supporting multiple  
      address register components.  
  
      program results - A set of 4-component vectors to hold the final results  
      of a vertex program.  The program results correspond closely to the set  
      of vertex attributes used during primitive assembly and rasterization.  
        
      program variables - Variable names used to identify a specific vertex  
      attribute, program parameter, temporary, address register, or result.  
  
      program binding - A program statement that declares a variable and  
      associates it with a specific vertex attribute, program parameter, or  
      program result.  
  
      implicit binding - When an executable instruction refers to a specific  
      vertex attribute, program parameter, program result, or constant by  
      name, without using an explicit program binding statement.  When such  
      values are encountered, an implicit binding to an anonymous variable  
      name is created.  
  
      program invocation - The act of implicitly or explicitly kicking off  
      program execution.  Vertex programs are invoked automatically when  
      vertex program mode is enabled and vertices are received.  Vertex  
      programs are also invoked automatically when the current raster position  
      is specified.  
  
    (3) What part of OpenGL do vertex programs specifically bypass?  
  
      Vertex programs bypass the following OpenGL functionality:  
  
        - The modelview and projection matrix vertex transformations.  
  
        - Vertex weighting/blending (ARB_vertex_blend).  
  
        - Normal transformation, rescaling, and normalization.  
  
        - Color material.  
  
        - Per-vertex lighting.  
  
        - Texture coordinate generation and texture matrix transformations.  
  
        - Per-vertex point size computations in ARB/EXT_point_parameters  
  
        - Per-vertex fog coordinate computations in EXT_fog_coord and  
          NV_fog_distance.  
  
        - Client-defined clip planes.  
  
        - The normalization of AUTO_NORMAL evaluated normals  
  
        - All of the above, when computing the current raster position.  
  
      Operations not subsumed by vertex programs  
  
        - Clipping to the view frustum.  
  
        - Perspective divide (division by w).  
  
        - The viewport transformation.  
  
        - The depth range transformation.  
  
        - Front and back color selection (for two-sided lighting and  
          coloring).  
  
        - Clamping the primary and secondary colors to [0,1].  
  
        - Primitive assembly and subsequent operations.  
  
        - Evaluators (except the AUTO_NORMAL normalization).  
  
    (5) This extension adds a set of generic vertex attributes to the existing  
    conventional attributes.  The sum of the number of generic and  
    conventional attributes supported on a given platform may exceed the total  
    number of per-vertex attributes supported in hardware.  How should this  
    situation be handled?  
  
      RESOLVED:  Implementations may alias conventional and generic vertex  
      attributes, where pairs of conventional and generic vertex attributes  
      share the same storage.  Such aliasing will effectively reduce the  
      number of vertex attributes a hardware platforms.  While implementations  
      may alias attributes, that behavior is not required.  To accommodate both  
      behaviors, changing a generic vertex attribute leaves the corresponding  
      conventional attribute undefined, and vice versa.  
  
      This undefined behavior is a compromise between the existing  
      EXT_vertex_shader extension (which does not permit aliasing) and the  
      NV_vertex_program extension (which requires aliasing).  The mapping  
      between generic and conventional vertex attributes is found in Table X.1  
      below.  This mapping is taken from the NV_vertex_program specification  
      and generalized to define behavior for >8 texture coordinate sets.  
  
      Applications that mix conventional and generic vertex attributes in a  
      single rendering pass should be careful to avoid using attributes that  
      may alias.  To limit inadvertent use of such attributes, loading a  
      vertex program that used a pair of attributes that may alias is  
      guaranteed to fail.  Applications requiring a small number of generic  
      vertex attributes can always safely use generic attributes 6 and 7, and  
      any supported attributes corresponding to unused or unsupported texture  
      units.  For example, if an implementation supports only four texture  
      units, generic attributes 12 through 15 can always be used safely.  
  
    (6) Should there be a "VertexAttribs" entry point to specify multiple  
    vertex attributes in one immediate mode call.  
  
      RESOLVED:  No.  Not providing such functionality serves to reduce the  
      already large number of required immediate mode entry points.  A  
      "VertexAttribs" command would improve the efficiency of vertex attribute  
      transfer, but vertex arrays or display lists should still be better.  
  
    (7) Should a full complement of data types (signed and unsigned bytes,  
    shorts, and ints, as well as floats and doubles) be supported for vertex  
    attributes?  Should fixed-point data types be supported in both normalized  
    (map the range to [0,1] or [-1,1]) and unnormalized form?  
  
      RESOLVED:  For vertex arrays, all data type combinations are supported.  
  
      For immediate mode, a smaller subset is supported, to limit the number  
      of immediate-mode entry points added by this extension.  In fully  
      general form, 112 immediate-mode entry points (4 sizes x 2  
      vector/non-vector x 14 data types) would be required.  
  
      Immediate mode support is available for non-normalized shorts, floats,  
      and doubles for all component counts.  Additionally, immediate mode  
      support is available for 4-component vectors of all data types  
      (normalized and unnormalized).  
  
      Note also that in immediate mode, the "N" qualifier in function names  
      like VertexAttrib4Nub will be used to indicate that fixed-point data  
      should be normalized.  
  
    (8) How should applications indicate that fixed-point generic vertex  
    attribute array components should be converted to [-1,+1] or [0,1] ranges?  
  
      RESOLVED:  The function VertexAttribPointerARB takes a boolean argument  
      <normalized> that indicates whether fixed-point array data should be  
      normalized to [-1,+1] or [0,1].    
  
      One alternate approach would have been to extend to set of enumerants to  
      include values such as NORMALIZED_UNSIGNED_BYTE_ARB.  Adding such  
      enumerants in some sense implies that UNSIGNED_BYTE is not normalized,  
      even though it usually is.  
  
    (9) In unextended OpenGL, calling Vertex() specifies a vertex and causes  
    vertex transformation operations to be performed on the vertex.  Should  
    there be an equivalent method to specify a vertex using generic vertex  
    attributes?  If so, how should this be accomplished?  
  
      RESOLVED:  Setting generic vertex attribute zero will always specify a  
      vertex.  Vertex*(...) and VertexAttrib*(0,...) are specified to be  
      equivalent, whether or not vertex program mode is enabled.  Allowing  
      generic vertex attribute zero to specify a vertex allows applications to  
      write vertex programs that use only generic attributes; otherwise,  
      applications would have had to use Vertex() to provoke vertex  
      processing.  
  
    (10) How is this extension different from previous vertex program  
    extensions, such as EXT_vertex_shader or NV_vertex_program?  What pitfalls  
    are there in porting vertex programs to/from this extension?  
      
      RESOLVED:  See "Interactions with NV_vertex_program" and "Interactions  
      with EXT_vertex_shader" sections near the end of this specification.    
  
    (11) Should program parameter variables bound to GL state be updated  
    automatically after the bound state changes?  If so, when?  
  
      RESOLVED:  Yes.  Such variables are updated automatically prior to the  
      next vertex program invocation with no application intervention  
      required.  A proposal to reduce the burden by requiring a manual "update  
      state" step was considered and rejected.  
  
    (12) How should this specification handle variable bindings to Material  
    state?  Material is allowed inside a Begin/End, so material properties are  
    technically per-vertex state.  
  
      RESOLVED:  Materials can be bound only as program parameters.  Changes  
      to material properties inside a Begin/End will leave the bindings  
      undefined until the subsequent End command.  At that point, all material  
      property bindings are guaranteed to be updated, and any material  
      property changes up to the next Begin command are guaranteed to take  
      effect immediately.  
  
      Supporting per-vertex material properties places additional pressure on  
      the number of per-vertex bindings an implementation can support, which  
      was already a problem.  See issue (5).    
  
      In practice, material properties are usually not changed in this manner.  
      Applications needing to change material properties inside a Begin/End in  
      vertex program mode can work around this limitation by storing the color  
      in a conventional or generic vertex attribute and modifying the vertex  
      program accordingly.  
  
    (13) What semantic restrictions, if any, should be imposed on binding the  
    same GL state to multiple variables?  The grammar permits such bindings,  
    but allowing this behavior means that single state updates must update  
    multiple variables.  
  
      RESOLVED:  Cases where a single state update necessarily requires  
      updating multiple variables are disallowed.  The only restriction  
      resulting from this decision is that a single state variable can not be  
      bound more than once in the collection of arrays that are accessed using  
      relative addressing (at run time).  The driver can and will coalesce all  
      other bindings accessed only at fixed offsets into a single binding.  
  
      This restriction and a little driver work allows the same state variable  
      to be used multiple times without requiring that a single state change  
      update multiple variables.  
  
    (14) What semantic restrictions, if any, should be imposed on using  
    multiple vertex attributes or program parameters in the same instruction?  
  
      RESOLVED:  None.  If the underlying hardware implementation does not  
      support reads of multiple attributes or program parameters, the driver  
      may need to transparently insert additional instructions and/or consume  
      temporaries to perform the operation.  
      
    (15) How and when should related state be combined into a single program  
    parameter binding?  Additionally, should any values derived from core GL  
    state be exposed, too?  
  
      RESOLVED:  Related state should be combined when possible, as long as  
      the binding name remains somewhat sensible.  Additionally, certain  
      pre-computed state items useful for performance reasons are also  
      exposed.  In particular, the following GL state combinations are  
      supported:  
  
        * Light attenuation constants and the spot light exponent are combined  
          into a single vector called "state.light[n].attenuation" (spot  
          lights can attenuate the lit result).  
  
        * Spot light direction and cutoff angle cosine are called  
          "state.light[n].spot.direction" (cutoff is directional information).  
          Binding the cutoff angle itself is pretty useless, so the cosine is  
          used.  
  
        * A pre-computed half angle for lighting with infinite lights and an  
          infinite viewer is provided and called "state.light[n].half".  
  
        * Pre-computed products of ambient, diffuse, and specular light colors  
          with the corresponding front or back material colors are supported,  
          and are called "state.lightprod[n].<face>.<property>".  
  
        * Exponential fog density, linear fog start and end parameters, as  
          well as the pre-computed reciprocal of (end-start) are combined into  
          one vector called "state.fog.params".  
  
        * The core point size, minimum and maximum size clamps  
          (ARB_point_parameters), and multisample fade size threshold  
          (ARB_point_parameters) are combined into a single vector called  
          "state.point.size".  
  
        * Precomputed transpose, inverse, and inverse transpose matrices are  
          supported for each base matrix type.  
  
    (16) Should the initial values of temporaries and results be undefined?  
  
      RESOLVED:  Since the underlying hardware differs, it was decided to  
      leave these values uninitalized.  There are a few issues related to this  
      behavior that programs should keep in mind:  
  
        * Since any results not written by the program are undefined, programs  
          should write to all result registers that are needed during  
          rasterization.  
  
        * In particular, the initial vertex position result is undefined, and  
          will remain undefined if not written by a program.  To achieve  
          proper results, vertex programs should be careful to write to all  
          four components of the vertex position.  Otherwise, primitives may  
          be completely clipped or produce undefined results during  
          rasterization.  There is no semantic requirement that programs must  
          write a transformed vertex position, so erroneous programs will load  
          succesfully, but will produce undefined (and probably useless)  
          results.  Such a semantic requirement may be impossible to enforce  
          in future language versions that support run-time branching.  
  
        * Since vertex programs may be executed when the raster position is  
          set, any attributes not written by the program will result in  
          undefined state in the current raster position.  Programs should  
          write to all result registers that would be used when rasterizing  
          pixel primitives using the current raster position.  
  
        * If conventional OpenGL texture mapping operations are performed, a  
          program should always write to the "w" coordinate of any texture  
          coordinates result registers it needs to use.  Conventional OpenGL  
          texture accesses always use projective texture coordinates (e.g.,  
          s/q, t/q, r/q), even though q is almost always 1.0.  An undefined q  
          coordinate (coming from the "w" component of the result register)  
          may produce undefined coordinates on the texture lookup.  
  
    (17) Should vertex programs be required to have a header token and an end  
    token?  
  
      RESOLVED:  Yes.  The header token for this extension is named  
      "!!ARBvp1.0".  The ARB may standardize future language versions which  
      would be expected to have tokens like "!!ARBvp2.0".  Vertex programs  
      must end with the "END" token.  
  
      The initial header token reminds the programmer what type of program  
      they are writing.  If vertex programs are ever read from disk files, the  
      header token can be used to specifically identify vertex programs.  The  
      initial header tokens will also make it easier for programmers to  
      distinguish between multiple types of vertex programs and between vertex  
      programs and another future type of programs.  
  
      We expect that programs may be generated by concatenation of program  
      fragments.  The "END" token will hopefully reduce bugs due to specifying  
      an incorrectly concatenated program.  
  
    (18) Should ProgramStringARB take a <program> specifier?  Should  
    ProgramLocalParameterARB and GetProgramLocalParameterARB take a <program>  
    specifier?  How about GetProgramivARB and GetProgramStringARB?  
  
      RESOLVED:  No to all.  Instead, these calls are specified to always  
      query or modify the currently bound program object.  Using bound objects  
      allows GL implementations to avoid locking and name lookup overhead on  
      each such call.  
  
      This behavior does imply that applications loading a sequence of program  
      objects must bind each in turn.  
  
    (19) Should relative addressing be performed using an address register  
    (load up an integer register) or by taking a floating-point scalar?  
  
      RESOLVED:  Address register.  It would not be a good idea to support  
      both syntaxes simultaneously, since using a floating-point scalar may  
      consume the only available address register in the process.  The current  
      address register syntax can be easily extended to allow for multiple  
      integer registers and/or enable other integer operations in a later  
      extension.  
  
      Using a floating-point index may require an extra instruction on some  
      architectures, and would require optimization work to eliminate  
      redundant loads.  Using a floating-point index may consume one of a  
      small number of temporary registers.  On the other hand, for  
      implementations without a dedicated address register, it may be  
      necessary to dedicate a general-purpose register (or register component)  
      to hold the address register contents.  
  
    (20) How should user-defined clipping be supported in this specification?  
  
      RESOLVED:  User-defined clipping is not supported in standard vertex  
      program mode.  User-defined clipping support will be provided for  
      programs that use the "position invariant" option, where all vertex  
      transformation operations are performed by the fixed-function pipeline.  
        
      It is expected that future vertex program extensions or a future  
      language standard may provide more powerful user clipping functionality.  
  
      The options considered were:  
  
      (1) Not at all.  Does not work for applications requiring user clipping.  
          User clipping could be supported through a language extension.  
  
      (2) Support only through the "position_invariant" option, where vertex  
          transformation is performed by the fixed-function pipeline.  
  
      (3) Support by using the fixed-function pipeline to generate eye  
          coordinates and perform user clipping as specified for conventional  
          transformation.  May not work properly if the vertex transformation  
          doesn't match the standard "multiply by modelview and projection  
          matrices" model.  
    
      (4) Project existing fixed-function clip planes into clip coordinates  
          and perform the clip test in clip space.  The clip planes would be  
          transformed by the inverse of the projection matrix, which will not  
          work if the projection matrix is singular.  
  
      (5) Provide a 4-component "user clip coordinate" result that can be  
          bound by a vertex program.  User clipping is performed as in  
          unextended OpenGL, using the "user clip coordinate" in place of the  
          non-existant eye coordinates.  This approach allows an application  
          to do user clipping in any coordinate system.  Clipping would not be  
          independent of primitive tesselation as in the conventional  
          pipeline.  Additionally, the implicit transformation of specified  
          clip planes by the modelview matrix may be undesirable (e.g.,  
          clipping in object coordinates).  
  
      (6) Provide one or more "clip plane distance" results that can be bound  
          by a vertex program.  For conventional clipping applications, vertex  
          programs would compute the dot products normally computed by  
          fixed-function hardware.  Additionally, this method would enable  
          additional unconventional clipping effects.  Primitives would be  
          clipped to the portion whose interpolated clip distances are greater  
          than or equal to zero.  This approach has the same issues as (5).  
  
    (21) How should future vertex program opcodes be named?  
  
      RESOLVED:  Three-character names are recommended for brevity.  Three  
      character names are not a hard-and-fast requirement; extra characters  
      may be needed for clarity or to disambiguate instructions.  
  
    (22) Should anything be said about the precision used for carrying out the  
    instructions?  
  
      RESOLVED:  Not much; precision will vary across platforms.  The minimum  
      precision requirements (1 part in 10^5 or roughly 17 bits) are spelled  
      out in section 2.1.1.  In practice, implementations will generally  
      provide precision comparable to that obtained using single precision  
      floats.  Documenting exact precision across implementations is  
      difficult.  Additionally, it is difficult to spell out precision  
      requirements for "compound" operations such as DP4.  
  
    (23) Should this extension support evaluator maps for generic vertex  
    attributes?  If so, what attribute sizes should be supported?  Note that  
    such maps are not supported at all for texture units except zero.  
  
      RESOLVED:  No.  Evaluator support has not been consistently extended in  
      previous extensions.  For example, neither ARB_multitexture nor OpenGL  
      1.3 provide support for evaluators for texture units other than unit  
      zero.  Adding evaluators for generic attributes involves a large amount  
      of new state and complexity, particularly if evaluators should be  
      supported in general form (1, 2, 3, and 4 components, all supported data  
      type).  
  
    (25) The number of generic vertex attributes is implementation-dependent  
    and is at least 16.  Each generic vertex attribute has a vertex array  
    enable.  Should two new entry points be provided to accept an arbitrary  
    attribute number, or should we reserve a range of enumerants that is  
    "large enough"?  
  
      RESOLVED:  Yes.  EnableVertexAttribArrayARB and  
      DisableVertexAttribArrayARB.  This allows the number of vertex  
      attributes to be unbounded, instead of using a limited range.  
  
    (26) What limits should be imposed on the constants that can be added to  
    or subtracted from the address register for relative addressing?  Negative  
    offsets are sometimes useful for shifting down in an array.  
  
      RESOLVED:  -64 to +63 should be sufficient for the time being.  Offset  
      sizes are limited to allow offsets to be baked into device-dependent  
      instruction encodings.  
  
    (28) What level of precision should be guaranteed for the EXP and LOG  
    instructions?  And for the EX2 and LG2 instructions?  
  
      RESOLVED:  The low precision EXP and LOG instructions should give at  
      least 10 bits (2^-11 maximum relative error).  No specific treatment  
      will be added for EX2/LG2, implying that the computations should at  
      least meet the minimal floating-point precision required by the spec.  
  
    (29) Should incremental program compilation be supported?  
  
      RESOLVED:  No.  Applications can compile programs just as easily using  
      string concatenation.  
  
    (30) Should the execution environment be identified by the program itself  
    or as an additional "language" parameter to ProgramStringARB?  
  
      RESOLVED:  Programs should identify their execution environment in the  
      header.  The header (plus any specified options) make it clear what kind  
      of program is being defined.  
  
    (31) Should this extension provide support for character sets other than  
    7-bit ASCII?  
  
      RESOLVED:  Provide a <format> argument to ProgramStringARB to allow for  
      future extensions.  Only ASCII will be supported by this extension;  
      additional character sets or encodings could be supported using separate  
      extensions.  
  
    (32) Support for "program object" functionality may be applicable to  
    future program targets.  Should this functionality be factored out into a  
    separate extension?  
  
      RESOLVED:  No, such separation is not necessary.  This extension was  
      designed to allow to easily accommodate future program target types.  It  
      would be straightforward to put program object functionality into a  
      separate extension, but the functionality provided by that extension  
      would be of no value by itself.  
  
    (33) Should program residency management be supported?  
  
      RESOLVED:  No.  This functionality can be supported in a separate  
      extension if desired.  If may be desirable to address residency  
      management in a more general form, where an application may desire a  
      diverse set of objects (textures, programs) to be resident at once.  
  
    (34) Should program object management APIs (GenProgramsARB,  
    DeleteProgramsARB) work like texture objects or display lists?  
  
      RESOLVED:  Texture objects.    
  
      Both approaches have their merits.  Pluses for the display list model  
      include:  no need to keep around multiple indices if you want to  
      allocate a group of object, contiguous indices may fall out on  
      implementations that share one block allocator for textures and display  
      lists.  Pluses for the texture object model:  non-contiguous indices may  
      be more optimizable -- new objects can be mapped to empty blocks in a  
      hash table to avoid collisions with existing objects, separate indices  
      are more compatible with a future handle-based object paradigm, and a  
      larger base of extensions using this model.  Note that display list  
      allocations needed to be contiguous to support CallLists, but no such  
      requirement for texture or program objects exists for programs.  
  
    (35) Should there be support for a program object zero?  With texture  
    objects, texture object zero is "special" because it is the default  
    texture object for each target type.  Is there something like this for  
    program objects?  
  
      RESOLVED:  Yes.  Like texture objects, there should be a separate  
      program object zero for each program type.  This allows applications to  
      use vertex programs without needing to generate and manage program  
      objects.  
  
      With texture objects, an object zero was needed for backward  
      compatibility with pre-OpenGL 1.1 applications.  There is no such  
      requirement here, but providing an object zero nicely matches the  
      familiar texture object model.  
  
    (36) How should this extension provide feedback on why a program failed to  
    load?  
  
      RESOLVED:  Two queries are provided.  Calling GetIntegerv() with  
      PROGRAM_ERROR_POSITION_ARB provides the offset of an offending  
      instruction in the program string.  An error position of -1 indicates  
      that a program loaded successfully.  Calling GetString() with  
      PROGRAM_ERROR_STRING_ARB returns an implementation-dependent error  
      string explaining the reason for the failure.  The error string can be  
      queried even on successful program loads to check for warning messages.  
  
      The error string may be kept in a static buffer managed by the GL  
      implementation.  Implementations may reuse the same buffer on subsequent  
      calls to ProgramStringARB, so returned error strings are guaranteed to  
      be valid only until the next such call.  
  
    (37) How does ARB_vertex_blend's WEIGHT_SUM_UNITY_ARB mode interact with  
    this extension?  This mode allows an application to specify N-1 weights,  
    and have the Nth weight computed by the GL.  
  
      RESOLVED:  The ARB_vertex_blend spec (as of May, 2002) specifies that  
      the nth weight is automatically computed by the GL and is effectively  
      current state.  In practice, ARB_vertex_blend implementations compute  
      the nth weight on the fly in the fixed-function transformation pipeline,  
      implying that the ARB_vertex_blend spec may require a fix.  For the  
      purposes of this extension, the WEIGHT_SUM_UNITY_ARB enable is ignored  
      in vertex program mode.  Applications performing a vertex weighting  
      operation in a vertex program are free to compute the extra weight in  
      the program.  
  
    (38) Should program environment parameters be pushed and popped?  
  
      RESOLVED:  No.  There is no need to push and pop this large set of  
      state, much like pixel maps.  Adding a new attribute bit would have  
      complicated logistics (would the bit be included in ALL_ATTRIB_BITS?).  
      Having program local parameters provides a method for making localized  
      changes to certain state simply by switching programs.  
  
    (39) How should this extension interact with color material?  
  
      RESOLVED:  When color material is enabled, any bindings of material  
      colors that track the current color should be updated when the current  
      color is updated.  In this specification, material properties can be  
      bound only as program parameters, and any changes to the material  
      properties inside a Begin/End leave the bindings undefined until the  
      next End command.  Similarly, any indirect changes to the material  
      properties (through ColorMaterial) will have a similar effect.  
  
      Several other options were considered here.  One option was to support  
      per-vertex material property bindings and have programs that reference  
      tracked material properties should get the current color.  This could be  
      handled either by broadcasting the current color to multiple vertex  
      attributes, or recompiling the vertex program so that references to a  
      tracked material property are redirected to the vertex color.  Both such  
      solutions are somewhat complex.  A second option would be to ignore the  
      COLOR_MATERIAL enable and instead use an "old" material color.  This  
      breaks the standard color material model.  Implementations can and often  
      do defer such updates (making an "old" color available), some conditions  
      may cause an implementation to update of material state at odd times.  
  
    (41) What about when the execution environment involves support for other  
    extensions?  In particular, the execution environment subsumes some  
    functionality from EXT/ARB_point_parameters, EXT_fog_coord,  
    EXT_secondary_color, and ARB_multitexture.  
  
      RESOLVED:  This extension assumes support for functionality that  
      includes a fog coordinate, secondary color, per-vertex point sizes, and  
      multiple texture coordinates (at least to the extent that it exposes >1  
      texture coordinate).  All of these extensions are supported fairly  
      widely.  On some platforms, some of this functionality may require  
      software fallbacks.  
  
    (42) How does PointSize work with vertex programs?  
  
      RESOLVED:  If VERTEX_PROGRAM_POINT_SIZE_ARB is disabled, the size of  
      points is determined by the PointSize state and is not attenuated, even  
      if EXT_point_parameters is supported.  If enabled, the point size is the  
      point size result value, and is clamped to implementation-dependent  
      point size limits during point rasterization.  
  
    (43) What do we say about the alpha component of the secondary color?  
  
      RESOLVED:  The alpha component of the secondary color has generally been  
      treated as zero.  This extension specifies that only the R, G, and B  
      components are added in the color sum operation, making the alpha  
      component of the secondary color irrelevant.  Other downstream  
      extensions may allow applications to make use of this component.  
  
    (44) How are edge flags handled?  
  
      RESOLVED:  Edge flags are passed through without the ability to be  
      modified by a vertex program.  Applications are free to send edge flags  
      when vertex program mode is enabled.  
  
    (45) Should programs be C-style null-terminated strings?  
        
      RESOLVED:  No.  Programs should be specified as an array of GLubyte with  
      an explicit length parameter.  OpenGL has no precedent for passing  
      null-terminated strings into the API (though GetString returns  
      null-terminated strings).  Null-terminated strings may be problematic  
      for some programming languages.  
  
    (46) Should all existing OpenGL transform functionality and extensions be  
    implementable as vertex programs?  
  
      RESOLVED:  Yes.  Vertex programs should be a complete superset of what  
      you can do with OpenGL 1.2 and existing vertex transform extensions.  To  
      implement EXT_point_parameters, the VERTEX_PROGRAM_POINT_SIZE_ARB enable  
      is introduced.  To implement two-sided lighting, the  
      VERTEX_PROGRAM_TWO_SIDE_ARB enable is introduced.  To implement color  
      material, applications should refer to the per-vertex color attribute in  
      their vertex programs.  
  
    (47) Should there be a plural version of ProgramEnvParameter and  
    ProgramLocalParameter, which would set multiple parameters in a single  
    call?  
  
      RESOLVED:  No; not necessary.  
  
    (48) Can the currently bound vertex program object be deleted or reloaded?  
  
      RESOLVED:  Yes.  When ProgramStringARB is called to reload a program  
      object, subsequent program executions will use the new program.  When  
      DeleteProgramsARB deletes a currently bound program object, object zero  
      becomes the new current program object.  
  
    (49) What happens if you transform vertices in vertex program mode, but  
    the current program object does not contain a valid vertex program?  
  
      RESOLVED:  Begin will fail with an INVALID_OPERATION error if the  
      currently bound vertex program object does not have a valid program.  
      The same applies to RasterPos and any command (Rect, DrawArrays,  
      DrawElements) that implies a Begin.  
  
      Because Vertex is ignored outside of a Begin/End pair (without  
      generating an error) it is impossible to provoke a vertex program if the  
      current vertex program object is nonexistent or invalid.  Other  
      per-vertex parameters (for examples those set by Color, Normal, and  
      VertexAttrib*ARB when the attribute number is not zero) are allowed  
      since they are legal outside of a Begin/End.  
  
    (50) Discussing matrices is confusing because of row-major versus  
    column-major issues.  Can you give an example of how a matrix is bound?  
  
      RESOLVED:  Assume program matrix zero were loaded with the following  
      code:  
   
        // When loaded, the first row is "1, 2, 3, 4", because of column-major  
        // (OpenGL spec) vs. row-major (C) differences.  
        GLfloat matrix[16] = { 1, 5, 9,  13,  
                               2, 6, 10, 14,  
                               3, 7, 11, 15,  
                               4, 8, 12, 16 };  
        glMatrixMode(GL_MATRIX0_ARB);  
        glLoadMatrixf(matrix);  
  
      Then in the program  
  
        !!ARBvp1.0  
        PARAM mat1[4] = { state.matrix.program[0] };  
        PARAM mat2[4] = { state.matrix.program[0].transpose };  
  
      mat1[0] would have (1,2,3,4), mat1[3] would have (13,14,15,16), mat2[0]  
      would have (1,5,9,13), and mat2[3] would have (4,8,12,16).  
  
    (51) Should the new vertex program-related enables push/pop with  
    ENABLE_BIT?  
  
      RESOLVED:  Yes.  Pushing and popping enable bits is easy.  
  
    (52) Should all the vertex attribute state push/pop with CURRENT_BIT?  
  
      RESOLVED:  Yes.  
  
    (53) Should all the vertex attrib vertex array state push/pop with  
    CLIENT_VERTEX_ARRAY_BIT?  
  
      RESOLVED:  Yes.  
  
    (55) Should we generate an INVALID_VALUE operation if updating a vertex  
    attribute greater than MAX_VERTEX_ATTRIBS_ARB?  
  
      RESOLVED:  Yes.  The other option would be to leave the behavior  
      undefined, as with MultiTexCoord() functions.  An implementation could  
      mask or modulo the vertex attribute index with MAX_VERTEX_ATTRIB_ARB if  
      it were a power of two.  This error check will be a minor performance  
      issue with VertexAttrib*ARB() and VertexAttribArrayARB() calls.  There  
      will be no per-vertex overhead when using vertex arrays or display  
      lists.  
  
    (56) Should writes to program environment or local parameters during a  
    vertex program be supported?  
  
      RESOLVED.  No.  Writes to program parameter registers from within a  
      vertex program would require the execution of vertex programs to be  
      serialized with respect to each other.  This would create a severe  
      implementation penalty for pipelined or parallel vertex program  
      execution implementations.  
  
    (58) Should program objects be shared among rendering contexts in the same  
    manner as display lists and texture objects?  
  
      RESOLVED:  Yes.  
  
    (60) Should there be a MatrixMode or ActiveTexture-style selector for  
    vertex attributes?  
  
      RESOLVED:  No.  While this would reduce the number of enumerants used by  
      this extensions, it would create programming a hassle in lots of cases.  
      Consider having to change the vertex attribute mode to enable a set of  
      vertex arrays.  
  
    (61) How should queries of vertex attribute arrays work?  
  
      RESOLVED:  Add new get commands.  Using the existing calls would require  
      adding 6 sets of 16+ enumerants for current state and vertex attribute  
      array state.  That's too many new enumerants.  Instead, add  
      GetVertexAttribARB and GetVertexAttribPointervARB.  GetVertexAttribARB  
      will be used to query vertex attribute array state and the current  
      values of the generic vertex attributes.  Get and GetPointerv will not  
      return vertex attribute array state and pointers.  
  
    (63) What should be said about rendering invariances?  
  
      RESOLVED:  See the Appendix A additions below.  
  
      The justification for the two rules cited is to support multi-pass  
      rendering when using vertex programs.  Different rendering passes will  
      likely use different programs so there must be some means of  
      guaranteeing that two different programs can generate particular  
      identical vertex results between different passes.  
  
      In practice, this does limit the type of vertex program implementations  
      that are possible.  
  
      For example, consider a limited hardware implementation of vertex  
      programs that uses a different floating-point implementation than the  
      CPU's floating-point implementation.  If the limited hardware  
      implementation can only run small vertex programs (say the hardware  
      provides on 4 temporary registers instead of the required 12), the  
      implementation is incorrect and non-conformant if programs that only  
      require 4 temporary registers use the vertex program hardware, but  
      programs that require more than 4 temporary registers are implemented by  
      the CPU.  
  
      This is a very important practical requirement.  Consider a multi-pass  
      rendering algorithm where one pass uses a vertex program that uses only  
      4 temporary registers, but a different pass uses a vertex program that  
      uses 5 temporary registers.  If two programs have instruction sequences  
      that given the same input state compute identical resulting vertex  
      positions, the multi-pass algorithm should generate identically  
      positioned primitives for each pass.  But given the non-conformant  
      vertex program implementation described above, this could not be  
      guaranteed.  
  
      This does not mean that schemes for splitting vertex program  
      implementations between dedicated hardware and CPUs are impossible.  If  
      the CPU and dedicated vertex program hardware used IDENTICAL  
      floating-point implementations and therefore generated exactly identical  
      results, the above described could work.  
  
      While these invariance rules are vital for vertex programs operating  
      correctly for multi-pass algorithms, there is no requirement that  
      conventional OpenGL vertex transform mode will be invariant with vertex  
      program mode.  A multi-pass algorithm should not assume that one pass  
      using vertex program mode and another pass using conventional GL vertex  
      transform mode will generate identically positioned primitives.  
  
      Consider that while the conventional OpenGL vertex program mode is  
      repeatable with itself, the exact procedure used to transform vertices  
      is not specified nor is the procedure's precision specified.  The GL  
      specification indicates that vertex coordinates are transformed by the  
      modelview matrix and then transformed by the projection matrix.  Some  
      implementations may perform this sequence of transformations exactly,  
      but other implementations may transform vertex coordinates by the  
      composite of the modelview and projection matrices (one matrix transform  
      instead of two matrix transforms in sequence).  Given this  
      implementation flexibility, there is no way for a vertex program author  
      to exactly duplicate the precise computations used by the conventional  
      OpenGL vertex transform mode.  
  
      The guidance to OpenGL application programs is clear.  If you are going  
      to implement multi-pass rendering algorithms that require certain  
      invariances between the multiple passes, choose either vertex program  
      mode or the conventional OpenGL vertex transform mode for your rendering  
      passes, but do not mix the two modes.  
  
    (64) Should there be a way to guarantee position invariance with respect  
    to conventional vertex transformation?  
  
      RESOLVED:  Yes.  The "OPTION ARB_position_invariant" program option  
      addresses this issue.  This program option will be available on all  
      implementations of this extension.  
  
      John Carmack advocated the need for this.  
  
    (65) Why must RCP of 1.0 always be 1.0?  
  
      RESOLVED:  This is important for 3D graphics so that non-projective  
      textures and orthogonal projections work as expected.  Basically when q  
      or w is 1.0, things should work as expected.  Stronger requirements such  
      as "RCP of -1.0 must always be -1.0" are encouraged, but there is no  
      compelling reason to state such requirements explicitly as is the case  
      for "RCP of 1.0 must always be 1.0".  
  
    (66) What happens when the source scalar value for the ARL instruction is  
    an extremely large positive or negative floating-point value?  Is there a  
    problem mapping the value to a constrained integer range?  
  
      RESOLVED:  In this extension, address registers are only useful for  
      relative addressing.  The range of offsets that can be added to an  
      address register is limited (-64 to +63) and the set of valid array  
      indices is also limited to MAX_PROGRAM_PARAMETERS_ARB.  So, the set of  
      floating-point values that needs to be handled properly is  
      well-constrained.  
  
    (67) How do you perform a 3-component normalize in three instructions?  
  
      RESOLVED:  As follows.  
  
        DP3 result.w, vector, vector;     # result.w = nx^2+ny^2+nz^2  
        RSQ result.w, result.w;           # result.w = 1/sqrt(nx^2+ny^2+nz^2)  
        MUL result.xyz, result.w, vector;  
  
    (69) How do you compute the determinant of a 3x3 matrix in three  
    instructions?  
  
      RESOLVED:  As follows.  
  
        #  
        # Determinant of | vec0.x  vec0.y  vec0.z | into result.  
        #                | vec1.x  vec1.y  vec1.z |  
        #                | vec2.x  vec2.y  vec2.z |  
        #  
        MUL result, vec1.zxyw, vec2.yzxw;  
        MAD result, vec1.yzxw, vec2.zxyw, -result;  
        DP3 result, vec0, result;  
  
    (70) How do you transform a vertex position by a 4x4 matrix and then  
    perform a homogeneous divide?  
  
      RESOLVED:  As follows.  
  
        ATTRIB  pos = vertex.position;  
        TEMP    result, temp;  
        PARAM   mat[4] = { state.matrix.modelview };  
  
        DP4     result.w, pos, mat[3];  
        DP4     result.x, pos, mat[0];  
        DP4     result.y, pos, mat[1];  
        DP4     result.z, pos, mat[2];  
        RCP     temp.w, result.w;  
        MUL     result, result, temp.w;  
  
    (71) How do you perform a vector weighting of two vectors using a single  
    weight?  
  
      RESOLVED:  As follows.  
  
        # result = a * vec0 + (1-a) * vec1  
        #        = vec1 + a * (vec0 - vec1)  
        SUB result, vec0, vec1;  
        MAD result, a, result, vec1;  
  
    (72) How do you reduce a value to some fundamental period such as 2*PI?  
  
      RESOLVED:  As follows.  
  
        # result = 2*PI * fraction(in/(2*PI))  
        # piVec = (1/(2*PI), 2*PI, 0, 0)  
        PARAM piVec = { 0.159154943, 6.283185307, 0, 0 };  
  
        MUL result, in, piVec.x;  
        EXP result, result.x;  
        MUL result, result.y, piVec.y;  
  
    (73) How do you implement a simple ambient, specular, and diffuse infinite  
    lighting computation with a single light and an eye-space normal?  
  
      RESOLVED:  As follows.  
  
        !!ARBvp1.0  
        ATTRIB iPos         = vertex.position;  
        ATTRIB iNormal      = vertex.normal;  
        PARAM  mvinv[4]     = { state.matrix.modelview.invtrans };  
        PARAM  mvp[4]       = { state.matrix.mvp };  
        PARAM  lightDir     = state.light[0].position;  
        PARAM  halfDir      = state.light[0].half;  
        PARAM  specExp      = state.material.shininess;  
        PARAM  ambientCol   = state.lightprod[0].ambient;  
        PARAM  diffuseCol   = state.lightprod[0].diffuse;  
        PARAM  specularCol  = state.lightprod[0].specular;  
        TEMP   xfNormal, temp, dots;  
        OUTPUT oPos         = result.position;  
        OUTPUT oColor       = result.color;  
  
        # Transform the vertex to clip coordinates.     
        DP4   oPos.x, mvp[0], iPos;  
        DP4   oPos.y, mvp[1], iPos;  
        DP4   oPos.z, mvp[2], iPos;  
        DP4   oPos.w, mvp[3], iPos;  
  
        # Transform the normal to eye coordinates.  
        DP3   xfNormal.x, mvinv[0], iNormal;  
        DP3   xfNormal.y, mvinv[1], iNormal;  
        DP3   xfNormal.z, mvinv[2], iNormal;  
          
        # Compute diffuse and specular dot products and use LIT to compute  
        # lighting coefficients.  
        DP3   dots.x, xfNormal, lightDir;  
        DP3   dots.y, xfNormal, halfDir;  
        MOV   dots.w, specExp.x;  
        LIT   dots, dots;  
  
        # Accumulate color contributions.  
        MAD   temp, dots.y, diffuseCol, ambientCol;  
        MAD   oColor.xyz, dots.z, specularCol, temp;  
        MOV   oColor.w, diffuseCol.w;  
        END  
  
    (75) Can you perturb transformed vertex positions with a vertex program?  
  
       RESOLVED: Yes.  Here is an example that performs an object-space  
       diffuse lighting computations and perturbs the vertex position based on  
       this lighting result.  Do not take this example too seriously.  
  
         !!ARBvp1.0  
         #  
         # Program environment parameters:  
         # c[0].xyz = normalized light direction in object-space  
         #  
         # outputs diffuse illumination for color and perturbed position  
         #  
         ATTRIB iPos         = vertex.position;  
         ATTRIB iNormal      = vertex.normal;  
         PARAM  mvp[4]       = { state.matrix.mvp };  
         PARAM  lightDir     = program.env[0];  
         PARAM  diffuseCol   = { 1, 1, 0, 1 };  
         TEMP   temp;  
         OUTPUT oPos         = result.position;  
         OUTPUT oColor       = result.color;  
   
         DP3   temp, lightDir, iNormal;  
         MUL   oColor.xyz, temp, diffuseCol;  
         MAX   temp, temp, 0;            # clamp dot product to zero  
         MUL   temp, temp, iNormal;      # align in direction of normal  
         MUL   temp, temp, 0.125;        # scale displacement by 1/8  
         SUB   temp, temp, iPos;         # perturb  
         DP4   oPos.x, mvp[0], temp;     # xform using perturbed position  
         DP4   oPos.y, mvp[1], temp;  
         DP4   oPos.z, mvp[2], temp;  
         DP4   oPos.w, mvp[3], temp;  
         END  
  
    (76) Should this extension provide any method for updating program  
    parameters in a program itself?  
  
      RESOLVED:  No.  NV_vertex_program provided a special mechanism to do  
      this using a "vertex state program" manually executed by calling  
      ExecuteProgramNV.  This capability has not proven itself particularly  
      useful to date.  
  
    (78) Should there be a different ProgramStringARB call for every distinct  
    program target?  Arguably, 1D, 2D, and 3D textures each have their own  
    TexImage command for specifying their image data.  
  
      RESOLVED:  No.  All program objects can/should be loaded with  
      ProgramStringARB.  We expect the string to be a sufficient to express  
      any kind of programmability.  
  
      Moreover, the 1D, 2D, and 3D TexImage commands describe the image being  
      specified as opposed to the texture target being updated.  With cube map  
      textures, there are six face texture targets that use the TexImage2D  
      command but not with the TEXTURE_2D target.  
  
    (79) This extension introduces a collection of new matrices for use by  
    vertex programs (and possibly other programs as well).  What should these  
    matrices be called?  
  
      RESOLVED:  Program matrices.  These matrices are referred to as  
      "tracking matrices" in NV_vertex_program, but the functionality is  
      equivalent.  
  
    (80) With ARB_vertex_blend and EXT_vertex_weighting, there are multiple  
    modelview matrices.  This extension provides a single "MVP" matrix,  
    defined to be the product of modelview matrix 0 and the projection  
    matrices.  Should this extension instead provide one MVP matrix per  
    modelview matrix?  
  
      RESOLVED:  No.  Providing multiple MVP matrices allows applications to  
      do N transformations into clip space and then one weighting operation,  
      instead of N transformations into eye space, a weighting operation, and  
      then a single transformation into clip space.  This would potentially  
      save instructions, but this optimization would be of no value if the  
      program did any other operations that required eye coordinates.  
        
      Note also that the MVP transformations are likely general 4x4 matrix  
      multiplies (4 DP4 instructions per transform).  On the other hand,  
      object and eye coordinates are often 3D coordinates with a constant W of  
      1.0.  So each transformation to eye coordinates may require only 3 DP4  
      instructions, in which case the comparison may be 4N instructions (clip  
      weighting) vs. 3N+4 (eye weighting).  
  
    (81) Should variable declarations be allowed to be anywhere within the  
    program body, or should they instead be required to be done at the  
    beginning of the program?  Should the possibility of branching in a future  
    standard affect this resolution?  
  
      RESOLVED:  Declarations will be allowed anywhere in the program text;  
      the only ordering requirement is that the declaration of a variable must  
      precede its use in the program text.  Requiring up-front variable  
      declarations may require multiple passes for applications that build  
      programs on the fly.  
  
      While declarations can appear anywhere in the program body, they are not  
      executable statements.  Any corresponding bindings (including constant  
      initializations) are resolved before the program executes.  The bindings  
      will be resolved even if a program were to "branch around" a  
      declaration.  
  
    (82) Should address register variables be treated as vectors?  If so,  
    should a variable number of components (up to four) be supported by this  
    extension?  
  
      RESOLVED:  In the future, four-component address vectors may be  
      supported, and vector notation is used for forward compatibility.  Using  
      this notation makes address registers consistent with all the other  
      vector data types in this extension.  However, support for more than one  
      usable component will be left for future extensions, but could be added  
      via a program option or in a new language revision (e.g., !!ARBvp2.0).  
  
    (83) Should program local parameters be logically connected to the program  
    string or the program object?  
  
      RESOLVED:  Program local parameters are properties of a program object.  
      Their values persist even after a new program is loaded into the object.  
      This model does allow applications to recompile the program in a given  
      object based on certain rendering settings without having to  
      re-initialize any state stored in the object.  
  
    (84) Should this extension provide a method to specify "anonymous" program  
    local parameters and query an index into the program parameter array.  
  
      RESOLVED:  No.  It would be nice to declare a variable in a program such  
      as  
  
        PARAM foo = program.local;  # note no index in the array  
  
      after which an application could query the location of "foo" in the  
      program local parameter array.  However, given that local parameters  
      persist even across program loads, it would be difficult to specify what  
      program local parameter "foo" would be assigned to.  
  
    (85) EXT_vertex_weighting provides a single vertex blend weight.  
    ARB_vertex_blend generalizes this concept to a weight vector.  Both pieces  
    of state are specified separately, and could be thought of as distinct.  
    Should distinct bindings be provided in this extension?  
  
      RESOLVED:  No.  No current implementation supports both extensions, but  
      the vendors involved in this standardization process agree that the  
      state should not be considered distinct.  If an implementation supported  
      both extensions, the APIs would modify the same state.  
  
    (86) Should this extension provide functionality for variable aliasing?  
    If so, how should it be specified and what types of variables can be  
    aliasesed?  
  
      RESOLVED:  Yes, for all variable types.  The syntax is a simple text  
      replacement:  
  
        ALIAS a = b;  
  
      This functionality allows applications to "share" variables, and thereby  
      exceed implementation-dependent limits on the number of variable  
      declarations.  This may be particularly significant for temporaries,  
      where the limit on the number of variables may be fairly low.  
  
    (87) How do you determine whether a given program option is supported by  
    the GL implementation?  
  
      RESOLVED:  Program options may be introduced in OpenGL extensions and  
      may be added to future OpenGL specifications.  An option will be  
      supported if and only if (1) the corresponding OpenGL extension appears  
      in the implementation-dependent EXTENSIONS string or (2) the option is  
      documented in the OpenGL specification version corresponding to the  
      implementation's VERSION string.  
  
      The ARB_position_invariant option is provided by this extension, and  
      will always be available (provided this extension is supported).  
  
    (88) What's the deal with binding the alpha component of light colors, fog  
    colors, and material colors (other than diffuse)?  They don't do anything,  
    right?  
  
      RESOLVED:  The GL state for these different colors includes alpha  
      components, which will be returned by queries.  However, in the  
      conventional OpenGL pipeline, most of these alpha components are  
      effectively ignored.  However, since they are present in the GL state,  
      they will be exposed in bindings.  What is done with these alpha values  
      in program mode is completely up to the vertex program.  
  
      Vertex programs need to be careful to ensure that the alpha component is  
      computed correctly when evaluating lighting equations.  When  
      accumulating light contributions, it may be necessary to use write masks  
      to disable writes to the alpha component.  
  
    (89) The LOG instruction takes the logarithm of the absolute value of its  
    operand while the LG2 instruction takes the logarithm of the operand  
    itself.  In LG2, the logarithm of negative numbers is undefined.  
  
      RESOLVED:  The LOG instruction is present for (1) compatibility with  
      NV_vertex_program and DirectX 8 languages and (2) because it may  
      outperform LG2 on some platforms.  For compatibility, it is defined to  
      behave identically to existing languages.  
  
    (90) With vertex programs, fog coordinates and point sizes can be computed  
    on a per-vertex basis.  How are the fog coordinates and point sizes  
    associated with vertices introduced by clipping computed?  
  
      RESOLVED:  Fog coordinates and point sizes for clipped vertices are  
      computed by interpolating the computed values at the original vertices  
      in exactly the same manner as colors and texture coordinates are  
      interpolated in section 2.13.8 of the OpenGL 1.3 specification.  
  
    (91) Vertex programs support only RGBA colors, but do not support color  
    index inputs or results.  What happens if an application uses vertex  
    programs in color index mode.  
  
      RESOLVED:  The results of vertex program execution are undefined if the  
      GL is in color index mode.  
  
    (92) Should automatic normalization of evaluated normals (AUTO_NORMAL) be  
    supported when the GL is in vertex program mode?  
  
      RESOLVED:  Automatic normalization of normals will be disabled in vertex  
      program mode.  The current vertex program can easily normalize the  
      normal if required.  This can lead to greater efficiency if the vertex  
      program transforms the normal to another coordinate system such as  
      eye-space with a transform that preserves vector length.  Then a single  
      normalize after transform is more efficient than normalizing after  
      evaluation and normalizing again after transform.  Conceptually, the  
      normalize mandated for AUTO_NORMAL in section 5.1 is just one of the  
      many transformation operations subsumed by vertex programs.  
  
    (93) This extension allows applications to name their own variables.  What  
    keywords should be reserved?  
  
      RESOLVED:  Instruction names and declaration keywords (e.g., PARAM) will  
      be reserved.  Additionally, since attribute, parameter, and result  
      bindings are allowed in the program text, the binding prefix keywords  
      "vertex", "state", "program", and "result" are reserved to simplify  
      parsing.  This prevents the need to distinguish between  
      "vertex.position" ("vertex" as a binding) and "vertex.xyzw" ("vertex" as  
      a variable).  
  
    (94) When counting the number of program parameter bindings, multiple  
    constant vectors with the same components are counted only once.  How is  
    this determined?  
  
      RESOLVED:  The implementation does a numerical comparison after the  
      specified constants are converted to an internal floating-point  
      representation.  Due to floating-point representation limits, such  
      conversions are not always precise.  Constants specified with different  
      text that are "equivalent" (e.g., "12" and "1.2E+01") are not guaranteed  
      to resolve to the same value.  Additionally, constants that are not  
      "equivalent" but have only small relative differences (e.g., "200000000"  
      and "200000001") may end up resolving to the same value.  Constants  
      specified with the same text should always be identical.  
  
    (95) What characters are allowed in identifier names?  
  
      RESOLVED:  Letters ("A"-"Z", "a"-"z"), numbers ("0"-"9"), underscores  
      ("_"), and dollar signs ("$").  
  
    (96) How should future programmability extensions interact with this one?  
  
      RESOLVED:  Future programmability extensions are expected to fall in one  
      of two classes:  (1) extensions that bring programmability to new  
      sections and (2) extensions the extend existing programmability models.  
      The former class should introduce a new program target; the latter class  
      would extend the functionality of an existing target.  
  
      Recommendations for extensions introducing new program targets include:  
  
        * Re-use and reference the functionality specified in this extension  
          (or in a future OpenGL specification incorporating this extension)  
          as much as possible, to maintain a consistent model.  
  
        * Provide a program header allowing for easy identification and  
          versioning of programs for the new target.  
  
      Recommendations for extensions modifying existing program targets  
      include:  
  
        * The option mechanism (section 2.14.4.5) should be used to provide  
          minor modifications to the program language.  
  
        * The program header/version string (section 2.14.2) should be used to  
          provide major modifications to the language, or potentially to  
          provide a commonly used collection of options.  Program header  
          string changes should be multi-vendor extensions as much as  
          possible.  
  
        * For portability, programs should not be allowed to use extended  
          language features without specifying the corresponding program  
          options or program header.  
  
  
homeprevnext New Procedures and Functions
  
    void VertexAttrib1sARB(uint index, short x);  
    void VertexAttrib1fARB(uint index, float x);  
    void VertexAttrib1dARB(uint index, double x);  
    void VertexAttrib2sARB(uint index, short x, short y);  
    void VertexAttrib2fARB(uint index, float x, float y);  
    void VertexAttrib2dARB(uint index, double x, double y);  
    void VertexAttrib3sARB(uint index, short x, short y, short z);  
    void VertexAttrib3fARB(uint index, float x, float y, float z);  
    void VertexAttrib3dARB(uint index, double x, double y, double z);  
    void VertexAttrib4sARB(uint index, short x, short y, short z, short w);  
    void VertexAttrib4fARB(uint index, float x, float y, float z, float w);  
    void VertexAttrib4dARB(uint index, double x, double y, double z, double w);  
    void VertexAttrib4NubARB(uint index, ubyte x, ubyte y, ubyte z, ubyte w);  
  
    void VertexAttrib1svARB(uint index, const short *v);  
    void VertexAttrib1fvARB(uint index, const float *v);  
    void VertexAttrib1dvARB(uint index, const double *v);  
    void VertexAttrib2svARB(uint index, const short *v);  
    void VertexAttrib2fvARB(uint index, const float *v);  
    void VertexAttrib2dvARB(uint index, const double *v);  
    void VertexAttrib3svARB(uint index, const short *v);  
    void VertexAttrib3fvARB(uint index, const float *v);  
    void VertexAttrib3dvARB(uint index, const double *v);  
    void VertexAttrib4bvARB(uint index, const byte *v);  
    void VertexAttrib4svARB(uint index, const short *v);  
    void VertexAttrib4ivARB(uint index, const int *v);  
    void VertexAttrib4ubvARB(uint index, const ubyte *v);  
    void VertexAttrib4usvARB(uint index, const ushort *v);  
    void VertexAttrib4uivARB(uint index, const uint *v);  
    void VertexAttrib4fvARB(uint index, const float *v);  
    void VertexAttrib4dvARB(uint index, const double *v);  
    void VertexAttrib4NbvARB(uint index, const byte *v);  
    void VertexAttrib4NsvARB(uint index, const short *v);  
    void VertexAttrib4NivARB(uint index, const int *v);  
    void VertexAttrib4NubvARB(uint index, const ubyte *v);  
    void VertexAttrib4NusvARB(uint index, const ushort *v);  
    void VertexAttrib4NuivARB(uint index, const uint *v);  
  
    void VertexAttribPointerARB(uint index, int size, enum type,   
                                boolean normalized, sizei stride,  
                                const void *pointer);  
  
    void EnableVertexAttribArrayARB(uint index);  
    void DisableVertexAttribArrayARB(uint index);  
  
    void ProgramStringARB(enum target, enum format, sizei len,   
                          const void *string);   
  
    void BindProgramARB(enum target, uint program);  
  
    void DeleteProgramsARB(sizei n, const uint *programs);  
  
    void GenProgramsARB(sizei n, uint *programs);  
  
    void ProgramEnvParameter4dARB(enum target, uint index,  
                                  double x, double y, double z, double w);  
    void ProgramEnvParameter4dvARB(enum target, uint index,  
                                   const double *params);  
    void ProgramEnvParameter4fARB(enum target, uint index,  
                                  float x, float y, float z, float w);  
    void ProgramEnvParameter4fvARB(enum target, uint index,  
                                   const float *params);  
  
    void ProgramLocalParameter4dARB(enum target, uint index,  
                                    double x, double y, double z, double w);  
    void ProgramLocalParameter4dvARB(enum target, uint index,  
                                     const double *params);  
    void ProgramLocalParameter4fARB(enum target, uint index,  
                                    float x, float y, float z, float w);  
    void ProgramLocalParameter4fvARB(enum target, uint index,  
                                     const float *params);  
  
    void GetProgramEnvParameterdvARB(enum target, uint index,  
                                     double *params);  
    void GetProgramEnvParameterfvARB(enum target, uint index,   
                                     float *params);  
  
    void GetProgramLocalParameterdvARB(enum target, uint index,  
                                       double *params);  
    void GetProgramLocalParameterfvARB(enum target, uint index,   
                                       float *params);  
  
    void GetProgramivARB(enum target, enum pname, int *params);  
  
    void GetProgramStringARB(enum target, enum pname, void *string);  
  
    void GetVertexAttribdvARB(uint index, enum pname, double *params);  
    void GetVertexAttribfvARB(uint index, enum pname, float *params);  
    void GetVertexAttribivARB(uint index, enum pname, int *params);  
  
    void GetVertexAttribPointervARB(uint index, enum pname, void **pointer);  
  
    boolean IsProgramARB(uint program);  
  
  
homeprevnext New Tokens
  
    Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, by the  
    <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev,  
    and by the <target> parameter of ProgramStringARB, BindProgramARB,  
    ProgramEnvParameter4[df][v]ARB, ProgramLocalParameter4[df][v]ARB,  
    GetProgramEnvParameter[df]vARB, GetProgramLocalParameter[df]vARB,  
    GetProgramivARB, and GetProgramStringARB.  
  
        VERTEX_PROGRAM_ARB                              0x8620  
  
    Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, and by  
    the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and  
    GetDoublev:  
  
        VERTEX_PROGRAM_POINT_SIZE_ARB                   0x8642  
        VERTEX_PROGRAM_TWO_SIDE_ARB                     0x8643  
        COLOR_SUM_ARB                                   0x8458  
  
    Accepted by the <format> parameter of ProgramStringARB:  
  
        PROGRAM_FORMAT_ASCII_ARB                        0x8875  
  
    Accepted by the <pname> parameter of GetVertexAttrib[dfi]vARB:  
  
        VERTEX_ATTRIB_ARRAY_ENABLED_ARB                 0x8622  
        VERTEX_ATTRIB_ARRAY_SIZE_ARB                    0x8623  
        VERTEX_ATTRIB_ARRAY_STRIDE_ARB                  0x8624  
        VERTEX_ATTRIB_ARRAY_TYPE_ARB                    0x8625  
        VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB              0x886A  
        CURRENT_VERTEX_ATTRIB_ARB                       0x8626  
  
    Accepted by the <pname> parameter of GetVertexAttribPointervARB:  
  
        VERTEX_ATTRIB_ARRAY_POINTER_ARB                 0x8645  
  
    Accepted by the <pname> parameter of GetProgramivARB:  
  
        PROGRAM_LENGTH_ARB                              0x8627  
        PROGRAM_FORMAT_ARB                              0x8876  
        PROGRAM_BINDING_ARB                             0x8677  
        PROGRAM_INSTRUCTIONS_ARB                        0x88A0  
        MAX_PROGRAM_INSTRUCTIONS_ARB                    0x88A1  
        PROGRAM_NATIVE_INSTRUCTIONS_ARB                 0x88A2  
        MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB             0x88A3  
        PROGRAM_TEMPORARIES_ARB                         0x88A4  
        MAX_PROGRAM_TEMPORARIES_ARB                     0x88A5  
        PROGRAM_NATIVE_TEMPORARIES_ARB                  0x88A6  
        MAX_PROGRAM_NATIVE_TEMPORARIES_ARB              0x88A7  
        PROGRAM_PARAMETERS_ARB                          0x88A8  
        MAX_PROGRAM_PARAMETERS_ARB                      0x88A9  
        PROGRAM_NATIVE_PARAMETERS_ARB                   0x88AA  
        MAX_PROGRAM_NATIVE_PARAMETERS_ARB               0x88AB  
        PROGRAM_ATTRIBS_ARB                             0x88AC  
        MAX_PROGRAM_ATTRIBS_ARB                         0x88AD  
        PROGRAM_NATIVE_ATTRIBS_ARB                      0x88AE  
        MAX_PROGRAM_NATIVE_ATTRIBS_ARB                  0x88AF  
        PROGRAM_ADDRESS_REGISTERS_ARB                   0x88B0  
        MAX_PROGRAM_ADDRESS_REGISTERS_ARB               0x88B1  
        PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB            0x88B2  
        MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB        0x88B3  
        MAX_PROGRAM_LOCAL_PARAMETERS_ARB                0x88B4  
        MAX_PROGRAM_ENV_PARAMETERS_ARB                  0x88B5  
        PROGRAM_UNDER_NATIVE_LIMITS_ARB                 0x88B6  
  
    Accepted by the <pname> parameter of GetProgramStringARB:  
  
        PROGRAM_STRING_ARB                              0x8628  
  
    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,  
    GetFloatv, and GetDoublev:  
  
        PROGRAM_ERROR_POSITION_ARB                      0x864B  
        CURRENT_MATRIX_ARB                              0x8641  
        TRANSPOSE_CURRENT_MATRIX_ARB                    0x88B7  
        CURRENT_MATRIX_STACK_DEPTH_ARB                  0x8640  
        MAX_VERTEX_ATTRIBS_ARB                          0x8869  
        MAX_PROGRAM_MATRICES_ARB                        0x862F  
        MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB              0x862E  
  
    Accepted by the <name> parameter of GetString:  
  
        PROGRAM_ERROR_STRING_ARB                        0x8874  
  
    Accepted by the <mode> parameter of MatrixMode:  
      
        MATRIX0_ARB                                     0x88C0  
        MATRIX1_ARB                                     0x88C1  
        MATRIX2_ARB                                     0x88C2  
        MATRIX3_ARB                                     0x88C3  
        MATRIX4_ARB                                     0x88C4  
        MATRIX5_ARB                                     0x88C5  
        MATRIX6_ARB                                     0x88C6  
        MATRIX7_ARB                                     0x88C7  
        MATRIX8_ARB                                     0x88C8  
        MATRIX9_ARB                                     0x88C9  
        MATRIX10_ARB                                    0x88CA  
        MATRIX11_ARB                                    0x88CB  
        MATRIX12_ARB                                    0x88CC  
        MATRIX13_ARB                                    0x88CD  
        MATRIX14_ARB                                    0x88CE  
        MATRIX15_ARB                                    0x88CF  
        MATRIX16_ARB                                    0x88D0  
        MATRIX17_ARB                                    0x88D1  
        MATRIX18_ARB                                    0x88D2  
        MATRIX19_ARB                                    0x88D3  
        MATRIX20_ARB                                    0x88D4  
        MATRIX21_ARB                                    0x88D5  
        MATRIX22_ARB                                    0x88D6  
        MATRIX23_ARB                                    0x88D7  
        MATRIX24_ARB                                    0x88D8  
        MATRIX25_ARB                                    0x88D9  
        MATRIX26_ARB                                    0x88DA  
        MATRIX27_ARB                                    0x88DB  
        MATRIX28_ARB                                    0x88DC  
        MATRIX29_ARB                                    0x88DD  
        MATRIX30_ARB                                    0x88DE  
        MATRIX31_ARB                                    0x88DF  
  
homeprevnext Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation)
  
    Modify Section 2.6, Begin/End Paradigm (p. 12)  
  
    (modify last paragraph, p. 12) ... In addition, a current normal, a  
    current color, multiple current texture coordinate sets, and multiple  
    generic vertex attributes may be used in processing each vertex.  Normals  
    are used by the GL in lighting calculations; the current normal is a  
    three-dimensional vector that may be set by sending three coordinates that  
    specify it.  Texture coordinates determine how a texture image is mapped  
    onto a primitive.  Multiple sets of texture coordinates may be used to  
    specify how multiple texture images are mapped onto a primitive.  Generic  
    vertex attributes do not have any specific function but can be used in  
    vertex program mode (section 2.14) to compute final values for any data  
    associated with a vertex.  
  
  
    Modify Section 2.6.3, GL Commands within Begin/End (p. 19)  
  
    (modify first paragraph of section, p. 19) The only GL commands that are  
    allowed within any Begin/End pairs are the commands for specifying vertex  
    coordinates, vertex color, normal coordinates, texture coordinates, and  
    generic vertex attributes (Vertex, Color, Index, Normal, TexCoord,  
    VertexAttrib*ARB), ...  
  
  
    Modify Section 2.7, Vertex Specification (p. 19)  
  
    (remove the "Finally" from the next-to-last paragraph, p. 20) There are  
    several ways to set the current color. The GL stores both a current  
    single-valued color index, and a current four-valued RGBA color. One  
  
    (add new paragraph before last paragraph of section, p. 21) Vertex  
    programs (section 2.14) can access an array of four-component generic  
    current vertex attributes.  The first entry of this array is numbered  
    zero, and the number of entries in the array is given by the  
    implementation-dependent constant MAX_VERTEX_ATTRIBS_ARB.  The commands  
  
      void VertexAttrib{1234}{sfd}ARB(uint index, T coords);  
      void VertexAttrib{123}{sfd}vARB(uint index, T coords);  
      void VertexAttrib4{bsifd ubusui}vARB(uint index, T coords);  
  
    specify the current vertex attribute numbered <index>, whose components  
    are named <x>, <y>, <z>, and <w>.  The VertexAttrib1ARB family of commands  
    sets the <x> coordinate to the provided single argument while setting <y>  
    and <z> to 0 and <w> to 1.  Similarly, VertexAttrib2ARB commands set <x>  
    and <y> to the specified values, <z> to 0 and <w> to 1; VertexAttrib3ARB  
    commands set <x>, <y>, and <z>, with <w> set to 1, and VertexAttrib4ARB  
    commands set all four coordinates.  The error INVALID_VALUE is generated  
    if <index> is greater than or equal to MAX_VERTEX_ATTRIBS_ARB.  
  
    The commands  
  
      void VertexAttrib4NubARB(uint index, T coords);  
      void VertexAttrib4N{bsi ubusui}vARB(uint index, T coords);  
  
    also specify vertex attributes with fixed-point coordinates that are  
    scaled to the range [0,1] or [-1,1], according to Table 2.6.  
  
    Setting generic vertex attribute zero specifies a vertex; the four vertex  
    coordinates are taken from the values of attribute zero.  A Vertex2,  
    Vertex3, or Vertex4 command is completely equivalent to the corresponding  
    VertexAttrib command with an index of zero.  Setting any other generic  
    vertex attribute updates the current values of the attribute.  There are  
    no current values for vertex attribute zero.  
  
    Implementations may, but do not necessarily, use the same storage for the  
    current values of generic and certain conventional vertex attributes.  
    When any generic vertex attribute other than zero is specified, the  
    current values for the corresponding conventional attribute in Table X.1  
    become undefined.  Additionally, when a conventional vertex attribute is  
    specified, the current values for the corresponding generic vertex  
    attribute in Table X.1 become undefined.  For example, setting the current  
    normal will leave generic vertex attribute 2 undefined, and vice versa.  
  
    Generic  
    Attribute   Conventional Attribute       Conventional Attribute Command  
    ---------   ------------------------     ------------------------------  
         0      vertex position              Vertex  
         1      vertex weights 0-3           WeightARB, VertexWeightEXT  
         2      normal                       Normal  
         3      primary color                Color  
         4      secondary color              SecondaryColorEXT  
         5      fog coordinate               FogCoordEXT  
         6      -                            -  
         7      -                            -  
         8      texture coordinate set 0     MultiTexCoord(TEXTURE0, ...)  
         9      texture coordinate set 1     MultiTexCoord(TEXTURE1, ...)  
        10      texture coordinate set 2     MultiTexCoord(TEXTURE2, ...)  
        11      texture coordinate set 3     MultiTexCoord(TEXTURE3, ...)  
        12      texture coordinate set 4     MultiTexCoord(TEXTURE4, ...)  
        13      texture coordinate set 5     MultiTexCoord(TEXTURE5, ...)  
        14      texture coordinate set 6     MultiTexCoord(TEXTURE6, ...)  
        15      texture coordinate set 7     MultiTexCoord(TEXTURE7, ...)  
       8+n      texture coordinate set n     MultiTexCoord(TEXTURE0+n, ...)  
  
    Table X.1, Generic and Conventional Vertex Attribute Mappings.  For each  
    row, the current value of the conventional attribute becomes undefined  
    when the corresponding generic attribute is set, and vice versa.  
    Attribute zero corresponds to the vertex position and has no current  
    state.  
  
    Setting any conventional vertex attribute not listed in Table X.1  
    (including vertex weights 4 and above, if supported) will not cause any  
    generic vertex attribute to become undefined, and such attributes will not  
    become undefined when any generic vertex attribute is set.  
  
  
  
    (modify the last paragraph in the section, p.21) The state required to  
    support vertex specification consists of four floating-point numbers per  
    texture unit to store the current texture coordinates s, t, r, and q,  
    three floating-point numbers to store the three coordinates of the current  
    normal, four floating-point values to store the current RGBA color, one  
    floating-point value to store the current color index, and  
    MAX_VERTEX_ATTRIBS_ARB-1 four-component floating-point vectors for generic  
    vertex attributes.  There is no notion of a current vertex, so no state is  
    devoted to vertex coordinates or vertex attribute zero.  The initial  
    texture coordinates are (S,T,R,Q) = (0,0,0,1) for each texture unit. The  
    initial current normal has coordinates (0,0,1). The initial RGBA color is  
    (R,G,B,A) = (1,1,1,1). The initial color index is 1.  The initial values  
    for all generic vertex attributes are undefined.  
  
      
    Modify Section 2.8, Vertex Arrays (p. 21)  
  
    (modify first paragraph of section, p.21) The vertex specification  
    commands described in section 2.7 accept data in almost any format, but  
    their use requires many command executions to specify even simple  
    geometry. Vertex data may also be placed into arrays that are stored in  
    the client's address space. Blocks of data in these arrays may then be  
    used to specify multiple geometric primitives through the execution of a  
    single GL command. The client may specify up to 5 plus the values of  
    MAX_TEXTURE_UNITS and MAX_VERTEX_ATTRIBS_ARB arrays: one each to store  
    vertex coordinates, edge flags, colors, color indices, normals, one or  
    more texture coordinate sets, and one or more generic vertex attributes.  
    The commands  
  
      ...  
  
      void VertexAttribPointerARB(uint index, int size, enum type,   
                                  boolean normalized, sizei stride,   
                                  const void *pointer);  
  
    describe the locations and organizations...  
  
    (add after the first paragraph, p.22) The <index> parameter in the  
    VertexAttribPointer command identifies the generic vertex attribute array  
    being described.  The error INVALID_VALUE is generated if <index> is  
    greater than or equal to MAX_VERTEX_ATTRIBS_ARB.  The <normalized>  
    parameter in the VertexAttribPointer command identifies whether  
    fixed-point types should be normalized when converted to floating-point.  
    If <normalized> is TRUE, fixed-point data are converted as specified in  
    Table 2.6; otherwise, the fixed-point values are converted directly.  
  
    (add after first paragraph, p.23) An individual generic vertex attribute  
    array is enabled or disabled by calling one of  
  
      void EnableVertexAttribArrayARB(uint index);  
      void DisableVertexAttribArrayARB(uint index);  
  
    where <index> identifies the generic vertex attribute array to enable or  
    disable.  The error INVALID_VALUE is generated if <index> is greater than  
    or equal to MAX_VERTEX_ATTRIBS_ARB.  
  
    (modify Table 2.4, p.23)  
  
                                       Normal      
      Command                 Sizes    ized?   Types  
      ----------------------  -------  ------  --------------------------------  
      VertexPointer           2,3,4     no     short, int, float, double  
      NormalPointer           3         yes    byte, short, int, float, double  
      ColorPointer            3,4       yes    byte, ubyte, short, ushort,  
                                               int, uint, float, double  
      IndexPointer            1         no     ubyte, short, int, float, double  
      TexCoordPointer         1,2,3,4   no     short, int, float, double  
      EdgeFlagPointer         1         no     boolean  
      VertexAttribPointerARB  1,2,3,4   flag   byte, ubyte, short, ushort,  
                                               int, uint, float, double  
      WeightPointerARB        >=1       yes    byte, ubyte, short, ushort,  
                                               int, uint, float, double  
      VertexWeightPointerEXT  1         n/a    float  
      SecondaryColor-         3         yes    byte, ubyte, short, ushort,  
        PointerEXT                             int, uint, float, double  
      FogCoordPointerEXT      1         n/a    float, double  
      MatrixIndexPointerARB   >=1       no     ubyte, ushort, uint  
  
      Table 2.4: Vertex array sizes (values per vertex) and data types.  The  
      "normalized" column indicates whether fixed-point types are accepted  
      directly or normalized to [0,1] (for unsigned types) or [-1,1] (for  
      singed types). For generic vertex attributes, fixed-point data are  
      normalized if and only if the <normalized> flag is set.  
  
    (modify last paragraph, p.23) The command  
  
      void ArrayElement(int i);   
  
    transfers the ith element of every enabled array to the GL.  The effect of  
    ArrayElement(i) is the same as the effect of the command sequence  
  
      if (ARB_vertex_blend vertex weight array enabled) {  
        Weight[type]vARB(vertex weight array size,   
                         vertex weight array element i);  
      }  
      if (EXT_vertex_weighting vertex weight array enabled) {  
        VertexWeight[type]vARB(vertex weight array element i);  
      }  
      if (normal array enabled) {  
        Normal3[type]v(normal array element i);  
      }  
      if (color array enabled) {  
        Color[size][type]v(color array element i);  
      }  
      if (secondary color array enabled) {  
        SecondaryColor3[type]vEXT(secondary color array element i);  
      }  
      if (fog coordinate array enabled) {  
        FogCoord[type]vEXT(fog coordinate array element i);  
      }  
      if (matrix index array enabled) {  
        MatrixIndex[type]vARB(matrix index array size,  
                              matrix index array element i);  
      }  
      for (j = 0; j < textureUnits; j++) {  
        if (texture coordinate set j array enabled) {  
          MultiTexCoord[size][type]v(TEXTURE0 + j,  
                                     texture coordinate set j  
                                     array element i);  
      }  
      if (color index array enabled) {  
        Index[type]v(color index array element i);  
      }  
      if (edge flag array enabled) {  
        EdgeFlagv(edge flag array element i);  
      }  
      for (j = 1; j < genericAttributes; j++) {  
        if (generic vertex attribute j array enabled) {  
          if (generic vertex attribute j array normalization flag  
              is set, and type is not FLOAT or DOUBLE) {  
            VertexAttrib[size]N[type]vARB(j, generic vertex attribute j  
                                             array element i);  
          } else {  
            VertexAttrib[size][type]vARB(j, generic vertex attribute j  
                                            array element i);  
          }  
        }  
      }  
      if (generic attribute array 0 enabled) {  
        if (generic vertex attribute j array normalization flag  
            is set, and type is not FLOAT or DOUBLE) {  
          VertexAttrib[size]N[type]vARB(0, generic vertex attribute 0  
                                           array element i);  
        } else {  
          VertexAttrib[size][type]vARB(0, generic vertex attribute 0  
                                          array element i);  
        }  
      } else if (vertex array enabled) {  
        Vertex[size][type]vARB(vertex array element i);  
      }  
  
    where <textureUnits> and <genericAttributes> give the number of texture  
    units and generic vertex attributes supported by the implementation,  
    respectively.  "[size]" and "[type]" correspond to the size and type of  
    the corresponding array.  For generic vertex attributes, it is assumed  
    that a complete set of vertex attribute commands exists, even though not  
    all such functions are provided by the GL.  Both generic attribute array  
    zero and the vertex array can specify a vertex if enabled, but only one  
    such array is used.  As described in section 2.7, setting a generic vertex  
    attributes listed in Table X.1 will leave the corresponding conventional  
    vertex attribute undefined, and vice versa.  
  
  
    (modify last paragraph of section, p.28) If the number of supported  
    texture units (the value of MAX TEXTURE UNITS) is m and the number of  
    supported generic vertex attributes (MAX_VERTEX_ATTRIBS_ARB) is n, then  
    the client state required to implement vertex arrays consists of 5+m+n  
    boolean enables, 5+m+n memory pointers, 5+m+n integer stride values, 4+m+n  
    symbolic constants representing array types, 2+m+n integers representing  
    values per element, and n boolean normalization flags. In the initial  
    state, the enable values are each disabled, the memory pointers are each  
    null, the strides are each zero, the array types are each FLOAT, the  
    integers representing values per element are each four, and the  
    normalization flags are disabled..  
  
  
    Modify Section 2.10, Coordinate Transformations (p. 29)  
  
    (add new paragraphs) Vertex attributes are transformed before the vertex  
    is used to generate primitives for rasterization, establish a raster  
    position, or generate vertices for selection or feedback.  The attributes  
    of each vertex are transformed using one of two vertex transformation  
    modes.  The first mode, described in this and subsequent sections, is GL's  
    conventional vertex transformation model.  The second mode, known as  
    vertex program mode and described in section 2.14, transforms vertex  
    attributes as specified in an application-supplied vertex program.  
  
    Vertex program mode is enabled and disabled, respectively, by  
  
      void Enable(enum target);  
  
    and  
  
      void Disable(enum target);  
  
    with <target> equal to VERTEX_PROGRAM_ARB.  When vertex program mode is  
    enabled, vertices are transformed by the currently bound vertex program as  
    discussed in section 2.14.  
  
    When vertex program mode is disabled, vertices, normals, and texture  
    coordinates are transformed before their coordinates are used to produce  
    an image in the framebuffer.  We begin with a description of how vertex  
    coordinates are transformed and how the transformation is controlled in  
    this case.  The discussion that continues through section 2.13 applies  
    when vertex program mode is disabled.  
  
  
    Modify Section 2.10.2, Matrices (p. 31)  
  
    (modify 1st paragraph) The projection matrix and model-view matrix are set  
    and modified with a variety of commands.  The affected matrix is  
    determined by the current matrix mode.  The current matrix mode is set  
    with  
  
      void MatrixMode(enum mode);  
  
    which takes one of the pre-defined constants TEXTURE, MODELVIEW, COLOR,  
    PROJECTION, or MATRIX<i>_ARB as the argument.  In the case of  
    MATRIX<i>_ARB, <i> is an integer between 0 and <n>-1 indicating one of <n>  
    program matrices where <n> is the value of the implementation defined  
    constant MAX_PROGRAM_MATRICES_ARB.  Such program matrices are described in  
    section 2.14.6.  TEXTURE is described later in section 2.10.2, and COLOR  
    is described in section 3.6.3.  If the current matrix mode is MODELVIEW,  
    then matrix operations apply to the model-view matrix; if PROJECTION, then  
    they apply to the projection matrix.  
  
    (modify last paragraph of section) The state required to implement  
    transformations consists of a <n>-value integer indicating the current  
    matrix mode (where <n> is 4 + the number of supported texture and program  
    matrices), a stack of at least two 4x4 matrices for each of COLOR,  
    PROJECTION, and TEXTURE with associated stack pointers, <n> stacks (where  
    <n> is at least 8) of at least one 4x4 matrix for each MATRIX<i>_ARB with  
    associated stack pointers, and a stack of at least 32 4x4 matrices with an  
    associated stack pointer for MODELVIEW.  Initially, there is only one  
    matrix on each stack, and all matrices are set to the identity.  The  
    initial matrix mode is MODELVIEW.  The initial value of ACTIVE_TEXTURE is  
    TEXTURE0.  
  
  
    Modify Section 2.11, Clipping (p. 39)  
  
    (add to end of next-to-last paragraph, p. 40) ... User clipping is not  
    supported in vertex program mode if the current program is not  
    position-invariant (section 2.14.4.5.1).  In this case, client-defined  
    clip planes are always treated as disabled.  
  
  
    Modify Section 2.12, Current Raster Position (p. 42)  
  
    (modify fourth paragraph, p.42) The coordinates are treated as if they  
    were specified in a Vertex command.  If vertex program mode is enabled,  
    the currently bound vertex program is executed, using the x, y, z, and w  
    coordinates as the object coordinates of the vertex.  Otherwise, the x, y,  
    z, and w coordinates are transformed by the current model-view and  
    projection matrices. These coordinates, along with current values, are  
    used to generate a color and texture coordinates just as is done for a  
    vertex. The color and texture coordinates produced using either method  
    replace the color and texture coordinates stored in the current raster  
    position's associated data.  When in vertex program mode, the "x"  
    component of the fog coordinate result replaces the current raster  
    distance; otherwise, the distance from the origin of the eye coordinate  
    system to the vertex as transformed by only the current model-view matrix  
    replaces the current raster distance.  The latter distance can be  
    approximated (see section 3.10).  
  
    Rename and Modify Section 2.13.8, Color and Vertex Data Clipping (p.56)  
  
    (modify second paragraph, p.57) Texture coordinates, as well as fog  
    coordinates and point sizes computed on a per-vertex basis, must also be  
    clipped when a primitive is clipped.  The method is exactly analogous to  
    that used for color clipping.  
  
  
    Add New Section 2.14 and subsections (p. 57).  
  
    Section 2.14, Vertex Programs  
      
    The conventional GL vertex transformation model described in sections 2.10  
    through 2.13 is a configurable but essentially hard-wired sequence of  
    per-vertex computations based on a canonical set of per-vertex parameters  
    and vertex transformation related state such as transformation matrices,  
    lighting parameters, and texture coordinate generation parameters.  The  
    general success and utility of the conventional GL vertex transformation  
    model reflects its basic correspondence to the typical vertex  
    transformation requirements of 3D applications.  
  
    However when the conventional GL vertex transformation model is not  
    sufficient, the vertex program mode provides a substantially more flexible  
    model for vertex transformation.  The vertex program mode permits  
    applications to define their own vertex programs.  
  
    A vertex program is a character string that specifies a sequence of  
    operations to perform.  Vertex program instructions are typically  
    4-component vector operations that operate on per-vertex attributes and  
    program parameters.  Vertex programs execute on a per-vertex basis and  
    operate on each vertex completely independently from any other vertices.  
    Vertex programs execute a finite fixed sequence of instructions with no  
    branching or looping.  Vertex programs execute without data hazards so  
    results computed in one instruction can be used immediately afterwards.  
    The result of a vertex program is a set of vertex result registers that  
    becomes the set of transformed vertex attributes used during clipping and  
    primitive assembly.  
  
    Vertex programs are defined to operate only in RGBA mode.  The results of  
    vertex program execution are undefined if the GL is in color index mode.  
  
  
    Section 2.14.1,  Program Objects  
  
    The GL provides one or more program targets, each identifying a portion of  
    the GL that can be controlled through application-specified programs.  The  
    program target for vertex programs is VERTEX_PROGRAM_ARB.  Each program  
    target has an associated program object, called the current program  
    object.  Each program target also has a default program object, which is  
    initially the current program object.  
  
    Each program object has an associated program string.  The command  
  
      ProgramStringARB(enum target, enum format, sizei len,   
                       const void *string);  
  
    updates the program string for the current program object for <target>.  
    <format> describes the format of the program string, which must currently  
    be PROGRAM_FORMAT_ASCII_ARB.  <string> is a pointer to the array of bytes  
    representing the program string being loaded, which need not be  
    null-terminated.  The length of the array is given by <len>.  If <string>  
    is null-terminated, <len> should not include the terminator.  
  
    When a program string is loaded, it is interpreted according to syntactic  
    and semantic rules corresponding to the program target specified by  
    <target>.  If a program violates the syntactic or semantic restrictions of  
    the program target, ProgramStringARB generates the error  
    INVALID_OPERATION.  
  
    Additionally, ProgramString will update the program error position  
    (PROGRAM_ERROR_POSITION_ARB) and error string (PROGRAM_ERROR_STRING_ARB).  
    If a program fails to load, the value of the program error position is set  
    to the ubyte offset into the specified program string indicating where the  
    first program error was detected.  If the program fails to load because of  
    a semantic restriction that is not detected until the program is fully  
    scanned, the error position is set to the value of <len>.  If a program  
    loads successfully, the error position is set to the value negative one.  
    The implementation-dependent program error string contains one or more  
    error or warning messages.  If a program loads succesfully, the error  
    string may either contain warning messages or be empty.  
  
    Each program object has an associated array of program local parameters.  
    The number and type of program local parameters is target- and  
    implementation-dependent.  For vertex programs, program local parameters  
    are four-component floating-point vectors.  The number of vectors is given  
    by the implementation-dependent constant MAX_PROGRAM_LOCAL_PARAMETERS_ARB,  
    which must be at least 96.  The commands  
  
      void ProgramLocalParameter4fARB(enum target, uint index,  
                                      float x, float y, float z, float w);  
      void ProgramLocalParameter4fvARB(enum target, uint index,   
                                       const float *params);  
      void ProgramLocalParameter4dARB(enum target, uint index,  
                                      double x, double y, double z, double w);  
      void ProgramLocalParameter4dvARB(enum target, uint index,   
                                       const double *params);  
  
    update the values of the program local parameter numbered <index>  
    belonging to the program object currently bound to <target>.  For  
    ProgramLocalParameter4fARB and ProgramLocalParameter4dARB, the four  
    components of the parameter are updated with the values of <x>, <y>, <z>,  
    and <w>, respectively.  For ProgramLocalParameter4fvARB and  
    ProgramLocalParameter4dvARB, the four components of the parameter are  
    updated with the array of four values pointed to by <params>.  The error  
    INVALID_VALUE is generated if <index> is greater than or equal to the  
    number of program local parameters supported by <target>.  
  
    Additionally, each program target has an associated array of program  
    environment parameters.  Unlike program local parameters, program  
    environment parameters are shared by all program objects of a given  
    target.  The number and type of program environment parameters is target-  
    and implementation-dependent.  For vertex programs, program environment  
    parameters are four-component floating-point vectors.  The number of  
    vectors is given by the implementation-dependent constant  
    MAX_PROGRAM_ENV_PARAMETERS_ARB, which must be at least 96.  The commands  
  
      void ProgramEnvParameter4fARB(enum target, uint index,  
                                    float x, float y, float z, float w);  
      void ProgramEnvParameter4fvARB(enum target, uint index,  
                                     const float *params);  
      void ProgramEnvParameter4dARB(enum target, uint index,  
                                    double x, double y, double z, double w);  
      void ProgramEnvParameter4dvARB(enum target, uint index,  
                                     const double *params);  
  
    update the values of the program environment parameter numbered <index>  
    for the given program target <target>.  For ProgramEnvParameter4fARB and  
    ProgramEnvParameter4dARB, the four components of the parameter are updated  
    with the values of <x>, <y>, <z>, and <w>, respectively.  For  
    ProgramEnvParameter4fvARB and ProgramEnvParameter4dvARB, the four  
    components of the parameter are updated with the array of four values  
    pointed to by <params>.  The error INVALID_VALUE is generated if <index>  
    is greater than or equal to the number of program environment parameters  
    supported by <target>.  
  
    Each program target has a default program object.  Additionally, named  
    program objects can be created and operated upon.  The name space for  
    program objects is the positive integers and is shared by programs of all  
    targets.  The name zero is reserved by the GL.  
  
    A named program object is created by binding an unused program object name  
    to a valid program target.  The binding is effected by calling  
  
      BindProgramARB(enum target, uint program);  
  
    with <target> set to the desired program target and <program> set to the  
    unused program name.  The resulting program object has a program target  
    given by <target> and is assigned target-specific default values (see  
    section 2.14.7 for vertex programs).  BindProgramARB may also be used to  
    bind an existing program object to a program target.  If <program> is  
    zero, the default program object for <target> is bound.  If <program> is  
    the name of an existing program object whose associated program target is  
    <target>, the named program object is bound.  The error INVALID_OPERATION  
    is generated if <program> names an existing program object whose  
    associated program target is anything other than <target>.  
  
    Programs objects are deleted by calling  
  
      void DeleteProgramsARB(sizei n, const uint *programs);  
  
    <programs> contains <n> names of programs to be deleted.  After a program  
    object is deleted, its name is again unused.  If a program object that is  
    bound to any target is deleted, it is as though BindProgramARB is first  
    executed with same target and a <program> of zero.  Unused names in  
    <programs> are silently ignored, as is the value zero.  
  
    The command  
  
      void GenProgramsARB(sizei n, uint *programs);  
  
    returns <n> currently unused program names in <programs>.  These names are  
    marked as used, for the purposes of GenProgramsARB only, but objects are  
    created only when they are first bound using BindProgramARB.  
  
  
    Section 2.14.2,  Vertex Program Grammar and Semantic Restrictions  
  
    Vertex program strings are specified as an array of ASCII characters  
    containing the program text.  When a vertex program is loaded by a call to  
    ProgramStringARB, the program string is parsed into a set of tokens  
    possibly separated by whitespace.  Spaces, tabs, newlines, carriage  
    returns, and comments are considered whitespace.  Comments begin with the  
    character "#" and are terminated by a newline, a carriage return, or the  
    end of the program array.  
  
    The Backus-Naur Form (BNF) grammar below specifies the syntactically valid  
    sequences for vertex programs.  The set of valid tokens can be inferred  
    from the grammar.  The token "" represents an empty string and is used to  
    indicate optional rules.  A program is invalid if it contains any  
    undefined tokens or characters.  
  
    A vertex program is required to begin with the header string "!!ARBvp1.0",  
    without any preceding whitespace.  This string identifies the subsequent  
    program text as a vertex program (version 1.0) that should be parsed  
    according to the following grammar and semantic rules.  Program string  
    parsing begins with the character immediately following the header string.  
  
    <program>              ::= <optionSequence> <statementSequence> "END"  
  
    <optionSequence>       ::= <optionSequence> <option>  
                             | ""  
  
    <option>               ::= "OPTION" <identifier> ";"  
  
    <statementSequence>    ::= <statementSequence> <statement>  
                             | ""  
  
    <statement>            ::= <instruction> ";"  
                             | <namingStatement> ";"  
  
    <instruction>          ::= <ARL_instruction>  
                             | <VECTORop_instruction>  
                             | <SCALARop_instruction>  
                             | <BINSCop_instruction>  
                             | <BINop_instruction>  
                             | <TRIop_instruction>  
                             | <SWZ_instruction>  
  
    <ARL_instruction>      ::= "ARL" <maskedAddrReg> "," <scalarSrcReg>  
  
    <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg>  
  
    <VECTORop>             ::= "ABS"  
                             | "FLR"  
                             | "FRC"  
                             | "LIT"  
                             | "MOV"  
  
    <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg>  
  
    <SCALARop>             ::= "EX2"  
                             | "EXP"  
                             | "LG2"  
                             | "LOG"                            
                             | "RCP"  
                             | "RSQ"  
  
    <BINSCop_instruction>  ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> ","  
                               <scalarSrcReg>   
  
    <BINSCop>              ::= "POW"  
   
    <BINop_instruction>    ::= <BINop> <maskedDstReg> ","  
                               <swizzleSrcReg> "," <swizzleSrcReg>  
  
    <BINop>                ::= "ADD"  
                             | "DP3"  
                             | "DP4"  
                             | "DPH"  
                             | "DST"  
                             | "MAX"  
                             | "MIN"  
                             | "MUL"  
                             | "SGE"  
                             | "SLT"  
                             | "SUB"  
                             | "XPD"  
  
    <TRIop_instruction>    ::= <TRIop> <maskedDstReg> ","  
                               <swizzleSrcReg> "," <swizzleSrcReg> ","  
                               <swizzleSrcReg>  
  
    <TRIop>                ::= "MAD"  
  
    <SWZ_instruction>      ::= "SWZ" <maskedDstReg> "," <srcReg> ","   
                               <extendedSwizzle>  
  
    <scalarSrcReg>         ::= <optionalSign> <srcReg> <scalarSuffix>  
  
    <swizzleSrcReg>        ::= <optionalSign> <srcReg> <swizzleSuffix>  
  
    <maskedDstReg>         ::= <dstReg> <optionalMask>  
  
    <maskedAddrReg>        ::= <addrReg> <addrWriteMask>  
  
    <extendedSwizzle>      ::= <extSwizComp> "," <extSwizComp> ","   
                                 <extSwizComp> "," <extSwizComp>  
  
    <extSwizComp>          ::= <optionalSign> <extSwizSel>  
  
    <extSwizSel>           ::= "0"   
                             | "1"   
                             | <component>  
  
    <srcReg>               ::= <vertexAttribReg>  
                             | <temporaryReg>  
                             | <progParamReg>  
  
    <dstReg>               ::= <temporaryReg>  
                             | <vertexResultReg>  
  
    <vertexAttribReg>      ::= <establishedName>  
                             | <vtxAttribBinding>  
  
    <temporaryReg>         ::= <establishedName>  
  
    <progParamReg>         ::= <progParamSingle>  
                             | <progParamArray> "[" <progParamArrayMem> "]"  
                             | <paramSingleItemUse>  
  
    <progParamSingle>      ::= <establishedName>  
  
    <progParamArray>       ::= <establishedName>  
      
    <progParamArrayMem>    ::= <progParamArrayAbs>  
                             | <progParamArrayRel>  
                               
    <progParamArrayAbs>    ::= <integer>  
  
    <progParamArrayRel>    ::= <addrReg> <addrComponent> <addrRegRelOffset>  
  
    <addrRegRelOffset>     ::= ""  
                             | "+" <addrRegPosOffset>  
                             | "-" <addrRegNegOffset>  
  
    <addrRegPosOffset>     ::= <integer> from 0 to 63  
  
    <addrRegNegOffset>     ::= <integer> from 0 to 64  
  
    <vertexResultReg>      ::= <establishedName>  
                             | <resultBinding>  
  
    <addrReg>              ::= <establishedName>  
  
    <addrComponent>        ::= "." "x"  
  
    <addrWriteMask>        ::= "." "x"  
  
    <scalarSuffix>         ::= "." <component>  
  
    <swizzleSuffix>        ::= ""  
                             | "." <component>  
                             | "." <component> <component>  
                                   <component> <component>  
  
    <component>            ::= "x"  
                             | "y"  
                             | "z"  
                             | "w"  
  
    <optionalMask>         ::= ""  
                             | "." "x"  
                             | "." "y"  
                             | "." "xy"  
                             | "." "z"  
                             | "." "xz"  
                             | "." "yz"  
                             | "." "xyz"  
                             | "." "w"  
                             | "." "xw"  
                             | "." "yw"  
                             | "." "xyw"  
                             | "." "zw"  
                             | "." "xzw"  
                             | "." "yzw"  
                             | "." "xyzw"  
  
    <namingStatement>      ::= <ATTRIB_statement>  
                             | <PARAM_statement>  
                             | <TEMP_statement>  
                             | <ADDRESS_statement>  
                             | <OUTPUT_statement>  
                             | <ALIAS_statement>  
  
    <ATTRIB_statement>     ::= "ATTRIB" <establishName> "="  
                                 <vtxAttribBinding>  
  
    <vtxAttribBinding>     ::= "vertex" "." <vtxAttribItem>  
  
    <vtxAttribItem>        ::= "position"  
                             | "weight" <vtxOptWeightNum>  
                             | "normal"  
                             | "color" <optColorType>  
                             | "fogcoord"  
                             | "texcoord" <optTexCoordNum>  
                             | "matrixindex" "[" <vtxWeightNum> "]"  
                             | "attrib" "[" <vtxAttribNum> "]"  
  
    <vtxAttribNum>         ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1  
  
    <vtxOptWeightNum>      ::= ""  
                             | "[" <vtxWeightNum> "]"  
  
    <vtxWeightNum>         ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1,  
                                 must be divisible by four  
  
    <PARAM_statement>      ::= <PARAM_singleStmt>  
                             | <PARAM_multipleStmt>  
  
    <PARAM_singleStmt>     ::= "PARAM" <establishName> <paramSingleInit>  
  
    <PARAM_multipleStmt>   ::= "PARAM" <establishName> "[" <optArraySize> "]"  
                                   <paramMultipleInit>  
  
    <optArraySize>         ::= ""  
                             | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB  
                                 (maximum number of allowed program   
                                  parameter bindings)  
  
    <paramSingleInit>      ::= "=" <paramSingleItemDecl>  
  
    <paramMultipleInit>    ::= "=" "{" <paramMultInitList> "}"  
  
    <paramMultInitList>    ::= <paramMultipleItem>  
                             | <paramMultipleItem> "," <paramMultiInitList>  
  
    <paramSingleItemDecl>  ::= <stateSingleItem>  
                             | <programSingleItem>  
                             | <paramConstDecl>  
  
    <paramSingleItemUse>   ::= <stateSingleItem>  
                             | <programSingleItem>  
                             | <paramConstUse>  
  
    <paramMultipleItem>    ::= <stateMultipleItem>  
                             | <programMultipleItem>  
                             | <paramConstDecl>  
  
    <stateMultipleItem>    ::= <stateSingleItem>  
                             | "state" "." <stateMatrixRows>  
  
    <stateSingleItem>      ::= "state" "." <stateMaterialItem>  
                             | "state" "." <stateLightItem>  
                             | "state" "." <stateLightModelItem>  
                             | "state" "." <stateLightProdItem>  
                             | "state" "." <stateTexGenItem>  
                             | "state" "." <stateFogItem>  
                             | "state" "." <stateClipPlaneItem>  
                             | "state" "." <statePointItem>  
                             | "state" "." <stateMatrixRow>  
  
    <stateMaterialItem>    ::= "material" <optFaceType> "." <stateMatProperty>  
  
    <stateMatProperty>     ::= "ambient"  
                             | "diffuse"  
                             | "specular"  
                             | "emission"  
                             | "shininess"  
  
    <stateLightItem>       ::= "light" "[" <stateLightNumber> "]" "."   
                                 <stateLightProperty>  
  
    <stateLightProperty>   ::= "ambient"  
                             | "diffuse"   
                             | "specular"  
                             | "position"  
                             | "attenuation"  
                             | "spot" "." <stateSpotProperty>  
                             | "half"  
  
    <stateSpotProperty>    ::= "direction"   
  
    <stateLightModelItem>  ::= "lightmodel" <stateLModProperty>  
  
    <stateLModProperty>    ::= "." "ambient"  
                             | <optFaceType> "." "scenecolor"  
  
    <stateLightProdItem>   ::= "lightprod" "[" <stateLightNumber> "]"   
                                 <optFaceType> "." <stateLProdProperty>  
  
    <stateLProdProperty>   ::= "ambient"  
                             | "diffuse"  
                             | "specular"  
  
    <stateLightNumber>     ::= <integer> from 0 to MAX_LIGHTS-1  
  
    <stateTexGenItem>      ::= "texgen" <optTexCoordNum> "."   
                                 <stateTexGenType> "." <stateTexGenCoord>  
  
    <stateTexGenType>      ::= "eye"  
                             | "object"  
  
    <stateTexGenCoord>     ::= "s"   
                             | "t"   
                             | "r"   
                             | "q"  
  
    <stateFogItem>         ::= "fog" "." <stateFogProperty>  
  
    <stateFogProperty>     ::= "color"   
                             | "params"   
  
    <stateClipPlaneItem>   ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane"  
  
    <stateClipPlaneNum>    ::= <integer> from 0 to MAX_CLIP_PLANES-1  
  
    <statePointItem>       ::= "point" "." <statePointProperty>  
  
    <statePointProperty>   ::= "size"  
                             | "attenuation"  
  
    <stateMatrixRow>       ::= <stateMatrixItem> "." "row" "["   
                                  <stateMatrixRowNum> "]"  
  
    <stateMatrixRows>      ::= <stateMatrixItem> <optMatrixRows>  
  
    <optMatrixRows>        ::= ""  
                             | "." "row" "[" <stateMatrixRowNum> ".."   
                                  <stateMatrixRowNum> "]"  
  
    <stateMatrixItem>      ::= "matrix" "." <stateMatrixName>   
                               <stateOptMatModifier>  
  
    <stateOptMatModifier>  ::= ""  
                             | "." <stateMatModifier>  
  
    <stateMatModifier>     ::= "inverse"   
                             | "transpose"   
                             | "invtrans"  
  
    <stateMatrixRowNum>    ::= <integer> from 0 to 3  
  
    <stateMatrixName>      ::= "modelview" <stateOptModMatNum>  
                             | "projection"  
                             | "mvp"  
                             | "texture" <optTexCoordNum>  
                             | "palette" "[" <statePaletteMatNum> "]"  
                             | "program" "[" <stateProgramMatNum> "]"  
                               
    <stateOptModMatNum>    ::= ""  
                             | "[" <stateModMatNum> "]"  
  
    <stateModMatNum>       ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1  
  
    <statePaletteMatNum>   ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1  
  
    <stateProgramMatNum>   ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1  
  
    <programSingleItem>    ::= <progEnvParam>  
                             | <progLocalParam>  
  
    <programMultipleItem>  ::= <progEnvParams>  
                             | <progLocalParams>  
  
    <progEnvParams>        ::= "program" "." "env"   
                                 "[" <progEnvParamNums> "]"  
  
    <progEnvParamNums>     ::= <progEnvParamNum>  
                             | <progEnvParamNum> ".." <progEnvParamNum>  
  
    <progEnvParam>         ::= "program" "." "env"   
                                 "[" <progEnvParamNum> "]"  
  
    <progLocalParams>      ::= "program" "." "local"   
                                 "[" <progLocalParamNums> "]"  
  
    <progLocalParamNums>   ::= <progLocalParamNum>  
                             | <progLocalParamNum> ".." <progLocalParamNum>  
  
    <progLocalParam>       ::= "program" "." "local"   
                                 "[" <progLocalParamNum> "]"  
  
    <progEnvParamNum>      ::= <integer> from 0 to  
                               MAX_PROGRAM_ENV_PARAMETERS_ARB - 1  
  
    <progLocalParamNum>    ::= <integer> from 0 to  
                               MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1  
  
    <paramConstDecl>       ::= <paramConstScalarDecl>  
                             | <paramConstVector>  
  
    <paramConstUse>        ::= <paramConstScalarUse>  
                             | <paramConstVector>  
  
    <paramConstScalarDecl> ::= <signedFloatConstant>  
  
    <paramConstScalarUse>  ::= <floatConstant>  
  
    <paramConstVector>     ::= "{" <signedFloatConstant> "}"  
                             | "{" <signedFloatConstant> ","   
                                   <signedFloatConstant> "}"  
                             | "{" <signedFloatConstant> ","   
                                   <signedFloatConstant> ","  
                                   <signedFloatConstant> "}"  
                             | "{" <signedFloatConstant> ","   
                                   <signedFloatConstant> ","  
                                   <signedFloatConstant> ","   
                                   <signedFloatConstant> "}"  
  
    <signedFloatConstant>  ::= <optionalSign> <floatConstant>  
  
    <floatConstant>        ::= see text  
  
    <optionalSign>         ::= ""  
                             | "-"  
                             | "+"  
  
    <TEMP_statement>       ::= "TEMP" <varNameList>  
  
    <ADDRESS_statement>    ::= "ADDRESS" <varNameList>  
  
    <varNameList>          ::= <establishName>  
                             | <establishName> "," <varNameList>  
  
    <OUTPUT_statement>     ::= "OUTPUT" <establishName> "="  
                                 <resultBinding>  
  
    <resultBinding>        ::= "result" "." "position"  
                             | "result" "." <resultColBinding>  
                             | "result" "." "fogcoord"  
                             | "result" "." "pointsize"  
                             | "result" "." "texcoord" <optTexCoordNum>  
  
    <resultColBinding>     ::= "color" <optFaceType> <optColorType>  
  
    <optFaceType>          ::= ""  
                             | "." "front"  
                             | "." "back"  
  
    <optColorType>         ::= ""  
                             | "." "primary"  
                             | "." "secondary"  
  
    <optTexCoordNum>       ::= ""  
                             | "[" <texCoordNum> "]"  
  
    <texCoordNum>          ::= <integer> from 0 to MAX_TEXTURE_UNITS-1  
  
    <ALIAS_statement>      ::= "ALIAS" <establishName> "="  
                                 <establishedName>  
  
    <establishName>        ::= <identifier>  
  
    <establishedName>      ::= <identifier>  
  
    <identifier>           ::= see text  
  
    The <integer> rule matches an integer constant.  The integer consists  
    of a sequence of one or more digits ("0" through "9").  
  
    The <floatConstant> rule matches a floating-point constant consisting  
    of an integer part, a decimal point, a fraction part, an "e" or  
    "E", and an optionally signed integer exponent.  The integer and  
    fraction parts both consist of a sequence of one or more digits ("0"  
    through "9").  Either the integer part or the fraction parts (not  
    both) may be missing; either the decimal point or the "e" (or "E")  
    and the exponent (not both) may be missing.  
  
    The <identifier> rule matches a sequence of one or more letters ("A"  
    through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"),  
    or dollar signs ("$"); the first character must not be a number.  Upper  
    and lower case letters are considered different (names are  
    case-sensitive).  The following strings are reserved keywords and may not  
    be used as identifiers:  
  
        ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2,  
        EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT,  
        PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result,  
        state, and vertex.  
  
    The error INVALID_OPERATION is generated if a vertex program fails to load  
    because it is not syntactically correct or for one of the semantic  
    restrictions described in the following sections.  
  
    A successfully loaded vertex program is parsed into a sequence of  
    instructions.  Each instruction is identified by its tokenized name.  The  
    operation of these instructions when executed is defined in section  
    2.14.5.  A successfully loaded program string replaces the program string  
    previously loaded into the specified program object.  If the OUT_OF_MEMORY  
    error is generated by ProgramStringARB, no change is made to the previous  
    contents of the current program object.  
  
  
    Section 2.14.3,  Vertex Program Variables  
  
    Vertex programs may access a number of different variables during their  
    execution.  The following sections define the variables that can be  
    declared and used by a vertex program.  
  
    Explicit variable declarations allow a vertex program to establish a  
    variable name that can be used to refer to a specified resource in  
    subsequent instructions.  A vertex program will fail to load if it  
    declares the same variable name more than once or if it refers to a  
    variable name that has not been previously declared in the program string.  
  
    Implicit variable declarations allow a vertex program to use the name of  
    certain available resources by name.  
  
    Section 2.14.3.1,  Vertex Attributes  
  
    Vertex program attribute variables are a set of four-component  
    floating-point vectors holding the attributes of the vertex being  
    processed.  Vertex attribute variables are read-only during vertex program  
    execution.  
  
    Vertex attribute variables can be declared explicitly using the  
    <ATTRIB_statement> grammar rule, or implicitly using the  
    <vtxAttribBinding> grammar rule in an executable instruction.  
  
    Each vertex attribute variable is bound to a single item of vertex state  
    according to the <vtxAttrBinding> grammar rule.  The set of GL state that  
    can be bound to a vertex attribute variable is given in Table X.2.  Vertex  
    attribute variables are initialized at each vertex program invocation with  
    the current values of the bound state.  
  
      Vertex Attribute Binding  Components  Underlying State  
      ------------------------  ----------  ------------------------------  
      vertex.position           (x,y,z,w)   object coordinates  
      vertex.weight             (w,w,w,w)   vertex weights 0-3  
      vertex.weight[n]          (w,w,w,w)   vertex weights n-n+3  
      vertex.normal             (x,y,z,1)   normal  
      vertex.color              (r,g,b,a)   primary color  
      vertex.color.primary      (r,g,b,a)   primary color  
      vertex.color.secondary    (r,g,b,a)   secondary color  
      vertex.fogcoord           (f,0,0,1)   fog coordinate  
      vertex.texcoord           (s,t,r,q)   texture coordinate, unit 0  
      vertex.texcoord[n]        (s,t,r,q)   texture coordinate, unit n  
      vertex.matrixindex        (i,i,i,i)   vertex matrix indices 0-3  
      vertex.matrixindex[n]     (i,i,i,i)   vertex matrix indices n-n+3  
      vertex.attrib[n]          (x,y,z,w)   generic vertex attribute n  
  
      Table X.2:  Vertex Attribute Bindings.  The "Components" column  
      indicates the mapping of the state in the "Underlying State" column.  
      Values of "0" or "1" in the "Components" column indicate the constants  
      0.0 and 1.0, respectively.  Bindings containing "[n]" require an integer  
      value of <n> to select an individual item.  
  
    If a vertex attribute binding matches "vertex.position", the "x", "y", "z"  
    and "w" components of the vertex attribute variable are filled with the  
    "x", "y", "z", and "w" components, respectively, of the vertex position.  
  
    If a vertex attribute binding matches "vertex.normal", the "x", "y", and  
    "z" components of the vertex attribute variable are filled with the "x",  
    "y", and "z" components, respectively, of the vertex normal.  The "w"  
    component is filled with 1.  
  
    If a vertex attribute binding matches "vertex.color" or  
    "vertex.color.primary", the "x", "y", "z", and "w" components of the  
    vertex attribute variable are filled with the "r", "g", "b", and "a"  
    components, respectively, of the vertex color.  
  
    If a vertex attribute binding matches "vertex.color.secondary", the "x",  
    "y", "z", and "w" components of the vertex attribute variable are filled  
    with the "r", "g", "b", and "a" components, respectively, of the vertex  
    secondary color.  
  
    If a vertex attribute binding matches "vertex.fogcoord", the "x" component  
    of the vertex attribute variable is filled with the vertex fog coordinate.  
    The "y", "z", and "w" coordinates are filled with 0, 0, and 1,  
    respectively.  
  
    If a vertex attribute binding matches "vertex.texcoord" or  
    "vertex.texcoord[n]", the "x", "y", "z", and "w" components of the vertex  
    attribute variable are filled with the "s", "t", "r", and "q" components,  
    respectively, of the vertex texture coordinates for texture unit <n>.  If  
    "[n]" is omitted, texture unit zero is used.  
  
    If a vertex attribute binding matches "vertex.weight" or  
    "vertex.weight[n]", the "x", "y", "z", and "w" components of the vertex  
    attribute variable are filled with vertex weights <n> through <n>+3,  
    respectively.  If "[n]" is omitted, weights zero through three are used.  
    For the purposes of this binding, all weights supported by the  
    implementation but not set by the application are set to zero, including  
    the extra derived weight corresponding to the fixed-function  
    WEIGHT_SUM_UNITY_ARB enable.  For components whose corresponding weight is  
    not supported by the implementation (i.e., numbered MAX_VERTEX_UNITS_ARB  
    or larger), "y" and "z" components are set to 0.0 and "w" components are  
    set to 1.0.  A vertex program will fail to load if a vertex attribute  
    binding specifies a weight number <n> that is greater than or equal to  
    MAX_VERTEX_UNITS_ARB or is not divisible by four.  
  
    If a vertex attribute binding matches "vertex.matrixindex" or  
    "vertex.matrixindex[n]", the "x", "y", "z", and "w" components of the  
    vertex attribute variable are filled with matrix indices <n> through <n>+3  
    of the vertex, respectively.  If "[n]" is omitted, matrix indices zero  
    through three are used.  For components whose corresponding matrix index  
    is not supported by the implementation (i.e., numbered  
    MAX_VERTEX_UNITS_ARB or larger), "y", and "z" components are set to 0.0  
    and "w" components are set to 1.0.  A vertex program will fail to load if  
    an attribute binding specifies a matrix index number <n> that is greater  
    than or equal MAX_VERTEX_UNITS_ARB or is not divisible by four.  
  
    If a vertex attribute binding matches "vertex.attrib[n]", the "x", "y",  
    "z" and "w" components of the vertex attribute variable are filled with  
    the "x", "y", "z", and "w" components, respectively, of generic vertex  
    attribute <n>.  Note that "vertex.attrib[0]" and "vertex.position" are  
    equivalent.  
  
    As described in section 2.7, setting a generic vertex attribute may leave  
    a corresponding conventional vertex attribute undefined, and vice versa.  
    To prevent inadvertent use of attribute pairs with undefined attributes, a  
    vertex program will fail to load if it binds both a conventional vertex  
    attribute and a generic vertex attribute listed in the same row of Table  
    X.2.1.  
  
      Conventional Attribute Binding      Generic Attribute Binding  
      ------------------------------      -------------------------  
      vertex.position                     vertex.attrib[0]  
      vertex.weight                       vertex.attrib[1]  
      vertex.weight[0]                    vertex.attrib[1]  
      vertex.normal                       vertex.attrib[2]  
      vertex.color                        vertex.attrib[3]  
      vertex.color.primary                vertex.attrib[3]  
      vertex.color.secondary              vertex.attrib[4]          
      vertex.fogcoord                     vertex.attrib[5]  
      vertex.texcoord                     vertex.attrib[8]  
      vertex.texcoord[0]                  vertex.attrib[8]  
      vertex.texcoord[1]                  vertex.attrib[9]  
      vertex.texcoord[2]                  vertex.attrib[10]  
      vertex.texcoord[3]                  vertex.attrib[11]  
      vertex.texcoord[4]                  vertex.attrib[12]  
      vertex.texcoord[5]                  vertex.attrib[13]  
      vertex.texcoord[6]                  vertex.attrib[14]  
      vertex.texcoord[7]                  vertex.attrib[15]  
      vertex.texcoord[n]                  vertex.attrib[8+n]  
  
      Table X.2.1:  Invalid Vertex Attribute Binding Pairs.  Vertex programs  
      may not bind both attributes listed in any row.  The <n> in the last row  
      matches the number of any valid texture unit.  
  
  
    Section 2.14.3.2,  Vertex Program Parameters  
  
    Vertex program parameter variables are a set of four-component  
    floating-point vectors used as constants during vertex program execution.  
    Vertex program parameters retain their values across vertex program  
    invocations, although their values can change between invocations due to  
    GL state changes.  
  
    Single program parameter variables and arrays of program parameter  
    variables can be declared explicitly using the <PARAM_statement> grammar  
    rule.  Single program parameter variables can also be declared implicitly  
    using the <paramSingleItemUse> grammar rule in an executable instruction.  
  
    Each single program parameter variable is bound to a constant vector or to  
    a GL state vector according to the <paramSingleInit> grammar rule.  
    Individual items of a program parameter array are bound to constant  
    vectors or GL state vectors according to the <programMultipleInit> grammar  
    rule.  The set of GL state that can be bound to program parameter  
    variables are given in Tables X.3.1 through X.3.8.  
  
  
    Constant Bindings  
  
    A program parameter variable can be bound to a scalar or vector constant  
    using the <paramConstDecl> grammar rule (explicit declarations) or the  
    <paramConstUse> grammar rule (implicit declarations).    
  
    If a program parameter binding matches the <paramConstScalarDecl> or  
    <paramConstScalarUse> grammar rules, the corresponding program parameter  
    variable is bound to the vector (X,X,X,X), where X is the value of the  
    specified constant.  Note that the <paramConstScalarUse> grammar rule,  
    used only in implicit declarations, allows only non-negative constants.  
    This disambiguates cases like "-2", which could conceivably be taken to  
    mean either the vector "(2,2,2,2)" with all components negated or  
    "(-2,-2,-2,-2)" without negation.  Only the former interpretation is  
    allowed by the grammar.  
  
    If a program parameter binding matches <paramConstVector>, the  
    corresponding program parameter variable is bound to the vector (X,Y,Z,W),  
    where X, Y, Z, and W are the values corresponding to the first, second,  
    third, and fourth match of <signedFloatConstant>.  If fewer than four  
    constants are specified, Y, Z, and W assume the values 0.0, 0.0, and 1.0,  
    if their respective constants are not specified.  
  
    Program parameter variables initialized to constant values can never be  
    modified.  
  
  
    Program Environment/Local Parameter Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      program.env[a]                 (x,y,z,w)   program environment   
                                                 parameter a  
      program.local[a]               (x,y,z,w)   program local parameter a  
      program.env[a..b]              (x,y,z,w)   program environment  
                                                 parameters a through b  
      program.local[a..b]            (x,y,z,w)   program local parameters  
                                                 a through b  
  
      Table X.3.1:  Program Environment/Local Parameter Bindings.  <a> and <b>  
      indicate parameter numbers, where <a> must be less than or equal to <b>.  
  
    If a program parameter binding matches "program.env[a]" or  
    "program.local[a]", the four components of the program parameter variable  
    are filled with the four components of program environment parameter <a>  
    or program local parameter <a>, respectively.  
  
    Additionally, for program parameter array bindings, "program.env[a..b]"  
    and "program.local[a..b]" are equivalent to specifying program environment  
    parameters <a> through <b> in order or program local parameters <a>  
    through <b> in order, respectively.  In either case, a program will fail  
    to load if <a> is greater than <b>.  
  
  
    Material Property Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      state.material.ambient         (r,g,b,a)   front ambient material color  
      state.material.diffuse         (r,g,b,a)   front diffuse material color  
      state.material.specular        (r,g,b,a)   front specular material color  
      state.material.emission        (r,g,b,a)   front emissive material color  
      state.material.shininess       (s,0,0,1)   front material shininess  
      state.material.front.ambient   (r,g,b,a)   front ambient material color  
      state.material.front.diffuse   (r,g,b,a)   front diffuse material color  
      state.material.front.specular  (r,g,b,a)   front specular material color  
      state.material.front.emission  (r,g,b,a)   front emissive material color  
      state.material.front.shininess (s,0,0,1)   front material shininess  
      state.material.back.ambient    (r,g,b,a)   back ambient material color  
      state.material.back.diffuse    (r,g,b,a)   back diffuse material color  
      state.material.back.specular   (r,g,b,a)   back specular material color  
      state.material.back.emission   (r,g,b,a)   back emissive material color  
      state.material.back.shininess  (s,0,0,1)   back material shininess  
  
      Table X.3.2:  Material Property Bindings.  If a material face is not  
      specified in the binding, the front property is used.  
  
    If a program parameter binding matches any of the material properties  
    listed in Table X.3.2, the program parameter variable is filled according  
    to the table.  For ambient, diffuse, specular, or emissive colors, the  
    "x", "y", "z", and "w" components are filled with the "r", "g", "b", and  
    "a" components, respectively, of the corresponding material color.  For  
    material shininess, the "x" component is filled with the material's  
    specular exponent, and the "y", "z", and "w" components are filled with 0,  
    0, and 1, respectively.  Bindings containing ".back" refer to the back  
    material; all other bindings refer to the front material.  
  
    Material properties can be changed inside a Begin/End pair, either  
    directly by calling Material, or indirectly through color material.  
    However, such property changes are not guaranteed to update program  
    parameter bindings until the following End command.  Program parameter  
    variables bound to material properties changed inside a Begin/End pair are  
    undefined until the following End command.  
  
  
    Light Property Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      state.light[n].ambient         (r,g,b,a)   light n ambient color  
      state.light[n].diffuse         (r,g,b,a)   light n diffuse color  
      state.light[n].specular        (r,g,b,a)   light n specular color  
      state.light[n].position        (x,y,z,w)   light n position  
      state.light[n].attenuation     (a,b,c,e)   light n attenuation constants  
                                                 and spot light exponent  
      state.light[n].spot.direction  (x,y,z,c)   light n spot direction and  
                                                 cutoff angle cosine  
      state.light[n].half            (x,y,z,1)   light n infinite half-angle  
      state.lightmodel.ambient       (r,g,b,a)   light model ambient color  
      state.lightmodel.scenecolor    (r,g,b,a)   light model front scene color  
      state.lightmodel.              (r,g,b,a)   light model front scene color  
               front.scenecolor  
      state.lightmodel.              (r,g,b,a)   light model back scene color  
               back.scenecolor  
      state.lightprod[n].ambient     (r,g,b,a)   light n / front material  
                                                 ambient color product  
      state.lightprod[n].diffuse     (r,g,b,a)   light n / front material  
                                                 diffuse color product  
      state.lightprod[n].specular    (r,g,b,a)   light n / front material  
                                                 specular color product  
      state.lightprod[n].            (r,g,b,a)   light n / front material  
              front.ambient                      ambient color product  
      state.lightprod[n].            (r,g,b,a)   light n / front material  
              front.diffuse                      diffuse color product  
      state.lightprod[n].            (r,g,b,a)   light n / front material  
              front.specular                     specular color product  
      state.lightprod[n].            (r,g,b,a)   light n / back material  
              back.ambient                       ambient color product  
      state.lightprod[n].            (r,g,b,a)   light n / back material  
              back.diffuse                       diffuse color product  
      state.lightprod[n].            (r,g,b,a)   light n / back material  
              back.specular                      specular color product  
  
      Table X.3.3: Light Property Bindings.  <n> indicates a light number.  
  
    If a program parameter binding matches "state.light[n].ambient",  
    "state.light[n].diffuse", or "state.light[n].specular", the "x", "y", "z",  
    and "w" components of the program parameter variable are filled with the  
    "r", "g", "b", and "a" components, respectively, of the corresponding  
    light color.  
  
    If a program parameter binding matches "state.light[n].position", the "x",  
    "y", "z", and "w" components of the program parameter variable are filled  
    with the "x", "y", "z", and "w" components, respectively, of the light  
    position.  
      
    If a program parameter binding matches "state.light[n].attenuation", the  
    "x", "y", and "z" components of the program parameter variable are filled  
    with the constant, linear, and quadratic attenuation parameters of the  
    specified light, respectively (section 2.13.1).  The "w" component of the  
    program parameter variable is filled with the spot light exponent of the  
    specified light.  
  
    If a program parameter binding matches "state.light[n].spot.direction",  
    the "x", "y", and "z" components of the program parameter variable are  
    filled with the "x", "y", and "z" components of the spot light direction  
    of the specified light, respectively (section 2.13.1).  The "w" component  
    of the program parameter variable is filled with the cosine of the spot  
    light cutoff angle of the specified light.  
  
    If a program parameter binding matches "state.light[n].half", the "x",  
    "y", and "z" components of the program parameter variable are filled with  
    the x, y, and z components, respectively, of the normalized infinite  
    half-angle vector  
  
      h_inf = || P + (0, 0, 1) ||.  
  
    The "w" component is filled with 1.  In the computation of h_inf, P  
    consists of the x, y, and z coordinates of the normalized vector from the  
    eye position P_e to the eye-space light position P_pli (section 2.13.1).  
    h_inf is defined to correspond to the normalized half-angle vector when  
    using an infinite light (w coordinate of the position is zero) and an  
    infinite viewer (v_bs is FALSE).  For local lights or a local viewer,  
    h_inf is well-defined but does not match the normalized half-angle vector,  
    which will vary depending on the vertex position.  
  
    If a program parameter binding matches "state.lightmodel.ambient", the  
    "x", "y", "z", and "w" components of the program parameter variable are  
    filled with the "r", "g", "b", and "a" components of the light model  
    ambient color, respectively.  
  
    If a program parameter binding matches "state.lightmodel.scenecolor" or  
    "state.lightmodel.front.scenecolor", the "x", "y", and "z" components of  
    the program parameter variable are filled with the "r", "g", and "b"  
    components respectively of the "front scene color"  
  
      c_scene = a_cs * a_cm + e_cm,  
  
    where a_cs is the light model ambient color, a_cm is the front ambient  
    material color, and e_cm is the front emissive material color.  The "w"  
    component of the program parameter variable is filled with the alpha  
    component of the front diffuse material color.  If a program parameter  
    binding matches "state.lightmodel.back.scenecolor", a similar back scene  
    color, computed using back-facing material properties, is used.  The front  
    and back scene colors match the values that would be assigned to vertices  
    using conventional lighting if all lights were disabled.  
  
    If a program parameter binding matches anything beginning with  
    "state.lightprod[n]", the "x", "y", and "z" components of the program  
    parameter variable are filled with the "r", "g", and "b" components,  
    respectively, of the corresponding light product.  The three light product  
    components are the products of the corresponding color components of the  
    specified material property and the light color of the specified light  
    (see Table X.3.3).  The "w" component of the program parameter variable is  
    filled with the alpha component of the specified material property.  
  
    Light products depend on material properties, which can be changed inside  
    a Begin/End pair.  Such property changes are not guaranteed to take effect  
    until the following End command.  Program parameter variables bound to  
    light products whose corresponding material property changes inside a  
    Begin/End pair are undefined until the following End command.  
  
  
    Texture Coordinate Generation Property Bindings  
  
      Binding                    Components  Underlying State  
      -------------------------  ----------  ----------------------------  
      state.texgen[n].eye.s      (a,b,c,d)   TexGen eye linear plane  
                                             coefficients, s coord, unit n  
      state.texgen[n].eye.t      (a,b,c,d)   TexGen eye linear plane  
                                             coefficients, t coord, unit n  
      state.texgen[n].eye.r      (a,b,c,d)   TexGen eye linear plane  
                                             coefficients, r coord, unit n  
      state.texgen[n].eye.q      (a,b,c,d)   TexGen eye linear plane  
                                             coefficients, q coord, unit n  
      state.texgen[n].object.s   (a,b,c,d)   TexGen object linear plane  
                                             coefficients, s coord, unit n  
      state.texgen[n].object.t   (a,b,c,d)   TexGen object linear plane  
                                             coefficients, t coord, unit n  
      state.texgen[n].object.r   (a,b,c,d)   TexGen object linear plane  
                                             coefficients, r coord, unit n  
      state.texgen[n].object.q   (a,b,c,d)   TexGen object linear plane  
                                             coefficients, q coord, unit n  
  
      Table X.3.4:  Texture Coordinate Generation Property Bindings.  "[n]" is  
      optional -- texture unit <n> is used if specified; texture unit 0 is  
      used otherwise.  
  
    If a program parameter binding matches a set of TexGen plane coefficients,  
    the "x", "y", "z", and "w" components of the program parameter variable  
    are filled with the coefficients p1, p2, p3, and p4, respectively, for  
    object linear coefficients, and the coefficents p1', p2', p3', and p4',  
    respectively, for eye linear coefficients (section 2.10.4).  
  
  
    Fog Property Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      state.fog.color                (r,g,b,a)   RGB fog color (section 3.10)  
      state.fog.params               (d,s,e,r)   fog density, linear start  
                                                 and end, and 1/(end-start)  
                                                 (section 3.10)   
  
      Table X.3.5:  Fog Property Bindings  
  
    If a program parameter binding matches "state.fog.color", the "x", "y",  
    "z", and "w" components of the program parameter variable are filled with  
    the "r", "g", "b", and "a" components, respectively, of the fog color  
    (section 3.10).  
  
    If a program parameter binding matches "state.fog.params", the "x", "y",  
    and "z" components of the program parameter variable are filled with the  
    fog density, linear fog start, and linear fog end parameters (section  
    3.10), respectively.  The "w" component is filled with 1/(end-start),  
    where end and start are the linear fog end and start parameters,  
    respectively.  
  
  
    Clip Plane Property Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      state.clip[n].plane            (a,b,c,d)   clip plane n coefficients  
  
      Table X.3.6:  Clip Plane Property Bindings.  <n> specifies the clip  
      plane number, and is required.  
  
    If a program parameter binding matches "state.clip[n].plane", the "x",  
    "y", "z", and "w" components of the program parameter variable are filled  
    with the coefficients p1', p2', p3', and p4', respectively, of clip plane  
    <n> (section 2.11).  
  
  
    Point Property Bindings  
  
      Binding                        Components  Underlying State  
      -----------------------------  ----------  ----------------------------  
      state.point.size               (s,n,x,f)   point size, min and max size  
                                                 clamps, and fade threshold  
                                                 (section 3.3)   
      state.point.attenuation        (a,b,c,1)   point size attenuation consts  
  
      Table X.3.7:  Point Property Bindings  
  
    If a program parameter binding matches "state.point.size", the "x", "y",  
    "z", and "w" components of the program parameter variable are filled with  
    the point size, minimum point size, maximum point size, and fade  
    threshold, respectively (section 3.3).  
  
    If a program parameter binding matches "state.point.attenuation", the "x",  
    "y", and "z" components of the program parameter variable are filled with  
    the constant, linear, and quadratic point size attenuation parameters (a,  
    b, and c), respectively (section 3.3).  The "w" component is filled with  
    1.  
  
  
    Matrix Property Bindings  
  
      Binding                               Underlying State  
      ------------------------------------  ---------------------------  
      * state.matrix.modelview[n]           modelview matrix n  
        state.matrix.projection             projection matrix  
        state.matrix.mvp                    modelview-projection matrix  
      * state.matrix.texture[n]             texture matrix n  
        state.matrix.palette[n]             modelview palette matrix n  
        state.matrix.program[n]             program matrix n  
  
      Table X.3.8:  Base Matrix Property Bindings.  The "[n]" syntax indicates  
      a specific matrix number.  For modelview and texture matrices, a matrix  
      number is optional, and matrix zero will be used if the matrix number is  
      omitted.  These base bindings may further be modified by a  
      inverse/transpose selector and a row selector.  
  
    If the beginning of a program parameter binding matches any of the matrix  
    binding names listed in Table X.3.8, the binding corresponds to a 4x4  
    matrix.  If the parameter binding is followed by ".inverse", ".transpose",  
    or ".invtrans" (<stateMatModifier> grammar rule), the inverse, transpose,  
    or transpose of the inverse, respectively, of the matrix specified in  
    Table X.3.8 is selected.  Otherwise, the matrix specified in Table X.3.8  
    is selected.  If the specified matrix is poorly-conditioned (singular or  
    nearly so), its inverse matrix is undefined.  The binding name  
    "state.matrix.mvp" refers to the product of modelview matrix zero and the  
    projection matrix, defined as  
  
       MVP = P * M0,  
  
    where P is the projection matrix and M0 is modelview matrix zero.  
  
    If the selected matrix is followed by ".row[<a>]" (matching the  
    <stateMatrixRow> grammar rule), the "x", "y", "z", and "w" components of  
    the program parameter variable are filled with the four entries of row <a>  
    of the selected matrix.  In the example,  
  
      PARAM m0 = state.matrix.modelview[1].row[0];  
      PARAM m1 = state.matrix.projection.transpose.row[3];  
  
    the variable "m0" is set to the first row (row 0) of modelview matrix 1  
    and "m1" is set to the last row (row 3) of the transpose of the projection  
    matrix.  
  
    For program parameter array bindings, multiple rows of the selected matrix  
    can be bound via the <stateMatrixRows> grammar rule.  If the selected  
    matrix binding is followed by ".row[<a>..<b>]", the result is equivalent  
    to specifying matrix rows <a> through <b>, in order.  A program will fail  
    to load if <a> is greater than <b>.  If no row selection is specified  
    (<optMatrixRows> matches ""), matrix rows 0 through 3 are bound in order.  
    In the example,  
  
      PARAM m2[] = { state.matrix.program[0].row[1..2] };  
      PARAM m3[] = { state.matrix.program[0].transpose };  
  
    the array "m2" has two entries, containing rows 1 and 2 of program matrix  
    zero, and "m3" has four entries, containing all four rows of the transpose  
    of program matrix zero.  
  
  
    Program Parameter Arrays  
  
    A program parameter array variable can be declared explicitly by matching  
    the <PARAM_multipleStmt> grammar rule.  Programs can optionally specify  
    the number of individual program parameters in the array, using the  
    <optArraySize> grammar rule.  Program parameter arrays may not be declared  
    implicity.  
  
    Individual parameter variables in a program parameter array are bound to  
    GL state vectors or constant vectors as specified by the grammar rule  
    <paramMultInitList>.  Each individual parameter in the array is bound in  
    turn as described above.    
  
    The total number of entries in the array is equal to the number of  
    parameters bound in the initializer list.  A vertex program that specifies  
    an array size (<optArraySize> matches <integer>) that does not match the  
    number of parameter bindings in the initialization list will fail to load.  
  
    Program parameter array variables may be accessed using absolute  
    addressing by matching the <progParamArrayAbs> grammar rule, or relative  
    addressing by matching the <progParamArrayRel> grammar rule.  
  
    Array accesses using absolute addressing are checked against the limits of  
    the array.  If any vertex program instruction accesses a program parameter  
    array using absolute addressing with an out-of-range index (greater than  
    or equal to the size of the array), the vertex program will fail to load.  
  
    Individual state vectors can have no more than one unique binding in any  
    given program.  The GL will automatically combine multiple bindings of the  
    same state vector into a single unique binding, except for the case where  
    a state vector is bound multiple times in program parameter arrays  
    accessed using relative addressing.  A vertex program will fail to load if  
    any GL state vector is bound multiple times in a single array accessed  
    using relative addressing or bound once in two or more arrays accessed  
    using relative addressing.  
  
  
    Section 2.14.3.3,  Vertex Program Temporaries  
  
    Vertex program temporary variables are a set of four-component  
    floating-point vectors used to hold temporary results during vertex  
    program execution.  Temporaries do not persist between program  
    invocations, and are undefined at the beginning of each vertex program  
    invocation.  
  
    Vertex program temporary variables can be declared explicitly using the  
    <TEMP_statement> grammar rule.  Each such statement can declare one or  
    more temporaries.  Vertex program temporary variables can not be declared  
    implicitly.  
  
  
    Section 2.14.3.4,  Vertex Program Results  
  
    Vertex program result variables are a set of four-component floating-point  
    vectors used to hold the final results of a vertex program.  Vertex  
    program result variables are write-only during vertex program execution.  
  
    Vertex program result variables can be declared explicitly using the  
    <OUTPUT_statement> grammar rule, or implicitly using the <resultBinding>  
    grammar rule in an executable instruction.  Each vertex program result  
    variable is bound to a transformed vertex attribute used during primitive  
    assembly and rasterization.  The set of vertex program result variable  
    bindings is given in Table X.4.  
  
      Binding                        Components  Description  
      -----------------------------  ----------  ----------------------------  
      result.position                (x,y,z,w)   position in clip coordinates  
      result.color                   (r,g,b,a)   front-facing primary color  
      result.color.primary           (r,g,b,a)   front-facing primary color  
      result.color.secondary         (r,g,b,a)   front-facing secondary color  
      result.color.front             (r,g,b,a)   front-facing primary color  
      result.color.front.primary     (r,g,b,a)   front-facing primary color  
      result.color.front.secondary   (r,g,b,a)   front-facing secondary color  
      result.color.back              (r,g,b,a)   back-facing primary color  
      result.color.back.primary      (r,g,b,a)   back-facing primary color  
      result.color.back.secondary    (r,g,b,a)   back-facing secondary color  
      result.fogcoord                (f,*,*,*)   fog coordinate  
      result.pointsize               (s,*,*,*)   point size  
      result.texcoord                (s,t,r,q)   texture coordinate, unit 0  
      result.texcoord[n]             (s,t,r,q)   texture coordinate, unit n  
  
      Table X.4:  Vertex Result Variable Bindings.  Components labeled "*" are  
      unused.  
  
    If a result variable binding matches "result.position", updates to the  
    "x", "y", "z", and "w" components of the result variable modify the "x",  
    "y", "z", and "w" components, respectively, of the transformed vertex's  
    clip coordinates.  Final window coordinates will be generated for the  
    vertex as described in section 2.14.4.4.  
  
    If a result variable binding match begins with "result.color", updates to  
    the "x", "y", "z", and "w" components of the result variable modify the  
    "r", "g", "b", and "a" components, respectively, of the corresponding  
    vertex color attribute in Table X.4.  Color bindings that do not specify  
    "front" or "back" are consided to refer to front-facing colors.  Color  
    bindings that do not specify "primary" or "secondary" are considered to  
    refer to primary colors.  
  
    If a result variable binding matches "result.fogcoord", updates to the "x"  
    component of the result variable set the transformed vertex's fog  
    coordinate.  Updates to the "y", "z", and "w" components of the result  
    variable have no effect.  
  
    If a result variable binding matches "result.pointsize", updates to the  
    "x" component of the result variable set the transformed vertex's point  
    size.  Updates to the "y", "z", and "w" components of the result variable  
    have no effect.  
  
    If a result variable binding matches "result.texcoord" or  
    "result.texcoord[n]", updates to the "x", "y", "z", and "w" components of  
    the result variable set the "s", "t", "r" and "q" components,  
    respectively, of the transformed vertex's texture coordinates for texture  
    unit <n>.  If "[n]" is omitted, texture unit zero is selected.  
  
    When in vertex program mode, all attributes of a transformed vertex are  
    undefined at each vertex program invocation.  Any results, or even  
    individual components of results, that are not written to during vertex  
    program execution remain undefined.  
  
  
    Section 2.14.3.5,  Vertex Program Address Registers  
  
    Vertex program address register variables are a set of four-component  
    signed integer vectors where only the "x" component of the address  
    registers is currently accessible.  Address registers are used as indices  
    when performing relative addressing in program parameter arrays (section  
    2.14.4.2).  
  
    Vertex program address registers can be declared explicitly using the  
    <ADDRESS_statement> grammar rule.  Each such statement can declare one or  
    more address registers.  Vertex program address registers can not be  
    declared implicitly.  
  
    Vertex program address register variables are undefined at each vertex  
    program invocation.  Address registers can be written by the ARL  
    instruction (section 2.14.5.3), and will be read when a program uses  
    relative addressing in program parameter arrays.  
  
  
    Section 2.14.3.6, Vertex Program Aliases  
  
    Vertex programs can create aliases by matching the <ALIAS_statement>  
    grammar rule.  Aliases allow programs to use multiple variable names to  
    refer to a single underlying variable.  For example, the statement  
  
      ALIAS var1 = var0  
  
    establishes a variable name named "var1".  Subsequent references to "var1"  
    in the program text are treated as references to "var0".  The left hand  
    side of an ALIAS statement must be a new variable name, and the right hand  
    side must be an established variable name.  
  
    Aliases are not considered variable declarations, so do not count against  
    the limits on the number of variable declarations allowed in the program  
    text.  
  
  
    Section 2.14.3.7, Vertex Program Resource Limits  
  
    The vertex program execution environment provides implementation-dependent  
    resource limits on the number of instructions, temporary variable  
    declarations, vertex attribute bindings, address register declarations,  
    and program parameter bindings.  A program that exceeds any of these  
    resource limits will fail to load.  The resource limits for vertex  
    programs can be queried by calling GetProgramiv (section 6.1.12) with a  
    target of VERTEX_PROGRAM_ARB.  
  
    The limit on vertex program instructions can be queried with a <pname> of  
    MAX_PROGRAM_INSTRUCTIONS_ARB, and must be at least 128.  Each instruction  
    in the program (matching the <instruction> grammar rule) counts against  
    this limit.  
  
    The limit on vertex program temporary variable declarations can be queried  
    with a <pname> of MAX_PROGRAM_TEMPORARIES_ARB, and must be at least 12.  
    Each temporary declared in the program, using the <TEMP_statement> grammar  
    rule, counts against this limit.  Aliases of declared temporaries do not.  
      
    The limit on vertex program attribute bindings can be queried with a  
    <pname> of MAX_PROGRAM_ATTRIBS_ARB and must be at least 16.  Each distinct  
    vertex attribute bound explicitly or implicitly in the program counts  
    against this limit; vertex attributes bound multiple times count only  
    once.  
  
    The limit on vertex program address register declarations can be queried  
    with a <pname> of MAX_PROGRAM_ADDRESS_REGISTERS_ARB, and must be at least  
    1.  Each address register declared in the program, using the  
    <ADDRESS_statement> grammar rule, counts against this limit.  
      
    The limit on vertex program parameter bindings can be queried with a  
    <pname> of MAX_PROGRAM_PARAMETERS_ARB, and must be at least 96.  Each  
    distinct GL state vector bound explicitly or implicitly in the program  
    counts against this limit; GL state vectors bound multiple times count  
    only once.  Each constant vector bound to an array accessed using relative  
    addressing counts against this limit, even if the same constant vector is  
    bound multiple times or in multiple arrays.  Every other constant vector  
    bound in the program is counted if and only if an identical constant  
    vector has not already been counted.  Two constant vectors are considered  
    identical if the four component values are numerically equivalent.  Recall  
    that scalar constants bound in a program are treated as vector constants  
    with the scalar value replicated.  In the following code  
  
           PARAM arr1[4] = { {1,2,3,4}, {1,2,3,4}, {4,4,4,4}, {5,6,7,8} };  
           PARAM arr2[3] = { {1,2,3,4}, {5,6,7,8}, {0,1,2,3} };  
           PARAM x = {4,3,2,1};  
           PARAM y = {1,2,3,4};  
           PARAM z = 4;  
           PARAM r = {4,3,2,1};  
  
    assume that arr1 is accessed using relative addressing but arr2 is not.  
    The four constants in arr1 all count against the limit.  Only two other  
    constants, {0,1,2,3} in arr2, and {4,3,2,1} in x, are counted; the other  
    constants are identical to constants that had been previously counted.  
  
    In addition to the limits described above, the GL provides a similar set  
    of implementation-dependent native resource limits.  These limits,  
    specified in section 6.1.12, provide guidance as to whether the program is  
    small enough to use a "native" mode where vertex programs may be executed  
    with higher performance.  The native resource limits and usage counts are  
    implementation-dependent and may not exactly correspond to limits and  
    counts described above.  In particular, native resource consumption may be  
    reduced by program optimizations performed by the GL, or increased due to  
    emulation of non-native instructions.  Programs that satisfy the program  
    resource limits described above, but whose native resource usage exceeds  
    one or more native resource limits, are guaranteed to load but may execute  
    suboptimally.  
  
    To assist in resource counting, the GL additionally provides GetProgram  
    queries to determine the resource usage and native resource usage of the  
    currently bound program, and to determine whether the bound program  
    exceeds any native resource limit.  
  
  
    Section 2.14.4,  Vertex Program Execution Environment  
  
    If vertex program mode is enabled, the currently bound vertex program is  
    executed when a vertex is specified directly through the Vertex command,  
    indirectly through vertex arrays or evaluators (section 5.1), or when the  
    current raster position is updated.    
  
    If vertex program mode is enabled and the currently bound program object  
    does not contain a valid vertex program, the error INVALID_OPERATION will  
    be generated by Begin, RasterPos, and any command that implicitly calls  
    Begin (e.g., DrawArrays).  
  
    Vertex programs execute a sequence of instructions without  
    branching.  Vertex programs begin by executing the first instruction in  
    the program, and execute instructions in the order specified in the  
    program until the last instruction is completed.  
      
    There are twenty-seven vertex program instructions.  The instructions and  
    their respective input and output parameters are summarized in Table X.5.  
  
      Instruction    Inputs  Output   Description  
      -----------    ------  ------   --------------------------------  
      ABS            v       v        absolute value  
      ADD            v,v     v        add  
      ARL            s       a        address register load  
      DP3            v,v     ssss     3-component dot product  
      DP4            v,v     ssss     4-component dot product  
      DPH            v,v     ssss     homogeneous dot product  
      DST            v,v     v        distance vector  
      EX2            s       ssss     exponential base 2  
      EXP            s       v        exponential base 2 (approximate)  
      FLR            v       v        floor  
      FRC            v       v        fraction  
      LG2            s       ssss     logarithm base 2  
      LIT            v       v        compute light coefficients  
      LOG            s       v        logarithm base 2 (approximate)  
      MAD            v,v,v   v        multiply and add  
      MAX            v,v     v        maximum  
      MIN            v,v     v        minimum  
      MOV            v       v        move  
      MUL            v,v     v        multiply  
      POW            s,s     ssss     exponentiate  
      RCP            s       ssss     reciprocal  
      RSQ            s       ssss     reciprocal square root  
      SGE            v,v     v        set on greater than or equal  
      SLT            v,v     v        set on less than  
      SUB            v,v     v        subtract  
      SWZ            v       v        extended swizzle  
      XPD            v,v     v        cross product  
  
      Table X.5:  Summary of vertex program instructions.  "v" indicates a  
      floating-point vector input or output, "s" indicates a floating-point  
      scalar input, "ssss" indicates a scalar output replicated across a  
      4-component result vector, and "a" indicates a single address register  
      component.  
  
  
    Section 2.14.4.1, Vertex Program Operands  
  
    Most vertex program instructions operate on floating-point vectors or  
    scalars, as indicated by the grammar rules <swizzleSrcReg> and  
    <scalarSrcReg>, respectively.  
  
    Vector and scalar operands can be obtained from vertex attribute, program  
    parameter, or temporary registers, as indicated by the <srcReg> rule.  For  
    scalar operands, a single vector component is selected by the  
    <scalarSuffix> rule, where the characters "x", "y", "z", and "w" select  
    the x, y, z, and w components, respectively, of the vector.  
  
    Vector operands can be swizzled according to the <swizzleSuffix> rule.  In  
    its most general form, the <swizzleSuffix> rule matches the pattern  
    ".????" where each question mark is replaced with one of "x", "y", "z", or  
    "w".  For such patterns, the x, y, z, and w components of the operand are  
    taken from the vector components named by the first, second, third, and  
    fourth character of the pattern, respectively.  For example, if the  
    swizzle suffix is ".yzzx" and the specified source contains {2,8,9,0}, the  
    swizzled operand used by the instruction is {8,9,9,2}.  
  
    If the <swizzleSuffix> rule matches "", it is treated as though it were  
    ".xyzw".  If the <swizzleSuffix> rule matches (ignoring whitespace) ".x",  
    ".y", ".z", or ".w", these are treated the same as ".xxxx", ".yyyy",  
    ".zzzz", and ".wwww" respectively.  
  
    Floating-point scalar or vector operands can optionally be negated  
    according to the <optionalSign> rule in <scalarSrcReg> and  
    <swizzleSrcReg>.  If the <optionalSign> matches "-", each operand or  
    operand component is negated.  
  
    The following pseudo-code spells out the operand generation process.  In  
    the example, "float" is a floating-point scalar type, while "floatVec" is  
    a four-component vector.  "source" refers to the register used for the  
    operand, matching the <srcReg> rule.  "negate" is TRUE if the  
    <optionalSign> rule in <scalarSrcReg> or <swizzleSrcReg> matches "-" and  
    FALSE otherwise.  The ".c***", ".*c**", ".**c*", ".***c" modifiers refer  
    to the x, y, z, and w components obtained by the swizzle operation; the  
    ".c" modifier refers to the single component selected for a scalar load.  
  
      floatVec VectorLoad(floatVec source)  
      {  
          floatVec operand;  
  
          operand.x = source.c***;  
          operand.y = source.*c**;  
          operand.z = source.**c*;  
          operand.w = source.***c;  
          if (negate) {  
             operand.x = -operand.x;  
             operand.y = -operand.y;  
             operand.z = -operand.z;  
             operand.w = -operand.w;  
          }  
  
          return operand;  
      }  
  
      float ScalarLoad(floatVec source)   
      {  
          float operand;  
  
          operand = source.c;  
          if (negate) {  
            operand = -operand;  
          }  
  
          return operand;  
      }  
  
    Section 2.14.4.2,  Vertex Program Parameter Arrays  
  
    A vertex program can load a single element of a program parameter array  
    using either absolute or relative addressing.  Program parameter arrays  
    are accessed when the <progParamArray> rule is matched.  
  
    Absolute addressing is used when the <progParamArrayMem> grammar rule  
    matches <progParamArrayAbs>.  When using absolute addressing, the offset  
    of the selected entry in the array is given by the number matching  
    <progParamRegNum>.  
  
    Relative addressing is used when the <progParamArrayMem> grammar rule  
    matches <progParamArrayRel>.  When using relative addressing, the offset  
    of the selected entry in the array is computed by adding the address  
    register component specified by the <addrReg> and <addrComponent> rules to  
    the positive or negative offset specified by the <addrRegRelOffset> rule.  
    If <addrRegRelOffset> matches "", no fixed offset is added to the address  
    register component.  If the computed offset is negative or exceeds the  
    size of the array, the results of the access are undefined, but may not  
    lead to program or GL termination.  
  
    The following pseudo-code spells out the process of loading a program  
    parameter from an array.  "addrReg" refers to the address register  
    component used for relative addressing, "absolute" is TRUE if the operand  
    uses absolute addressing and FALSE otherwise.  "paramNumber" is the  
    program parameter number for absolute addressing; "paramOffset" is the  
    constant program parameter offset for relative addressing.  "paramArray"  
    is the parameter array that matches the <progParamArray> rule.  
  
      floatVec ProgramParameterLoad(int addrReg)  
      {  
        int index;  
          
        if (absolute) {  
          index = paramNumber;  
        } else {  
          index = addrReg + paramOffset  
        }  
  
        return paramArray[index];  
      }  
  
    Relative addressing can only be used for accessing program parameter  
    arrays.  
  
  
    Section 2.14.4.3,  Vertex Program Destination Register Update  
  
    Most vertex program instructions write a 4-component result vector to a  
    single temporary or vertex result register.  Writes to individual  
    components of the destination register are controlled by individual  
    component write masks specified as part of the instruction.  
  
    The component write mask is specified by the <optionalMask> rule found in  
    the <maskedDstReg> rule.  If the optional mask is "", all components are  
    enabled.  Otherwise, the optional mask names the individual components to  
    enable.  The characters "x", "y", "z", and "w" match the x, y, z, and w  
    components respectively.  For example, an optional mask of ".xzw"  
    indicates that the x, z, and w components should be enabled for writing  
    but the y component should not.  The grammar requires that the destination  
    register mask components must be listed in "xyzw" order.  
  
    Each component of the destination register is updated with the result of  
    the vertex program instruction if and only if the component is enabled for  
    writes by the component write mask.  Otherwise, the component of the  
    destination register remains unchanged.  
  
    The following pseudocode illustrates the process of writing a result  
    vector to the destination register.  In the pseudocode, "instrmask" refers  
    to the component write mask given by the <optionalMask> rule.  "result"  
    and "destination" refer to the result vector and the register selected by  
    <dstReg>, respectively.  
  
      void UpdateDestination(floatVec destination, floatVec result)  
      {  
          floatVec merged;  
  
          // Merge the converted result into the destination register, under  
          // control of the compile-time write mask.  
          merged = destination;  
          if (instrMask.x) {  
              merged.x = result.x;  
          }  
          if (instrMask.y) {  
              merged.y = result.y;  
          }  
          if (instrMask.z) {  
              merged.z = result.z;  
          }  
          if (instrMask.w) {  
              merged.w = result.w;  
          }  
  
          // Write out the new destination register.  
          destination = merged;  
      }  
  
    The "ARL" instruction updates the single address register component  
    similarly; the grammar is designed so that it writes to only the "x"  
    component of an address register variable.  
  
  
    Section 2.14.4.4,  Vertex Program Result Processing  
  
    As a vertex program executes, it will write to one or more result  
    registers that are mapped to transformed vertex attributes.  When a vertex  
    program completes, the transformed vertex attributes are used to generate  
    primitives.  
  
    The clip coordinates written to "result.position" are used to generate  
    normalized device coordinates and window coordinates for the vertex in the  
    manner described section 2.10.  
  
    Transformed vertices are then assembled into primitives and clipped as  
    described in section 2.11.  
  
    The selection between front-facing and back-facing color attributes  
    depends on the primitive to which the vertex belongs.  If the primitive is  
    a point or a line segment, or if vertex program two-sided color mode is  
    disabled, the front-facing colors are always selected.  If it is a polygon  
    and two-sided color mode is enabled, then the selection is performed in  
    exactly the same way as in two-sided lighting mode (section 2.13.1).  
    Vertex program two-sided color mode is enabled and disabled by calling  
    Enable or Disable with the symbolic value VERTEX_PROGRAM_TWO_SIDE_ARB.  
  
    Finally, as primitives are assembled, color clamping (section 2.13.6),  
    flatshading (section 2.13.7), color, attribute clipping (section 2.13.8),  
    and final color processing (section 2.13.9) operations are applied to the  
    transformed vertices.  
  
  
    Section 2.14.4.5,  Vertex Program Options  
  
    The <optionSequence> grammar rule provides a mechanism for programs to  
    indicate that one or more extended language features are used by the  
    program.  All program options used by the program must be declared at the  
    beginning of the program string.  Each program option specified in a  
    program string will modify the syntactic or semantic rules used to  
    interpet the program and the execution environment used to execute the  
    program.  Program options not present in the program string are ignored,  
    even if they are supported by the GL.  
  
    The <identifier> token in the <option> rule must match the name of a  
    program option supported by the implementation.  To avoid option name  
    conflicts, option identifiers are required to begin with a vendor prefix.  
    A program will fail to load if it specifies a program option not supported  
    by the GL.  
  
    Vertex program options should confine their semantic changes to the domain  
    of vertex programs.  Support for a vertex program option should not change  
    the specification and behavior of vertex programs not requesting use of  
    that option.  
  
    2.14.4.5.1,  Position-Invariant Vertex Program Option  
  
    If a vertex program specifies the "ARB_position_invariant" option, the  
    program is used to generate all transformed vertex attributes except for  
    position.  Instead, clip coordinates are computed as specified in section  
    2.10.  Additionally, user clipping is performed as described in section  
    2.11.  Use of position-invariant vertex programs should generally  
    guarantee that the transformed position of a vertex should be the same  
    whether vertex program mode is enabled or disabled, allowing for correct  
    mixed multi-pass rendering semantics.  
  
    When the position-invariant option is specified in a vertex program,  
    vertex programs can no longer produced a transformed position.  The  
    <resultBinding> rule is modified to remove "result.position" from the list  
    of token sequences matching the rule.  A semantic restriction is added to  
    indicate that a vertex program will fail to load if the number of  
    instructions it contains exceeds the implementation-dependent limit minus  
    four.  
  
  
    Section 2.14.5,  Vertex Program Instruction Set  
  
    The following sections describe the set of supported vertex program  
    instructions.  Each section contains pseudocode describing the  
    instruction.  Instructions will have up to three operands, referred to as  
    "op0", "op1", and "op2".  The operands are loaded using the mechanisms  
    specified in section 2.14.4.1.  The variables "tmp", "tmp0", "tmp1", and  
    "tmp2" describe scalars or vectors used to hold intermediate results in  
    the instruction.  Most instructions will generate a result vector called  
    "result".  The result vector is then written to the destination register  
    specified in the instruction as described in section 2.14.4.3.  
  
  
    Section 2.14.5.1,  ABS:  Absolute Value  
  
    The ABS instruction performs a component-wise absolute value operation on  
    the single operand to yield a result vector.  
  
      tmp = VectorLoad(op0);   
      result.x = fabs(tmp.x);  
      result.y = fabs(tmp.y);  
      result.z = fabs(tmp.z);  
      result.w = fabs(tmp.w);  
  
  
    Section 2.14.5.2,  ADD:  Add  
  
    The ADD instruction performs a component-wise add of the two operands to  
    yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = tmp0.x + tmp1.x;  
      result.y = tmp0.y + tmp1.y;  
      result.z = tmp0.z + tmp1.z;  
      result.w = tmp0.w + tmp1.w;  
  
    The following rules apply to addition:  
  
      1. <x> + <y> == <y> + <x>, for all <x> and <y>.  
      2. <x> + 0.0 == <x>, for all <x>.  
  
  
    Section 2.14.5.3,  ARL:  Address Register Load  
  
    The ARL instruction loads a single scalar operand and performs a floor  
    operation to generate a signed integer scalar result:  
  
        result = floor(ScalarLoad(op0));  
  
    The floor operation returns the largest integer less than or equal to the  
    operand.  For example floor(-1.7) = -2.0, floor(+1.0) = +1.0, and  
    floor(+3.7) = +3.0.  
  
  
    Section 2.14.5.4,  DP3:  Three-Component Dot Product  
  
    The DP3 instruction computes a three-component dot product of the two  
    operands (using the x, y, and z components) and replicates the dot product  
    to all four components of the result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +   
            (tmp0.z * tmp1.z);  
      result.x = dot;  
      result.y = dot;  
      result.z = dot;  
      result.w = dot;  
  
  
    Section 2.14.5.5,  DP4:  Four-Component Dot Product  
  
    The DP4 instruction computes a four-component dot product of the two  
    operands and replicates the dot product to all four components of the  
    result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1):  
      dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +   
            (tmp0.z * tmp1.z) + (tmp0.w * tmp1.w);  
      result.x = dot;  
      result.y = dot;  
      result.z = dot;  
      result.w = dot;  
  
  
    Section 2.14.5.6,  DPH:  Homogeneous Dot Product  
  
    The DPH instruction computes a three-component dot product of the two  
    operands (using the x, y, and z components), adds the w component of the  
    second operand, and replicates the sum to all four components of the  
    result vector.  This is equivalent to a four-component dot product where  
    the w component of the first operand is forced to 1.0.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1):  
      dot = (tmp0.x * tmp1.x) + (tmp0.y * tmp1.y) +   
            (tmp0.z * tmp1.z) + tmp1.w;  
      result.x = dot;  
      result.y = dot;  
      result.z = dot;  
      result.w = dot;  
  
  
    Section 2.14.5.7,  DST:  Distance Vector  
  
    The DST instruction computes a distance vector from two specially-  
    formatted operands.  The first operand should be of the form [NA, d^2,  
    d^2, NA] and the second operand should be of the form [NA, 1/d, NA, 1/d],  
    where NA values are not relevant to the calculation and d is a vector  
    length.  If both vectors satisfy these conditions, the result vector will  
    be of the form [1.0, d, d^2, 1/d].  
  
    The exact behavior is specified in the following pseudo-code:  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = 1.0;  
      result.y = tmp0.y * tmp1.y;  
      result.z = tmp0.z;  
      result.w = tmp1.w;  
  
    Given an arbitrary vector, d^2 can be obtained using the DP3 instruction  
    (using the same vector for both operands) and 1/d can be obtained from d^2  
    using the RSQ instruction.  
  
    This distance vector is useful for per-vertex light attenuation  
    calculations:  a DP3 operation using the distance vector and an  
    attenuation constants vector as operands will yield the attenuation  
    factor.  
  
  
    Section 2.14.5.8,  EX2:  Exponential Base 2  
  
    The EX2 instruction approximates 2 raised to the power of the scalar  
    operand and replicates the approximation to all four components of the  
    result vector.  
  
      tmp = ScalarLoad(op0);  
      result.x = Approx2ToX(tmp);  
      result.y = Approx2ToX(tmp);  
      result.z = Approx2ToX(tmp);  
      result.w = Approx2ToX(tmp);  
  
  
    Section 2.14.5.9,  EXP:  Exponential Base 2 (approximate)  
  
    The EXP instruction computes a rough approximation of 2 raised to the  
    power of the scalar operand.  The approximation is returned in the "z"  
    component of the result vector.  A vertex program can also use the "x" and  
    "y" components of the result vector to generate a more accurate  
    approximation by evaluating  
  
        result.x * f(result.y),  
      
    where f(x) is a user-defined function that approximates 2^x over the  
    domain [0.0, 1.0).  The "w" component of the result vector is always 1.0.  
      
    The exact behavior is specified in the following pseudo-code:  
  
      tmp = ScalarLoad(op0);  
      result.x = 2^floor(tmp);  
      result.y = tmp - floor(tmp);  
      result.z = RoughApprox2ToX(tmp);  
      result.w = 1.0;  
  
    The approximation function is accurate to at least 10 bits:  
  
      | RoughApprox2ToX(x) - 2^x | < 1.0 / 2^11, if 0.0 <= x < 1.0,  
  
    and, in general,  
     
      | RoughApprox2ToX(x) - 2^x | < (1.0 / 2^11) * (2^floor(x)).  
  
  
    Section 2.14.5.10,  FLR:  Floor  
  
    The FLR instruction performs a component-wise floor operation on the  
    operand to generate a result vector.  The floor of a value is defined as  
    the largest integer less than or equal to the value.  The floor of 2.3 is  
    2.0; the floor of -3.6 is -4.0.  
  
      tmp = VectorLoad(op0);  
      result.x = floor(tmp.x);  
      result.y = floor(tmp.y);  
      result.z = floor(tmp.z);  
      result.w = floor(tmp.w);  
  
  
    Section 2.14.5.11,  FRC:  Fraction  
  
    The FRC instruction extracts the fractional portion of each component of  
    the operand to generate a result vector.  The fractional portion of a  
    component is defined as the result after subtracting off the floor of the  
    component (see FLR), and is always in the range [0.0, 1.0).  
  
    For negative values, the fractional portion is NOT the number written to  
    the right of the decimal point -- the fractional portion of -1.7 is not  
    0.7 -- it is 0.3.  0.3 is produced by subtracting the floor of -1.7 (-2.0)  
    from -1.7.  
  
      tmp = VectorLoad(op0);  
      result.x = fraction(tmp.x);  
      result.y = fraction(tmp.y);  
      result.z = fraction(tmp.z);  
      result.w = fraction(tmp.w);  
  
  
    Section 2.14.5.12,  LG2:  Logarithm Base 2  
  
    The LG2 instruction approximates the base 2 logarithm of the scalar  
    operand and replicates it to all four components of the result vector.  
  
      tmp = ScalarLoad(op0);  
      result.x = ApproxLog2(tmp);  
      result.y = ApproxLog2(tmp);  
      result.z = ApproxLog2(tmp);  
      result.w = ApproxLog2(tmp);  
  
    If the scalar operand is zero or negative, the result is undefined.  
  
  
    Section 2.14.5.13,  LIT:  Light Coefficients  
  
    The LIT instruction accelerates per-vertex lighting by computing lighting  
    coefficients for ambient, diffuse, and specular light contributions.  The  
    "x" component of the single operand is assumed to hold a diffuse dot  
    product (n dot VP_pli, as in the vertex lighting equations in Section  
    2.13.1).  The "y" component of the operand is assumed to hold a specular  
    dot product (n dot h_i).  The "w" component of the operand is assumed to  
    hold the specular exponent of the material (s_rm), and is clamped to the  
    range (-128, +128) exclusive.  
  
    The "x" component of the result vector receives the value that should be  
    multiplied by the ambient light/material product (always 1.0).  The "y"  
    component of the result vector receives the value that should be  
    multiplied by the diffuse light/material product (n dot VP_pli).  The "z"  
    component of the result vector receives the value that should be  
    multiplied by the specular light/material product (f_i * (n dot h_i) ^  
    s_rm).  The "w" component of the result is the constant 1.0.  
  
    Negative diffuse and specular dot products are clamped to 0.0, as is done  
    in the standard per-vertex lighting operations.  In addition, if the  
    diffuse dot product is zero or negative, the specular coefficient is  
    forced to zero.  
  
      tmp = VectorLoad(op0);  
      if (tmp.x < 0) tmp.x = 0;  
      if (tmp.y < 0) tmp.y = 0;  
      if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon);  
      else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon;  
      result.x = 1.0;  
      result.y = tmp.x;  
      result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0;  
      result.w = 1.0;  
  
    The exponentiation approximation function may be defined in terms of the  
    base 2 exponentiation and logarithm approximation operations in the EXP  
    and LOG instructions, where  
  
      RoughApproxPower(a,b) = RoughApproxExp2(b * RoughApproxLog2(a)).  
  
    In particular, the approximation may not be any more accurate than the  
    underlying EXP and LOG operations.  
  
    Also, since 0^0 is defined to be 1, RoughApproxPower(0.0, 0.0) will  
    produce 1.0.  
  
  
    Section 2.14.5.14,  LOG:  Logarithm Base 2 (approximate)  
  
    The LOG instruction computes a rough approximation of the base 2 logarithm  
    of the absolute value of the scalar operand.  The approximation is  
    returned in the "z" component of the result vector.  A vertex program can  
    also use the "x" and "y" components of the result vector to generate a  
    more accurate approximation by evaluating  
  
        result.x + f(result.y),  
      
    where f(x) is a user-defined function that approximates 2^x over the  
    domain [1.0, 2.0).  The "w" component of the result vector is always 1.0.  
  
    The exact behavior is specified in the following pseudo-code:  
  
      tmp = fabs(ScalarLoad(op0));  
      result.x = floor(log2(tmp));  
      result.y = tmp / 2^(floor(log2(tmp)));  
      result.z = RoughApproxLog2(tmp);  
      result.w = 1.0;  
     
    Here, "floor(log2(tmp))" refers to the floor of the exact logarithm, which  
    can be easily computed for standard floating-point representations.  The  
    approximation function is accurate to at least 10 bits:  
  
      | RoughApproxLog2(x) - log_2(x) | < 1.0 / 2^11.  
  
  
    Section 2.14.5.15,  MAD:  Multiply and Add  
  
    The MAD instruction performs a component-wise multiply of the first two  
    operands, and then does a component-wise add of the product to the third  
    operand to yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      tmp2 = VectorLoad(op2);  
      result.x = tmp0.x * tmp1.x + tmp2.x;  
      result.y = tmp0.y * tmp1.y + tmp2.y;  
      result.z = tmp0.z * tmp1.z + tmp2.z;  
      result.w = tmp0.w * tmp1.w + tmp2.w;  
  
    The multiplication and addition operations in this instruction are subject  
    to the same rules as described for the MUL and ADD instructions.  
  
  
    Section 2.14.5.16,  MAX:  Maximum  
  
    The MAX instruction computes component-wise maximums of the values in the  
    two operands to yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x > tmp1.x) ? tmp0.x : tmp1.x;  
      result.y = (tmp0.y > tmp1.y) ? tmp0.y : tmp1.y;  
      result.z = (tmp0.z > tmp1.z) ? tmp0.z : tmp1.z;  
      result.w = (tmp0.w > tmp1.w) ? tmp0.w : tmp1.w;  
  
  
    Section 2.14.5.17,  MIN:  Minimum  
  
    The MIN instruction computes component-wise minimums of the values in the  
    two operands to yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x > tmp1.x) ? tmp1.x : tmp0.x;  
      result.y = (tmp0.y > tmp1.y) ? tmp1.y : tmp0.y;  
      result.z = (tmp0.z > tmp1.z) ? tmp1.z : tmp0.z;  
      result.w = (tmp0.w > tmp1.w) ? tmp1.w : tmp0.w;  
  
  
    Section 2.14.5.18,  MOV:  Move  
  
    The MOV instruction copies the value of the operand to yield a result  
    vector.  
  
      result = VectorLoad(op0);  
  
  
    Section 2.14.5.19,  MUL:  Multiply  
  
    The MUL instruction performs a component-wise multiply of the two operands  
    to yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = tmp0.x * tmp1.x;  
      result.y = tmp0.y * tmp1.y;  
      result.z = tmp0.z * tmp1.z;  
      result.w = tmp0.w * tmp1.w;  
  
    The following rules apply to multiplication:  
  
      1. <x> * <y> == <y> * <x>, for all <x> and <y>.  
      2. +/-0.0 * <x> = +/-0.0, at least for all <x> that correspond to  
         representable numbers (IEEE "not a number" and "infinity" encodings  
         may be exceptions).  
      3. +1.0 * <x> = <x>, for all <x>.  
  
    Multiplication by zero and one should be invariant, as it may be used to  
    evaluate conditional expressions without branching.  
  
  
    Section 2.14.5.20,  POW:  Exponentiate  
  
    The POW instruction approximates the value of the first scalar operand  
    raised to the power of the second scalar operand and replicates it to all  
    four components of the result vector.  
  
      tmp0 = ScalarLoad(op0);  
      tmp1 = ScalarLoad(op1);  
      result.x = ApproxPower(tmp0, tmp1);  
      result.y = ApproxPower(tmp0, tmp1);  
      result.z = ApproxPower(tmp0, tmp1);  
      result.w = ApproxPower(tmp0, tmp1);  
  
    The exponentiation approximation function may be implemented using the  
    base 2 exponentiation and logarithm approximation operations in the EX2  
    and LG2 instructions.  In particular,  
  
      ApproxPower(a,b) = ApproxExp2(b * ApproxLog2(a)).  
  
    Note that a logarithm may be involved even for cases where the exponent is  
    an integer.  This means that it may not be possible to exponentiate  
    correctly with a negative base.  In constrast, it is possible in a  
    "normal" mathematical formulation to raise negative numbers to integral  
    powers (e.g., (-3)^2== 9, and (-0.5)^-2==4).  
  
  
    Section 2.14.5.21,  RCP:  Reciprocal  
  
    The RCP instruction approximates the reciprocal of the scalar operand and  
    replicates it to all four components of the result vector.  
  
      tmp = ScalarLoad(op0);  
      result.x = ApproxReciprocal(tmp);  
      result.y = ApproxReciprocal(tmp);  
      result.z = ApproxReciprocal(tmp);  
      result.w = ApproxReciprocal(tmp);  
  
    The following rule applies to reciprocation:  
  
      1. ApproxReciprocal(+1.0) = +1.0.  
  
  
    Section 2.14.5.22,  RSQ:  Reciprocal Square Root  
  
    The RSQ instruction approximates the reciprocal of the square root of the  
    absolute value of the scalar operand and replicates it to all four  
    components of the result vector.  
  
      tmp = fabs(ScalarLoad(op0));  
      result.x = ApproxRSQRT(tmp);  
      result.y = ApproxRSQRT(tmp);  
      result.z = ApproxRSQRT(tmp);  
      result.w = ApproxRSQRT(tmp);  
  
  
    Section 2.14.5.23,  SGE:  Set On Greater or Equal Than  
  
    The SGE instruction performs a component-wise comparison of the two  
    operands.  Each component of the result vector is 1.0 if the corresponding  
    component of the first operands is greater than or equal that of the  
    second, and 0.0 otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x >= tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y >= tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z >= tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w >= tmp1.w) ? 1.0 : 0.0;  
  
  
    Section 2.14.5.24,  SLT:  Set On Less Than  
  
    The SLT instruction performs a component-wise comparison of the two  
    operands.  Each component of the result vector is 1.0 if the corresponding  
    component of the first operand is less than that of the second, and 0.0  
    otherwise.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = (tmp0.x < tmp1.x) ? 1.0 : 0.0;  
      result.y = (tmp0.y < tmp1.y) ? 1.0 : 0.0;  
      result.z = (tmp0.z < tmp1.z) ? 1.0 : 0.0;  
      result.w = (tmp0.w < tmp1.w) ? 1.0 : 0.0;  
  
  
    Section 2.14.5.25,  SUB:  Subtract  
  
    The SUB instruction performs a component-wise subtraction of the second  
    operand from the first to yield a result vector.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = tmp0.x - tmp1.x;  
      result.y = tmp0.y - tmp1.y;  
      result.z = tmp0.z - tmp1.z;  
      result.w = tmp0.w - tmp1.w;  
  
  
    Section 2.14.5.26,  SWZ:  Extended Swizzle  
  
    The SWZ instruction loads the single vector operand, and performs a  
    swizzle operation more powerful than that provided for loading normal  
    vector operands to yield an instruction vector.  
  
    After the operand is loaded, the "x", "y", "z", and "w" components of the  
    result vector are selected by the first, second, third, and fourth matches  
    of the <extSwizComp> pattern in the <extendedSwizzle> rule.  
  
    A result component can be selected from any of the four components of the  
    operand or the constants 0.0 and 1.0.  The result component can also be  
    optionally negated.  The following pseudocode describes the component  
    selection method.  "operand" refers to the vector operand, "select" is an  
    enumerant where the values ZERO, ONE, X, Y, Z, and W correspond to the  
    <extSwizSel> rule matching "0", "1", "x", "y", "z", and "w", respectively.  
    "negate" is TRUE if and only if the <optionalSign> rule in <extSwizComp>  
    matches "-".  
  
      float ExtSwizComponent(floatVec operand, enum select, boolean negate)  
      {  
          float result;  
          switch (select) {  
            case ZERO:  result = 0.0; break;  
            case ONE:   result = 1.0; break;  
            case X:     result = operand.x; break;  
            case Y:     result = operand.y; break;  
            case Z:     result = operand.z; break;  
            case W:     result = operand.w; break;  
          }  
          if (negate) {  
            result = -result;  
          }  
          return result;  
      }  
  
    The entire extended swizzle operation is then defined using the following  
    pseudocode:  
  
      tmp = VectorLoad(op0);  
      result.x = ExtSwizComponent(tmp, xSelect, xNegate);  
      result.y = ExtSwizComponent(tmp, ySelect, yNegate);  
      result.z = ExtSwizComponent(tmp, zSelect, zNegate);  
      result.w = ExtSwizComponent(tmp, wSelect, wNegate);  
  
    "xSelect", "xNegate", "ySelect", "yNegate", "zSelect", "zNegate",  
    "wSelect", and "wNegate" correspond to the "select" and "negate" values  
    above for the four <extSwizComp> matches.    
  
    Since this instruction allows for component selection and negation for  
    each individual component, the grammar does not allow the use of the  
    normal swizzle and negation operations allowed for vector operands in  
    other instructions.  
  
  
    Section 2.14.5.27,  XPD:  Cross Product  
  
    The XPD instruction computes the cross product using the first three  
    components of its two vector operands to generate the x, y, and z  
    components of the result vector.  The w component of the result vector is  
    undefined.  
  
      tmp0 = VectorLoad(op0);  
      tmp1 = VectorLoad(op1);  
      result.x = tmp0.y * tmp1.z - tmp0.z * tmp1.y;  
      result.y = tmp0.z * tmp1.x - tmp0.x * tmp1.z;  
      result.z = tmp0.x * tmp1.y - tmp0.y * tmp1.x;  
  
  
    Section 2.14.6,  Program Matrices  
  
    In addition to GL's conventional matrices, several additional program  
    matrices are available for use as program parameters.  These matrices have  
    names of the form MATRIX<i>_ARB where <i> is between zero and <n>-1 where  
    <n> is the value of the implementation-dependent constant  
    MAX_PROGRAM_MATRICES_ARB.  The MATRIX<i>_ARB constants obey MATRIX<i>_ARB  
    = MATRIX0_ARB + <i>.  The value of MAX_PROGRAM_MATRICES_ARB must be at  
    least eight.  The maximum stack depth for program matrices is defined by  
    the MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB and must be at least 1.  
  
  
    Section 2.14.7  Required Vertex Program State   
  
    The state required to support program objects of all targets consists of:  
  
      an integer for the program error position, initially -1;  
  
      an array of ubytes for the program error string, initially empty;  
  
      and the state that must be maintained to indicate which integers are  
      currently in use as program object names.  
  
    The state required to support the vertex program target consists of:  
  
      a bit indicating whether or not program mode is enabled, initially  
      disabled;  
  
      a bit indicating whether or not vertex program two-sided color mode is  
      enabled, initially disabled;  
  
      a bit indicating whether or not vertex program point size mode is  
      enabled, initially disabled;  
  
      a set of MAX_PROGRAM_ENV_PARAMETERS_ARB four-component floating-point  
      program environment parameters, initially set to (0,0,0,0);  
  
      and an unsigned integer naming the currently bound vertex program,  
      initially zero.  
  
   The state required for each vertex program object consists of:  
  
      an unsigned integer indicating the program object name;  
  
      an array of type ubyte containing the program string, initially empty;  
  
      an unsigned integer holding the length of the program string, initially  
      zero;  
  
      an enum indicating the program string format, initially  
      PROGRAM_FORMAT_ASCII_ARB;  
  
      five unsigned integers holding the number of instruction, temporary  
      variable, vertex attribute binding, address register, and program  
      parameter binding resources used by the program, initially all zero;  
  
      five unsigned integers holding the number of native instruction,  
      temporary variable, vertex attribute binding, address register, and  
      program parameter binding resources used by the program, initially all  
      zero;  
  
      and a set of MAX_PROGRAM_LOCAL_PARAMETERS_ARB four-component  
      floating-point program local parameters, initially set to (0,0,0,0).  
  
   Initially, no vertex program objects exist.  
  
  
homeprevnext Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization)
  
    Modify Section 3.3, Points (p. 63)  
  
    (replace the first paragraph) When vertex program mode and vertex progam  
    point size mode are both enabled, the point size used for point  
    rasterization is taken from the transformed vertex's point size attribute.  
    Otherwise, it is controlled with  
  
     void PointSize(float size);  
  
    size specifies the width or diameter of a point.  The initial point size  
    value is 1.0.  A value less than or equal to zero results in the error  
    INVALID_VALUE.  
  
    Vertex program point size mode is enabled and disabled by calling Enable  
    or Disable with the symbolic value VERTEX_PROGRAM_POINT_SIZE_ARB.  
  
  
    Modify Section 3.9, Color Sum (p. 154)  
  
    After texturing, a fragment has two RGBA colors: a primary color c_pri  
    (which texturing, if enabled, may have modified) and a secondary color  
    c_sec.  If color sum is enabled, the R, G, and B components of these two  
    colors are summed, and with the A component of the primary color produce a  
    single post-texturing RGBA color c. The components of c are then clamped  
    to the range [0,1].  If color sum is disabled, then c_pri is assigned to  
    the post-texturing color.  
  
    Color sum is enabled or disabled using the generic Enable and Disable  
    commands, respectively, with the symbolic constant COLOR_SUM_ARB.  If  
    vertex program mode is disabled and lighting is enabled, the color sum  
    stage is always applied, ignoring the value of COLOR_SUM_ARB.  
  
    The state required is a single bit indicating whether color sum is enabled  
    or disabled. In the initial state, color sum is disabled.  
  
  
    Modify Section 3.10, Fog (p. 154)  
  
    (modify second paragraph) This factor f may be computed according to one  
    of three equations:  
  
            f = exp(-d*c),                               (3.24)  
            f = exp(-(d*c)^2), or                        (3.25)  
            f = (e-c)/(e-s)                              (3.26)  
  
    If vertex program mode is enabled or if the fog source (as defined below)  
    is FOG_COORDINATE_EXT, then c is the fragment's fog coordinate.  
    Otherwise, the c is the eye-coordinate distance from the eye, (0,0,0,1) in  
    eye-coordinates, to the fragment center. ...  
  
homeprevnext Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment Operations and the Framebuffer)
  
    None  
  
homeprevnext Additions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions)
  
    Modify Section 5.1, Evaluators (p. 181)  
  
    (modify next-to-last paragraph, p. 184) For MAP VERTEX 3, let q = p. For  
    MAP VERTEX 4, let q=(x/w,y/w,z/w), where (x; y; z;w) = p. Then let   
  
            dq   dq  
        m = -- x --.  
            du   dv  
  
    The the generated analytic normal, n, is given by n=m if vertex program  
    mode is enabled or by n=m/|m| if vertex program mode is disabled.  
  
  
    Modify Section 5.4, Display Lists (p. 191)  
  
    (modify third paragraph, p. 195) ... These are IsList, GenLists, ...,  
    IsProgramARB, GenProgramsARB, DeleteProgramsARB, and  
    VertexAttribPointerARB, EnableVertexAttribArrayARB,  
    DisableVertexAttribArrayARB, as well as IsEnabled and all the Get commands  
    (chapter 6).  
  
  
homeprevnext Additions to Chapter 6 of the OpenGL 1.3 Specification (State and State Requests)
  
    Modify Section 6.1.2, Data Conversions (p. 198)  
  
    (add before last paragraph, p. 198) The matrix selected by the current  
    matrix mode can be queried by calling GetBooleanv, GetIntegerv, GetFloatv,  
    and GetDoublev with <pname> set to CURRENT_MATRIX_ARB; the matrix will be  
    returned in transposed form with <pname> set to  
    TRANSPOSE_CURRENT_MATRIX_ARB.  The depth of the selected matrix stack can  
    be queried with <pname> set to CURRENT_MATRIX_STACK_DEPTH_ARB.  Querying  
    CURRENT_MATRIX_ARB and CURRENT_MATRIX_STACK_DEPTH_ARB is the only means  
    for querying the matrix and matrix stack depth of the program matrices  
    described in section 2.14.6.  
  
  
    Modify Section 6.1.11, Pointer and String Queries (p. 206)  
  
    (modify last paragraph, p. 206) ... The possible values for <name> are  
    VENDOR, RENDERER, VERSION, EXTENSIONS, and PROGRAM_ERROR_STRING_ARB.  
  
    (add after last paragraph of section, p. 207) Queries of  
    PROGRAM_ERROR_STRING_ARB return a pointer to an implementation-dependent  
    program load error string.  If the last call to ProgramStringARB failed to  
    load a program, the returned string describes at least one reason why the  
    program failed to load.  If the last call to ProgramStringARB successfully  
    loaded a program, the returned string may be empty (containing only a zero  
    terminator) or may contain one or more implementation-dependent warning  
    messages.  The contents of the error string are guaranteed to remain  
    constant only until the next ProgramStringARB command, which may overwrite  
    the error string.  
  
  
    Insert a new Section 6.1.12, Program Queries (p. 207), between existing  
    sections 6.1.11 and 6.1.12.  
  
    Section 6.1.12, Program Queries  
  
    The commands  
  
      void GetProgramEnvParameterdvARB(enum target, uint index,  
                                       double *params);  
      void GetProgramEnvParameterfvARB(enum target, uint index,  
                                       float *params);  
  
    obtain the current value for the program environment parameter numbered  
    <index> for the given program target <target>, and places the information  
    in the array <params>.  The error INVALID_ENUM is generated if <target>  
    specifies a nonexistent program target or a program target that does not  
    support program environment parameters.  The error INVALID_VALUE is  
    generated if <index> is greater than or equal to the  
    implementation-dependent number of supported program environment  
    parameters for the program target.  
  
    When <target> is VERTEX_PROGRAM_ARB, each program parameter returned is an  
    array of four values.  
  
    The commands  
  
      void GetProgramLocalParameterdvARB(enum target, uint index,  
                                         double *params);  
      void GetProgramLocalParameterfvARB(enum target, uint index,  
                                         float *params);  
  
    obtain the current value for the program local parameter numbered <index>  
    belonging to the program object currently bound to <target>, and places  
    the information in the array <params>.  The error INVALID_ENUM is  
    generated if <target> specifies a nonexistent program target or a program  
    target that does not support program local parameters.  The error  
    INVALID_VALUE is generated if <index> is greater than or equal to the  
    implementation-dependent number of supported program local parameters for  
    the program target.  
  
    When the program target type is VERTEX_PROGRAM_ARB, each program  
    local parameter returned is an array of four values.  
  
    The command  
  
      void GetProgramivARB(enum target, enum pname, int *params);  
  
    obtains program state for the program target <target>, writing the state  
    into the array given by <params>.  GetProgramivARB can be used to  
    determine the properties of the currently bound program object or  
    implementation limits for <target>.  
  
    If <pname> is PROGRAM_LENGTH_ARB, PROGRAM_FORMAT_ARB, or  
    PROGRAM_BINDING_ARB, GetProgramivARB returns one integer holding the  
    program string length (in bytes), program string format, and program name,  
    respectively, for the program object currently bound to <target>.  
  
    If <pname> is MAX_PROGRAM_LOCAL_PARAMETERS_ARB or  
    MAX_PROGRAM_ENV_PARAMETERS_ARB, GetProgramivARB returns one integer  
    holding the maximum number of program local parameters or program  
    environment parameters, respectively, supported for the program target  
    <target>.  
  
    If <pname> is MAX_PROGRAM_INSTRUCTIONS_ARB, MAX_PROGRAM_TEMPORARIES_ARB,  
    MAX_PROGRAM_PARAMETERS_ARB, MAX_PROGRAM_ATTRIBS_ARB, or  
    MAX_PROGRAM_ADDRESS_REGISTERS_ARB, GetProgramivARB returns a single  
    integer giving the maximum number of instructions, temporaries,  
    parameters, attributes, and address registers that can be used by a  
    program of type <target>.  If <pname> is PROGRAM_INSTRUCTIONS_ARB,  
    PROGRAM_TEMPORARIES_ARB, PROGRAM_PARAMETERS_ARB, PROGRAM_ATTRIBS_ARB, or  
    PROGRAM_ADDRESS_REGISTERS_ARB, GetProgramivARB returns a single integer  
    giving the number of instructions, temporaries, parameters, attributes,  
    and address registers used by the current program for <target>.  
  
    If <pname> is MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,  
    MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, MAX_PROGRAM_NATIVE_PARAMETERS_ARB,  
    MAX_PROGRAM_NATIVE_ATTRIBS_ARB, or  
    MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, GetProgramivARB returns a single  
    integer giving the maximum number of native instruction, temporary,  
    parameter, attribute, and address register resources available to a  
    program of type <target>.  If <pname> is PROGRAM_NATIVE_INSTRUCTIONS_ARB,  
    PROGRAM_NATIVE_TEMPORARIES_ARB, PROGRAM_NATIVE_PARAMETERS_ARB,  
    PROGRAM_NATIVE_ATTRIBS_ARB, or PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB,  
    GetProgramivARB returns a single integer giving the number of native  
    instruction, temporary, parameter, attribute, and address register  
    resources consumed by the program currently bound to <target>.  Native  
    resource counts will reflect the results of implementation-dependent  
    scheduling and optimization algorithms applied by the GL, as well as  
    emulation of non-native features.  If <pname> is  
    PROGRAM_UNDER_NATIVE_LIMITS_ARB, GetProgramivARB returns 0 if the native  
    resource consumption of the program currently bound to <target> exceeds  
    the number of available resources for any resource type, and 1 otherwise.  
  
    The command  
  
      void GetProgramStringARB(enum target, enum pname, void *string);  
  
    obtains the program string for the program object bound to <target> and  
    places the information in the array <string>.  <pname> must be  
    PROGRAM_STRING_ARB.  <n> ubytes are returned into the array program where  
    <n> is the length of the program in ubytes, as returned by GetProgramivARB  
    when <pname> is PROGRAM_LENGTH_ARB.  The program string is always returned  
    using the format given when the program string was specified.  
  
    The commands  
  
      void GetVertexAttribdvARB(uint index, enum pname, double *params);  
      void GetVertexAttribfvARB(uint index, enum pname, float *params);  
      void GetVertexAttribivARB(uint index, enum pname, int *params);  
  
    obtain the vertex attribute state named by <pname> for the vertex  
    attribute numbered <index> and places the information in the array  
    <params>.  <pname> must be one of VERTEX_ATTRIB_ARRAY_ENABLED_ARB,  
    VERTEX_ATTRIB_ARRAY_SIZE_ARB, VERTEX_ATTRIB_ARRAY_STRIDE_ARB,  
    VERTEX_ATTRIB_ARRAY_TYPE_ARB, VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB, or  
    CURRENT_VERTEX_ATTRIB_ARB.  Note that all the queries except  
    CURRENT_VERTEX_ATTRIB_ARB return client state.  The error INVALID_VALUE is  
    generated if <index> is greater than or equal to MAX_VERTEX_ATTRIBS_ARB.  
    The error INVALID_OPERATION is generated if <index> is zero and <pname> is  
    CURRENT_VERTEX_ATTRIB_ARB, as there is no current value for vertex  
    attribute zero.  
  
    The command  
  
      void GetVertexAttribPointervARB(uint index, enum pname, void **pointer);  
      
    obtains the pointer named <pname> for vertex attribute numbered <index>  
    and places the information in the array <pointer>.  <pname> must be  
    VERTEX_ATTRIB_ARRAY_POINTER_ARB.  The INVALID_VALUE error is generated if  
    <index> is greater than or equal to MAX_VERTEX_ATTRIBS_ARB.  
  
    The command  
  
      boolean IsProgramARB(uint program);  
  
    returns TRUE if <program> is the name of a program object.  If <program>  
    is zero or is a non-zero value that is not the name of a program object,  
    or if an error condition occurs, IsProgramARB returns FALSE.  A name  
    returned by GenProgramsARB, but not yet bound, is not the name of a  
    program object.  
  
  
    Concerning Section 6.1.12, Saving and Restoring State (p. 207):  
  
    (no actual modifications to the spec) Only the enables, current vertex  
    attributes, and vertex array state introduced by this extension can be  
    pushed and popped.  See the attribute column in Table X.6 for determining  
    what vertex program state can be pushed and popped with PushAttrib,  
    PopAttrib, PushClientAttrib, and PopClientAttrib.  
  
  
homeprevnext Additions to Appendix A of the OpenGL 1.3 Specification (Invariance)
  
    Add to end of Section A.3 (p. 242):  
  
      Rule 4.  Vertex program instructions not relevant to the calculation of  
      any result must have no effect on that result.  
  
      Rule 5.  Vertex program instructions relevant to the calculation of any  
      result must always produce the identical result.  
  
    Instructions relevant to the calculation of a result are any instructions  
    in a sequence of instructions that eventually determine the source values  
    for the calculation under consideration.  
  
    There is no guaranteed invariance between vertices transformed by  
    conventional GL vertex transform mode and vertices transformed by vertex  
    program mode.  Multi-pass rendering algorithms that require rendering  
    invariances to operate correctly should not mix conventional GL vertex  
    transform mode with vertex program mode for different rendering passes,  
    except by using the position invariance option (section 2.14.4.5.1) in all  
    vertex program mode passes.  However, such algorithms will operate  
    correctly if the algorithms limit themselves to a single mode of vertex  
    transformation.  
  
  
homeprevnext Additions to the AGL/GLX/WGL Specifications
  
    Program objects are shared between AGL/GLX/WGL rendering contexts if  
    and only if the rendering contexts share display lists.  No change  
    is made to the AGL/GLX/WGL API.  
  
    Changes to program objects shared between multiple rendering contexts will  
    be serialized (i.e., the changes will occur in a specific order).    
  
    Changes to a program object made by one rendering context are not  
    guaranteed to take effect in another rendering context until the other  
    calls BindProgram to bind the program object.    
  
    When a program object is deleted by one rendering context, the object  
    itself is not destroyed until it is no longer the current program object  
    in any context.  However, the name of the deleted object is removed from  
    the program object name space, so the next attempt to bind a program using  
    the same name will create a new program object.  Recall that destroying a  
    program object bound in the current rendering context effectively unbinds  
    the object being destroyed.  
  
  
homeprevnext Dependencies on EXT_vertex_weighting and ARB_vertex_blend
  
    If EXT_vertex_weighting and ARB_vertex_blend are both not supported, all  
    discussions of vertex weights should be removed.    
  
    In particular, references to vertex weights should be removed from Table  
    X.1, and the description of ArrayElement in section 2.8.  The line  
  
      "weight" <vtxOptWeightNum>  
  
    should be removed from the <vtxAttribItem> grammar rule, and the grammar  
    rules <vtxOptWeightNum> and <vtxWeightNum> should be deleted.  
    "vertex.weight" and "vertex.weight[n]" should be removed from Table X.2.  
    The discussion of vertex weights in section 2.14.3.1 should be removed.  
  
    Additionally, the first line of Table X.3.8 should be modified to read:  
  
      Binding                               Underlying State  
      ------------------------------------  ---------------------------  
        state.matrix.modelview              modelview matrix  
      
  
homeprevnext Dependencies on ARB_matrix_palette:
  
    If ARB_matrix_palette is not supported, all discussions of per-vertex  
    matrix indices and the matrix palette should be removed.  
  
    In particular, the reference to matrix indices should be removed from the  
    description of ArrayElement in section 2.8.  The line  
  
      "matrixindex" "[" <vtxWeightNum> "]"  
  
    should be removed from the <vtxAttribItem> grammar rule.  The line  
  
      "palette" "[" <statePaletteMatNum> "]"  
  
    should be removed from the <stateMatrixName> grammar rule, and the  
    <statePaletteMatNum> grammar rule should be removed entirely.  
    "vertex.matrixindex[n]" should be removed from Table X.2, and  
    "state.matrix.palette[n]" should be removed from Table X.3.8.  The  
    discussion of vertex matrix indices in section 2.14.3.1 should be removed.  
  
homeprevnext Dependencies on EXT_point_parameters and ARB_point_parameters
  
    The discussion of point size determination in EXT/ARB_point_parameters  
    should qualified to indicate that this functionality only applies when  
    vertex program mode is disabled.  
  
    If EXT/ARB_point_parameters is not supported, references to point  
    parameter state should be eliminated.  In particular,  
  
      "attenuation"  
  
    should be eliminated from the <statePointProperty> grammar rule, and the  
    corresponding entries in Table X.3.7 should be eliminated.  
  
    Additionally, references to the minimum and maximum point sizes and the  
    fade threshold should be removed from Table X.3.7 and the explanatory text  
    immediately thereafter.  The components column of the "state.point.size"  
    binding in Table X.3.7 should read (s,0,0,1).  
  
    Even if EXT/ARB_point_parameters is not supported, the point size result  
    (result.pointsize) still operates as specified.  
  
homeprevnext Dependencies on EXT_fog_coord
  
    If EXT_fog_coord is not supported, references to fog coordinates should be  
    removed from Table X.1, and the description of ArrayElement in section  
    2.8.  The line "fogcoord" should be removed from the <vtxAttribItem>  
    grammar rule, and "vertex.fogcoord" should be removed from Table X.2.  
    Also, the use of FOG_COORDINATE_SOURCE_EXT in section 3.10 should be  
    removed.  
  
    Even if EXT_fog_coord is not supported, the fog coordinate output  
    (result.fogcoord) still operates as specified.  When in vertex program  
    mode, there are no well-defined eye coordinates that could be used for  
    fog.  This means that the functionality of EXT_fog_coord is required to  
    implement ARB_vertex_program even if the EXT_fog_coord extension itself is  
    not supported.  
  
homeprevnext Dependencies on EXT_secondary_color
  
    If EXT_secondary_color is not supported, references to secondary color  
    should be removed from Table X.1, and the description of ArrayElement in  
    section 2.8.  The line "secondary" should be removed from the  
    <vtxOptColorType> grammar rule, and "vertex.color.secondary" should be  
    removed from Table X.2.  
  
    Even if EXT_secondary_color is not supported, the secondary color results  
    (result.color.secondary, result.color.front.secondary,  
    result.color.back.secondary) still operate as specified in program mode,  
    and when in program mode, the color sum enable behaves exactly as  
    specified in EXT_secondary_color.  These vertex result registers are  
    required to implement OpenGL 1.2's separate specular mode within a vertex  
    program.  
  
    The color sum enable enumerant from EXT_secondary_color has been brought  
    over and renamed to COLOR_SUM_ARB.  The enumerant value itself is  
    unchanged from EXT_secondary_color.  
  
homeprevnext Dependencies on ARB_transpose_matrix
  
    If ARB_transpose_matrix is not supported, the discussion of  
    TRANSPOSE_CURRENT_MATRIX_ARB in the edits to section 6.1.2 should be  
    removed.  
  
homeprevnext Interactions with NV_vertex_program
  
    The existing NV_vertex_program extension, if supported, also provides a  
    similar vertex programming model.  This extension is incompatible with  
    NV_vertex_program in a number of different ways.  Mixing the two models in  
    a single application is possible but not recommended.  The interactions  
    between the extensions are defined below.  
  
    Functions, enumerants, and programs defined in NV_vertex_program are  
    called "NV functions", "NV enumerants", and "NV programs" respectively.  
    Functions, enumerants, and programs defined in ARB_vertex_program are  
    called "ARB functions", "ARB enumerants", and "ARB programs" respectively.  
  
    The following enumerants are identical in the two extensions:  
  
      ARB_vertex_program                  NV_vertex_program  
      ------------------------------      ------------------------------  
      VERTEX_PROGRAM_ARB                  VERTEX_PROGRAM_NV  
      VERTEX_PROGRAM_POINT_SIZE_ARB       VERTEX_PROGRAM_POINT_SIZE_NV  
      VERTEX_PROGRAM_TWO_SIDE_ARB         VERTEX_PROGRAM_TWO_SIDE_NV  
      VERTEX_ATTRIB_ARRAY_SIZE_ARB        ATTRIB_ARRAY_SIZE_NV  
      VERTEX_ATTRIB_ARRAY_STRIDE_ARB      ATTRIB_ARRAY_STRIDE_NV  
      VERTEX_ATTRIB_ARRAY_TYPE_ARB        ATTRIB_ARRAY_TYPE_NV  
      CURRENT_VERTEX_ATTRIB_ARB           CURRENT_ATTRIB_NV  
      VERTEX_ATTRIB_ARRAY_POINTER_ARB     ATTRIB_ARRAY_POINTER_NV  
      PROGRAM_LENGTH_ARB                  PROGRAM_LENGTH_NV  
      PROGRAM_STRING_ARB                  PROGRAM_STRING_NV  
      PROGRAM_ERROR_POSITION_ARB          PROGRAM_ERROR_POSITION_NV  
      CURRENT_MATRIX_ARB                  CURRENT_MATRIX_NV  
      CURRENT_MATRIX_STACK_DEPTH_ARB      CURRENT_MATRIX_STACK_DEPTH_NV  
      MAX_PROGRAM_MATRICES_ARB            MAX_TRACK_MATRICES_NV  
      MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB  MAX_TRACK_MATRIX_STACK_DEPTH_NV  
          
    The following GL state is identical in the two extensions and can be set  
    or queried using either NV functions or ARB functions.  
  
      - Vertex program mode enable.  
  
      - Vertex program point size mode enable.  
  
      - Vertex program two sided mode enable.  
  
      - Program error position.  
  
      - NV_vertex_program "program parameters" and ARB_vertex_program "program  
        environment parameters".  
  
      - Current values of generic vertex attributes.  Conventional and generic  
        vertex attributes will alias according to the NV_vertex_program spec,  
        which is permissible but optional under ARB_vertex_program.  
  
      - NV_vertex_program "tracking matrices" and ARB_vertex_program "program  
        matrices".  The NV and ARB enumerants passed to MatrixMode are  
        different, however.  
  
      - Vertex attribute array sizes, types, strides, and pointers.  
  
      - Vertex program object names, targets, formats, program string, program  
        string lengths, and residency information.  The ARB and NV query  
        functions operate differently.  The ARB query function does not allow  
        queries of target (passed in to the query) and residency information.  
        The NV query function does not allow queries of program name (passed  
        in to the query) or format.  The format of NV programs is always  
        PROGRAM_FORMAT_ASCII_ARB.  
  
      - Current matrix and current matrix stack depth.  
  
      - Implementation-dependent limits on number of tracking/program matrices  
        and tracking/program matrix stack depth.  
  
      - Program object name space.  Program objects are created differently in  
        the NV and ARB specs.  Under the NV spec, program objects are created  
        by calling LoadProgramNV.  Under the ARB spec, program objects are  
        created by calling BindProgramARB with an unused program name.  
         
    The following state is provided only by ARB_vertex_program:  
  
      - Program error string.  Querying the error string after calling  
        LoadProgramNV produces undefined results.  
  
      - Vertex attribute array normalization enables.  Setting up vertex  
        attribute arrays through NV functions will set the normalization  
        enable appropriately based on the NV spec.  
  
      - Vertex program object resource counts and native resource counts.  
        These values are undefined for NV programs.  
  
      - Vertex program local parameters.  They can not be used by NV programs.  
  
      - Implementation-dependent limits on the number of program environment  
        parameters, program local parameters, resource counts, and native  
        resource counts.  These limits are baked into the NV spec, except for  
        native counts, which don't exist.  
  
    The following state is provided only by NV_vertex_program:  
  
      - TrackMatrix enables and transforms.  
  
      - Generic vertex attribute evaluator maps.  The NV evaluator  
        functionality will be supported even for ARB programs.  
  
    The following are additional functional differences between  
    ARB_vertex_program and NV_vertex_program:  
  
      - ARB program temporaries, address registers, and result registers are  
        initially undefined.  The corresponding values in NV programs are  
        initialized to (0,0,0,0), 0, and (0,0,0,1), respectively.  ARB  
        programs running on NV_vertex_program platforms can not rely on  
        NV_vertex_program initialization behavior for temporaries or address  
        registers, but result registers will be initialized to (0,0,0,1).  In  
        any event, ARB programs that rely on NV_vertex_program initialization  
        may not behave properly on other platforms that support  
        ARB_vertex_program but not NV_vertex_program.  
  
      - NV programs use a set of fixed variable and register names, with no  
        support for user-defined variables.  ARB programs provide no support  
        for fixed variable names; all variables must be declared, explicitly  
        or implicitly, in the program.  
  
      - ARB programs support parameter variables that can be bound to selected  
        GL state variables, and are updated automatically when the underlying  
        state changes.  NV programs provide no such support; applications must  
        set program parameters themselves.  
  
      - ARB programs allow program constants to be declared in the program  
        text; NV programs require that constants be loaded into the program  
        parameter array.  
  
      - ARB programs support program local parameters; NV programs do not.  
        Applications using multiple NV programs must manage the shared program  
        parameter array appropriately.  
  
      - ARB_vertex_program vertex array support provides a normalized flag to  
        optionally normalize fixed-point array data to the [0,1] or [-1,1]  
        range.  ARB_vertex_program also provides several immediate-mode entry  
        points with the same support.  NV_vertex_program supports normalized  
        data only for unsigned byte data types, and does not support  
        non-normalized unsigned bytes.  VertexAttrib4ub{v}NV was renamed to  
        VertexAttrib4Nub{v}ARB to indicate that the 4ub call normalizes its  
        parameters to a [0,1] range.  
  
      - ARB_vertex_blend and ARB_matrix_palette support are documented by the  
        ARB spec, but not by the NV spec.  
  
      - ARB_vertex_program contains an OPTION mechanism for future  
        extensibility, and a position invariant program option.  Both features  
        are found in NV_vertex_program1_1, but not in NV_vertex_program.  
  
      - NV_vertex_program supports a vertex state program target that allows  
        programs to write to program parameters (VERTEX_STATE_PROGRAM_NV).  No  
        such support exists in ARB_vertex_program.  Running a NV state program  
        will update the program parameter/program environment parameter array,  
        and such updates can be visible through ARB programs.  
  
      - LoadProgramNV entry point was changed to ProgramStringARB to match  
        OpenGL convention that a verb should not be included in a command name  
        that merely sets state.  
  
      - The formal parameter name for program objects was "id" in  
        NV_vertex_program; in ARB_vertex_program, this formal name is now  
        "program" to match how texture object routines name their formal  
        texture object names "texture".  
  
      - NV_vertex_program has language that makes it sound that LoadProgramNV  
        (ProgramStringARB) only accepts the VERTEX_PROGRAM_NV target and the  
        start token must be "!!VP1.0".  This extension clarifies the language  
        so that it is clear that other targets and start token types are  
        permitted.  
  
      - NV_vertex_program numeric requirements are not present in the ARB  
        spec.  The ARB spec requires nothing more than the numeric  
        requirements spelled out in section 2.1.1 (Floating-Point  
        Computations) in the core specification.  
  
      - ARB programs allow single instructions to source multiple distinct  
        vertex attributes or program parameters.  NV programs do not.  On  
        current NV_vertex_program hardware, such instructions may require  
        additional instructions and temporaries to execute.  
  
      - ARB programs support the folowing instructions not supported by NV  
        "VP1.0" programs:  
  
            * ABS:  absolute value.  Supported on VP1.1 NV programs, but not  
              on VP1.0 programs.  Equivalent to "MAX dst, src, -src".  
  
            * EX2:  exponential base 2.  On VP1.0 and VP1.1 hardware, this  
              instruction will be emulated using EXP and a number of  
              additional instructions.  
  
            * FLR:  floor.  On VP1.0 and VP1.1 hardware, this instruction will  
              be emulated using an EXP and an ADD instruction.  
  
            * FRC:  fraction.  On VP1.0 and VP1.1 hardware, this instruction  
              will be emulated using an EXP instruction, and possibly a MOV  
              instruction to replicate the scalar result.  
  
            * LG2:  logarithm base 2.  On VP1.0 and VP1.1 hardware, this  
              instruction will be emulated using LOG and a number of  
              additional instructions.  
  
            * POW:  exponentiation.  On VP1.0 and VP1.1 hardware, this  
              instruction will be emulated using LOG, MUL, and EXP  
              instructions, and possibly additional instructions to generate a  
              high-precision result.  
  
            * SUB:  subtraction.  Supported on VP1.1 NV programs, but not on  
              VP1.0 programs.  Equivalent to "ADD dst, src1, -src2".  
  
            * SWZ:  extended swizzle.  On VP1.0 and VP1.1 hardware, this  
              instruction will be emulated using a single MAD instruction and  
              a program parameter constant.  
  
            * XPD:  cross product.  On VP1.0 and VP1.1 hardware, this  
              instruction will be emulated using a MUL and a MAD instruction.  
  
      - The COLOR_SUM_EXT enable is ignored when NV programs are executed  
        (default secondary color outputs are zero) but not when ARB programs  
        are executed (default secondary color outputs are undefined).  The  
        driver will take care of the color sum operation based on which type  
        of program is currently bound.  
  
      - NV programs are required to write a vertex position; ARB programs are  
        not.  
  
      - There is both an ARB and an NV boolean enable for each generic  
        array (two booleans per generic array).  Each generic array's NV  
        enable is enabled with EnableClientState(VERTEX_ATTRIB_ARRAYn_NV)  
        or disabled with DisableClientState(VERTEX_ATTRIB_ARRAYn_NV)  
        while each generic array's ARB enable is enabled  
        with EnableVertexAttribArrayARB(n) and disabled with  
        DisableVertexAttribArrayARB(n).  
  
        Enabling (or disabling) an ARB generic array enables (or disables)  
        BOTH the NV and ARB generic array booleans.  
  
        However enabling (or disabling) the NV generic array enable  
        changes only the NV generic array enable (the ARB enable is  
        UNchanged).  
  
        When an enabled valid current vertex program (whether specified  
        as an ARB or NV vertex program) is bound, the NV generic array  
        enables are considered (and the ARB enables are ignored).  If a  
        given NV generic array enable is true, the corresponding generic  
        array state is applied.  However if there is an enabled valid  
        vertex program and a particular NV generic array is disabled, then  
        the corresponding conventional aliased array state is applied.  
  
        When the current vertex program is disabled or not valid (so  
        conventional vertex processing is performed), the ARB generic  
        array enables are considered (and the NV enables are ignored).  
        If a given ARB generic array enable is true, the corresponding  
        generic array state is applied.  However if the current vertex  
        program is disabled or NOT valid and a particular ARB generic  
        array is disabled, then the corresponding conventional aliased  
        array state is applied.  
  
        This behavior means generic vertex arrays can be applied to  
        conventional vertex processing when the ARB generic vertex array  
        enable boolean is true.  For example, you can send normalized  
        UNSIGNED_SHORT texture coordinate set arrays as aliased generic  
        vertex arrays where conventionally UNSIGNED_SHORT texture  
        coordinate set arrays are unnormalized.  
  
    NV_vertex_program interaction Issues:  
  
      - Should matrix tracking support extend to ARB program environment  
        parameters?  
  
  
homeprevnext Interactions with EXT_vertex_shader
  
    The existing EXT_vertex_shader extension, if supported, also provides a  
    similar vertex programming model. This extension is incompatible with  
    ARB_vertex_program in a number of different ways.  Mixing the two models  
    in a single application is possible but not recommended. The interactions  
    between the extensions are defined below.  
  
    First, it should be trivially noted that an EXT_vertex_shader "shader"  
    serves the same purpose as an ARB_vertex_program "program".  The two terms  
    will be used interchangeably throughout this discussion.  
  
    The most obvious difference between the two extensions is that the  
    definition of the vertex program is accomplished in EXT_vertex_shader  
    through the use of instruction-specifying procedure calls and is  
    accomplished in ARB_vertex_program by providing a textual string  
    describing the program. This is mostly a distinction of interface rather  
    than functionality.  
  
    Each extension provides its own distinct set of GL state, entry points,  
    and enumerants. However, there are several areas of overlap both in  
    conceptual framework and in programming model that are worth noting for  
    those familiar with both API's.  
  
    1. Resource terminology and types  
  
       Both ARB_vertex_program and EXT_vertex_shader offer access to similar  
       types of resources for use by vertex programs.  
  
       The following terms describe roughly equivalent resources in their  
       respective extensions:  
  
       EXT_vertex_shader   ARB_vertex_program                    Note  
       -----------------   ------------------                    ----  
       instructions        instructions  
       variants            attributes  
       locals              temporaries  
       local constants     parameters bound to inline constants  (a)  
       invariants          parameters bound to GL state and      (b)  
                           program environment parameters  
  
         a. ARB_vertex_program has no intrinsic storage type that corresponds  
            to EXT_vertex_shader's LOCAL_CONSTANT storage type, but rather  
            supports program parameters bound to inline constant vectors  
            specified within the program text. This essentially makes  
            LOCAL_CONSTANT a special case of an ARB_vertex_program program  
            parameter. The values of these inline constant parameters can not  
            be changed without redefining the program itself, just like the  
            values of EXT_vertex_shader LOCAL_CONSTANTs.  
  
         b. ARB_vertex_program has no intrinsic storage type that corresponds  
            to EXT_vertex_shader's INVARIANT storage type, but rather supports  
            program parameters bound to GL state variables, program  
            environment parameters, and program local parameters. This  
            essentially makes INVARIANT a special case of an  
            ARB_vertex_program program parameter. The values of these bound  
            program parameters can be changed without redefining the program  
            itself, but remain constant from vertex to vertex during vertex  
            program execution, just like the values of EXT_vertex_shader  
            INVARIANTs.  
  
       ARB_vertex_program also adds the concept of a program local parameter,  
       which has no direct analogue in EXT_vertex_shader, as it represents a  
       parameter that is stored locally with the program object, but the  
       values of these parameters can be changed without redefining the  
       program itself.  
  
    2. Resource usage queries  
  
       Both ARB_vertex_program and EXT_vertex_shader provide queries to assist  
       in determining the resource usage of a given shader and whether the  
       shader would "fit" within the limits imposed by the underlying hardware  
       implementation. The application can investigate the maximum numbers of  
       shader resources supported by an implementation, shader resources  
       available in hardware, and resources consumed by a given shader after  
       being compiled into the implementation's native representation.  
  
       In EXT_vertex_shader (see the end of section 2.14 of the  
       EXT_vertex_shader specification), the queries are handled by glGet.  
  
       In ARB_vertex_programs (see section 2.14.3.7 of this specification),  
       similar queries are handled by GetProgramivARB, with a target of  
       VERTEX_PROGRAM_ARB.  
  
       The following queries exist in both extensions and serve roughly  
       equivalent purposes in each:  
  
       EXT_vertex_shader                             ARB_vertex_program  
       -----------------                             ------------------  
       MAX_VERTEX_SHADER_INSTRUCTIONS_EXT            MAX_PROGRAM_INSTRUCTIONS_ARB  
       MAX_VERTEX_SHADER_VARIANTS_EXT                MAX_PROGRAM_ATTRIBS_ARB  
       MAX_VERTEX_SHADER_LOCALS_EXT                  MAX_PROGRAM_TEMPORARIES_ARB  
  
       MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT  MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB  
       MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT      MAX_PROGRAM_NATIVE_ATTRIBS_ARB  
       MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT        MAX_PROGRAM_NATIVE_TEMPORARIES_ARB  
  
       VERTEX_SHADER_INSTRUCTIONS_EXT                PROGRAM_NATIVE_INSTRUCTIONS_ARB  
       VERTEX_SHADER_VARIANTS_EXT                    PROGRAM_NATIVE_ATTRIBS_ARB  
       VERTEX_SHADER_LOCALS_EXT                      PROGRAM_NATIVE_TEMPORARIES_ARB  
  
       VERTEX_SHADER_OPTIMIZED_EXT                   PROGRAM_UNDER_NATIVE_LIMITS_ARB  
  
       ARB_vertex_program offers additional queries to account for differences  
       in some of the resource definitions (program environment parameters and  
       program local parameters, address registers, etc.) as well as the  
       ability to separately query a compiled program's resource usage  
       according to the specification versus a possibly more efficient  
       resource usage obtained by passing the program through by a "smart"  
       compiler.  
  
       The following queries do not exist in ARB_vertex_program due to the  
       slightly different resource models:  
  
       EXT_vertex_shader                                    ARB_vertex_program  
       -----------------                                    ------------------  
       {MAX_}{OPTIMIZED_}VERTEX_SHADER_INVARIANTS_EXT       (a)  
       {MAX_}{OPTIMIZED_}VERTEX_SHADER_LOCAL_CONSTANTS_EXT  (a)  
  
         a. ARB_vertex_program coalesces all of the different program  
            parameters (environment, local, inline constant, and those bound  
            to GL state) into a single queryable resource for  
            PROGRAM_PARAMETERS.  EXT_vertex_shader provides separate queries  
            even though these parameters may consume the same resource on some  
            implementations.  
  
       The following queries do not exist in EXT_vertex_shader due to the  
       slightly different resource models:  
  
       EXT_vertex_shader    ARB_vertex_program  
       -----------------    ------------------  
       (b)                  PROGRAM_*_ARB  
  
       (c)                  {MAX_}{NATIVE_}PROGRAM_PARAMETERS_ARB  
  
       (d)                  {MAX_}{NATIVE_}PROGRAM_ADDRESS_REGISTERS_ARB  
  
         b. These queries are used to find out how many resources a given  
            program used according to the specification, *before* running the  
            program through an optimizing compiler.  This distinction is not  
            made in EXT_vertex_shader.  
  
         c. These queries are used to find out how many parameters were used  
            by a program or are allowed by an implementation, in total without  
            distinguishing between environment parameters, program local  
            parameters, inline constant parameters, or parameters bound to GL  
            state.  EXT_vertex_shader does not provide this information.  
  
         d. EXT_vertex_shader does not provide have any address register  
            resources since all dynamic array references are handled with the  
            atomic OP_INDEX instruction.  
  
    3. Symbols and variable names  
  
       In EXT_vertex_shader resources that represent storage locations  
       (i.e. INVARIANTS, VARIANTS, LOCALS, LOCAL_CONSTANTS) are abstractly  
       referenced through a GL-allocated symbol id obtained from  
       GenSymbolsEXT. This level of abstraction is provided to allow the  
       implementation to make hardware-dependent decisions about the best way  
       to arrange, allocate, and re-use hardware resources.  
  
       Though ARB_vertex_program does not use symbol id's to refer to similar  
       types of resources, it does provide similar functionality by allowing a  
       vertex program to declare arbitrarily named variables for each resource  
       in use. These names are assigned using the declaration syntax  
       associated with the "PARAM", "ATTRIB", "TEMP", and "OUTPUT", and  
       "ADDRESS" keywords.  
  
    4. Program management  
  
       With the exception of the actual program specification itself,  
       EXT_vertex_shader and ARB_vertex_program have very similar program  
       management API's.  
  
       The following procedures serve roughly equivalent functions in their  
       respective extensions.  
  
       EXT_vertex_shader            ARB_vertex_program  
       -----------------            ------------------  
       BindVertexShaderEXT          BindProgramARB  
       GenVertexShadersEXT          GenProgramsARB  
       DeleteVertexShaderEXT        DeleteProgramsARB  
         
       The following procedures are used in EXT_vertex_shader to define the  
       program instruction sequence, and are not present in ARB_vertex_program  
       since the string provided to ProgramStringARB fully defines the program  
       contents.  
         
           ShaderOp1EXT  
           ShaderOp2EXT  
           ShaderOp3EXT  
           SwizzleEXT  
           WriteMaskEXT  
           InsertComponentEXT  
           ExtractComponentEXT  
  
    5. Data specification routines  
  
       With the exception of the discrepancies in data types and resource  
       names described above, EXT_vertex_shader and ARB_vertex_program provide  
       similar program data specification and "current data query" API's.  
  
       The following procedures serve roughly equivalent functions in their  
       respective extensions:  
  
       EXT_vertex_shader            ARB_vertex_program           Note  
       -----------------            ------------------           -----  
       SetInvariantEXT              ProgramEnvParameter4*ARB     (a)  
       GetInvariant*vEXT            GetProgramEnvParameter*vARB  (a)  
       Variant*vEXT                 VertexAttrib*ARB  
       VariantPointerEXT            VertexAttribPointerARB  
       GetVariant*vEXT              GetVertexAttrib*vARB  
       GetVariantPointervEXT        GetVertexAttribPointervARB  
       EnableVariantClientStateEXT  EnableVertexAttribArrayARB  
       DisableVariantClientStateEXT DisableVertexAttribArrayARB  
       IsVariantEnabledEXT          GetVertexAttrib*vARB         (b)  
  
         a. See item #1 and #2 for more information on the relationship  
            between EXT_vertex_shader invariants and ARB_vertex_program  
            program parameters.  
  
         b. The enabled state of an attribute array in ARB_vertex_program can  
            be queried with GetVertexAttrib*v and a parameter of  
            VERTEX_ATTRIB_ARRAY_ENABLED_ARB. In EXT_vertex_shader there is a  
            dedicated enabled query procedure.  
  
       However, there are some data specification routines in  
       EXT_vertex_shader that have no procedure call analogue in  
       ARB_vertex_program as their functions are subsumed by the string  
       representation of the program itself.  
  
       The following procedures in EXT_vertex_shader have functionality  
       roughly covered by the following strings within the program text in  
       ARB_vertex_shader:  
  
       EXT_vertex_shader            ARB_vertex_program           Note  
       -----------------            ------------------           -----  
       SetLocalConstantEXT          PARAM C = {<x>,<y>,<z>,<w>};  (c)  
  
       BindLightParameterEXT        state.light[n].*  
       BindMaterialParameterEXT     state.material.*              (d)  
       BindTexGenParameterEXT       state.texgen[n].*  
  
       BindTextureUnitParameterEXT  
         CURRENT_TEXTURE_COORDS     vertex.texcoord[n]  
         TEXTURE_MATRIX             state.matrix.texture[n]  
  
       BindParameterEXT  
         CURRENT_VERTEX_EXT         vertex.position  
         CURRENT_NORMAL             vertex.normal  
         CURRENT_COLOR              vertex.color.*  
         MODELVIEW_MATRIX           state.matrix.modelview[n]  
         PROJECTION_MATRIX          state.matrix.projection  
         MVP_MATRIX_EXT             state.matrix.mvp  
         COLOR_MATRIX               <unavailable>                 (e)  
         CLIP_PLANE                 state.clip[n].plane  
         FOG_COLOR                  state.fog.color  
         FOG_DENSITY                state.fog.params.x  
         FOG_START                  state.fog.params.y  
         FOG_END                    state.fog.params.z  
         LIGHT_MODEL_AMBIENT        state.lightmodel.ambient  
  
         c. Note that while EXT_vertex_shader style local constants can be  
            specified using inline constants in the program text, there is no  
            functionality in ARB_vertex_program that corresponds to the  
            GetLocalConstant*vEXT call. That is, program parameters bound to  
            inline constant vectors can be set in the text, but not queried  
            from the application.  
  
         d. Note that while EXT_vertex_shader supports binding material  
            properties to variants, ARB_vertex_shader only supports binding  
            them to program parameters (invariants). See item #11 below for  
            more information.  
  
         e. Note that while EXT_vertex_shader supports binding color matrix if  
            the ARB_imaging subset is supported, ARB_vertex_shader does not  
            allow for such a binding. See item #11 below for more information.  
  
    6. Data types  
  
       EXT_vertex_shader supports data types of SCALAR, VECTOR, and MATRIX.  
  
       ARB_vertex_program intrinsically supports only vectors, though it  
       allows for the definition of a matrix as a contiguous allocation of  
       four row vectors. Some operations that, in EXT_vertex_shader require  
       scalar inputs or scalar outputs, will, in ARB_vertex_program, use the  
       selected component of the source vector as input and/or replicate their  
       output to all components.  
  
       Further, EXT_vertex_shader supports a pair of InsertComponents and  
       ExtractComponents functions that are not available (nor required) in  
       ARB_vertex_program, as they essentially provide for conversion between  
       the SCALAR, VECTOR, and MATRIX data types.  
  
    7. Input swizzles and output write-masks  
  
       In EXT_vertex_shader, write masks are specified as a type of  
       "instruction", using WriteMaskEXT, while in ARB_vertex_program, write  
       masks are specified as modifiers to the destination resource with  
       writemask modifiers, such as ".xyz" or ".w".  
  
       In EXT_vertex_shader, source operand swizzles (component re- ordering,  
       negation, and hard-coding to the value 0 and +/- 1.0) are also  
       specified as a type of "instruction", using SwizzleEXT.  
  
       In ARB_vertex_program, swizzles can either be handled as instruction  
       ("SWZ") or as part of a modifier of the source argument to an  
       instruction. The only differences between the two methods is that the  
       source modifiers in ARB_vertex_program do not provide the ability to  
       use 0.0 and +/- 1.0, or negate individual components, while the "SWZ"  
       instruction does.  
  
   8. Support for clipping and user clip planes  
  
      Both extensions provide similar support for traditional clipping to the  
      view frustum, namely that frustum clipping is not subsumed by vertex  
      shader, or vertex program execution.  
  
      Additionally, EXT_vertex_shader supports user clip planes by  
      transforming the user clip planes from eye-space into clip space and  
      clipping in the clip space coordinate system. This is supported as long  
      as the projection matrix is non-singular.  
  
      ARB_vertex_program provides similar functionality but only for programs  
      specified using the "position invariant" option. For more information on  
      user clip-plane support, see issue #20 and section 2.14.4.5.1 of this  
      specification.  
  
   9. Support for glRasterPos  
  
      EXT_vertex_shader does not support transforming the current raster  
      position vertex by the current vertex shader, while ARB_vertex_program  
      does.  
  
  10. Relative addressing.  
  
      The string based syntax of ARB_vertex_program supports a relative  
      addressing model where a given declared array can be dynamically  
      dereferenced by first loading a declared ADDRESS register, using the  
      "ARL" instruction with a value obtained at program execution then using  
      that named ADDRESS register as the index to dereference a declared array  
      of parameters later on.  See section 2.14.3.5 of this specification for  
      details.  
  
      For example, in ARB_vertex_program you can specify the following  
      piece of a program.  
  
          PARAM arr[5]  = { program.env[0..4] };  
          ADDRESS addr;  
          ATTRIB v1 = vertex.attrib[1];  
          ARL addr, v1;  
          MOV result, arr[addr.x + 1];  
  
      EXT_vertex_shader supports relative addressing as as a single atomic  
      operation through the use of the instruction OP_INDEX_EXT, as in  
  
          ShaderOp2EXT(OP_INDEX_EXT, <res>, <arg1>, <arg2>).  
  
      OP_INDEX_EXT supports relative addressing by taking the value stored in  
      the register referred to by <arg1> and adding that value to the register  
      number referred to by <arg2>, and loading <res> with the value stored in  
      the register at the resulting offset.  EXT_vertex_shader has the  
      requirement that the register referred to by <arg2> is allocated as one  
      of a contiguous range of symbols obtained from a single call to  
      GenSymbolsEXT.  
  
      To achieve the same functionality as the above ARB_vertex_program, using  
      EXT_vertex_shader, one could allocate a LOCAL symbol to hold a "fake"  
      address register, and do a similar type of dynamic dereference  
      operation, placing the output in a temporary LOCAL before giving it as  
      an source argument to the "real" instruction.  
  
       arr_contiguousArraySymbol =  
            GenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 5);  
  
       addr_fakeAddressRegSymbol =  
            GenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);  
  
       v1_srcSymbolForARLOp =  
            GenSymbolsEXT(GL_VECTOR_EXT, GL_VARIANT_EXT, GL_FULL_RANGE_EXT, 1);  
  
       temp =  
            GenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);  
  
       result_ForMovOpSymbol =  
            GenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);  
  
        // load fake ADDRESS register  
        ExtractComponentEXT(  
            addr_fakeAddressRegSymbol,  
            v1_srcSymbolForARLOp,  
            0);  
  
        // do dynamic dereference into a temp  
        ShaderOp2EXT(  
            GL_OP_INDEX_EXT,  
            temp,  
            addr_fakeAddressRegSymbol,  
            contiguousArraySymbol);  
  
        // do operation we really wanted (MOV) using looked up src value  
        ShaderOp1EXT(  
            GL_OP_MOV_EXT,  
            result_ForMovOpSymbol,  
            temp,  
            (arr_contiguousArraySymbol + 1));  
  
   11. Available GL state bindings  
  
       Both EXT_vertex_shader and ARB_vertex_program offer the ability to bind  
       program resources to pieces of OpenGL state so that the values of  
       OpenGL state parameters are available to the program without the  
       application having to copy the state values manually into program  
       parameters.  
  
       The two extensions differ in exactly which pieces of state are  
       available to a vertex program, with the main difference being that  
       ARB_vertex_program offers a more comprehensive set of state bindings.  
  
       First, EXT_vertex_shader can bind pieces of GL state considered to be  
       "scalar" values to a single SCALAR symbol, whereas ARB_vertex_program,  
       which handles only vectors, packs up to 4 scalar bindings into a single  
       vector parameter.  
  
       Similarly, EXT_vertex_shader can bind pieces of GL state considered to  
       be "matrix" values to a single MATRIX symbol, whereas  
       ARB_vertex_program supports bindings to matrix data by using up to four  
       vectors to store the rows of the matrix.  
  
       Other differences between the state bindings available in both API's  
       are listed below:  
  
         a. In EXT_vertex_shader, the light attenuation factors (CONSTANT,  
            LINEAR, QUADRATIC, and SPOT_EXPONENT), are available as separate  
            SCALAR bindings.  
  
            In ARB_vertex_program, the light attenuation factors are all  
            packed into a single vector called state.light[n].attenuation with  
            the CONSTANT, LINEAR, QUADRATIC, and SPOT_EXPONENT factors in the  
            x,y,z, and w parameters respectively.  
  
         b. In EXT_vertex_shader the spotlight direction (SPOT_DIRECTION) and  
            spot light cutoff angle (SPOT_CUTOFF), are available as separate  
            bindings.  
  
            In ARB_vertex_program, these parameters are all packed into a  
            single vector called state.light[n].spot.direction with the with  
            the x,y,z parameters of the spotlight direction and the the  
            *cosine* of the cutoff angle in the x,y,z, and w parameters  
            respectively.  
  
         c. In EXT_vertex_shader, the fog equation factors (FOG_DENSITY,  
            FOG_START, FOG_END), are avaiable as separate SCALAR bindings.  
  
            In ARB_vertex_program, the fog equation factors are all packed  
            into a single vector called state.fog.params with the fog density,  
            linear start, linear end, and pre-computed 1.0/ (end-start)  
            factors in the x,y,z, and w parameters respectively.  
  
         d. In EXT_vertex_shader, material properties can be bound to a  
            variant (i.e. "attribute" in ARB_vertex_program terminology) and  
            can change per vertex, and the changes take effect immediately.  
  
            In ARB_vertex_program, material properties can only be bound to  
            program parameters, and any changes to material properties between  
            a Begin/End pair are not guaranteed to take effect until the  
            following End command.  
  
         e. In EXT_vertex_shader, the material shininess property is bound to  
            a SCALAR variable.  
  
            In ARB_vertex_program, the material shininess property is bound to  
            a vector with elements { s, 0.0, 0.0, 1.0 } where "s" is the  
            material shininess property.  
  
         f. In EXT_vertex_shader, a program can bind to the current modelview,  
            projection, composite modelview-projection, color, and texture  
            matrices only in their entirety.  
  
            In ARB_vertex_program, a program can bind to individual rows of  
            any matrix, with the exception of the color matrix, which is not  
            available in ARB_vertex_program.  
  
            Additionally, ARB_vertex_program adds the ability to bind to  
            multiple modelview matrices, multiple palette matrices, and a set  
            of matrices dedicated for use with vertex programs called "program  
            matrices". Further, ARB_vertex_program offers the ability to bind  
            to the inverse, transpose, and inverse_transpose of any of the  
            matrices available for binding.  
  
            If an application desires the functionality of binding to the  
            color matrix in ARB_vertex_program, that application can use one  
            of the other matrices, for instance program matrices, to store the  
            current color matrix.  
  
   12. Instruction set differences.  
  
       In general, ARB_vertex_program's instruction set is a super-set of the  
       EXT_vertex_shader instructions that take VECTOR inputs and produce  
       VECTOR outputs. The versions of the EXT_vertex_shader instructions that  
       take non-vector (i.e. SCALAR or MATRIX) operands are almost all  
       available in vector form as well.  
  
       The instructions from each set correspond as follows:  
  
       EXT_vertex_shader       ARB_vertex_program   Note  
       -----------------       ------------------   -----  
       OP_INDEX_EXT           <unavailable>         (a)  
       OP_NEGATE_EXT          <unavailable>         (b)  
       OP_DOT3_EXT             "DP3"                (c)  
       OP_DOT4_EXT             "DP4"  
       OP_MUL_EXT              "MUL"  
       OP_ADD_EXT              "ADD"  
       OP_MADD_EXT             "MAD"  
       OP_FRAC_EXT             "FRC"  
       OP_MAX_EXT              "MAX"  
       OP_MIN_EXT              "MIN"  
       OP_SET_GE_EXT           "SGE"  
       OP_SET_LT_EXT           "SLT"  
       OP_CLAMP_EXT           <unavailable>         (d)  
       OP_FLOOR_EXT            "FLR"  
       OP_ROUND_EXT           <unavailable>         (e)  
       OP_EXP_BASE_2_EXT       "EX2"                (f)  
       OP_LOG_BASE_2_EXT       "LG2"                (g)  
       OP_POWER_EXT            "POW"                (h)  
       OP_RECIP_EXT            "RCP"                (i)  
       OP_RECIP_SQRT_EXT       "RSQ"                (j)  
       OP_SUB_EXT              "SUB"  
       OP_CROSS_PRODUCT_EXT    "XPD"                (k)  
       OP_MULTIPLY_MATRIX_EXT <unavailable>         (l)  
       OP_MOV_EXT              "MOV"  
      <unavailable>            "ARL"                (a)  
      <unavailable>            "ABS"  
      <unavailable>            "LIT"  
      <unavailable>            "EXP"                (f)  
      <unavailable>            "LOG"                (g)  
      <unavailable>            "DPH"  
      <unavailable>            "DST"  
  
       There are a few minor differences, however.  
  
       a. EXT_vertex_shader's OP_INDEX_EXT is not available in  
          ARB_vertex_program which uses the "ARL" instruction and array syntax  
          to handle dynamically dereferencing source data. See item #10 above  
          and the discussion of "ARL" in section 2.14.3.5.  
  
       b. EXT_vertex_shader's OP_NEGATE_EXT is not available in  
          ARB_vertex_program. ARB_vertex_program can support a "NEGATE"  
          operation through the use of swizzle modifiers on source operands or  
          the "SWZ" instruction.  
  
            MOV tempA, -tempB;  
  
          or  
  
            SWZ tempA, -tempB, x,y,z,w;  
  
       c. The "w" component of EXT_vertex_shader's OP_DOT3_EXT instruction is  
          left unchanged.  
  
          However, in ARB_vertex_program, the "w" component gets the same  
          result as the "x", "y", and "z" components.  
  
       d. EXT_vertex_shader's OP_CLAMP_EXT is not available in  
          ARB_vertex_program. ARB_vertex_program can support a "CLAMP"  
          operation by using a pair of "MAX" and "MIN" instructions as in:  
  
            # CLAMP arg1 to be within [arg2, arg3]  
            MAX temp,   arg1, arg2;  
            MIN result, temp, arg3;  
  
       e. EXT_vertex_shader's OP_ROUND_EXT is not available in  
          ARB_vertex_program. ARB_vertex_program can support a "ROUND"  
          operation by using a pair of "ADD" and "FLOOR" instructions as in:  
  
            ADD   temp,   arg1, 0.5;  
            FLOOR result, temp;  
  
       f. EXT_vertex_shader's OP_EXP_BASE_2_EXT is designed to support high  
          precision calculations of base-2 exponentiation.  
  
          ARB_vertex_program's "EX2" is the equivalent function, however  
          ARB_vertex_program also offers an "EXP" function that is designed to  
          support a lower precision approximation of base-2 exponentiation  
          that can be further refined through an iterative process.  
            
          On some implementations, both "EX2" and "EXP" may be carried out  
          with the same high precision at no cost relative to each other.  As  
          such, if a vertex program is using "EXP" with the intent of  
          iteratively refining the approximation by using several successive  
          instructions it may be more efficient to use a single call to "EX2"  
          and get the high precision with a single instruction.  
  
          If on the other hand, a single approximation is good enough, there  
          is no additional cost to using "EXP" on such implementations.  
  
          Further note that in EXT_vertex_shader, OP_EXP_BASE_2_EXT is  
          specified to take a scalar operand, whereas ARB_vertex_program's  
          "EXP" and "EX2" instruction each take a vector operand, use the "x"  
          component, and then write (partial) results to all components of a  
          destination vector.  
  
       g. EXT_vertex_shader's OP_LOG_BASE_2_EXT is designed to support high  
          precision calculations of base-2 logarithms.  
  
          ARB_vertex_program's "LG2" is the equivalent function, however  
          ARB_vertex_program also offers an "LOG" function that is designed to  
          support a lower precision approximation of base-2 logarithms that  
          can be further refined through an iterative process.  
  
          On some implementations, both "LG2" and "LOG" may be carried out  
          with the same high precision at no cost relative to each other.  As  
          such, if a vertex program is using "LOG" with the intent of  
          iteratively refining the approximation by using several successive  
          instructions it may be more efficient to use a single call to "LG2"  
          and get the high precision with a single instruction.  
  
          If on the other hand, a single approximation is good enough, there  
          is no additional cost to using "LOG" on such implementations.  
  
          Further note that in EXT_vertex_shader, OP_LOG_BASE_2_EXT is  
          specified to take a scalar operand, whereas ARB_vertex_program's  
          "LOG" and "LOG2" instruction each take a vector operand, use the "x"  
          component, and then write (partial) results to all components of a  
          destination vector.  
  
       h. EXT_vertex_shader's OP_POWER_EXT is designed to support high  
          precision calculations of the power function.  
  
          ARB_vertex_program's "POW" is the equivalent function.  
  
          Further note that in EXT_vertex_shader, OP_POWER_EXT is specified to  
          take a scalar operand, whereas ARB_vertex_program's "POW"  
          instruction takes a vector operand, uses the "x" component, and  
          replicates the same result to all components of a destination  
          vector.  
  
       i. EXT_vertex_shader's OP_RECIP_EXT is specified to take a scalar  
          operand, whereas ARB_vertex_program's "RCP" instruction takes a  
          single component of a vector and replicates the same result to all  
          components of the destination vector.  
  
       j. EXT_vertex_shader's OP_RECIP_SQRT_EXT is specified to take a scalar  
          operand, whereas ARB_vertex_program's "RSQ" instruction takes a  
          single component of a vector and replicates the same result to all  
          components of the destination vector.  
  
       k. The "w" component of EXT_vertex_shader's OP_CROSS_PRODUCT_EXT  
          instruction is forced to 1.0;  
  
          However, in ARB_vertex_program, the "w" component is left undefined  
          and "writes to the w component of the destination are treated as  
          disabled, regardless of the write mask specified in the XPD  
          instruction".  
  
       l. EXT_vertex_shader's OP_MULTIPLY_MATRIX is not available in  
          ARB_vertex_program. ARB_vertex_program can support a "MATRIX  
          MULTIPLY" operation by using a series of "DP4" instructions as in:  
  
            PARAM mat[4] = { state.matrix.modelview };  
            DP4 result.x, vec, mat[0];  
            DP4 result.y, vec, mat[1];  
            DP4 result.z, vec, mat[2];  
            DP4 result.w, vec, mat[3];  
  
   13. Vertex provoking behavior  
  
       EXT_vertex_shader does not provoke vertex shader execution when variant  
       0 is specified (either using Variant*EXT, or variant  
       arrays). Applications are required to use the conventional Vertex* or  
       vertex arrays to provoke a vertex in both vertex shader mode and  
       conventional mode.  Variant 0 is considered current state and is  
       queryable.  
  
       Conversely, ARB_vertex_program does provoke vertex program execution  
       when attribute 0 is specified (either using VertexAttrib*vARB, or  
       attribute arrays) in both vertex program mode and conventional mode.  
       Attribute 0 is not considered current state and is not queryable.  
  
       For implementations that support both extensions, this means that if  
       ARB_vertex_program is disabled, and EXT_vertex_shader is enabled, then  
       specifying ARB_vertex_program's attribute 0 will still provoke  
       execution of the currently bound EXT_vertex_shader defined shader.  
  
   14. Enabled state  
  
       On implementations that support both EXT_vertex_shader, and  
       ARB_vertex_program, priority is given to ARB_vertex_program. That is to  
       say, if both are enabled, the implementation uses the program defined  
       by ARB_vertex_program and does not execute the currently bound  
       EXT_vertex_shader shader unless or until ARB_vertex_program is  
       subsequently disabled. Needless to say, it is not expected that a given  
       application will actually attempt to use both vertex program API's at  
       once.  
  
  
homeprevnext GLX Protocol
  
     The following rendering commands are sent to the server as part of a  
     glXRender request:  
  
        VertexAttrib1svARB  
            2           12              rendering command length  
            2           4189            rendering command opcode  
            4           CARD32          index  
            2           INT16           v[0]  
            2                           unused  
  
        VertexAttrib1fvARB  
            2           12              rendering command length  
            2           4193            rendering command opcode  
            4           CARD32          index  
            4           FLOAT32         v[0]  
  
        VertexAttrib1dvARB  
            2           16              rendering command length  
            2           4197            rendering command opcode  
            4           CARD32          index  
            8           FLOAT64         v[0]  
  
        VertexAttrib2svARB  
            2           12              rendering command length  
            2           4190            rendering command opcode  
            4           CARD32          index  
            2           INT16           v[0]  
            2           INT16           v[1]  
  
        VertexAttrib2fvARB  
            2           16              rendering command length  
            2           4194            rendering command opcode  
            4           CARD32          index  
            4           FLOAT32         v[0]  
            4           FLOAT32         v[1]  
  
        VertexAttrib2dvARB  
            2           24              rendering command length  
            2           4198            rendering command opcode  
            4           CARD32          index  
            8           FLOAT64         v[0]  
            8           FLOAT64         v[1]  
  
        VertexAttrib3svARB  
            2           16              rendering command length  
            2           4191            rendering command opcode  
            4           CARD32          index  
            2           INT16           v[0]  
            2           INT16           v[1]  
            2           INT16           v[2]  
            2                           unused  
  
        VertexAttrib3fvARB  
            2           20              rendering command length  
            2           4195            rendering command opcode  
            4           CARD32          index  
            4           FLOAT32         v[0]  
            4           FLOAT32         v[1]  
            4           FLOAT32         v[2]  
  
        VertexAttrib3dvARB  
            2           32              rendering command length  
            2           4199            rendering command opcode  
            4           CARD32          index  
            8           FLOAT64         v[0]  
            8           FLOAT64         v[1]  
            8           FLOAT64         v[2]  
  
        VertexAttrib4bvARB  
            2           12              rendering command length  
            2           4230            rendering command opcode  
            4           CARD32          index  
            1           INT8            v[0]  
            1           INT8            v[1]  
            1           INT8            v[2]  
            1           INT8            v[3]  
  
        VertexAttrib4svARB  
            2           16              rendering command length  
            2           4192            rendering command opcode  
            4           CARD32          index  
            2           INT16           v[0]  
            2           INT16           v[1]  
            2           INT16           v[2]  
            2           INT16           v[3]  
  
        VertexAttrib4ivARB  
            2           24              rendering command length  
            2           4231            rendering command opcode  
            4           CARD32          index  
            4           INT32           v[0]  
            4           INT32           v[1]  
            4           INT32           v[2]  
            4           INT32           v[3]  
  
        VertexAttrib4ubvARB  
            2           12              rendering command length  
            2           4232            rendering command opcode  
            4           CARD32          index  
            1           CARD8           v[0]  
            1           CARD8           v[1]  
            1           CARD8           v[2]  
            1           CARD8           v[3]  
  
        VertexAttrib4usvARB  
            2           16              rendering command length  
            2           4233            rendering command opcode  
            4           CARD32          index  
            2           CARD16          v[0]  
            2           CARD16          v[1]  
            2           CARD16          v[2]  
            2           CARD16          v[3]  
  
        VertexAttrib4uivARB  
            2           24              rendering command length  
            2           4234            rendering command opcode  
            4           CARD32          index  
            4           CARD32          v[0]  
            4           CARD32          v[1]  
            4           CARD32          v[2]  
            4           CARD32          v[3]  
  
        VertexAttrib4fvARB  
            2           24              rendering command length  
            2           4196            rendering command opcode  
            4           CARD32          index  
            4           FLOAT32         v[0]  
            4           FLOAT32         v[1]  
            4           FLOAT32         v[2]  
            4           FLOAT32         v[3]  
  
        VertexAttrib4dvARB  
            2           40              rendering command length  
            2           4200            rendering command opcode  
            4           CARD32          index  
            8           FLOAT64         v[0]  
            8           FLOAT64         v[1]  
            8           FLOAT64         v[2]  
            8           FLOAT64         v[3]  
  
        VertexAttrib4NbvARB  
            2           12              rendering command length  
            2           4235            rendering command opcode  
            4           CARD32          index  
            1           INT8            v[0]  
            1           INT8            v[1]  
            1           INT8            v[2]  
            1           INT8            v[3]  
  
        VertexAttrib4NsvARB  
            2           16              rendering command length  
            2           4236            rendering command opcode  
            4           CARD32          index  
            2           INT16           v[0]  
            2           INT16           v[1]  
            2           INT16           v[2]  
            2           INT16           v[3]  
  
        VertexAttrib4NivARB  
            2           24              rendering command length  
            2           4237            rendering command opcode  
            4           CARD32          index  
            4           INT32           v[0]  
            4           INT32           v[1]  
            4           INT32           v[2]  
            4           INT32           v[3]  
  
        VertexAttrib4NubvARB  
            2           12              rendering command length  
            2           4201            rendering command opcode  
            4           CARD32          index  
            1           CARD8           v[0]  
            1           CARD8           v[1]  
            1           CARD8           v[2]  
            1           CARD8           v[3]  
  
        VertexAttrib4NusvARB  
            2           16              rendering command length  
            2           4238            rendering command opcode  
            4           CARD32          index  
            2           CARD16          v[0]  
            2           CARD16          v[1]  
            2           CARD16          v[2]  
            2           CARD16          v[3]  
  
        VertexAttrib4NuivARB  
            2           24              rendering command length  
            2           4239            rendering command opcode  
            4           CARD32          index  
            4           CARD32          v[0]  
            4           CARD32          v[1]  
            4           CARD32          v[2]  
            4           CARD32          v[3]  
  
        BindProgramARB  
            2           12              rendering command length  
            2           4180            rendering command opcode  
            4           ENUM            target  
            4           CARD32          program  
  
        ProgramEnvParameter4fvARB  
            2           32              rendering command length  
            2           4184            rendering command opcode  
            4           ENUM            target  
            4           CARD32          index  
            4           FLOAT32         params[0]  
            4           FLOAT32         params[1]  
            4           FLOAT32         params[2]  
            4           FLOAT32         params[3]  
  
        ProgramEnvParameter4dvARB  
            2           44              rendering command length  
            2           4185            rendering command opcode  
            4           ENUM            target  
            4           CARD32          index  
            8           FLOAT64         params[0]  
            8           FLOAT64         params[1]  
            8           FLOAT64         params[2]  
            8           FLOAT64         params[3]  
  
        ProgramLocalParameter4fvARB  
            2           32              rendering command length  
            2           4215            rendering command opcode  
            4           ENUM            target  
            4           CARD32          index  
            4           FLOAT32         params[0]  
            4           FLOAT32         params[1]  
            4           FLOAT32         params[2]  
            4           FLOAT32         params[3]  
  
        ProgramLocalParameter4dvARB  
            2           44              rendering command length  
            2           4216            rendering command opcode  
            4           ENUM            target  
            4           CARD32          index  
            8           FLOAT64         params[0]  
            8           FLOAT64         params[1]  
            8           FLOAT64         params[2]  
            8           FLOAT64         params[3]  
  
    The ProgramStringARB is potentially large, and hence can be sent in a  
    glXRender or glXRenderLarge request.  
  
        ProgramStringARB  
            2           16+len+p        rendering command length  
            2           4217            rendering command opcode  
            4           ENUM            target  
            4           ENUM            format  
            4           sizei           len  
            len         LISTofBYTE      program  
            p                           unused, p=pad(len)  
  
         If the command is encoded in a glxRenderLarge request, the command  
         opcode and command length fields above are expanded to 4 bytes each:  
  
            4           16+len+p        rendering command length  
            4           4217            rendering command opcode  
  
    VertexAttribPointerARB, EnableVertexAttribArrayARB, and  
    DisableVertexAttribArrayARB are entirely client-side commands.  
  
    The remaining commands are non-rendering commands.  These commands are  
    sent separately (i.e., not as part of a glXRender or glXRenderLarge  
    request), using the glXVendorPrivateWithReply request:  
  
        DeleteProgramsARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4+n             request length  
            4           1294            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
            n*4         LISTofCARD32    programs  
  
        GenProgramsARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1295            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           n               reply length  
            24                          unused  
            n*4         LISTofCARD322   programs  
  
        GetProgramEnvParameterfvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           6               request length  
            4           1296            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           CARD32          index  
            4                           unused  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n (number of parameter components)  
  
            if (n=1) this follows:  
  
            4           FLOAT32         params  
            12                          unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*4         LISTofFLOAT32   params  
  
        GetProgramEnvParameterdvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           6               request length  
            4           1297            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           CARD32          index  
            4                           unused  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n*2)  
            4                           unused  
            4           CARD32          n (number of parameter components)  
  
            if (n=1) this follows:  
  
            8           FLOAT64         params  
            8                           unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*8         LISTofFLOAT64   params  
  
        GetProgramLocalParameterfvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           6               request length  
            4           1305            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           CARD32          index  
            4                           unused  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n (number of parameter components)  
  
            if (n=1) this follows:  
  
            4           FLOAT32         params  
            12                          unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*4         LISTofFLOAT32   params  
  
        GetProgramLocalParameterdvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           6               request length  
            4           1306            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           CARD32          index  
            4                           unused  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n*2)  
            4                           unused  
            4           CARD32          n (number of parameter components)  
  
            if (n=1) this follows:  
  
            8           FLOAT64         params  
            8                           unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*8         LISTofFLOAT64   params  
  
        GetProgramivARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1307            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           ENUM            pname  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n  
  
            if (n=1) this follows:  
  
            4           INT32           params  
            12                          unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*4         LISTofINT32     params  
  
        GetProgramStringARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1308            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           ENUM            target  
            4           ENUM            pname  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           (n+p)/4         reply length  
            4                           unused  
            4           CARD32          n  
            16                          unused  
            n           STRING          program  
            p                           unused, p=pad(n)  
  
        Note that VERTEX_ATTRIB_ARRAY_ENABLED_ARB,  
        VERTEX_ATTRIB_ARRAY_SIZE_ARB, VERTEX_ATTRIB_ARRAY_STRIDE_ARB,  
        VERTEX_ATTRIB_ARRAY_TYPE_ARB, and VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB  
        may be queried by GetVertexAttrib[dfi]ARB, but generate no protocol  
        and return client-side state.  
  
        GetVertexAttribdvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1301            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           index  
            4           ENUM            pname  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n*2)  
            4                           unused  
            4           CARD32          n  
  
            if (n=1) this follows:  
  
            8           FLOAT64         params  
            8                           unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*8         LISTofFLOAT64   params  
  
        GetVertexAttribfvARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1302            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           index  
            4           ENUM            pname  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n  
  
            if (n=1) this follows:  
  
            4           FLOAT32         params  
            12                          unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*4         LISTofFLOAT32   params  
  
        GetVertexAttribivARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1303            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           index  
            4           ENUM            pname  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n  
  
            if (n=1) this follows:  
  
            4           INT32           params  
            12                          unused  
  
            otherwise this follows:  
  
            16                          unused  
            n*4         LISTofINT32     params  
  
        IsProgramARB  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1304            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
          =>  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           0               reply length  
            4           BOOL32          return value  
            20                          unused  
  
     When transferring vertex attribute array elements, there may not be a  
     protocol encoding that exactly matches the combination of combination of  
     size, normalization enable, and data type in the array.  If no match  
     protocol encoding exists, the encoding for the corresponding 4-component  
     attribute is used.  v[1] and v[2] are set to zero if not specified in the  
     vertex array.  If v[3] is not specified in the vertex array, it is set to  
     0x7F, 0x7FFF, 0x7FFFFFFF, 0xFF, 0xFFFF, or 0xFFFFFFFF for the  
     VertexAttrib4NbvARB, VertexAttrib4NsvARB, VertexAttrib4NivARB,  
     VertexAttrib4NubvARB, VertexAttrib4NusvARB, and VertexAttrib4NuivARB  
     protocol encodings, respectively.  v[3] is set to one if it is not  
     specified in the vertex array for the the VertexAttrib4bvARB,  
     VertexAttrib4svARB, VertexAttrib4ivARB, VertexAttrib4ubvARB,  
     VertexAttrib4usvARB, and VertexAttrib4uivARB protocol encodings.  
  
  
homeprevnext Errors
   
    The error INVALID_VALUE is generated by any VertexAttrib*ARB or  
    GetVertexAttrib*ARB command if <index> is greater than or equal to  
    MAX_VERTEX_ATTRIBS_ARB.  
  
    The error INVALID_VALUE is generated by VertexAttribPointerARB or  
    GetVertexAttribPointervARB if <index> is greater than or equal to  
    MAX_VERTEX_ATTRIBS_ARB.  
  
    The error INVALID_VALUE is generated by VertexAttribPointerARB if <size>  
    is not one of 1, 2, 3, or 4.  
  
    The error INVALID_VALUE is generated by VertexAttribPointerARB if <stride>  
    is negative.  
  
    The error INVALID_VALUE is generated by EnableVertexAttribArrayARB or  
    DisableVertexAttribArrayARB if <index> is greater than or equal to  
    MAX_VERTEX_ATTRIBS_ARB.  
  
    The error INVALID_OPERATION is generated by ProgramStringARB if the  
    program string <string> is syntactically incorrect or violates any  
    semantic restriction of the execution environment of the specified program  
    target <target>.  
  
    The error INVALID_OPERATION is generated by BindProgramARB if <program> is  
    the name of a program whose target does not match <target>.  
  
    The error INVALID_VALUE is generated by any ProgramEnvParameter*ARB or  
    GetProgramEnvParameter*ARB command if <index> is greater than or equal to  
    the value of MAX_PROGRAM_ENV_PARAMETERS_ARB corresponding to the program  
    target <target>.  
  
    The error INVALID_VALUE is generated by any ProgramLocalParameter*ARB or  
    GetProgramLocalParameter*ARB command if <index> is greater than or equal  
    to the value of MAX_PROGRAM_LOCAL_PARAMETERS_ARB corresponding to the  
    program target <target>.  
  
    The error INVALID_OPERATION is generated if Begin, RasterPos, or any  
    command that performs an explicit Begin is called when vertex program mode  
    is enabled and the currently bound vertex program object does not contain  
    a valid vertex program.  
  
    The error INVALID_OPERATION is generated by GetVertexAttrib*ARB if <index>  
    is zero and <pname> is CURRENT_VERTEX_ATTRIB_ARB.  
  
  
homeprevnext New State
  
  
Get Value                        Type    Get Command    Initial Value Description         Section       Attribute  
-------------------------------  ------  -------------  ------------- ------------------  ------------  ------------  
VERTEX_PROGRAM_ARB               B       IsEnabled      False         vertex program      2.10          enable  
                                                                      enable  
VERTEX_PROGRAM_POINT_SIZE_ARB    B       IsEnabled      False         program-specified   2.14.3.7      enable  
                                                                      point size mode  
VERTEX_PROGRAM_TWO_SIDE_ARB      B       IsEnabled      False         two-sided color     2.14.3.7      enable  
                                                                      mode  
-                                96+xR4  GetProgramEnv- (0,0,0,0)     program environment 2.14.1        -  
                                         ParameterARB                 parameters  
CURRENT_VERTEX_ATTRIB_ARB        16+xR4  GetVertex-     undefined     generic vertex      2.7           current  
                                         AttribARB                    attributes  
PROGRAM_ERROR_POSITION_ARB       Z       GetIntegerv    -1            last program error  2.14.1        -  
                                                                      position  
PROGRAM_ERROR_STRING_ARB         0+xub   GetString      ""            last program error  2.14.1        -  
                                                                      string  
  
Table X.6.  New Accessible State Introduced by ARB_vertex_program.  
  
  
Get Value                        Type    Get Command    Initial Value Description         Section       Attribute  
-------------------------------  ------  -------------  ------------- ------------------  ------------  ------------  
VERTEX_ATTRIB_ARRAY_ENABLED_ARB  16+xB   GetVertex-     False         vertex attrib       2.8           vertex-array  
                                         AttribARB                    array enable  
VERTEX_ATTRIB_ARRAY_SIZE_ARB     16+xZ   GetVertex-     4             vertex attrib       2.8           vertex-array  
                                         AttribARB                    array size  
VERTEX_ATTRIB_ARRAY_STRIDE_ARB   16+xZ+  GetVertex-     0             vertex attrib       2.8           vertex-array  
                                         AttribARB                    array stride  
VERTEX_ATTRIB_ARRAY_TYPE_ARB     16+xZ4  GetVertex-     FLOAT         vertex attrib       2.8           vertex-array  
                                         AttribARB                    array type  
VERTEX_ATTRIB_ARRAY_             16+xB   GetVertex-     False         vertex attrib       2.8           vertex-array  
    NORMALIZED_ARB                       AttribARB                    array normalized  
VERTEX_ATTRIB_ARRAY_POINTER_ARB  16+xP   GetVertex-     NULL          vertex attrib       2.8           vertex-array  
                                         AttribPointerARB             array pointer  
  
Table X.7.  New Accessible Client State Introduced by ARB_vertex_program.  
  
  
Get Value                        Type   Get Command          Initial Value    Description             Sec       Attrib  
--------------------             -----  -------------------  ---------------  ----------------------  --------  ------  
PROGRAM_BINDING_ARB              Z+     GetProgramivARB      object-specific  bound program name      6.1.12    -  
PROGRAM_LENGTH_ARB               Z+     GetProgramivARB      0                bound program length    6.1.12    -  
PROGRAM_FORMAT_ARB               Z1     GetProgramivARB      PROGRAM_FORMAT_  bound program format    6.1.12    -  
                                                             ASCII_ARB  
PROGRAM_STRING_ARB               ubxn   GetProgramStringARB  (empty)          bound program string    6.1.12    -  
PROGRAM_INSTRUCTIONS_ARB         Z+     GetProgramivARB      0                bound program           6.1.12    -  
                                                                              instructions  
PROGRAM_TEMPORARIES_ARB          Z+     GetProgramivARB      0                bound program           6.1.12    -  
                                                                              temporaries  
PROGRAM_PARAMETERS_ARB           Z+     GetProgramivARB      0                bound program           6.1.12    -  
                                                                              parameter bindings  
PROGRAM_ATTRIBS_ARB              Z+     GetProgramivARB      0                bound program           6.1.12    -  
                                                                              attribute bindings  
PROGRAM_ADDRESS_REGISTERS_ARB    Z+     GetProgramivARB      0                bound program           6.1.12    -  
                                                                              address registers  
PROGRAM_NATIVE_INSTRUCTIONS_ARB  Z+     GetProgramivARB      0                bound program native    6.1.12    -  
                                                                              instructions  
PROGRAM_NATIVE_TEMPORARIES_ARB   Z+     GetProgramivARB      0                bound program native    6.1.12    -  
                                                                              temporaries  
PROGRAM_NATIVE_PARAMETERS_ARB    Z+     GetProgramivARB      0                bound program native    6.1.12    -  
                                                                              parameter bindings  
PROGRAM_NATIVE_ATTRIBS_ARB       Z+     GetProgramivARB      0                bound program native    6.1.12    -  
                                                                              attribute bindings  
PROGRAM_NATIVE_ADDRESS_          Z+     GetProgramivARB      0                bound program native    6.1.12    -  
    REGISTERS_ARB                                                             address registers  
PROGRAM_UNDER_NATIVE_LIMITS_ARB  B      GetProgramivARB      0                bound program under     6.1.12    -  
                                                                              native resource limits  
-                                96+xR4 GetProgramLocal-     (0,0,0,0)        bound program local     2.14.1    -  
                                        ParameterARB                          parameter value  
  
Table X.8.  Program Object State.  Program object queries return attributes of  
the program object currently bound to the program target <target>.  
  
  
Get Value    Type    Get Command   Initial Value  Description              Sec       Attribute  
---------    ------  -----------   -------------  -----------------------  --------  ---------  
-            12+xR4  -             undefined      temporary registers      2.14.3.6  -  
-            8+xR4   -             undefined      vertex result registers  2.14.3.7  -  
             1+xZ1   -             undefined      vertex program           2.14.3.8  -  
                                                  address registers  
  
Table X.9.  Vertex Program Per-vertex Execution State.  All per-vertex  
execution state registers are uninitialized at the beginning of program  
execution.  
  
  
Get Value                          Type      Get Command      Initial Value  Description          Sec      Attribute  
------------------------------     --------  --------------   -------------  -------------------  -------  ---------  
CURRENT_MATRIX_ARB                 m*n*xM^4  GetFloatv        Identity       current matrix       6.1.2    -  
CURRENT_MATRIX_STACK_DEPTH_ARB     m*Z+      GetIntegerv      1              current stack depth  6.1.2    -  
  
Table X.10.  Current matrix state where m is the total number of matrices  
including texture matrices and program matrices and n is the number of  
matrices on each particular matrix stack.  Note that this state is aliased  
with existing matrix state.  
  
  
homeprevnext New Implementation Dependent State
                                                              Minimum  
Get Value                            Type    Get Command      Value       Description             Sec           Attrib  
-----------------------------------  ----    ---------------  ----------  --------------------    ------------  ------  
MAX_PROGRAM_ENV_PARAMETERS_ARB       Z+      GetProgramivARB  96          maximum program         2.14.1        -  
                                                                          env parameters  
MAX_PROGRAM_LOCAL_PARAMETERS_ARB     Z+      GetProgramivARB  96          maximum program         2.14.1        -  
                                                                          local parameters  
MAX_PROGRAM_MATRICES_ARB             Z+      GetIntegerv      8 (not to   maximum number of       2.14.6        -  
                                                              exceed 32)  program matrices  
MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB   Z+      GetIntegerv      1           maximum program         2.14.6        -  
                                                                          matrix stack depth  
MAX_PROGRAM_INSTRUCTIONS_ARB         Z+      GetProgramivARB  128         maximum program         6.1.12        -  
                                                                          instructions  
MAX_PROGRAM_TEMPORARIES_ARB          Z+      GetProgramivARB  12          maximum program         6.1.12        -  
                                                                          temporaries  
MAX_PROGRAM_PARAMETERS_ARB           Z+      GetProgramivARB  96          maximum program         6.1.12        -  
                                                                          parameter bindings  
MAX_PROGRAM_ATTRIBS_ARB              Z+      GetProgramivARB  16          maximum program         6.1.12        -  
                                                                          attribute bindings  
MAX_PROGRAM_ADDRESS_REGISTERS_ARB    Z+      GetProgramivARB  1           maximum program         6.1.12        -  
                                                                          address registers  
MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB  Z+      GetProgramivARB  -           maximum program native  6.1.12        -  
                                                                          instructions  
MAX_PROGRAM_NATIVE_TEMPORARIES_ARB   Z+      GetProgramivARB  -           maximum program native  6.1.12        -  
                                                                          temporaries  
MAX_PROGRAM_NATIVE_PARAMETERS_ARB    Z+      GetProgramivARB  -           maximum program native  6.1.12        -  
                                                                          parameter bindings  
MAX_PROGRAM_NATIVE_ATTRIBS_ARB       Z+      GetProgramivARB  -           maximum program native  6.1.12        -  
                                                                          attribute bindings  
MAX_PROGRAM_NATIVE_ADDRESS_          Z+      GetProgramivARB  -           maximum program native  6.1.12        -  
    REGISTERS_ARB                                                         address registers  
  
Table X.11.  New Implementation-Dependent Values Introduced by  
ARB_vertex_program.  Values queried by GetProgramivARB require a <pname> of  
VERTEX_PROGRAM_ARB.  
  
  
homeprevnext Revision History
  
    Rev.    Date    Author    Changes  
    ----  --------  --------  --------------------------------------------  
    46    07/25/07  mjk       Document how the ARB and NV generic arrays  
                              interact.  This documents NVIDIA's  
                              long-standing implemented behavior.  
  
    45    09/27/04  pbrown    Fixed GLX protocol, removing the unused <pname>  
                              parameters for GetProgram{Env,Local}Parameter  
                              [df]vARB, leaving an unused CARD32 in its place.  
                              This was an error when propogating  
                              NV_vertex_program protocol, which did have a  
                              <pname> parameter.  
  
    44    09/12/03  pbrown    Fixed opcode table entry for "ARL" -- it takes a  
                              scalar operand as specified in the grammar.  
  
    43    08/17/03  pbrown    Fixed a couple minor typos (missing quotes)  
                              in the grammar.  
  
    42    05/01/03  pbrown    Clarified the handling of color sum; old text  
                              suggested that COLOR_SUM controlled the  
                              operation even when doing separate specular  
                              lighting.  
  
    41    04/18/03  pbrown    Add a couple overlooked contributors.  
  
    40    03/03/03  pbrown    Fixed list of immediate-mode VertexAttrib  
                              functions in Section 2.7 -- there are no  
                              normalized float functions (e.g.,   
                              VertexAttrib4Nfv).  Clarified issue (42)  
                              describing how point size is handled in vertex  
                              program mode.  
  
    39    01/31/03  pbrown    Fixed minor bug in the description of vertex  
                              array state kept by the GL -- normalization  
                              flags were omitted from the text (but were in  
                              the state tables).  
  
    38    01/08/03  pbrown    Fixed bug where "state.matrix.mvp" was specified  
                              incorrectly -- it should be P*M0 rather than  
                              M0*P.  
  
    37    12/23/02  pbrown    Fixed minor typos.  Fixed state table bug where   
                              CURRENT_VERTEX_ATTRIB_ARB was incorrectly called  
                              CURRENT_ATTRIB_ARB.  
  
    36    09/09/02  pbrown    Fixed incorrect example of matrix row bindings  
                              (and transposition).  Small wording/typo fixes.  
  
    35    08/27/02  pbrown    Fixed several minor typos.  Documented that a  
                              program string should not include a null  
                              terminator in its first <len> characters.  Fixed  
                              dangling reference in <paramMultipleItem>  
                              grammar rule.  Fix incorrect wording in  
                              computation of state.light.half vector.  
                              Documented that the inverse of a singular matrix  
                              is undefined.  Clarified that native  
                              instructions can include additions due to  
                              emulation of features not supported natively.  
                              Documented that LG2 produces undefined results  
                              with zero or negative inputs.  Clarified that  
                              POW may be a LOG/MUL/EXP sequence, but isn't  
                              necessarily so.  Disallowed multiple modelview  
                              matrix syntax if ARB_vertex_blend or  
                              EXT_vertex_weighting is unsupported.  Fixed  
                              state table query function for attribute array  
                              enables.  Added missing state table entry for  
                              PROGRAM_UNDER_NATIVE_LIMITS_ARB.  
  
    34    07/19/02  pbrown    Fixed typo in ArrayElement pseudo-code.  
  
    33    07/17/02  pbrown    Fixed bug in the <stateLModProperty> grammar  
                              rule.  Fixed documentation to indicate that  
                              Enable/DisableVertexAttribArray are not display  
                              listable.  
  
    31    07/15/02  pbrown    Fixed <SWZ_instruction> grammar rule to match  
                              the spec language -- base operand negation  
                              doesn't apply, since you can independently  
                              negate components.  Modified "XPD" instruction  
                              to eliminate the implicit masking of the "w"  
                              component; slight efficiency gain for some SW  
                              implementations.  Modified "scenecolor" binding  
                              to pass the diffuse alpha instead of the ambient  
                              alpha; the former is more useful.  
  
    30    07/02/02  pbrown    Minor wording fixes.  
  
    29    06/21/02  pbrown    Mostly minor bug fixes from reviewer feedback;  
                              also added one new item approved at ARB meeting.  
  
                              Additions:  Added a "lightmodel.*.scenecolor"  
                              holding lit color containing the composite  
                              lighting result ignoring individual lights --  
                              i.e., from only emissive materials and the light  
                              model.  Added GLX protocol.  
  
                              Minor changes:  Numerous minor typo and wording  
                              fixes.  Added missing vertex array types to  
                              vertex array size/type/normalized table.  Added  
                              missing description of ambient light model color  
                              binding.  Removed several references to language  
                              features long since deleted.  Documented that  
                              POW is not necessarily implemented as  
                              LOG/MUL/EXP.  Fixed a couple minor errata in the  
                              EXT_vertex_shader interaction section.  Added a  
                              list of reserved keywords.  
  
    28    06/16/02  pbrown    Minor updates based on feedback given on  
                              versions 26 and 27.  
  
                              Additions:  Added section on EXT_vertex_shader  
                              interaction, provided by ATI.  
  
                              Minor changes:  Minor grammar and readability  
                              fixes.  Fixed several incomplete definitions.  
                              Removed "GL" and "gl" prefixes from several  
                              enumerants and function names to match spec  
                              conventions.  Clarified the precision issue on  
                              EX2/LG2.  Added missing functions that take  
                              VERTEX_PROGRAM_ARB.  Clarified component  
                              normalization on vertex arrays.  Clarified  
                              clipping section to note that user clipping is  
                              done with position invariant programs.  
                              Clarified the handling of program zero in  
                              BindProgramARB.  Fixed a couple incorrect  
                              grammar rules.  Fixed incorrect grammar  
                              references in description of vertex program  
                              parameter array accesses.  Documented that the  
                              SWZ instruction doesn't take "normal" swizzle  
                              and negation modifiers, since it already has  
                              some.  Clarified some NV_vertex_program  
                              interactions.  
  
    27    06/07/02  pbrown    Minor update based on ARB_vertex_program sample  
                              implementation work.  
  
                              Changes:  Changed fog coordinate attribute and  
                              result binding name to "fogcoord" (was "fog").  
                              Rearranged grammar based on sample  
                              implementation verification.  There might be a  
                              minor fix or two stuck in there.  
  
    26    06/04/02  pbrown    Spec checkpoint published on the working group  
                              web site.  Resolves most of the remaining open  
                              issues.   
  
                              Deletions:  Removed the ability to bind the  
                              color matrix (from ARB_imaging).  
  
                              Changes:  Resolved the handling of vertex  
                              attribute zero (it always specifies a vertex, in  
                              program mode or not).  Resolved the handling of  
                              generic and conventional vertex attribute arrays  
                              (they are always sent, although they also have  
                              "undefined aliasing" behavior).  Default values  
                              of generic attributes are undefined, to  
                              accommodate aliasing and non-aliasing  
                              implementations.  Added pseudocode to document  
                              the processing of ArrayElement.  Moved program  
                              object language into the vertex program section.  
                              Renamed the fog coordinate attribute and result  
                              binding to "fogcoord".  Added missing  
                              documentation of the agreed-upon semantic  
                              restriction that programs can't bind  
                              conventional / generic attribute pairs that may  
                              alias.  Added documentation of what happens when  
                              multiple contexts share program objects  
                              Disallowed queries of generic attribute zero.  
  
                              Fixes:  Fixed prototype for VertexAttrib4Nub.    
  
                              Minor Changes:  Minor typo and language  
                              fixes. Added guidelines for future  
                              programmability extensions.  Added several  
                              missing grammar rules.  
  
    25    05/30/02  pbrown    Spec checkpoint published on the working group  
                              web site.  
  
                              Additions:  Add "DPH" (dot product homogeneous)  
                              instruction.  Added the ability to query the  
                              current matrix in transposed form.  Assigned  
                              enumerant values for program matrices.  Added  
                              the ability bind selected rows of a matrix.  
                              Added ability to bind matrix palette matrices.  
  
                              Changes:  Renamed PROGRAM_NAME_ARB to  
                              PROGRAM_BINDING_ARB.  Specifying the number of  
                              elements in parameter arrays is now optional,  
                              but compilation will fail if the specified count  
                              does not match.  Programs performing  
                              out-of-bounds array accesses using absolute  
                              addressing will now fail to load.  Allow "$" in  
                              token names.  
  
                              Minor changes:  Completed scrub of the issues  
                              and error list.  Added new issues about reserved  
                              keywords, identifier characters, and parsing of  
                              floating-point constants in programs.  
                              Miscellaneous typo fixes.  Updated the grammar  
                              to include light products and half angles, moved  
                              material properties from per-vertex to parameter  
                              bindings, and a few other miscellaneous fixes.  
                              Simplified the matrix binding table.  Modified  
                              the color sum portion of the spec to explicitly  
                              add R,G,B only.  Removed several incorrect  
                              errors.  Fixed program object state table.  
  
    24    05/21/02  pbrown    Spec checkpoint published on the working group  
                              web site.  
  
                              Deletions:  Removed the semantic requirement  
                              that vertex programs write a vertex position,  
                              per working group resolution.  
                                
                              Minor changes:  Cleaned up cruft in a number of  
                              issues; many more to go.  Added several issues.  
                              Documented that VertexAttrib functions are  
                              allowed inside Begin/End pairs.  Changed default  
                              initialization values of generic attributes to  
                              accommodate attribute aliasing.  Documented that  
                              point sizes and fog coordinates computed by  
                              vertex programs are clipped during primitive  
                              clipping.  Documented that vertex program  
                              behavior is undefined in color index mode.  
  
    23    05/21/02  pbrown    Spec checkpoint.  More changes from working  
                              group deliberations.  
  
                              Additions:  Added vertex materials as allowed  
                              program parameter bindings.  Allow programs to  
                              use vertex attribute binding names, program  
                              parameter binding names, result variable binding  
                              names, and constants in executable statements,  
                              resulting in implicit bindings.  Added support  
                              for binding a single row of a matrix.  Added  
                              support for binding precomputed light/material  
                              products.  Added restriction that a single GL  
                              state vector can't be bound multiple times in  
                              two separate arrays accessed with relative  
                              addressing.  Added new section documenting the  
                              various resource limits, and introducting the  
                              idea of "native" resource limits and counts.  
  
                              Deletions:  Removed vertex materials as allowed  
                              vertex attribute bindings.  
  
                              Minor changes:  Added more names to the  
                              contributors list.  Updated issues concerning  
                              undefined aliasing.  Moved NV_vertex_program  
                              related issues to the NV_vertex_program  
                              interaction sections.  Updated NV_vertex_program  
                              interactions.  Updated lighting example using  
                              new derived state bindings.  Clarified that  
                              "!!ARBvp1.0" is not a token in the grammar and  
                              that programs are parsed beginning immediately  
                              after the header string.  Added text to explain  
                              all attribute, program parameter, and result  
                              bindings instead of depending on binding table  
                              interpretations.  Broke the large program  
                              parameter binding table into several smaller  
                              tables, organized by function.  Documented that  
                              the queryable program error string may contain  
                              warnings when a program loads successfully, and  
                              that a queried program error string is  
                              guaranteed to remain constant only until the  
                              next program load attempt.  Added PROGRAM_NAME  
                              query to the appropriate state table.  
  
    22    05/20/02  pbrown    Spec checkpoint.  More changes from working  
                              group deliberations.   
  
                              Added functionality:  Assigned enumerant values.  
                              Added "undefined (vertex attribute) aliasing"  
                              language, where setting a generic attribute  
                              leaves a conventional one undefined, and vice  
                              versa.  Added support for matrix indices from  
                              ARB_matrix_palette.  Added default program  
                              object zero.  Added support for simple named  
                              variable aliasing.  Added queries of API-level  
                              and "native" resources used by a program and  
                              their corresponding limits.  Added general query  
                              to determine if a program fits in native limits.  
  
                              Removed functionality:  Removed extension string  
                              entry for position-invariant programs (now  
                              mandatory).  
  
                              Modified functionality:  GetProgram and  
                              GetProgramString now take a target instead of a  
                              program name.  Default values for 3 generic  
                              attributes are changed for consistent aliasing.  
                              Added 1/(end-start) binding for fog parameters.  
                              Added precomputed infinite light/viewer half  
                              angle binding.  ProgramString takes a "void *"  
                              instead of a "ubyte *".  
  
                              Minor Changes:  Clarified key terms for the  
                              extension.  Documented that user clipping is not  
                              supported in the base extension.  Added warnings  
                              on a couple pitfalls from uninitalized result  
                              registers.  Document that EXT_vertex_weighting  
                              and ARB_vertex_blend use the same weight.  
                              Cleaned up bindings for 4-component colors for  
                              cases where only three components are used.  
                              Documented the implicit absolute value operation  
                              on the LOG instruction.  Renamed query token for  
                              querying generic vertex attribute array enables.  
                              Renamed and relocated vertex program binding  
                              query.  Added language to Section 2.6.  Changed  
                              syntax to bind a range of the environment or  
                              local paramater array to use double dots ("..").  
                              Clarified what happens on a weight binding using  
                              more weights than an implementation supports.  
                              Clarified the component selection pseudocode for  
                              scalar operand loads.  Clarified what happens to  
                              vertex program results during primitive  
                              assembly.  Fixed a number of errors in the state  
                              tables.  
  
    21    04/29/02  pbrown    More changes from working group deliberations.  
  
                              Added functionality:  Added "FLR", "FRC", "POW",  
                              and "XPD" (cross product) instructions.  Added  
                              functions to enable/disable generic attribute  
                              arrays.  Added query of a program error string.  
                              Added "format" enum argument to ProgramStringARB  
                              to provide for possible programs not using ASCII  
                              text.  Added new enums to permit different  
                              limits for overall numbers of program  
                              environment and local parameters and the number  
                              of parameters that can be bound by a program.  
  
                              Removed functionality:  Removed support for  
                              evaluators for generic attributes.  Removed  
                              support for program residency management.  
                              Removed support for user clipping in standard  
                              vertex programs.  Removed functionality to set  
                              more than one program environment parameter at  
                              once.  
  
                              Issues/Changes:  Resolved set of immediate mode  
                              VertexAttrib functions.  Combined parameter  
                              bindings for several groups of related GL state.  
                              Resolved user clipping issue by disallowing  
                              except for position invariant programs.  
                              Resolved limits for array relative offsets.  
                              GenProgramsARB and DeleteProgramsARB will use  
                              texture object model.  Program environment  
                              parameters will not be pushed/popped.  
  
                              Bug fixes:  Fixed vertex attribute index  
                              prototypes (should be uint instead of int).  
                              Fixed tokens used to query generic attribute  
                              state (should have VERTEX prefixes).  Fixed  
                              documentation of the alpha component of material  
                              colors.  Fixed documentation of initial state  
                              for vertex program objects.  
  
                              Temporarily removed dated GLX protocol language  
                              (will restore in one pass after resolving  
                              remaining issues).  
  
    20    04/17/02  pbrown    Clarify the meaning of individual components of  
                              program parameters where the component mapping  
                              is not obvious from the mapping table.  
                                
    18    04/15/02  pbrown    Update spec to reflect issues resolved by the  
                              working group on 4/11.  
  
                              Started using "program matrix" terminology --  
                              was "tracking matrix".    
  
                              Address register variables must now be declared.  
                              The number of address registers can be queried.  
                              Only 1-component address registers are currently  
                              supported.    
  
                              VertexAttribPointer takes a separate argument to  
                              indicate normalized data, now called  
                              "normalized" (was "normalize").    
  
                              ProgramString and functions to set and query  
                              local parameters all take a <target> and refer  
                              to the currently bound program (previously took  
                              a program number).  Have not touched other  
                              somewhat related issues (e.g., is there a  
                              program object zero?).  
                                
                              Added COLOR_SUM enable (taken directly from  
                              EXT_secondary_color) for completeness and a  
                              few updates to EXT_secondary_color  
                              interactions.  
                                
                              Fixed cut-and-paste error in specification of  
                              the clip-space user clip dot product.  
                                
                              Documented special-case arithmetic for ADD, MAD,  
                              and MUL.  
  
                              Eliminated some wordiness in DP3 and DP4  
                              instruction pseudo-code.  
  
                              Minor changes not from working group:  More  
                              verbose documentation on the user clipping  
                              issue.  More detail on other opcode candidates.  
                              Removed redundant color material issue.  Minor  
                              fixes to error roundup (not complete) and to  
                              state tables to reflect that most program  
                              execution variables are initially undefined.  
  
    17    04/08/02  pbrown    Issues:  Enumerated other candidates for  
                              consideration in the instruction set -- there  
                              may be more that I missed.  Added a description  
                              of some of the considerations on how color  
                              material should be treated.  Added issues on the  
                              name of the program matrices, the number of MVP  
                              matrices, and where variable declarations   
                              can be done.  Added numbers to all spec issues.  
                              Fixed lighting example (issue 74) so it  
                              compiles, and so that the half vector is  
                              properly normalized.  
                                
                              Grammar:  Eliminated stale hardwired temporary,  
                              parameter array, and result register names  
                              (R<n>, c[<n>], and o[...]).  Should have been  
                              deleted going from revision 5 to revision 12.  
                              Added missing program matrix bindings to the  
                              grammar.  Eliminated state material-as-parameter  
                              bindings.  Fixed texgen paramete bindings, which  
                              should have had both "eye" and "object" planes.  
                              Added separate address register write masks and  
                              selectors to reflect the current single-  
                              component address register restriction.  Added  
                              an array[A0.x] rule -- before, you erroneously  
                              had to add or subtract a constant.  Modified SWZ  
                              so that the register being swizzled can't take a  
                              conventional swizzle suffix, too.  
  
                              Also reorganized grammar to closely mirror the  
                              sample implementation, consolidating a number of  
                              redundant rules.  Also fixed several bugs  
                              found by the implementation.  
  
                              Documentation changes to "LIT" to use the right  
                              variable name and also indicate that 0^0=1.  
                              Fixed the computation of result.y in the "LOG"  
                              instruction.  
  
                              Other:  Added dependency on ARB_imaging.  Added  
                              notation of Microsoft's IP claims.  Fixed name  
                              of MAX_VERTEX_PROGRAM_TEMPORARIES_ARB.  
  
                              A few minor typo fixes.  
  
    12    03/11/02  pbrown    Modified spec to reflect decisions made at  
                              the March 2002 ARB meeting.  Distributed  
                              to the OpenGL participants list.  
  
    5     03/03/02  pbrown    Distributed to the ARB prior to March 2002  
                              ARB meeting.  
                              ARB meeting.  
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.