Name

    EXT_draw_range_elements

Name Strings

    GL_EXT_draw_range_elements

Version

    $Date: 1997/5/19

Number

    112

Proposal:
Add a new vertex array rendering command:

void glDrawRangeElementsEXT(
	GLenum mode,
	GLuint start,
	GLuint end,
	GLsizei count,
	GLenum type,
	const GLvoid *indices
);

Add two implementation-dependent limits for describing data size
recommendations for glDrawRangeElementsEXT:

GL_MAX_ELEMENTS_VERTICES_EXT
GL_MAX_ELEMENTS_INDICES_EXT

glDrawRangeElementsEXT is a restricted form of glDrawElements.  All
vertices referenced by indices must lie between start and end inclusive.
Not all vertices between start and end must be referenced, however
unreferenced vertices may be sent through some of the vertex pipeline
before being discarded, reducing performance from what could be achieved
by an optimal index set.  Index values which lie outside the range will
cause implementation-dependent results.

glDrawRangeElementsEXT may also be further constrained to only operate
at maximum performance for limited amounts of data.  Implementations may
advertise recommended maximum amounts of vertex and index data using the
GL_MAX_ELEMENTS_VERTICES_EXT and GL_MAX_ELEMENTS_INDICES_EXT enumerants.
If a particular call to glDrawRangeElementsEXT has (end-start+1) greater
than GL_MAX_ELEMENTS_VERTICES_EXT or if count is greater than
GL_MAX_ELEMENTS_INDICES_EXT then the implementation may be forced to
process the data less efficiently than it could have with less data.  An
implementation which has no effective limits can advertise the maximum
integer value for the two enumerants.  An implementation must always
process a glDrawRangeElementsEXT call with valid parameters regardless
of the amount of data passed in the call.

GL_INVALID_VALUE will be returned if end is less than start.  Other
errors are as for glDrawElements.

Motivation:
Rendering primitives from indexed vertex lists is a fairly common
graphics operation, particularly in modeling applications such as VRML
viewers.  OpenGL 1.1 added support for the glDrawElements API to allow
rendering of primitives by indexing vertex array data.

The specification of glDrawElements does not allow optimal performance
for some OpenGL implementations, however.  In particular, it has no
restrictions on the number of indices given, the number of unique
vertices referenced nor a direct indication of the set of unique
vertices referenced by the given indices.  This forces some OpenGL
implementations to walk the index data given, building up a separate
list of unique vertex references for later use in the pipeline.
Additionally, since some OpenGL implementations have internal
limitations on how many vertices they can deal with simultaneously the
unbounded nature of glDrawElements requires the implementation to be
prepared to segment the input data and do multiple passes.  These
preprocessing steps can consume a significant amount of time.

Such preprocessing can be done once and stored when building display
lists but this only works for objects whose geometry does not change.
Applications using morphing objects or other objects that are changing
dynamically cannot take advantage of display lists and so must pay the
preprocessing penalty on every redraw.

glDrawRangeElementsEXT is designed to avoid the preprocessing steps
which may be necessary for glDrawElements.  As such it does not have the
flexibility of glDrawElements but it is sufficiently functional for a
large class of applications to benefit from its use.
glDrawRangeElementsEXT enhances glDrawElements in two ways:
1.  The set of unique vertices referenced by the indices is explicitly
indicated via the start and end parameters, removing the necessity to
determine this through examination of the index data.  The
implementation is given a contiguous chunk of vertex data that it can
immediately begin streaming through the vertex pipeline.
2.  Recommended limits on the amount of data to be processed can be
indicated by the implementation through GL_MAX_ELEMENTS_VERTICES_EXT and
GL_MAX_ELEMENTS_INDICES_EXT.  If an application respects these limits it
removes the need to split the incoming data into multiple chunks since
the maximums can be set to the optimal values for the implementation to
handle in one pass.

The first restriction isn't particularly onerous for applications since
they can always call glDrawElements in the case where they cannot or do
not know whether they can call glDrawRangeElementsEXT.  Performance
should be at least as good as it was calling glDrawElements alone.  The
second point isn't really a restriction as glDrawRangeElementsEXT
doesn't fail if the data size limits are exceeded.

OpenGL implementation effort is also minimal.  For implementations where
glDrawElements performance is not affected by preprocessing
glDrawRangeElementsEXT can be implemented simply as a call to
glDrawElements and the maximums set to the maximum integer value.  For
the case where glDrawElements is doing non-trivial preprocessing there
is probably already an underlying routine that takes consecutive, nicely
sectioned index and vertex chunks that glDrawRangeElementsEXT can plug
directly in to.

Design Decisions:
The idea of providing a set of vertex indices along with a set of
element indices was considered but dropped as it still may require some
preprocessing, although there is some reduction in overhead from
glDrawElements.  The implementation may require internal vertex data to
be contiguous, in which case a gather operation would have to be
performed with the vertex index list before vertex data could be
processed.  It is expected that most apps will keep vertex data for
particular elements packed consecutively anyway so the added flexibility
of a vertex index list would potentially impose overhead with little
expected benefit.  In the case where a vertex index list really is
necessary to avoid performance penalties due to sparse vertex usage
glDrawElements should provide performance similar to what such an API
would have.

The restriction on maximum data size cannot easily be lifted without
potential performance implications.  For implementations which have an
internal maximum vertex buffer size it would be necessary to break up
large data sets into multiple chunks.  Splitting indexed data requires
walking the indices and gathering those that fall within particular
chunks into sets for processing, a time-consuming operation.  Splitting
the indices themselves is easier but still requires some processing to
handle connected primitives that cross a split.
