Multiple Vertex Layout

Is there a way to use single vertex buffer object with multiple vertex formats? For example, it may contain batches that have different vertex layouts.

Is it okay to change the VertexAttribPointer’s on currently bound buffer after drawing a batch, and then proceed with next using the new vertex layout specified by VertexAttribPointer’s?

Thanks.

Yes that’s possible. glVertexAttribPointer is actually a kind of binding point, just need to make sure that the buffer object is binded when you call it.

One issue is that actually is works just like is would be 2 completely different draw calls

glBindBuffer(a)
glVertexAttribPointer(x)
glBindBuffer(0)

glDrawArrays();

glBindBuffer(b)
glVertexAttribPointer(x)
glBindBuffer(0)

glDrawArrays();

Whatever the value of a and b, that’s fine! With VAO you would have to bind 2 differents object anyway.

Some new opportunities appear with nVidia bindless extensions but it’s depend on what you actually want to do.

Groovounet, please don’t confuse the OP.
He was asking about multiple vertexformats in a single VBO.

glfreak, yes it is perfectly possible to use a sequence like this:

glBindBuffer(vbo)

glVertexPointer() // provide format and offset
glDrawArrays()/glDrawElements()

glVertexPointer () // provide other format and other offset
glDrawArrays()/glDrawElements()

you can even use the same vbo for the indices at the same time, if you want.

Another advice: glBindBuffer(0) is never needed in an application that does purely VBO array based rendering.

Additionally, the bindless stuff is not offering more features than standard VBOs, it just allows the same things to be done more efficiently.

I have added glBindBuffer(0) just to show that the array buffer binding point isn’t used at draw call, glVertexAttribPointer have their own binding points.

A and B could be the same buffer in my example.

If the vertex coordinates count and type do not change you can also just bind one vbo and use multiple ibo which could be use to draw different kind of primitives.

It also depends on how vertex data is stored in your vbo. If data is consecutively stored for each primitive type one after another, you may call glDrawArrays multiple times with different starting indexes.

But all I am saying here is only relevant if the nature and the number of vertex coordinates does not change among all vertex formats.

If you really want to go all-out, you can allocate a single huge VBO from which your application allocates chunks on demand for loaded geometry. The point is that a VBO is only a memory block which can be divided up between various blocks of vertex data and indices.

Thanks alot for help. However I was wondering if resetting VertexAttribPointer’s can be real-time performance bottleneck???

What if the Draw call has not finished yet and resetting the pointers may cause confusion to the GPU? How to synchronize this?

With buffer object, this synchronization issue doesn’t apply anymore … Actually this issue applies on vertex arrays and is being sure that the data still exist when the draw call command is processed.

If you change the vertex format, it’s just going to affect the next draw call.

VAO and recent nVidia bindless stuff have been added to reduce the CPU bottleneck or at least reduce cost of these glVertexAttribPointer and vertex layout setup.

On one hand, I’m not sure about any gain with VAO and to be fair I think this feature might be dead at birth in other hand the recent nVidia bindless stuff seems great and have already proof of results

As I understand from you, VAO is not what’s supposed to be, an onboard video memory buffer? Like in Direct3D?

Or is it the binding steps?

The driver makes sure all GL calls are processed in the right order.

No, that’s a buffer object. A VAO is a state object containing information about the vertex attribute bindings.