• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_draw_elements_base_vertex
4
5Name Strings
6
7    GL_EXT_draw_elements_base_vertex
8
9Contact
10
11    Daniel Koch, NVIDIA (dkoch 'at' nvidia.com)
12
13Contributors
14
15    Shannon Woods, Google
16    Dominik Witczak, Mobica
17    Contributors to ARB_draw_elements_base_vertex
18
19Notice
20
21    Copyright (c) 2009-2014 The Khronos Group Inc. Copyright terms at
22        http://www.khronos.org/registry/speccopyright.html
23
24    Portions Copyright (c) 2014 NVIDIA Corporation.
25
26Status
27
28    Complete.
29
30Version
31
32    Last Modified Date:  August 11, 2020
33    Version:             4
34
35Number
36
37    OpenGL ES Extension #204
38
39Dependencies
40
41    This specification is written against the OpenGL ES 3.1 (June 4, 2014)
42    Specifications, but can apply to prior specifications.
43
44    Requires OpenGL ES 2.0.
45
46    This extension interacts with OpenGL ES 3.1.
47
48    This extension interacts with OpenGL ES 3.0.
49
50    This extension interacts with EXT_draw_instanced.
51
52    This extension interacts with NV_draw_instanced.
53
54    This extension interacts with EXT_instanced_arrays.
55
56    This extension interacts with ANGLE_instanced_arrays.
57
58    This extension interacts with NV_instanced_arrays.
59
60    This extension interacts with EXT_multi_draw_arrays.
61
62Overview
63
64    This extension provides a method to specify a "base vertex offset"
65    value which is effectively added to every vertex index that is
66    transferred through DrawElements.
67
68    This mechanism can be used to decouple a set of indices from the
69    actual vertex array that it is referencing. This is useful if an
70    application stores multiple indexed models in a single vertex array.
71    The same index array can be used to draw the model no matter where
72    it ends up in a larger vertex array simply by changing the base
73    vertex value. Without this functionality, it would be necessary to
74    rebind all the vertex attributes every time geometry is switched and
75    this can have larger performance penalty.
76
77    For example consider the (very contrived and simple) example of
78    drawing two triangles to form a quad. In the typical example you
79    have the following setup:
80
81          vertices                indices
82         ----------                -----
83      0 | (-1,  1) |            0 |  0  |
84      1 | (-1, -1) |            1 |  1  |
85      2 | ( 1, -1) |            2 |  2  |
86      3 | ( 1,  1) |            3 |  3  |
87         ----------             4 |  0  |
88                                5 |  2  |
89                                   -----
90    which is normally rendered with the call
91
92       DrawElements(TRIANGLES, 6, UNSIGNED_BYTE, &indices).
93
94    Now consider the case where the vertices you want to draw are not at
95    the start of a vertex array but are instead located at offset 100
96    into a larger array:
97
98           vertices2             indices2
99           ----------             -----
100              ....             0 | 100 |
101      100 | (-1,  1) |         1 | 101 |
102      101 | (-1, -1) |         2 | 102 |
103      102 | ( 1, -1) |         3 | 103 |
104      103 | ( 1,  1) |         4 | 100 |
105              ....             5 | 102 |
106           ----------             -----
107
108    The typical choices for rendering this are to rebind your vertex
109    attributes with an additional offset of 100*stride, or to create an
110    new array of indices (as indices2 in the example). However both
111    rebinding vertex attributes and rebuilding index arrays can be quite
112    costly activities.
113
114    With the new drawing commands introduced by this extension you can
115    instead draw using vertices2 and the new draw call:
116
117       DrawElementsBaseVertexEXT(TRIANGLES, 6, UNSIGNED_BYTE, &indices, 100)
118
119New Procedures and Functions
120
121    void DrawElementsBaseVertexEXT(enum mode, sizei count, enum type,
122                                   const void *indices, int basevertex);
123
124    [[ If OpenGL ES 3.0 is supported: ]]
125
126    void DrawRangeElementsBaseVertexEXT(enum mode, uint start, uint end,
127                                        sizei count, enum type,
128                                        const void *indices, int basevertex);
129
130    void DrawElementsInstancedBaseVertexEXT(enum mode, sizei count,
131                                            enum type, const void *indices,
132                                            sizei instancecount,
133                                            int basevertex);
134
135    [[ If EXT_multi_draw_arrays is supported: ]]
136
137    void MultiDrawElementsBaseVertexEXT(enum mode,
138                                        const sizei *count,
139                                        enum type,
140                                        const void * const *indices,
141                                        sizei drawcount,
142                                        const int *basevertex);
143
144New Tokens
145
146    None
147
148Additions to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex
149Specification and Drawing Commands)
150
151    Modify section 10.3.7 "Array Indices in Buffer Objects" p. 244,
152    adding the following to the end of the third paragraph (beginning
153    with "While a non-zero buffer object name..."
154
155    "DrawElementsBaseVertexEXT, DrawRangeElementsBaseVertexEXT, and
156    DrawElementsInstancedBaseVertexEXT also source their indices from that
157    buffer object, adding the <basevertex> offset to the appropriate vertex
158    index as a final step before indexing into the vertex buffer; this does
159    not affect the calculation of the base pointer for the index array."
160
161    [[ If EXT_multi_draw_arrays is supported: ]]
162
163    "Finally, MultiDrawElementsEXT and MultiDrawElementsBaseVertexEXT also
164    source their indices from that buffer object, using its <indices>
165    parameter as a pointer to an array of pointers that represent
166    offsets into the buffer object."
167
168
169    Modify section 10.5 "Drawing Commands Using Vertex Arrays" as follows:
170
171    Replace the definition and paragraph describing
172    DrawElementsInstancedBaseVertex, bottom of p. 252 with the following:
173
174    "The commands
175      void DrawElementsBaseVertexEXT(enum mode, sizei count, enum type,
176                                    const void *indices, int basevertex);
177
178      void DrawRangeElementsBaseVertexEXT(enum mode, uint start, uint end,
179                                          sizei count, enum type,
180                                          const void *indices, int basevertex);
181
182      void DrawElementsInstancedBaseVertexEXT(enum mode, sizei count,
183                                              enum type, const void *indices,
184                                              sizei instancecount,
185                                              int basevertex);
186
187    are equivalent to the commands with the same base name (without the
188    "BaseVertexEXT" suffix) except that the <i>th element transferred by
189    the corresponding draw call will be taken from element
190       <indices>[<i>] + <basevertex>
191    of each enabled array. If the resulting value is larger than the maximum
192    value representable by <type> it should behave as if the calculation were
193    upconverted to 32-bit unsigned integers (with wrapping on overflow
194    conditions). The operation is undefined if the sum would be negative and
195    should be handled as described in Section 6.4. For
196    DrawRangeElementsBaseVertexEXT, the index values must lie between <start>
197    and <end> inclusive, prior to adding the <basevertex> offset. Index values
198    lying outside the range [<start>,<end>] are treated in the same way as
199    DrawRangeElements."
200
201    [[ If EXT_multi_draw_arrays is supported: ]]
202
203    "The command
204
205      void MultiDrawElementsBaseVertexEXT(enum mode,
206                                          const sizei *count,
207                                          enum type,
208                                          const void *const *indices,
209                                          sizei drawcount,
210                                          const int *basevertex);
211
212    behaves identically to DrawElementsBaseVertexEXT except that
213    <drawcount> separate lists of elements are specified instead. It has
214    the same effect as:
215
216      if (<mode> or <drawcount> is invalid)
217          generate appropriate error
218      else {
219          for (i = 0; i < <drawcount>; i++)
220              if (<count>[i] > 0)
221                  DrawElementsBaseVertexEXT(<mode>, <count>[i], <type>,
222                                            <indices>[i], <basevertex>[i]);
223      }"
224
225Additions to the EGL/AGL/GLX/WGL Specifications
226
227    None
228
229Dependencies on OpenGL ES 3.1
230
231    If OpenGL ES 3.1 is not supported apply the following modifications to the
232    OpenGL ES 3.0.3 specification:
233
234    Add the following to the end of Section 2.8.1 "Transferring Array Elements"
235
236    "When one of the *BaseVertex drawing commands specified in section
237    2.8.3 is used, the primitive restart comparison occurs before the
238    <basevertex> offset is added to the array index."
239
240    Replace the following references relative to the ES 3.1 specification
241    with the following references to the ES 3.0.3 specification:
242
243    Edits to section 10.3.7 "Array Indices in Buffer Objects" in ES 3.1 become
244    edits to section 2.9.7 "Array Indices in Buffer Objects" in ES 3.0.3.
245
246    Edits to section 10.5 "Draw Command using Vertex Arrays" in ES 3.1 become
247    edits to section 2.8.3 "Drawing Commands" in ES 3.0.3.
248
249    Replace references to section 6.4 in ES 3.1 with references to section
250    2.9.4 in ES 3.0.3.
251
252Dependencies on OpenGL ES 3.0
253
254    If OpenGL ES 3.0 is not supported, ignore all references to
255    DrawElementsInstanced and DrawElementsInstancedBaseVertexEXT (unless one
256    of the instanced_array or draw_instanced extensions is present).
257
258    If OpenGL ES 3.0 is not supported, ignore all references to
259    DrawRangeElements and DrawRangeElementsBaseVertexEXT.
260
261    If OpenGL ES 3.0 is not supported, ignore all references to primitive
262    restart index.
263
264Dependencies on the EXT_draw_instanced extension
265
266    If EXT_draw_instanced is supported, the functionality provided by
267    DrawElementsInstancedBaseVertexEXT can also be described in terms of
268    DrawElementsInstancedEXT instead of DrawElementsInstanced.
269
270Dependencies on the NV_draw_instanced extension
271
272    If NV_draw_instanced is supported, the functionality provided by
273    DrawElementsInstancedBaseVertexEXT can also be described in terms of
274    DrawElementsInstancedNV instead of DrawElementsInstanced.
275
276Dependencies on the EXT_instanced_arrays extension
277
278    If EXT_instanced_arrays is supported, the functionality provided by
279    DrawElementsInstancedBaseVertexEXT can also be described in
280    terms of DrawElementsInstancedEXT instead of DrawElementsInstanced.
281
282Dependencies on the ANGLE_instanced_arrays extension
283
284    If ANGLE_instanced_arrays is supported, the functionality provided by
285    DrawElementsInstancedBaseVertexEXT can also be described in
286    terms of DrawElementsInstancedANGLE instead of DrawElementsInstanced.
287
288Dependencies on the NV_instanced_arrays extension
289
290    If ARB_instanced_arrays is supported, the functionality provided by
291    DrawElementsInstancedBaseVertexEXT can also be described in
292    terms of DrawElementsInstancedNV instead of DrawElementsInstanced.
293
294Errors
295
296    The *BaseVertexEXT commands have identical error conditions to the
297    non-*BaseVertexEXT functions, and all values of <basevertex> are legal
298    (with the exception of ones which cause accesses outside of vertex
299    arrays or bound buffers as described in Section 6.4).
300
301New State
302
303    None
304
305New Implementation Dependent State
306
307    None
308
309Issues
310
311    Note: These issues apply specifically to the definition of the
312    EXT_draw_elements_base_vertex specification, which is based on the OpenGL
313    extension ARB_draw_elements_base_vertex as updated in OpenGL 4.4.
314    ARB_draw_elements_base_vertex can be found in the OpenGL Registry.
315
316    (0) This extension is based on ARB_draw_elements_base_vertex.  What are
317    the major differences?
318
319        - rebased on OpenGL ES 3.1
320        - renamed the "primcount" parameter to "instancecount" per GL4
321        - MultiDrawElementsBaseVertexEXT is only available if
322          GL_EXT_multi_draw_arrays is supported.
323
324    (1) Should we include MultiDrawElementsBaseVertexEXT in this extension?
325
326    RESOLVED: Yes, but only if EXT_multi_draw_arrays is supported, since
327    multi draw calls are not available in unextended OpenGL ES 2 or 3.
328
329    (2) Should we allow client memory to be used for vertex attributes and
330    for the <indices> in the *BaseVertexEXT commands?
331
332    RESOLVED: Yes. Since these are defined in terms of the non-BaseVertex
333    commands which already supports client memory for vertex attributes and
334    indices it makes sense to include support for these new commands as well.
335
336    (3) Which commands are supported on OpenGL ES 2.0 implementations that
337    support this extension?
338
339    RESOLVED: Only DrawElementsBaseVertexEXT, unless one of the instancing
340    extensions is supported in which case DrawElementsInstancedBaseVertexEXT
341    is also supported. DrawRangeElementsBaseVertexEXT is not supported because
342    OpenGL ES 2.0 doesn't include DrawRangeElements.
343
344    (4) Which commands are supported on OpenGL ES 3.0 implementations?
345
346    RESOLVED: All of the new drawing commands are applicable to OpenGL ES 3.0
347    implementations.
348
349    (5) Does the value of gl_VertexID in the shading language include the
350    the value of the <basevertex> offset?
351
352    RESOLVED: Yes. This is as clarified by Khronos bugs 12202 and 12756
353    and is consistent with the overview of ARB_shader_draw_parameters.
354    Essentially, the value of gl_VertexID should be the index of the
355    vertex that is being passed to the shader.
356     - DrawArrays: first + i
357     - DrawElements: indices[i]
358     - DrawElementsBaseVertex: indices[i] + basevertex
359
360
361Revision History
362
363    Rev.    Date    Author     Changes
364    ----  -------- ---------  ----------------------------------------------
365     4    08/11/20  pdaniell  Renamed the 'primcount' parameter of
366                              MultiDrawElementsBaseVertexEXT in the
367                              "New Procedures and Functions" section to
368                              'drawcount' to match the extension spec body.
369
370     3    09/30/14  dkoch     Resolved issues 1, 2 as proposed.
371                              Added issue 5. Mark complete.
372
373     2    06/24/14  dkoch     Add EXT_multi_draw_arrays interactions
374                              and typographical fixes from Dominik.
375
376     1    04/05/14  dkoch     Intial version for ES based on
377                              ARB_draw_elements_base_vertex v3.
378