I didn't read everyone's posts closely, but I'll just throw in some thoughts I have made about implementing VBO's while maintaining a "nice and clean" design. Nice and clean would include simplicity, thread-safety, loose coupling, and non-monopolization.
A hardware buffer can be regarded as a
relation between the video driver and the mesh buffer, since it depends on both, and logically only one is necessary for each mesh/driver pair. We want the hardware buffer to be able to update itself according to changes in the mesh buffer (although ideally it should remain static).
To achieve this, suppose a mesh buffer has a
Change ID, which is simply an integer with an initial value of 1. Every time the mesh is altered, it increases by 1. The HardwareBuffer object keeps a copy of the change ID it had last time the mesh was uploaded to the hardware. When the VBO is needed, it can quickly test if its mesh has been changed, and re-upload it if necessary, also updating its change ID.
This approach, which I personally call
Lazy Observer, has the advantage of being thread-safe, and the mesh buffer has no coupling to the video driver or the hardware buffer whatsoever. A downside is, of course, that you need to call a method like "changed()" after a sequence of changes in a mesh buffer.
Creating a hardware mesh buffer should be doable using a simple method like:
Code: Select all
createHardwareMeshBuffer(IMeshBuffer* meshBuffer)
And maybe a second one that simply retrieves a hardware mesh buffer of the given IMeshBuffer if it exists (somewhat like getTexture):
Code: Select all
getHardwareMeshBuffer(IMeshBuffer* meshBuffer)
When a mesh buffer is rendered using the drawMeshBuffer method, maybe the video driver can use a table or something to look for a hardware buffer using that mesh buffer.
I know it's not the traditional Irrlicht-approach, but those were a few thoughts of mine. There's a bit more to it than I wrote here, but make of it what you will.