Different drawArrays modes in WebGL

I find there are several mode in drawArrays function. They are POINTS, LINES, LINE_LOOP, LINE_STRIP, TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN.

As I know (and I hope my understanding is correct):
LINES can draw a line between two coordinates.
TRIANGLES can draw a triangles with three coordinates.
TRIANGLES can draw a rectangle with four coordinates.

However, I don’t know the mode of POINTS, LINE_LOOP, LINE_STRIP and TRIANGLE_FAN.
How can I use these mode to draw a model?

Assume, I have a list of coordinates that can be used to draw a cube (4 coordinates * 6 face = 24 coordinates), which method is the best to line to link up the edge of the cube? And which method is the best to draw six face?

Also, is it possible for me to draw the lines without the index buffer?

POINTS draws each vertex as a single pixel dot…so if there are 24 vertices, you get 24 dots.

LINES connects each pair of vertices by a straight line, so 24 vertices produces 12 separate lines.

LINESTRIP connects each vertex to the next by a straight line, so 24 vertices produces 23 lines that are all connected end-to-end.

LINELOOP is like LINESTRIP except that the last vertex is connected back to the first, so 24 vertices produces 24 straight lines - looping back to the start.

TRIANGLES connects each group of three consecutive vertices to make a triangle - so 24 vertices produces 8 separate triangles.

TRIANGLESTRIP is a little harder to get your head around…let’s letter our 24 vertices ‘A’ through ‘X’. This produces N-2 triangles where N is the number of vertices…the first triangle connects vertices A,B,C, the remaining triangles are each formed from the previous two vertices of the last triangle…(swapped over to keep the triangle facing the same way) plus one new vertex, so the second triangle is C,B,D, the third is C,D,E, the fourth is E,D,F…all the way through to the 22nd triangle which is made from W,V,X. This sounds messy but imagine that you are drawing something like a long, winding ribbon - with vertices A,C,E,G down one side of the ribbon and B,D,F,H down the otherside. You’ll need to sketch this one on some paper to get the hang of it.

TRIANGLEFAN - similar in concept to the STRIP but now we start with triangle A,B,C, then A,C,D, then A,D,E…and so on until A,W,X. The result looks like a ladies’ fan.

(In older OpenGL programs, you’ll also find QUADS and QUADSTRIPS - also POLYGON - but those were dumped for OpenGL-ES)

In theory, TRIANGLE_STRIP is the most efficient - for smooth “organic” shapes (terrain, people, cars, etc) you are averaging close to one vertex per triangle. But you often have to resort to weird stuff like making zero sized “degenerate” triangles to make your strips as long as possible. It’s painful.

To draw a cube (assuming you have vertex normals and/or texture coords), TRIANGLES with indexed vertices is really the only efficient way. There are 24 unique vertices and 12 triangles connecting them up. So put the 24 sets of vertex data into an array (or several arrays if you prefer) and create an index array with 36 indices corresponding to the 3 vertices of your 12 triangles. Draw it with TRIANGLES and you’re done with a single rendering “batch”.

You could use TRIANGLE_STRIPs (or FANS) - but the strip/fans would only be two triangles long because after you’ve drawn the two triangles corresponding to a particular face, you need to ‘break the chain’ and start with a new starting vertex. That mean that you have to make six draw calls to draw your cube. Even though you’re sending a little less data to the GPU by not duplicating the two shared vertices along the diagonal of each square face - the overhead of stopping and starting the data transmission after each face is going to kill performance.

Hence, many (most?) programs these days use nothing but TRIANGLES. With “indexed” rendering, this is almost as efficient as TRIANGLE_STRIPS, even for organic shapes where strips and fans are usable…and it’s much easier to deal with for angular objects that don’t share vertices.

So unless you are rendering something highly specialized (like maybe a molecular modelling application where you only ever draw spheres), you should probably only use TRIANGLES for solid geometry.

As for LINES/LINE_STRIP/LINE_LOOP - it depends entirely on the nature of what you’re doing. If you need “wireframe” rendering for a CAD application - then using a LINE_LOOP for every face makes sense. If you’re rendering contour lines on a map - then a mixture of LINE_LOOP and LINE_STRIP makes sense. If you’re rendering tracer fire from a machinegun - the LINES are the way to go.

I guess you could use POINTS for rendering stars in your night sky in an astronomy program.

– Steve