It's mostly about triangles really

There are a number of *Draw commands to render something in OpenGL.


The *Draw command contain a mode parameter that tell OpenGL what primitive to draw. The normal rule when a primitive starts can be changed with glPrimitiveRestartIndex. That way it is possible to draw more then on triangle strip at the same time.


Each vertex in the vertex stream is a point. Each point is drawn as a screen-aligned square. The size of a point can be set with glPointSize​ (https://www.opengl.org/wiki/GLAPI/glPointSize) or from a shaders gl_PointSize​ if GL_PROGRAM_POINT_SIZE​ is enabled. Max size of points depends on implementation. gl_PointCoord​ can be used in fragment shader to get position inside point (0-1).

GL_LINES: Every 2 vertices form a line.

GL_LINE_STRIP: All the vertices form a single line with n-1 segments.

GL_LINE_LOOP: All the vertices form a line loop with n segments.

GL_TRIANGLES: Every three vertices form a triangle.

GL_TRIANGLE_STRIP: Every group of 3 adjacent vertices form a triangle.

GL_TRIANGLE_FAN: Every group of 2 adjecent vertices beoynd the first will form a triangle with the first one.

Non-indexed or Indexed

There are two main groups of draw functions in opengl and they are non-indexed (*Arrays) and indexed (*Elements). A array function use the vertices in the order they appear in the buffers to form primitives. A Elements function reads a GL_ELEMENT_ARRAY_BUFFER and use the values found in it as indices into the vertex buffers. The most basic function in each group are glDrawArrays​ and glDrawElements​. Then there is many tweaks to the basic setup where each adds a new part of the names and makes them more and more horrible.

void glDrawArrays​( GLenum mode​, GLint first​, GLsizei count​ );

void glDrawElements​( GLenum mode​, GLsizei count​, GLenum type​, void * indices​ );


A BaseVertex​ functions are used on the indexed functions and takes a parameter used to offset the indices. So when this function is used the index 0 will be found at basevertex+0 in the vertex buffer.

void glDrawElementsBaseVertex​( GLenum mode​, GLsizei count​, GLenum type​, void *indices​, GLint basevertex​);


Hints to opengl that no indices in the draw call will be outside start and end.

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

void glDrawRangeElementsBaseVertex(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,GLvoid *indices,GLint basevertex);


An indirect draw command takes the parameter from a buffer object. To use them a buffer object must be bound with the parameters to the GL_DRAW_INDIRECT_BUFFER target.

void glDrawArraysIndirect(GLenum mode,const void *indirect);

void glDrawElementsIndirect(GLenum mode,GLenum type,const void *indirect);


If one combine more then one object into the buffers this can be used to select the ones to draw. It is like calling multiple glDrawArrays or glDrawElements​ in a row.

void glMultiDrawArrays​( GLenum mode​, GLint *first​, GLsizei *count​, GLsizei primcount​);

void glMultiDrawElements(GLenum mode,const GLsizei * count,GLenum type,const GLvoid * const * indices,GLsizei drawcount);

void glMultiDrawArraysIndirect(GLenum mode​, const void *indirect​, GLsizei drawcount​, GLsizei stride​);

void glMultiDrawElementsIndirect(GLenum mode,GLenum type,const void *indirect,GLsizei drawcount,GLsizei stride);

Instancing Draw

Instancing draw the same vertices multiple (instancecount​) times and it sends the number of the instance in a gl_InstanceID parameter to the shader.

void glDrawArraysInstanced​( GLenum mode​, GLint first​, GLsizei count​, GLsizei instancecount​ );

void glDrawElementsInstanced​( GLenum mode​, GLsizei count​, GLenum type​, const void *indices​, GLsizei instancecount​ );

void glDrawElementsInstancedBaseVertex(GLenum mode,GLsizei count,GLenum type,GLvoid *indices,GLsizei primcount,GLint basevertex);

Base Instance

void glDrawArraysInstancedBaseInstance(GLenum mode​, GLint first​, GLsizei count​, GLsizei primcount​, GLuint baseinstance​);

void glDrawElementsInstancedBaseInstance(GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount,GLuitn baseinstance);

void glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode,GLsizei count,GLenum type,GLvoid *indices,GLsizei primcount,GLint basevertex,

GLuint baseinstance);


MultiDrawIndirect - 2014

The Road to One Million Draws - 2013

OpenGL Instancing Demystified - 2013

Multi-Draw-Indirect is here - 2010

Rendering Lots of Cubes - 2010