2
\$\begingroup\$

I'm very new to OpenGL/LWJGL. I'm reading a lot of VBOs.

I'm sorry if I can't concretise my concern, but i'll try it:

  1. Why should I use VBOs? Whats the difference between using VBOs and glBegin() and glEnd()?

  2. My Game is organized like this:

    • One huge map
    • some static objects like trees on this map
    • Enemies and Characters

Enemies and Characters are spawned on the fly

and my gameLoop is like this: statemanager.render()=>Map.render()

Where Map has an Enemy[] and Character[], where both of them have a Tree of Meshes and Mesh has the Vertex-Arrays.

public class Tree<T>
{
  T data;
  T child;
}
abstract class MoveableObject
{
  Tree<Mesh> meshTree;
  public Vector3f pos;
  public Vector3f rot;
}

public class Mesh
{
  Vector3f[] vertices;
  Vector3f[] colors;
  Vector3f[] normals;
}

Where and how should I setup the VBOs? For example A map and the statics never change, can I setup a VBO once for them instead of setting it up every frame?

Most OpenGL Tutorials show prototypes of the methods, but never explain the parameters of these methods. It's hard to understand how they actually work, if you've never worked with it before. (Yes, I alread did that Triangle/Cube Tutorial)

\$\endgroup\$
  • \$\begingroup\$ vbo setup should be outside of frame loop. \$\endgroup\$ – tp1 Jan 11 '15 at 21:45
  • \$\begingroup\$ "can I setup a VBO once for them instead of setting it up every frame?" Yes! That's exactly what VBOs are for. And by doing that, OpenGL can go much faster. Your characters & enemies should be VBOs also, possibly manipulated every frame by either changing the data itself, or changing shader parameters like their object matrix and such. \$\endgroup\$ – david van brink Jan 11 '15 at 23:19
  • \$\begingroup\$ Imagine if you had a model with 50000 vertices. With glBegin/glEnd, you have to process all of those vertices every frame (even if the processing is just calling glVertex3f). \$\endgroup\$ – user253751 Jan 12 '15 at 4:35
3
\$\begingroup\$

TLDR: VBOs makes a huge difference in performance.

One simple reason to use them would be that OpenGL ES (mobile devices) don't support glBegin(...)/glEnd() so you have to use glDrawArrays() but not necessarily VBOs.

The main reason to use VBOs is that it allows the OpenGL driver to keep the vertex data in GPU memory, rather than CPU memory which forces the GPU to copy the data over the device bus (PCIe) every time you want to draw something.

So when you want to draw the map all the data is already in the 3D card's memory and the only thing that gets sent over the (slow) bus is essentially a single command:

  • Draw N triangles starting at address M

Rather than:

  • Mode: Triangle
  • Here's a color
  • Here's a normal
  • Here's a texture coordinate
  • Here's a vertex
  • Here's a color
  • Here's a normal
  • Here's a texture coordinate
  • Here's a vertex
  • Here's a color
  • Here's a normal
  • Here's a texture coordinate
  • Here's a vertex
  • Here's a color
  • Here's a normal
  • Here's a texture coordinate
  • Here's a vertex
  • ...

Note: this is a simplified explanation and yes there's 3D hardware that actually work this way with commands sent one-by-one like this.

Even if today's drivers pack everything between glBegin and glEnd into a buffer and send it over to the GPU in one block you're still making a whole bunch of OpenGL calls wasting CPU time, flushing caches for the buffer, and sending all that vertex data over the bus every time you draw something which keeps the memory bus busy, often preventing the CPU from doing other work at the same time.

Using VBOs leaves the device bus and CPU memory bus free. Letting the GPU do its thing in its own memory while the CPUs are doing something else with its memory like updating AIs, decoding & mixing audio, etc.

\$\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.