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?
glGenBuffer
, which every entity will use (id of buffer passed as argument to Render
methods) by writing its vertices to the buffer with glBufferSubData
.If one big buffer is better, how can I render all vertices in this buffer (from all entities) properly, with proper shaders and everything?
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.
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.
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.
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:
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:
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With