• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_vertex_attrib_binding
4
5Name Strings
6
7    GL_ARB_vertex_attrib_binding
8
9Contact
10
11    Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com)
12
13Contributors
14
15    Pat Brown, NVIDIA
16    Bruce Merry
17    Mark Kilgard
18
19Notice
20
21    Copyright (c) 2012-2013 The Khronos Group Inc. Copyright terms at
22        http://www.khronos.org/registry/speccopyright.html
23
24Specification Update Policy
25
26    Khronos-approved extension specifications are updated in response to
27    issues and bugs prioritized by the Khronos OpenGL Working Group. For
28    extensions which have been promoted to a core Specification, fixes will
29    first appear in the latest version of that core Specification, and will
30    eventually be backported to the extension document. This policy is
31    described in more detail at
32        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
33
34Status
35
36    Complete.
37    Approved by the ARB on 2012/06/12.
38
39Version
40
41    Last Modified Date: October 22, 2013
42    Revision: 5
43
44    EXT_direct_state_access interacton added with revision 3.
45
46Number
47
48    ARB Extension #125
49
50Dependencies
51
52    This extension is written against the OpenGL 4.2 Core specification.
53
54    NV_vertex_buffer_unified_memory affects the definition of this
55    extension.
56
57    EXT_direct_state_access affects the definition of this extension.
58
59    The Compatibility specification affects the definition of this extension.
60
61Overview
62
63    OpenGL currently supports (at least) 16 vertex attributes and 16 vertex
64    buffer bindings, with a fixed mapping between vertex attributes and
65    vertex buffer bindings. This extension allows the application to change
66    the mapping between attributes and bindings, which can make it more
67    efficient to update vertex buffer bindings for interleaved vertex formats
68    where many attributes share the same buffer.
69
70    This extension also separates the vertex binding update from the vertex
71    attribute format update, which saves applications the effort of
72    redundantly specifying the same format state over and over.
73
74    Conceptually, this extension splits the state for generic vertex attribute
75    arrays into:
76
77    - An array of vertex buffer binding points, each of which specifies:
78
79      - a bound buffer object,
80
81      - a starting offset for the vertex attribute data in that buffer object,
82
83      - a stride used by all attributes using that binding point, and
84
85      - a frequency divisor used by all attributes using that binding point.
86
87    - An array of generic vertex attribute format information records, each of
88      which specifies:
89
90      - a reference to one of the new buffer binding points above,
91
92      - a component count and format, and a normalization flag for the
93        attribute data, and
94
95      - the offset of the attribute data relative to the base offset of each
96        vertex found at the associated binding point.
97
98
99New Procedures and Functions
100
101    void BindVertexBuffer(uint bindingindex, uint buffer, intptr offset,
102                          sizei stride);
103
104    void VertexAttribFormat(uint attribindex, int size, enum type,
105                            boolean normalized, uint relativeoffset);
106    void VertexAttribIFormat(uint attribindex, int size, enum type,
107                             uint relativeoffset);
108    void VertexAttribLFormat(uint attribindex, int size, enum type,
109                             uint relativeoffset);
110
111    void VertexAttribBinding(uint attribindex, uint bindingindex);
112
113    void VertexBindingDivisor(uint bindingindex, uint divisor);
114
115    When EXT_direct_state_access is present:
116
117        void VertexArrayBindVertexBufferEXT(uint vaobj, uint bindingindex, uint buffer, intptr offset,
118                                            sizei stride);
119
120        void VertexArrayVertexAttribFormatEXT(uint vaobj, uint attribindex, int size, enum type,
121                                boolean normalized, uint relativeoffset);
122        void VertexArrayVertexAttribIFormatEXT(uint vaobj, uint attribindex, int size, enum type,
123                                 uint relativeoffset);
124        void VertexArrayVertexAttribLFormatEXT(uint vaobj, uint attribindex, int size, enum type,
125                                 uint relativeoffset);
126
127        void VertexArrayVertexAttribBindingEXT(uint vaobj, uint attribindex, uint bindingindex);
128
129        void VertexArrayVertexBindingDivisorEXT(uint vaobj, uint bindingindex, uint divisor);
130
131New Tokens
132
133    Accepted by the <pname> parameter of GetVertexAttrib*v:
134
135        VERTEX_ATTRIB_BINDING                           0x82D4
136        VERTEX_ATTRIB_RELATIVE_OFFSET                   0x82D5
137
138    Accepted by the <target> parameter of GetBooleani_v, GetIntegeri_v,
139    GetFloati_v, GetDoublei_v, and GetInteger64i_v:
140
141        VERTEX_BINDING_DIVISOR                          0x82D6
142        VERTEX_BINDING_OFFSET                           0x82D7
143        VERTEX_BINDING_STRIDE                           0x82D8
144        VERTEX_BINDING_BUFFER                           0x8F4F
145
146    Accepted by the <pname> parameter of GetIntegerv, ...
147
148        MAX_VERTEX_ATTRIB_RELATIVE_OFFSET               0x82D9
149        MAX_VERTEX_ATTRIB_BINDINGS                      0x82DA
150
151
152Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
153
154    Modify Section 2.8, "Vertex Arrays"
155
156    Vertex data are placed into arrays that are stored in the server's address
157    space (described in section 2.9). Blocks of data in these arrays may then
158    be used to specify multiple geometric primitives through the execution of
159    a single GL command. The client may specify up to the value of
160    MAX_VERTEX_ATTRIBS arrays to store one or more generic vertex attributes.
161    A generic vertex attribute array is described by an index into an array of
162    vertex buffer bindings which contain the vertex data and state describing
163    how that data is organized.
164
165    The commands
166
167      [Compatibility profile only: Keep the named attribute *Pointer
168                                   commands in this list]
169
170      void VertexAttribFormat(uint attribindex, int size, enum type,
171                              boolean normalized, uint relativeoffset);
172      void VertexAttribIFormat(uint attribindex, int size, enum type,
173                               uint relativeoffset);
174
175    describe the organizations of vertex arrays. For each command, <type>
176    specifies the data type of the values stored in the array. <size>
177    indicates the number of values per vertex that are stored in the array as
178    well as their component ordering. Table 2.5 indicates the allowable values
179    for <size> and <type> (when present). For <type> the values BYTE, SHORT,
180    INT, FIXED, FLOAT, HALF_FLOAT, and DOUBLE indicate types byte, short, int,
181    fixed, float, half, and double, respectively; the values UNSIGNED_BYTE,
182    UNSIGNED_SHORT, and UNSIGNED_INT indicate types ubyte, ushort, and uint,
183    respectively; and the values INT_2_10_10_10_REV and UNSIGNED_INT_2_-
184    10_10_10_REV, indicating respectively four signed or unsigned elements
185    packed into a single uint, both correspond to the term <packed> in that
186    table. <relativeoffset> is a byte offset of the first element relative
187    to the start of the vertex buffer binding this attribute fetches from.
188
189    An INVALID_VALUE error is generated if <size> is not one of the values
190    allowed in table 2.5 for the corresponding command.
191
192    An INVALID_OPERATION error is generated under any of the following
193    conditions:
194     - if no vertex array object is currently bound (see section 2.10);
195     - <size> is BGRA and <type> is not UNSIGNED_BYTE, INT_2_10_10_10_REV or
196       UNSIGNED_INT_2_10_10_10_REV;
197     - <type> is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, and <size>
198       is neither 4 or BGRA;
199     - <size> is BGRA and <normalized> is FALSE;
200
201    An INVALID_VALUE error is generated if <relativeoffset> is larger than
202    the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
203
204    The <attribIndex> parameter in the VertexAttribFormat and VertexAttribIFormat
205    commands identifies the generic vertex attribute array being described.
206    The error INVALID_VALUE is generated if index is greater than or equal to
207    the value of MAX_VERTEX_ATTRIBS. Generic attribute arrays with integer
208    type arguments can be handled in one of three ways: converted to float by
209    normalizing to [0, 1] or [-1, 1] as described in equations 2.1 and 2.2,
210    respectively; converted directly to float, or left as integers. Data for
211    an array specified by VertexAttribPointer will be converted to floating-
212    point by normalizing if <normalized> is TRUE, and converted directly to
213    floating-point otherwise. Data for an array specified by
214    VertexAttribIFormat will always be left as integer values; such data are
215    referred to as pure integers.
216
217    The command
218
219      void BindVertexBuffer(uint bindingindex, uint buffer, intptr offset,
220                            sizei stride);
221
222    binds a buffer indicated by <buffer> to the vertex buffer bind point
223    indicated by <bindingindex>, and sets the <stride> between elements
224    and <offset> (in basic machine units) of the first element in the buffer.
225    The error INVALID_VALUE is generated if <stride> or <offset> are negative.
226    Otherwise pointers to the ith and (i + 1)st elements of an array differ
227    by stride basic machine units (typically unsigned bytes), the pointer to
228    the (i + 1)st element being greater. An INVALID_OPERATION error is
229    generated if no vertex array object is bound. If <buffer> is zero, any
230    buffer object attached to this bindpoint is detached. An INVALID_VALUE
231    error is generated if <bindingindex> is greater than the value of
232    MAX_VERTEX_ATTRIB_BINDINGS.
233      [Core profile only:]
234    An INVALID_OPERATION error is generated if buffer is not zero or a
235    name returned from a previous call to GenBuffers, or if such a name
236    has since been deleted with DeleteBuffers.
237
238    The association between a vertex attribute and the vertex buffer binding
239    used by that attribute is set by the command
240
241      void VertexAttribBinding(uint attribindex, uint bindingindex);
242
243    <attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
244    <bindingindex> must be less than the value of MAX_VERTEX_ATTRIB_BINDINGS,
245    otherwise the error INVALID_VALUE is generated. An INVALID_OPERATION error
246    is generated if no vertex array object is bound.
247
248    Modify Table 2.5 to add the command VertexAttribFormat to the first row
249    and VertexAttribIFormat to the second row.
250
251    The one, two, three, or four values in an array that correspond to a
252    single vertex comprise an array element. When size is BGRA, it indicates
253    four values. The values within each array element are stored sequentially
254    in memory. However, if size is BGRA, the first, second, third, and fourth
255    values of each array element are taken from the third, second, first, and
256    fourth values in memory respectively.
257        [Compatibility profile only:]
258    For each *Pointer command, <pointer> specifies the location in
259    memory of the first value of the first element of the array being
260    specified.
261
262    The command
263
264      void VertexAttribLFormat(uint attribindex, int size, enum type,
265                               uint relativeoffset);
266
267    specifies state for a generic vertex attribute array associated with a
268    shader attribute variable declared with 64-bit double precision components.
269    <type> must be DOUBLE. <attribindex> and <size> behave as defined in all
270    other VertexAttrib*Format commands; <size> may be one, two, three or four.
271
272    Each component of an array specified by VertexAttribLFormat will be
273    encoded into one or more generic attribute components as specified for the
274    VertexAttribL* commands in section 2.7. The error INVALID_VALUE is
275    generated if <attribindex> is greater than or equal to the value of
276    MAX_VERTEX_ATTRIBS.
277
278    The commands
279
280      void VertexAttribPointer(uint index, int size, enum type,
281                               boolean normalized, sizei stride,
282                               const void *pointer);
283      void VertexAttribIPointer(uint index, int size, enum type,
284                                sizei stride, const void *pointer);
285      void VertexAttribLPointer(uint index, int size, enum type,
286                                sizei stride, const void *pointer);
287
288    control vertex attribute state, a vertex buffer binding, and the mapping
289    between a vertex attribute and a vertex buffer binding. They are
290    equivalent to (assuming no errors are generated):
291
292      if (no buffer is bound to ARRAY_BUFFER and pointer != NULL) {
293        generate INVALID_OPERATION;
294      }
295      VertexAttrib*Format(index, size, type, {normalized, }, 0);
296      VertexAttribBinding(index, index);
297      if (stride != 0) {
298        effectiveStride = stride;
299      } else {
300        compute effectiveStride based on size/type;
301      }
302      VERTEX_ATTRIB_ARRAY_STRIDE[index] = stride;
303      // VERTEX_BINDING_STRIDE will be set to effectiveStride
304      // by BindVertexBuffer.
305      BindVertexBuffer(index, <buffer bound to ARRAY_BUFFER>,
306                       (char *)pointer - (char *)NULL, effectiveStride);
307
308    If <stride> is specified as zero, then array elements are stored
309    sequentially.
310
311    An individual generic vertex attribute array is
312    enabled or disabled by calling one of
313
314      void EnableVertexAttribArray(uint index);
315      void DisableVertexAttribArray(uint index);
316
317    where <index> identifies the generic vertex attribute array to enable or
318    disable. An INVALID_VALUE error is generated if <index> is greater than or
319    equal to MAX_VERTEX_ATTRIBS.
320
321    An INVALID_OPERATION error is generated if no vertex array object is
322    bound.
323
324    The command
325
326      void VertexBindingDivisor(uint bindingindex, uint divisor);
327
328    modifies the rate at which generic vertex attributes advance when
329    rendering multiple instances of primitives in a single draw call. If
330    <divisor> is zero, the attributes using the buffer bound to <bindingindex>
331    advance once per vertex. If <divisor> is non-zero, the attributes advance
332    once per <divisor> instances of the set(s) of vertices being rendered. An
333    attribute is referred to as <instanced> if the corresponding <divisor>
334    value is non-zero.
335
336    An INVALID_VALUE error is generated if <bindingindex> is greater than or
337    equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.
338
339    An INVALID_OPERATION error is generated if no vertex array object is
340    bound.
341
342    The command
343
344      void VertexAttribDivisor(uint index, uint divisor);
345
346    is equivalent to (assuming no errors are generated):
347
348      VertexAttribBinding(index, index);
349      VertexBindingDivisor(index, divisor);
350
351    An INVALID_VALUE error is generated if <attribindex> is greater than or
352    equal to the value of MAX_VERTEX_ATTRIBS.
353
354
355    Modify Section 2.8.3, "Drawing Commands"
356
357    For any vertex attribute whose divisor is non-zero as set by
358    VertexBindingDivisor, the value "baseinstance" is used to determine the
359    element of the enabled instanced attribute arrays that will be transferred
360    for all vertices transferred by this function.
361
362    ...
363
364    Those attributes that have divisor N where N is other than zero (as
365    specified by VertexBindingDivisor) advance once every N instances.
366
367    ...
368
369    If an enabled vertex attribute array is instanced (it has a non-zero
370    binding divisor as specified by VertexAttribBinding and
371    VertexBindingDivisor), the element that is transferred to the GL is given
372    by:
373
374      floor(instance/divisor) + baseinstance
375
376    ...
377
378    If the number of supported generic vertex attributes (the value of MAX_-
379    VERTEX_ATTRIBS) is <n> and the number of vertex attribute bindings (the
380    value of MAX_VERTEX_ATTRIB_BINDINGS) is <k>, then the state required to
381    implement vertex arrays consists of <n> boolean values (enables), <n>
382    memory pointers, <n> integer stride values (VERTEX_ATTRIB_ARRAY_STRIDE),
383    <n> symbolic constants representing array types, <n> integers representing
384    values per element, <n> boolean values indicating normalization, <n>
385    boolean values indicating whether the attribute values are pure integers,
386    <k> integers representing vertex attribute divisors, <n> integer vertex
387    attribute binding indices, <n> integer relative offsets, <k> integer stride
388    values (VERTEX_BINDING_STRIDE), <k> 64-bit integer buffer offsets, and an
389    unsigned integer representing the restart index.
390
391    In the initial state, the boolean values are each false, the memory
392    pointers are each NULL, the VERTEX_ATTRIB_ARRAY_STRIDE strides are each
393    zero, the array types are each FLOAT, the integers representing values per
394    element are each four, the normalized and pure integer flags are each
395    false, the divisors are each zero, the vertex attribute binding indices
396    are <i> for attribute <i>, the relative offsets are each zero, the
397    VERTEX_BINDING_STRIDE values are each 16, the buffer offsets are each zero,
398    and the restart index is zero.
399
400
401    Modify Section 2.9.6, "Vertex Arrays in Buffer Objects"
402
403    When an array is sourced from a buffer object, the vertex attribute's
404    VERTEX_ATTRIB_BINDING indicates which vertex buffer binding is used. The
405    sum of the attribute's VERTEX_ATTRIB_RELATIVE_OFFSET and the vertex
406    buffer binding's VERTEX_BINDING_OFFSET is used as the offset (in basic
407    machine units) of the first element in that buffer's data store.
408
409    (Compatibility Only) Add to the final paragraph:
410
411    Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state.
412    That is, the logic for computing the address of the base of a vertex array
413    is:
414
415        bindingIndex = VERTEX_ATTRIB_BINDING[attribIndex];
416        buffer = VERTEX_BINDING_BUFFER[bindingIndex];
417
418        if (buffer->name != 0) {
419            address = buffer->baseAddress +
420                      VERTEX_BINDING_OFFSET[bindingIndex] +
421                      VERTEX_ATTRIB_RELATIVE_OFFSET[attribIndex];
422        } else {
423            address = VERTEX_ATTRIB_ARRAY_POINTER[attribIndex];
424        }
425
426
427Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
428
429    None.
430
431Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment
432Operations and the Frame Buffer)
433
434    None.
435
436Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
437
438    None.
439
440Additions to Chapter 6 of the OpenGL 2.0 Specification (State and
441State Requests)
442
443    Modify Section 6.1.18, "Shader and Program Queries", p. 500
444
445    (Append to the description of GetVertexAttrib)
446
447    Queries of VERTEX_ATTRIB_ARRAY_BUFFER_BINDING and VERTEX_ATTRIB_ARRAY_-
448    DIVISOR first map the requested attribute index to a binding index via
449    the VERTEX_ATTRIB_BINDING state, and then return the value of
450    VERTEX_BINDING_BUFFER or VERTEX_BINDING_DIVISOR, respectively.
451
452Additions to the AGL/GLX/WGL Specifications
453
454    None.
455
456GLX Protocol
457
458    TBD
459
460Dependencies on NV_vertex_buffer_unified_memory
461
462    When this extension is present, the GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV
463    state is modified to correspond to the <i>'th vertex buffer binding
464    rather than vertex attribute. Additionally, while the <buffer> and
465    <offset> set by BindVertexBuffer are irrelevant while
466    GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV is enabled, the command
467
468        BindVertexBuffer(bindingindex, 0, 0, stride);
469
470    can still be used to set the stride for a particular binding.
471
472    Note that NV_vertex_buffer_unified_memory uses the same function names
473    (VertexAttrib*FormatNV) as this extension, however the behavior of the
474    these functions is different.
475
476Dependencies on EXT_direct_state_access
477
478    When this extension is not present, ignore references to
479
480        VertexArrayBindVertexBufferEXT
481        VertexArrayVertexAttribFormatEXT
482        VertexArrayVertexAttribIFormatEXT
483        VertexArrayVertexAttribLFormatEXT
484        VertexArrayVertexAttribBindingEXT
485        VertexArrayVertexBindingDivisorEXT
486
487    When EXT_direct_state_access is present, add new entry points that take a
488    vertex array object handle:
489
490        void VertexArrayBindVertexBufferEXT(uint vaobj, uint bindingindex, uint buffer, intptr offset,
491                              sizei stride);
492
493        void VertexArrayVertexAttribFormatEXT(uint vaobj, uint attribindex, int size, enum type,
494                                boolean normalized, uint relativeoffset);
495        void VertexArrayVertexAttribIFormatEXT(uint vaobj, uint attribindex, int size, enum type,
496                                 uint relativeoffset);
497        void VertexArrayVertexAttribLFormatEXT(uint vaobj, uint attribindex, int size, enum type,
498                                 uint relativeoffset);
499
500        void VertexArrayVertexAttribBindingEXT(uint vaobj, uint attribindex, uint bindingindex);
501
502        void VertexArrayVertexBindingDivisorEXT(uint vaobj, uint bindingindex, uint divisor);
503
504    These commands behave identically to their
505    non-VertexArray/EXT-suffixed commands except they modify the state
506    of the vertex array object named by their initial vaobj parameter
507    (rather than the currently bound vertex array object).  The vertex
508    array object named by vaobj must be generated by GenVertexArrays
509    (and not since deleted); otherwise an INVALID_OPERATION error is
510    generated.
511
512    Modify the description of GetVertexArrayIntegeri_vEXT to allow
513    queries of VERTEX_BINDING_OFFSET and VERTEX_BINDING_STRIDE state:
514
515    "For GetVertexArrayIntegeri_vEXT, <pname> must be one of the
516    'Get value' tokens in tables 6.8 and 6.9 that use GetVertexAttribiv
517    or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_* and
518    VERTEX_BINDING_* tokens) or a token of the form TEXTURE_COORD_ARRAY_*;
519    <index> identifies the vertex attribute array to query, vertex binding to
520    query, or texture coordinate set index."
521
522Dependencies on the Compatibility profile
523
524    If the context is created with a compatibility profile, remove the
525    INVALID_OPERATION errors from all new commands if no vertex array
526    object is currently bound, and remove the INVALID_OPERATION error
527    from VertexAttrib*Pointer if no buffer is bound to ARRAY_BUFFER and
528    pointer != NULL.
529
530    Client vertex arrays are not changed to use the new state, that is,
531    VERTEX_ATTRIB_ARRAY_POINTER is still attribute state.
532
533Errors
534
535    !!!TODO
536
537New State
538
539    (Modify Table 6.5 -- Vertex Array Object State)
540
541                                                           Initial
542    Get Value                    Type    Get Command       Value    Description                Sec.
543    ---------                    ------- -----------       -------  ------------------------   ------
544    VERTEX_ATTRIB_BINDING        16*Z16* GetVertexAttribiv <i>[fn1] Vertex buffer binding      2.8
545                                                                    used by vertex attrib <i>
546    VERTEX_ATTRIB_RELATIVE_      16*Z+   GetVertexAttribiv    0     Byte offset added to       2.8
547      OFFSET                                                        vertex binding offset
548                                                                    for this attribute
549    VERTEX_BINDING_OFFSET        16*Z    GetInteger64i_v      0     Byte offset of the first   2.8
550                                                                    element in data store of
551                                                                    the buffer bound to vertex
552                                                                    binding <i>
553    VERTEX_BINDING_STRIDE        16*Z    GetIntegeri_v       16     Stride between elements in 2.8
554                                                                    vertex binding <i>
555    VERTEX_BINDING_DIVISOR       16*Z+   GetIntegeri_v        0     Instance divisor used for  2.8
556                                                                    vertex binding <i>
557    VERTEX_BINDING_BUFFER        16*Z+   GetIntegeri_v        0     Name of buffer bound to    2.8
558                                                                    vertex binding <i>
559
560    [fn1] The <i>'th attribute defaults to a value of <i>.
561
562    If the compatibility profile is supported, then all of these new state
563    values belong to the 'vertex-array' attribute.
564
565New Implementation Dependent State
566
567                                                      Minimum
568    Get Value                    Type    Get Command  Value   Description            Sec.
569    ---------                    ------- -----------  ------- --------------------   ------
570    MAX_VERTEX_ATTRIB_           Z       GetIntegerv  2047    Maximum offset added   2.8
571      RELATIVE_OFFSET                                         to vertex buffer
572                                                              binding offset
573    MAX_VERTEX_ATTRIB_BINDINGS   Z16*    GetIntegerv  16      Maxmimum number of     2.8
574                                                              vertex buffers
575
576NVIDIA Implementation Details
577
578    The VertexArrayVertexBindingDivisorEXT function was not missing
579    from early versions of this specification's interactions with
580    EXT_direct_state_access (an oversight).  NVIDIA driver implementations
581    (prior to Release 330.00, August 2013) do not advertise the function a
582    GetProcAddress call for the function name will return NULL.
583
584Examples
585
586    The following code will set up two interleaved vertex buffers, where
587    attribs 0 and 1 are vec3 position and vec3 color in buffer0, and attribs
588    2 and 3 come from are vec2 texcoords in buffer1.
589
590        // Set up formats and relative offsets within the interleaved data.
591        VertexAttribFormat(0, 3, FLOAT, FALSE, 0);
592        VertexAttribFormat(1, 3, FLOAT, FALSE, 12);
593        VertexAttribFormat(2, 2, FLOAT, FALSE, 0);
594        VertexAttribFormat(3, 2, FLOAT, FALSE, 8);
595
596        // Set up attrib->binding mapping
597        VertexAttribBinding(0, 0);
598        VertexAttribBinding(1, 0);
599        VertexAttribBinding(2, 1);
600        VertexAttribBinding(3, 1);
601
602        // Bind the vertex buffers to binding index 0 and 1.
603        BindVertexBuffer(0, buffer0, 0, 24);
604        BindVertexBuffer(1, buffer1, 0, 16);
605
606Issues
607
608    (1) Should the instance divisor (previously VertexAttribDivisor) be
609        attribute state or binding state?
610
611      RESOLVED: Make it per-binding, since some hardware requires this.
612
613    (2) How is a stride of zero interpreted in BindVertexBuffer?
614
615      RESOLVED: No error is generated, all array elements for a given
616      attribute will be sourced from the same location in the buffer.
617
618    (3) How is a stride of zero handled in VertexAttribPointer?
619
620      RESOLVED: BindVertexBuffer has no knowledge of the attrib format,
621      so VertexAttribPointer needs to compute the stride itself. However,
622      if an application specifies a stride of zero and then queries
623      VERTEX_ATTRIB_ARRAY_STRIDE, it returns zero. So the derived stride
624      that's passed to BindVertexBuffer must be tracked separately from the
625      stride originally passed to VertexAttribPointer, so this spec introduces
626      a separate piece of state (VERTEX_BINDING_STRIDE). Rendering always uses
627      VERTEX_BINDING_STRIDE.
628
629      This can potentially lead to misleading state queries if the API is
630      abused. For example:
631
632        VertexAttribPointer(0, 3, FLOAT, FALSE, 12, 0);
633        // VERTEX_ATTRIB_ARRAY_STRIDE = 12
634        // VERTEX_BINDING_STRIDE = 12
635        BindVertexBuffer(0, buffer, 0, 16)
636        // now VERTEX_ATTRIB_ARRAY_STRIDE is still 12, but
637        // VERTEX_BINDING_STRIDE = 16.
638
639    (4) How should the attrib->binding mapping be handled for legacy commands?
640
641      RESOLVED: Redefine legacy commands to reset the mapping to its initial
642      state for the attribute being operated on. This allows legacy code to
643      coexist in the same context/VAO with use of this extension even though
644      that code is oblivious to the fact that this mapping is now flexible.
645      As long as the legacy code sets up each attribute it wants to use, it
646      should operate as expected. This may be useful for applications using
647      middleware that they can't control.
648
649    (5) What is the minimum maximum value for VERTEX_ATTRIB_RELATIVE_OFFSET?
650
651      RESOLVED: Agreed on 2047 (inclusive).
652
653    (6) Can MAX_VERTEX_ATTRIBS and MAX_VERTEX_ATTRIB_BINDINGS have different
654    values?
655
656      RESOLVED: Decided that it's nice to have them be separate queries, but
657      that we don't want to deal with all the complexities that arise if the
658      two values are different. So this spec assumes that the two values are
659      the same.
660
661    (7) How does this extension interact with EXT_direct_state_access?
662
663      RESOLVED:  The EXT commands in this specification are available only when
664      EXT_direct_state_access is also advertised.
665
666      Note:  Early versions of this specification failed to document
667      the EXT_direct_state_access commands.  Revision 3 (August 2013)
668      corrects this oversight.
669
670    (8) Which state queries return information from attributes vs from
671        bindings?
672
673      RESOLVED: The general convention is that tokens starting with
674      VERTEX_BINDING return information corresponding to a buffer binding and
675      are queried with GetIntegeri_v, whereas tokens starting with
676      VERTEX_ATTRIB_ARRAY return information corresponding to a vertex
677      attribute index and are queried with GetVertexAttribiv.
678
679      For cases where there is both an "attribute" and "binding" token for the
680      same state, the "attribute" query returns state for the binding that
681      attribute is currently using (set via VertexAttribBinding). Specifically,
682      VERTEX_ATTRIB_ARRAY_BUFFER_BINDING returns a value from VERTEX_BINDING_-
683      BUFFER, and VERTEX_ATTRIB_ARRAY_DIVISOR returns a value from VERTEX_-
684      BINDING_DIVISOR.
685
686      A notable exception to this is for VERTEX_BINDING_STRIDE and
687      VERTEX_ATTRIB_ARRAY_STRIDE. As described in issue (3), these tokens track
688      separate state.
689
690
691Revision History
692
693    Rev.    Date    Author    Changes
694    ----  --------  --------  ------------------------------------------
695      5   10/22/13  jbolz     Added missing definition of
696                              VERTEX_BINDING_DIVISOR, and added
697                              VERTEX_BINDING_BUFFER, to keep things consistent.
698      4   08/06/13  mjk       Added EXT_direct_state_access interactions
699      3   07/19/13  Jon Leech Add error to BindVertexBuffer for the core
700                              profile if <buffer> is not a name returned
701                              by GenBuffers (Bug 10486).
702      2   08/13/12  Jon Leech Renumbered from #143 to #125
703      1             jbolz     Internal revisions.
704