1

How does one efficiently update the vertices between render calls and dynamically render lines between some of these points?

I am working on a basic OpenGL example and it's a static vertices array that renders using glDrawArrays and the GL_TRIANGLES Macro.

I would like to experiment a little with dynamically updated vertices and draw basic lines between random points.

some_id
  • 29,466
  • 62
  • 182
  • 304

1 Answers1

2

You actually have two questions here, one has to do with updating vertex data and the other has to do with drawing a subset of the vertices contained in your buffer.

When it comes to updating data in a vertex buffer, you can't (or rather, shouldn't) change data in a Vertex Buffer Objet that is flagged as static. I assume that is what you mean by static vertex data? The usage flag on VBOs is just a hint, but calling a VBO STATIC is supposed to tell the driver that you are going to send it data once and draw multiple times.

Your appropriate flag would either be STREAM (updated at least once after the initial data is supplied) or DYNAMIC (updated frequently).

Now when it comes to actually changing data in a Vertex Buffer Object, you have two options:

  1. Map it into your application's address space using glMapBuffer (...) and have the driver detect which regions of memory you modified.

  2. Send contiguous blocks of data using glBufferSubData (...).

Since you said you want to update random locations in your buffer, you might be better off mapping the buffer instead of making potentially hundreds of calls to glBufferSubData (...).

As for drawing lines between a couple of vertices, what you want to do is use an Index Array. In modern OpenGL you will use the same mechanism (namely Vertex Buffer Objects) to store indices into your vertex buffer. You call glDrawElements (...) with the type of primitive (GL_LINES) in this case to construct using the vertex indices in the Index Array, the first index to draw and the number of indices total.

glDrawElements (...) will run through your index array starting at the offset you supply and draw (NumberOfElements / NumberOfElementsPerPrimitiveType) primitives. For GL_LINES, each line is defined by 2 indices (so you will draw n/2 lines if you supply n indices).

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • How are lines drawn between vertexes at specific indexes in the array? e.g. first callback, draw a line between index 2 and 9, second render, draw a line between index 6 and 1 etc. – some_id Aug 18 '13 at 15:42
  • There's not really any callbacks. You are just telling OpenGL which vertices (by their index) to use when building primitives (lines in this case). There are LOOP modes (where each vertex connects to the next and the last one connects back to the first) and STRIP/FAN modes (where vertices/edges are shared to reduce the number of indexes you have to pass). Using plain GL_LINES, every 2 indices in your element array defines a unique line. – Andon M. Coleman Aug 18 '13 at 15:52
  • The beauty of element arrays is that the vertex shader only has to transform unique vertices once even if they are used by 20 or 30 different primitives in a single list of indices. It is all about efficient re-use of data. – Andon M. Coleman Aug 18 '13 at 15:54
  • Thanks. I am thinking more regarding rendering lines between GLPOINTS. E.g. 50 points in 3d space and I want to render lines between them at random, I dont see where this ties to the array of vertices and where the specific calls to draw the random lines are done. – some_id Aug 18 '13 at 15:58
  • You can do it in a single draw call if you pick your 50 random points by their index and put them into an array of elements. – Andon M. Coleman Aug 18 '13 at 16:04
  • Will the lines be drawn in real time or due to fast processing will they be rendered instantly? I would like to have them visibly render one at a time. I guess one line can be drawn per call, but is this optimal? – some_id Aug 18 '13 at 16:19
  • No, even if you make multiple draw calls, hardware/software is so fast these days that you would never see the lines being drawn over time - even if you did disable double buffering. For that, I would suggest you use a timer and draw each line after an interval of say 100-250 ms. – Andon M. Coleman Aug 18 '13 at 18:00