blob: 47a937be3750ba911c33f1b064b0b40d5eef3097 [file] [log] [blame]
Name
OES_draw_elements_base_vertex
Name Strings
GL_OES_draw_elements_base_vertex
Contact
Daniel Koch, NVIDIA (dkoch 'at' nvidia.com)
Contributors
Shannon Woods, Google
Dominik Witczak, Mobica
Contributors to ARB_draw_elements_base_vertex
Notice
Copyright (c) 2009-2014 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL ES Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
https://www.khronos.org/registry/OpenGL/docs/update_policy.php
Portions Copyright (c) 2014 NVIDIA Corporation.
Status
Approved by the OpenGL ES Working Group on October 8, 2014
Ratified by the Khronos Board of Promoters on November 21, 2014
Version
Last Modified Date: September 30, 2014
Version: 2
Number
OpenGL ES Extension #219
Dependencies
This specification is written against the OpenGL ES 3.1 (June 4, 2014)
Specifications, but can apply to prior specifications.
Requires OpenGL ES 2.0.
This extension interacts with OpenGL ES 3.1.
This extension interacts with OpenGL ES 3.0.
This extension interacts with EXT_draw_instanced.
This extension interacts with NV_draw_instanced.
This extension interacts with EXT_instanced_arrays.
This extension interacts with ANGLE_instanced_arrays.
This extension interacts with NV_instanced_arrays.
This extension interacts with EXT_multi_draw_arrays.
Overview
This extension provides a method to specify a "base vertex offset"
value which is effectively added to every vertex index that is
transferred through DrawElements.
This mechanism can be used to decouple a set of indices from the
actual vertex array that it is referencing. This is useful if an
application stores multiple indexed models in a single vertex array.
The same index array can be used to draw the model no matter where
it ends up in a larger vertex array simply by changing the base
vertex value. Without this functionality, it would be necessary to
rebind all the vertex attributes every time geometry is switched and
this can have larger performance penalty.
For example consider the (very contrived and simple) example of
drawing two triangles to form a quad. In the typical example you
have the following setup:
vertices indices
---------- -----
0 | (-1, 1) | 0 | 0 |
1 | (-1, -1) | 1 | 1 |
2 | ( 1, -1) | 2 | 2 |
3 | ( 1, 1) | 3 | 3 |
---------- 4 | 0 |
5 | 2 |
-----
which is normally rendered with the call
DrawElements(TRIANGLES, 6, UNSIGNED_BYTE, &indices).
Now consider the case where the vertices you want to draw are not at
the start of a vertex array but are instead located at offset 100
into a larger array:
vertices2 indices2
---------- -----
.... 0 | 100 |
100 | (-1, 1) | 1 | 101 |
101 | (-1, -1) | 2 | 102 |
102 | ( 1, -1) | 3 | 103 |
103 | ( 1, 1) | 4 | 100 |
.... 5 | 102 |
---------- -----
The typical choices for rendering this are to rebind your vertex
attributes with an additional offset of 100*stride, or to create an
new array of indices (as indices2 in the example). However both
rebinding vertex attributes and rebuilding index arrays can be quite
costly activities.
With the new drawing commands introduced by this extension you can
instead draw using vertices2 and the new draw call:
DrawElementsBaseVertexOES(TRIANGLES, 6, UNSIGNED_BYTE, &indices, 100)
New Procedures and Functions
void DrawElementsBaseVertexOES(enum mode, sizei count, enum type,
const void *indices, int basevertex);
[[ If OpenGL ES 3.0 is supported: ]]
void DrawRangeElementsBaseVertexOES(enum mode, uint start, uint end,
sizei count, enum type,
const void *indices, int basevertex);
void DrawElementsInstancedBaseVertexOES(enum mode, sizei count,
enum type, const void *indices,
sizei instancecount,
int basevertex);
[[ If EXT_multi_draw_arrays is supported: ]]
void MultiDrawElementsBaseVertexEXT(enum mode,
const sizei *count,
enum type,
const void * const *indices,
sizei primcount,
const int *basevertex);
New Tokens
None
Additions to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex
Specification and Drawing Commands)
Modify section 10.3.7 "Array Indices in Buffer Objects" p. 244,
adding the following to the end of the third paragraph (beginning
with "While a non-zero buffer object name..."
"DrawElementsBaseVertexOES, DrawRangeElementsBaseVertexOES, and
DrawElementsInstancedBaseVertexOES also source their indices from that
buffer object, adding the <basevertex> offset to the appropriate vertex
index as a final step before indexing into the vertex buffer; this does
not affect the calculation of the base pointer for the index array."
[[ If EXT_multi_draw_arrays is supported: ]]
"Finally, MultiDrawElementsEXT and MultiDrawElementsBaseVertexEXT also
source their indices from that buffer object, using its <indices>
parameter as a pointer to an array of pointers that represent
offsets into the buffer object."
Modify section 10.5 "Drawing Commands Using Vertex Arrays" as follows:
Replace the definition and paragraph describing
DrawElementsInstancedBaseVertex, bottom of p. 252 with the following:
"The commands
void DrawElementsBaseVertexOES(enum mode, sizei count, enum type,
const void *indices, int basevertex);
void DrawRangeElementsBaseVertexOES(enum mode, uint start, uint end,
sizei count, enum type,
const void *indices, int basevertex);
void DrawElementsInstancedBaseVertexOES(enum mode, sizei count,
enum type, const void *indices,
sizei instancecount,
int basevertex);
are equivalent to the commands with the same base name (without the
"BaseVertexOES" suffix) except that the <i>th element transferred by
the corresponding draw call will be taken from element
<indices>[<i>] + <basevertex>
of each enabled array. If the resulting value is larger than the maximum
value representable by <type> it should behave as if the calculation were
upconverted to 32-bit unsigned integers (with wrapping on overflow
conditions). The operation is undefined if the sum would be negative and
should be handled as described in Section 6.4. For
DrawRangeElementsBaseVertexOES, the index values must lie between <start>
and <end> inclusive, prior to adding the <basevertex> offset. Index values
lying outside the range [<start>,<end>] are treated in the same way as
DrawRangeElements."
[[ If EXT_multi_draw_arrays is supported: ]]
"The command
void MultiDrawElementsBaseVertexEXT(enum mode,
const sizei *count,
enum type,
const void *const *indices,
sizei drawcount,
const int *basevertex);
behaves identically to DrawElementsBaseVertexOES except that
<drawcount> separate lists of elements are specified instead. It has
the same effect as:
if (<mode> or <drawcount> is invalid)
generate appropriate error
else {
for (i = 0; i < <drawcount>; i++)
if (<count>[i] > 0)
DrawElementsBaseVertexOES(<mode>, <count>[i], <type>,
<indices>[i], <basevertex>[i]);
}"
Additions to the EGL/AGL/GLX/WGL Specifications
None
Dependencies on OpenGL ES 3.1
If OpenGL ES 3.1 is not supported apply the following modifications to the
OpenGL ES 3.0.3 specification:
Add the following to the end of Section 2.8.1 "Transferring Array Elements"
"When one of the *BaseVertex drawing commands specified in section
2.8.3 is used, the primitive restart comparison occurs before the
<basevertex> offset is added to the array index."
Replace the following references relative to the ES 3.1 specification
with the following references to the ES 3.0.3 specification:
Edits to section 10.3.7 "Array Indices in Buffer Objects" in ES 3.1 become
edits to section 2.9.7 "Array Indices in Buffer Objects" in ES 3.0.3.
Edits to section 10.5 "Draw Command using Vertex Arrays" in ES 3.1 become
edits to section 2.8.3 "Drawing Commands" in ES 3.0.3.
Replace references to section 6.4 in ES 3.1 with references to section
2.9.4 in ES 3.0.3.
Dependencies on OpenGL ES 3.0
If OpenGL ES 3.0 is not supported, ignore all references to
DrawElementsInstanced and DrawElementsInstancedBaseVertexOES (unless one
of the instanced_array or draw_instanced extensions is present).
If OpenGL ES 3.0 is not supported, ignore all references to
DrawRangeElements and DrawRangeElementsBaseVertexOES.
If OpenGL ES 3.0 is not supported, ignore all references to primitive
restart index.
Dependencies on the EXT_draw_instanced extension
If EXT_draw_instanced is supported, the functionality provided by
DrawElementsInstancedBaseVertexOES can also be described in terms of
DrawElementsInstancedEXT instead of DrawElementsInstanced.
Dependencies on the NV_draw_instanced extension
If NV_draw_instanced is supported, the functionality provided by
DrawElementsInstancedBaseVertexOES can also be described in terms of
DrawElementsInstancedNV instead of DrawElementsInstanced.
Dependencies on the EXT_instanced_arrays extension
If EXT_instanced_arrays is supported, the functionality provided by
DrawElementsInstancedBaseVertexOES can also be described in
terms of DrawElementsInstancedEXT instead of DrawElementsInstanced.
Dependencies on the ANGLE_instanced_arrays extension
If ANGLE_instanced_arrays is supported, the functionality provided by
DrawElementsInstancedBaseVertexOES can also be described in
terms of DrawElementsInstancedANGLE instead of DrawElementsInstanced.
Dependencies on the NV_instanced_arrays extension
If ARB_instanced_arrays is supported, the functionality provided by
DrawElementsInstancedBaseVertexOES can also be described in
terms of DrawElementsInstancedNV instead of DrawElementsInstanced.
Errors
The *BaseVertexOES commands have identical error conditions to the
non-*BaseVertexOES functions, and all values of <basevertex> are legal
(with the exception of ones which cause accesses outside of vertex
arrays or bound buffers as described in Section 6.4).
New State
None
New Implementation Dependent State
None
Issues
Note: These issues apply specifically to the definition of the
OES_draw_elements_base_vertex specification, which is based on the OpenGL
extension ARB_draw_elements_base_vertex as updated in OpenGL 4.4.
ARB_draw_elements_base_vertex can be found in the OpenGL Registry.
(0) This extension is based on ARB_draw_elements_base_vertex. What are
the major differences?
- rebased on OpenGL ES 3.1
- renamed the "primcount" parameter to "instancecount" per GL4
- MultiDrawElementsBaseVertexEXT is only available if
GL_EXT_multi_draw_arrays is supported.
(1) Should we include MultiDrawElementsBaseVertexEXT in this extension?
RESOLVED: Yes, but only if EXT_multi_draw_arrays is supported, since
multi draw calls are not available in unextended OpenGL ES 2 or 3.
(2) Should we allow client memory to be used for vertex attributes and
for the <indices> in the *BaseVertexOES commands?
RESOLVED: Yes. Since these are defined in terms of the non-BaseVertex
commands which already supports client memory for vertex attributes and
indices it makes sense to include support for these new commands as well.
(3) Which commands are supported on OpenGL ES 2.0 implementations that
support this extension?
RESOLVED: Only DrawElementsBaseVertexOES, unless one of the instancing
extensions is supported in which case DrawElementsInstancedBaseVertexOES
is also supported. DrawRangeElementsBaseVertexOES is not supported because
OpenGL ES 2.0 doesn't include DrawRangeElements.
(4) Which commands are supported on OpenGL ES 3.0 implementations?
RESOLVED: All of the new drawing commands are applicable to OpenGL ES 3.0
implementations.
(5) Does the value of gl_VertexID in the shading language include the
the value of the <basevertex> offset?
RESOLVED: Yes. This is as clarified by Khronos bugs 12202 and 12756
and is consistent with the overview of ARB_shader_draw_parameters.
Essentially, the value of gl_VertexID should be the index of the
vertex that is being passed to the shader.
- DrawArrays: first + i
- DrawElements: indices[i]
- DrawElementsBaseVertex: indices[i] + basevertex
Revision History
Rev. Date Author Changes
---- -------- --------- ----------------------------------------
2 09/30/14 dkoch Resolve issues 1, 2 as proposed.
Add Issue 5.
1 09/24/14 dkoch Initial OES version based on EXT.
No functional changes.