Vertex Buffer Object

Do you think having a single vertex buffer object class for all the shape/mesh/models is better than having more than one each?

If you don’t get it, I’ll try to explain it.

Example:

I have a triangle shape. I call vbotriangle->create(); to create the vbo for that certain shape then call another for another example for mesh, vbomesh->create() to create for that certain shape.

Is better than, For all the triangle,mesh and etc, I have only 1 class vbo so it means all the information for all the mesh and triangle is stored in a single class so if I call the draw function, it will draw everything with just a single call.

So which one is better? Hope you understand.

Generally speaking, fewer draw calls are better than more draw calls and fewer buffer binds are better than more buffer binds. Your approach reduces both.

However, if you’re vertex or fill limited transforming or rasterizing a bunch of stuff you can’t see in that big draw call, then it can slow you down vs. submitting multiple batches. If you had multiple batches grouped by spatial locality, you could cull them separately and potentially not even send some/most of those verts down the pipe at all. So batch size is a balancing act.

Also, some folks say there’s a perf penalty for using uint DrawElements indices over ushort indices, which tends to suggest an upper limit on batch size (under 64k verts).

However, to your original point about packing VBOs, yeah, if you have 2 or more batches you know will always render together if/when they render, pack-em in a smaller number of VBOs. The pro is fewer buffer binds (vs. having separate VBOs per batch). The con is more VBO bookkeeping if you have to support run-time generated/loaded content.

“Also, some folks say there’s a perf penalty for using uint DrawElements indices over ushort indices, which tends to suggest an upper limit on batch size (under 64k verts).”

Yep, and it makes real differences, when you are working with larger meshes. So putting < 64K vertices into a buffer and then only using short indices is a good idea. Though it’s not always possible to do that, depends on your data.

Jan.

Small correction: You can put a lot more data into a VBO, if you need.
ushort indices only limit how many vertices you can reference in one batch, not how many of them fit into a VBO. The “offset” parameter for all glXXXPointer() calls is there for a reason :wink:

Ok thanks for the information guys.

I’m creating a 3d game engine so what should I do? Should I separate it for easy organization over speed?

Imho, go for whatever’s easier for you (for starters). OpenGL is lightweight enough, and bluntest usage patterns are only ~3 times (in my experience) slower than the best optimizations. I’d love to hear corrections if my experience is too limited.

For starters i’d go with a solution that’s easy to implement.

Using VBOs is a good start already. The only mistake beginners often make, is that they put all their data into VBOs and then render each triangle with a separate drawcall. THAT’s bad.

A good guideline is to try to render >100 triangles with each drawcall IF POSSIBLE! That means, if you simply do not have that amount of geometry, don’t force it. There will always be cases, where you simply only have a single polygon textured with a certain texture. But if you have geometry that could be batched, try to do so. That means, sort your geometry by material (ie. texture / shader / other parameters) and then make few drawcalls to render each group. If you do that, your framerates will be quite good already and you won’t need many more optimizations (for now).

Jan.

I would say 10000 a least!

But I quite agree with the idea that using VBO is a good start, optimisations (and so much are possible!) should come later!

I would say it really depend on the context. I managed to reach a gain of 50x once with billboards just reworking the buffer data, the way they are organized, updated and display. It took me a while and I’m sure I could have speed it up event more but most of the times the issue is more about how much time I could spent to optimise a code.

First of all to use 16 bit indices you should use DrawRangeElements rather than offset your pointers. However, there are really a lot of issues when optimising vertex streams, depending on your application. A lot of useful information can be found in here: http://developer.nvidia.com/object/using_VBOs.html

There have been some good discussions about it in these forums, one was started by me (in a rather heated tone ahem) but I’m unble to find it now… censored by ATI?

The whole rigorous batching thing actually comes from d3d 9 and lower where kernel-mode operations were involved. In OpenGL it is much less of an issue and you can get away with a fair amount of draw calls.

The details that can affect your VBO allocations (formats, interleaving, data alignment, updates) really depend on application specifics. So, yeah, start with what’s easy and consider the finer points once you know what your requirements are.

Click :wink:

CatDog

Here are the results of some benchmarks I did recently: click

Here’s what I’m planning for my 3D engine right now.

int main(int argc, char *argv[])
{
//Create Engine
//Load md2 file 1
//Load md2 file 2
//Load md2 file 3
//Load terrain
//Load sky

while(1)
{
//handle input
//begin
//draw <--- vbo draw()
//end

}
}


I’ll pass all the vertex from the md2, terrain, sky class to the vbo class then the begin function will just draw everything.

That’s what I’m planning to do right now. Do you think it is a good idea?

it’s like the last 9 replies never happened, isn’t it?
I wonder if the level of patience shown from now on is proportional to the length of time since these guys last got laid?
:slight_smile:
funniest thread i’ve seen in a long time - thanks.