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