Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One big OpenGL vertex buffer, or many small ones?

Tags:

c++

opengl

Let's say I have 5 entities (objects) with a method Render(). Every entity needs to set its own vertices in a buffer for rendering.

Which of the following two options is better?

  1. Use one big pre-allocated buffer created with glGenBuffer, which every entity will use (id of buffer passed as argument to Render methods) by writing its vertices to the buffer with glBufferSubData.
  2. Every entity creates and uses its own buffer.

If one big buffer is better, how can I render all vertices in this buffer (from all entities) properly, with proper shaders and everything?

like image 698
nullable Avatar asked Oct 03 '14 06:10

nullable


People also ask

What is a vertex buffer in OpenGL?

A vertex buffer object (VBO) is an OpenGL feature that provides methods for uploading vertex data (position, normal vector, color, etc.) to the video device for non-immediate-mode rendering.

What is VAO OpenGL?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

What are vertex attributes?

A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.


2 Answers

Having multiple VBOs is fine as long as they have a certain size. What you want to avoid is to have a lot of small draw calls, and to have to bind different buffers very frequently.

How large the buffers have to be to avoid excessive overhead depends on so many factors that it's almost impossible to even give a rule of thumb. Factors that come into play include:

  • Hardware performance characteristics.
  • Driver efficiency.
  • Number of vertices relative to number of fragments (triangle size).
  • Complexity of shaders.

Generally it can make sense to keep similar/related objects that you typically draw at the same time in a single vertex buffer.

Putting everything in a single buffer seems extreme, and could in fact have adverse effects. Say you have a large "world", where you only render a small subset in any given frame. If you go to the extreme, an have all vertices in one giant buffer, that buffer needs to be accessible to the GPU for each draw call. Depending on the architecture, and how the buffer is allocated, this could mean:

  • Attempting to keep the buffer in dedicate GPU memory (e.g. VRAM), which could be problematic if it's too large.
  • Mapping the memory into the GPU address space.
  • Pinning/wiring the memory.

If any of the above needs to be applied to a very large buffer, but you end up using only a small fraction of it to render a frame, there is significant waste in these operations. In a system with VRAM, it could also prevent other allocations, like textures, to fit in VRAM.

If rendering is done with calls that can only access a subset of the buffer given by the arguments, like glDrawArrays() or glDrawRangeElements(), it might be possible for the driver to avoid making the whole buffer GPU accessible. But I wouldn't necessarily count on that happening.

like image 143
Reto Koradi Avatar answered Oct 24 '22 05:10

Reto Koradi


It's easier to use one VBO (Vertex Buffer Object) with glGenBuffer for each entity you have but it's not always the best things to do, this depend on the use. But, in most cases, this is not a problem to have 1 VBO for each entity and the rendering is rarely affected.

Good info is located at: OpenGL Vertex Specification Best Practices

like image 40
Rémi Avatar answered Oct 24 '22 04:10

Rémi