10
$\begingroup$

From my basic understanding, a Vertex Buffer Object works something like this (pseudo code):

Normally, if one wanted to say, draw a square, one could issue line drawing commands.

line (0, 0) -> (1, 0)
line (1, 0) -> (1, 1)
line (1, 1) -> (0, 1)
line (0, 1) -> (0, 0)

Using a VBO, if I understand correctly, would load the vertices into a VBO.

define VBO
load (0,0) -> VBO
load (1,0) -> VBO
load (1,1) -> VBO
load (0,1) -> VBO
load (0,0) -> VBO

Then you can issue one drawing command.

draw VBO vertices

While I understand how VBOs work, I don't know why they improve performance.

How do they improve performance?

$\endgroup$
11
$\begingroup$

In general, when you render an object in an immediate mode—issuing line drawing commands for instance—you build up a series of commands that you submit to the graphics card to draw. If you're drawing a lot of data, or drawing very frequently, you can waste a lot of time sending this data over and over again.

A vertex buffer allows you to produce a single object that you submit to the graphics card once. If you don't need to change your geometry, you can leave it on the graphics card and simply send the graphics card a request to draw that object. Since it avoids the copy every time you draw, there's much less overhead for each draw.

Note that using a vertex buffer object doesn't always provide a very significant speedup. If you're only drawing the object once per frame, and you're replacing the geometry in between each frame, then you don't get the benefits of avoiding the copy each frame.

Most of my experience comes from writing programs using graphics APIs like OpenGL, so someone who's messed with the backend of a graphics driver can probably provide a more detailed answer, but I hope this makes things a bit clearer.

$\endgroup$
10
$\begingroup$

There are two steps that make the VBO more efficient than immediate mode.

  1. Immediate mode (glBegin/glEnd, glVertex*, etc.) means that at each frame, you spoon feed the vertices, attribute per attribute (position, normal, color, etc.), to the driver, which then reformats them and finally sends the whole package as a command to the GPU. That a lot of function calls per vertex on each frame.
    (Note that immediate mode is deprecated since OpenGL 3.0, and is entirely removed from 3.2.)

  2. By using vertex arrays (see glDrawArrays, glDrawElements, glVertexPointer, etc.), you can give the driver the whole thing at once and save it the burden of reformatting the vertices. You're effectively replacing several function calls per vertex by just a handful of calls for the whole mesh. But you still need to do that once a frame.

  3. Vertex Buffer Object, or VBO (see glGenBuffers, glBindBuffer, etc.) go one step further and store the data on the GPU side: you send it only once, and then just refer to it by a handle. You save bandwidth by not sending the same data over and over at each frame.

$\endgroup$
6
$\begingroup$

By using an immediate mode interface (e.g. old style OpenGL glBegin()/glEnd()/glVertex()) you're effectively drip feeding data to the driver one piece at a time. It then has to take that single piece of data, reformat it and pass it on to the hardware (which these days means putting it into a command buffer).

By using a vertex buffer object, you're providing a (hopefully) large block of data to the driver ahead of when it needs to be used. It can perform a number of optimizations (reformatting, placing into video memory) as well as not having to feed the GPU piecemeal.

In practice if you're only drawing a small number of primitives then it probably won't make much difference, however if you're drawing a multi-million triangle mesh then VBOs in video memory are the way to go.

$\endgroup$

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.