1

Here is a fiddle of the simplest case: http://jsfiddle.net/headchem/r28mm/10/

Is there any way to avoid calling this line for every single triangle I wish to draw?

gl.drawArrays(gl.TRIANGLES, 0, numItems);

As a learning exercise, I'm trying to create a 2D game out of simple colored triangles. I'd like to put several hundred moving triangles on screen each frame, but my framerate is very slow with my current attempts. I suspect it's because of the hundreds of drawArrays() calls I am making each frame.

I've read a bit about Vertex Buffer Objects, and this question sounds promising, but I'm having trouble putting all the pieces together in my fiddle demo above. Is it possible to render hundreds of unique 2D triangle shapes + different colors + transparency in a single draw call with good performance?

Community
  • 1
  • 1
ElonU Webdev
  • 2,451
  • 14
  • 15
  • 1
    What you do is called ["immediate mode" rendering](http://stackoverflow.com/questions/6733934/what-does-immediate-mode-mean-in-opengl). And it is a terribly wrong way of doing OpenGL. Using *Vertex Buffer Objects* is a plain standard nowadays. Future optimizations could include static and dynamic *"batching"*, *"geometry instancing"*, generation of primitives in *geometry shader* or *tessellation shaders* and any combination of those. You will probably want to run some googling as now you have the keywords. Also, some basics of those topics are included in modern OpenGL books (OpenGL 3.0+). – Ivan Aksamentov - Drop Jul 06 '14 at 02:56
  • @Drop: Note the `opengl-es` and `webgl` tags. Most of the features you propose are not available in OpenGL ES 2.0 (which WebGL is based on). – Reto Koradi Jul 06 '14 at 04:36
  • @RetoKoradi Oh, I didn't see those tags. There was only `opengl` before ;) Anyway, VBO and batching are must have and are available everywhere. – Ivan Aksamentov - Drop Jul 06 '14 at 04:58
  • @Drop: Yeah, genpfault was fixing the tags just before I came across the question. – Reto Koradi Jul 06 '14 at 05:07
  • @Drop: no, that is _not_ immediate mode. Immediate mode is `glBegin/End` with several GL calls _per vertex_ and not even supported by wegbl. – derhass Jul 06 '14 at 12:43

1 Answers1

1

Weather you use a VBO or not you seem to have a major problem in your vertex data design as each object contains the data needed for drawing and those data are not in the same array. First thing you should consider is how to pack those data together. In my opinion it would be best to create an array of vertices in your case combined both positions and colours, then your triangle objects should have a reference to a specific point that array where its vertex data lay. For instance the first object would be at 0, second would be at (3*3 + 3*4) as in (number_of_vertices * number_of_floats_per_point + number_of_vertices * number_of_floats_per_color). In this case you can now draw all the triangles using a single draw call with this same array of vertex data.

There can be a few problems in this procedure as you might need to inflate/deflate the array of data but you should be able to make it.

As for VBO the procedure is exactly the same except you need to maintaing the whole array as the VBO, getting the pointer and changing the data on the fly. Now if those data are constantly moving (you are changing most of the data on every frame) then you will gain nothing from the VBO and it is useless to even crate it. But if you do use it try to have only 1 buffer for all the triangles.

Also note you do NEED to have a colour as an attribute and must be defined per-vertex to complete your drawing as a single draw call.

Matic Oblak
  • 16,318
  • 3
  • 24
  • 43
  • Marking as answer because this is eventually what I ended up doing (also thanks to the suggestions made by @Drop). I now have a follow-up question here: http://stackoverflow.com/questions/24616756/is-updating-the-entire-vbo-on-each-frame-the-most-efficient-way-to-draw-many-cha Thanks for your insight! – ElonU Webdev Jul 07 '14 at 17:56
  • Actually, I only implemented the VBO in my new question - I'm still working on combining the vertex array with the color array. The overall size of the data is the same, but does only updating a single buffer instead of two buffers really yield big performance gains? – ElonU Webdev Jul 07 '14 at 18:17
  • 1
    Success! http://jsfiddle.net/headchem/r28mm/14/ This is an update that uses only a single buffer for both vertices and color. It definitely improved performance. Thanks! – ElonU Webdev Jul 07 '14 at 18:48
  • For posterity, performance was again greatly improved by following the recommendations of this answer: http://stackoverflow.com/questions/24616756/is-updating-the-entire-vbo-on-each-frame-the-most-efficient-way-to-draw-many-cha/24623816#24623816 Here is the final result: http://jsfiddle.net/headchem/r28mm/16/ – ElonU Webdev Jul 08 '14 at 15:12