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