2
votes

I've been trying to find a way to draw thousands of lines in opengl and take as little performance loss as possible. I have to draw beteewn 10000 to 100000 unconnected lines with 21 points each, and I'm not sure how to go about this issue. From what I've found on the web I should try to minimize the overhead of drawing calls and also not to constantly send data to the gpu. Until now I've tried a few things:

  • Using just one VBO for everything.

This way I just send the data once, but end up having draw calls for each line separated by 21 points like glDrawArrays(GL_LINE_STRIP, i * 21, 21) where I iterate over i for the amount of lines. Though this kinda works, but it seems like there could be an easier, more elegant solution, without that many draw calls.

  • Using diferent VBOs for each line.

I didn't really think this was a good idea, it gets really messy and end up having just as many draw calls.

Is there a way to draw thousands of lines with one draw call?, and if not, how should I go about this issue?

I'm using OpenGL 3.3.

1
What is the version of OpenGL ?Kien Truong
Sorry about that, I'm using 3.3chromosome
Have you tried this approach which stores all point coordinates in one array, and then uses glVertexPointer to define an array of vertex data and afterwards draws them with one call to glDrawArrays ?wsdookadr
Maybe you can try one of this GL extensions: EXT_multi_draw_arrays or NV_primitive_restart.rodrigo
I think this can also be done with one call using GL_LINES. Instead of 10000 line_strips with 21 point each, you'll draw 210000 lines. Using glDrawElements will also save quite a lot of memory.Kien Truong

1 Answers

1
votes

That problem has 2 parts. Uploading the data to the GPU and minimizing the drawcalls.

The first you solved it by updating a single VBO. You could improve it if you were using GL 4.4's extension ARB_buffer_storage. With that extension you can have a single VBO again (x3 times the size of what you want) with persistent mapping. That extension minimizes CPU load by avoiding unnecessary copies and synchronization (at least that's what the extension is advertising).

The second problem (minimizing the drawcalls) is a bit tricky. You can use primitive restart as stated in a comment above but that implies having an index buffer. With primitive restart you can have line strips (=less size) and restart a new strip by appending a magic integer (=configurable on GL 3.3) in the index buffer whenever you want. You could also try having simple lines and not line stripes but that will double your buffer. Maybe there are other ways and I will edit this message if I think of something.