Two quick VBO Questions
Decided to convert my current project from Vertex Arrays to VBO yesterday, and all went smoothly (A nice surprise after working with DirectX's locking and unlocking for so long) But it left me with a couple of questions that I haven't found documentation for:
1) (Easy one first!) Is it preferable to use Seperate or Interleaved Arrays with VBO? I'm using Interleaved right now, and I haven't had any problems, but if Seperate arrays are optimal might as well use them instead, since it's not much trouble on my part.
2)When using an indexed array (glDrawRangedElements() in this case) is there an easy way to specify an offset into the Vertex array? For example, in DirectX when calling DrawIndexedPrimitive() you can specify the base vertex index, which will treat the specified vertex as index 0.
There is a similar parameter in glDrawArrays() that lets you specify the first vertex to use, and in fact the Nvidia white paper encourages using this rather than specifying the offset when calling glVertexPointer (or glInterleavedArrays(), as the case may be.)
This does you no good when using indexed verticies, however. With glDrawRangeElements() you can specify a "start" and "end" index, but I don't get the impression that theis affects the vertex array offset at all. Because of this, if I have a mesh that starts at Vertex 15 in my VBO, it seems I would either have to... a) Increment all my indices for that mesh by 15 or b) call glVertexPointer (or equivalent) for each mesh with the appropriate offset (but that's supposed to be bad. >_<)
I'd imagine these are both simple questions, but like I've said, there seems to be little in the way of good documentation on these little niggly subjects.
hi I'll give it a try:
1. Not sure it matters really - whatever is the most convenient for yourself to use - you could maybe do a few quick tests to see how much memory having seperate arrays for each would use in comparison. I can't see how either would be significantly faster/worse/whatever.
2. Ok, I think I know what you mean - I use glDrawElements to access from within the arrays eg I use it like this:
glDrawElements(GL_TRIANGLE_STRIP, length, GL_UNSIGNED_INT,
(const void *)&m_indexArray[from]);
Subsequent calls would have 'from' being a differnet place in the array and 'length' the new amount of vertices to process.
1. Not sure it matters really - whatever is the most convenient for yourself to use - you could maybe do a few quick tests to see how much memory having seperate arrays for each would use in comparison. I can't see how either would be significantly faster/worse/whatever.
2. Ok, I think I know what you mean - I use glDrawElements to access from within the arrays eg I use it like this:
glDrawElements(GL_TRIANGLE_STRIP, length, GL_UNSIGNED_INT,
(const void *)&m_indexArray[from]);
Subsequent calls would have 'from' being a differnet place in the array and 'length' the new amount of vertices to process.
1) Interleaved Arrays should be optimal. The reason being the GPU can stream the data over in chunks instead of having to grab one bit, then hop to another memory location, grab another, hope else where etc. Granted, the cache on the GPU can help with this, but it still wont be as good as being able to pull it from one memory location in one stream.
Two notes about this;
- Dont use glInterleavedArrays() to set this up. The formats for vertex data are far too restrictive, instead use the gl*Pointer() functions.
- Try to group your data in at least blocks of 32bytes (min. AGP transfer size). Dont go overboard on this however, the pre-T&L cache can store data, but the closer the better [smile]
2) gl*Pointer() is really the only way todo it with indexed vertex arrays. The 'start' and 'end' parameters of glDrawRangeElements() just tells the driver what the start and end indices of data you'll be using are, soit can optimise its coping.
gl*Pointer() is only bad on NV hardware due to how they handle VBOs and even 'bad' is pushing it, just dont over do it is what they are saying because they happen todo alot of the heavy work then (ATI do it at a different point I belive).
To be honest, if you've got a model which starts slighting into a VBO you'd probably be better off giving its own index buffer to work with.
Two notes about this;
- Dont use glInterleavedArrays() to set this up. The formats for vertex data are far too restrictive, instead use the gl*Pointer() functions.
- Try to group your data in at least blocks of 32bytes (min. AGP transfer size). Dont go overboard on this however, the pre-T&L cache can store data, but the closer the better [smile]
2) gl*Pointer() is really the only way todo it with indexed vertex arrays. The 'start' and 'end' parameters of glDrawRangeElements() just tells the driver what the start and end indices of data you'll be using are, soit can optimise its coping.
gl*Pointer() is only bad on NV hardware due to how they handle VBOs and even 'bad' is pushing it, just dont over do it is what they are saying because they happen todo alot of the heavy work then (ATI do it at a different point I belive).
To be honest, if you've got a model which starts slighting into a VBO you'd probably be better off giving its own index buffer to work with.
Thanks for the tips! Since I'm already using Interleaved Arrays I'll just leave it be. (Yay! Less code!) I'm still debating on what to do with the Vertex Offset, though.
@_the_phantom_: What do you mean by "if you've got a model which starts slighting into a VBO you'd probably be better off giving its own index buffer to work with?" What's slighting? A typo? Also, I'm not sure why having a seperate index buffer would be benifical. Could you expand on that a bit?
In any case, it's good to know that this is really an Nvidia thing only, which tells me that it could very easily change in future drivers ^_^ I think I'll fiddle a bit and see what the most efficent way of switching meshes is, but I've at least got a bit more to go on now. Thanks!
Any further comments/suggestions would be appreciated!
@_the_phantom_: What do you mean by "if you've got a model which starts slighting into a VBO you'd probably be better off giving its own index buffer to work with?" What's slighting? A typo? Also, I'm not sure why having a seperate index buffer would be benifical. Could you expand on that a bit?
In any case, it's good to know that this is really an Nvidia thing only, which tells me that it could very easily change in future drivers ^_^ I think I'll fiddle a bit and see what the most efficent way of switching meshes is, but I've at least got a bit more to go on now. Thanks!
Any further comments/suggestions would be appreciated!
*chuckles* yes, that should have been 'slightly' [grin]
Really, it depends on how you are structuring your data/models.
If you are packing multiple models into the same VBO then giving each model the correct index data will be better than rebinding the VBO at slightly different positions each time.
I wouldnt worry too much about strange cases such as that, remember you are in control of the data so you can lay it out how you want to. If you are packing then setup the indices as required.
Really, it depends on how you are structuring your data/models.
If you are packing multiple models into the same VBO then giving each model the correct index data will be better than rebinding the VBO at slightly different positions each time.
I wouldnt worry too much about strange cases such as that, remember you are in control of the data so you can lay it out how you want to. If you are packing then setup the indices as required.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement