Lizi
Lizi

Reputation: 173

OpenGL best practice regarding VBO updating when VAO are required

I made an engine in a team a while back and one of the engineer told me to use 2 vertex buffers and swap them, giving me this link : https://www.khronos.org/opengl/wiki/GLAPI/glBufferSubData

Where it says :

When replacing the entire data store, consider using glBufferSubData rather than completely recreating the data store with glBufferData. This avoids the cost of reallocating the data store.

Consider using multiple buffer objects to avoid stalling the rendering pipeline during data store updates. If any rendering in the pipeline makes reference to data in the buffer object being updated by glBufferSubData, especially from the specific region being updated, that rendering must drain from the pipeline before the data store can be updated.

So back then we instanced 2 VBOs, gave them a size with glBufferData and then every frame we would "swap" which of the two VBOs was used (to avoid getting the synchronization slow down that comes with glBufferSubData) by binding the other one, using glBufferSubData on it to update the data and then drawing.

I can't find information anywhere as if this is a best practice using OpenGL or if it would be better to just use 1 VBO and use glBufferData every frame instead.

I was also wondering, with GL 3.3 core requiring to declare a VAO, in the case of the 2 buffers would it be better to declare 2 VAOs as well and just swap between them or would it be better to only make 1 VAO and swap between the VBOs in this single VAO?

Upvotes: 1

Views: 917

Answers (1)

I would recommend to study the OpenGL wiki on that topic:

Streaming
Main article: Buffer Object Streaming

Streaming is the process of frequently uploading data to a buffer object and then using that buffer object in some OpenGL process.

...

The key to streaming is parallelism. The OpenGL specification permits an implementation to delay the execution of drawing commands. This allows you to draw a lot of stuff, and then let OpenGL handle things on its own time. Because of this, it is entirely possible that well after you called the rendering function with a buffer object, you might start trying to stream vertex data into that buffer. If this happens, the OpenGL specification requires that the thread halt until all drawing commands that could be affected by your update of the buffer object complete. This obviously misses the whole point of streaming.

The key to effective streaming is synchronization.

More info related to VBO's and VAO's can be found here: Vertex Specification, especially Vertex Buffer Object and Vertex Array Object.

You may also find this info useful: Vertex Specification Best Practices (Dynamic VBO - which could be the actual answer to your question).

Another thing you can do is double buffered VBO. This means you make 2 VBOs. On frame N, you update VBO 2 and you render with VBO 1. On frame N+1, you update VBO 1 and you render from VBO 2.

Upvotes: 1

Related Questions