nullable
nullable

Reputation: 101

One big OpenGL vertex buffer, or many small ones?

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?

Upvotes: 10

Views: 5325

Answers (2)

Reto Koradi
Reto Koradi

Reputation: 54642

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.

Upvotes: 12

Rémi
Rémi

Reputation: 533

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

Upvotes: 1

Related Questions