I am using OpenGL ES 2.0 I have a bunch a quads to be drawn, would love to be able to have to pass only 4 vertices per quad as if I were using GL_QUADS, but basically I just want to know the best way of drawing a bunch of separate quads.

So far what I've found I could do:

  • GL_TRIANGLES(6 vertices per quad)
  • Degenerate GL_TRIANGLE_STRIP(6 vertices per quad)

Possibilities I've found:

  • GL_TRIANGLE_STRIPS with a special index value that resets quad strip(this would mean 5 indexes per quad, but I don't think this is possible is OpenGL ES 2.0)

Just use index buffer and GL_TRIANGLES. In this case you need 4 vertices + 6 indices per quad (6 additional indices may sound large overhead but in reality it is not - once you have constructed your index buffer you don't have to touch it again). See this page for more information (search for glDrawElements)

Simple example code:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Also, if you are drawing just one quad you need only 4 vertices to draw it with triangle strips (as shown in wikipedia) but I guess you already knew this.

  • \$\begingroup\$ The traditional trick for merging multiple triangle strips into a single strip is "degenerate triangles": Repeating the last element of one strip and the first element of the next strip creates 2 triangles with zero area, that thus draw nothing. Consider second quad indices (4, 5, 6, 7). Index buffer for GL_TRIANGLE_STRIP of two quads could be: {0, 1, 2, 3, 3, 4, 4, 5, 6, 7}. The degenerate triangles are 3,3,4 and 3,4,4. Is it worth doing this? No, unless your quads tend to come in pairs (or more) with common edges. If 2nd quad is {3, 2, 4, 5} then strip is {0,1,3,2,5,4}. \$\endgroup\$ Sep 9 '14 at 5:24
  • 10
    \$\begingroup\$ And to make this clear to anyone who comes along and needs to draw a bunch of quads: For the sake of performance, DO NOT copy the above code, and make a glDrawElements call ONCE FOR EACH QUAD. Instead, build up ONE vertices array and ONE indices array that includes ALL the quads you want to draw. Using GL_TRIANGLES, two quads could have indices {0,1,2, 0,2,3, 4,5,6, 4,6,7} or equally good is {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Good class to help this is glText-Android/SpriteBatch \$\endgroup\$ Sep 9 '14 at 5:37

Using index buffers isn't necessarily faster, as indicated in the Apple docs, "For best performance, your models should be submitted as a single unindexed triangle strip using glDrawArrays".

So, while a GL_TRIANGLE_STRIP will do it in 4 vertices without needing an index buffer, and you can use an index buffer, it's pretty lame to try to "save" repeating 2 vertices. For this reason, I'd suggest you draw 2 separate GL_TRIANGLES and repeat the 2 vertices on the diagonal.

  • 9
    \$\begingroup\$ Um, no. What that doc says is that your models be submitted as a single INDEXED triangle strip. And the very next sentence is, "To avoid specifying data for the same vertex multiple times in the vertex buffer, use a separate index buffer and draw the triangle strip using the glDrawElements function". Which is exactly what you decided was 'lame'. \$\endgroup\$
    – davidf2281
    Mar 2 '14 at 13:30
  • 4
    \$\begingroup\$ Given that the doc paragraph now refers to glDrawElements rather than glDrawArrays, it has probably been re-written since this answer. Nevertheless, the point the doc was making was that, for performance, supply a single strip (rather than multiple strips, hence multiple gl calls). In this situation, I believe the difference between using indices or not is insignificant; what matters is getting everything into a single vertex array (plus an optional index array), so that you can make a single gl call. \$\endgroup\$ Sep 9 '14 at 5:06

The big gain on desktop is to move the data into GL_STATIC_DRAW VBOs. Presumably this is true on iPhone's MBX GPU too.


Using GL_TRIANGLE_FAN for a quad uses 4 vertices, not 6.

  • \$\begingroup\$ Yep, but so does GL_TRIANGLE_STRIP, as other answers have already pointed out. \$\endgroup\$
    – Anko
    Jul 31 '14 at 19:27
  • \$\begingroup\$ @Mr. Blah - You have missed the point of the question, which is how to efficiently do a bunch of quads. One should not make a gl call for each quad, but rather combine a lot of quads into a single array, that can be drawn with a single gl call. GL_TRIANGLE_FAN won't help with this, hence is rarely useful in high-performance rendering. \$\endgroup\$ Sep 9 '14 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.