The metaphor refers to one programming task leading to another. In this case, adding support for vertex buffer objects lead to writing a framework for managing OpenGL resource names/handles, and very nearly resulted in an all-out assault on the current content loading framework. Thanks be to Andreas Raab for advising against that (sometimes I can be hasty). But I digress...
What happened this week?
I finished the vertex buffer work alluded to in my last entry. Below, I'll discuss this in excruciating detail.
Work on Brie continues. Howard has been making progress with the coding, and we continue to discuss issues as they arise. A lot hinges on uncertainty about what TeaTime will actually look like. Now that I'm finished with the vertex buffer work, I'll be helping Howard with coding Brie. Fun!
So, tell me about those vertex buffers...
Such an interested audience!
I finished a prototype rendering path using vertex buffers shortly after my last blog posting. Preliminary results were very encouraging: for the previously mentioned large meshes, the frame rate jumped from approximately 5 fps to 35 fps. This encouraged me to implement this feature in a more robust fashion, suitable for general use in Croquet. This work had two major aspects: managing the low-level OpenGL names for the resources, and allowing the vertex buffer rendering path to be disabled when desired (currently, when the OpenGL implementation does not support vertex buffers, and whenever else desired).
In OpenGL, vertex buffers are named by an integer, as are many other types of resources such as textures and compiled shader programs. Recognizing the similarities between the way these resources are created, used, and destroyed, I designed a resource management framework that could support them all. I considered two major architectural approaches. The first was to generalize the functionality of OGLTextureManager, and the second was to create/destroy resource names within the scene graph objects as necessary (for example, this would involve modifying TTexture to directly hold an OpenGL name/handle, rather than referring to it indirectly via OGLTextureManager and OGLTextureHandle). The latter path was rejected because it would require significant reworking of TTexture, and more importantly because the handles are only valid in a single OpenGL context (disregarding resources shared between contexts, which is a can of worms that we can do without opening). Following the lead of OGLTextureManager, I created OGLResourceManager, which maps scenegraph objects (eg: TTexture, TVertexBuffer) to their low-level OpenGL counterparts (OGLTextureName, OGLBufferName).
Wow, that sounds pretty cool. How does this resource management fit in with rendering meshes?
With the resource manager in place, I turned to modifying TMesh to allow the use of vertex buffers. The cleanest way to do this was to make TVertexBuffer into a wrapper around the data (vertices, face indices, etc.). TVertexBuffer needs access to this data anyway, since it might have to create a new low-level vertex buffer object at any time (for example, if the Croquet image is saved and quit, and then restarted, an open TeapotMorph will create a new OpenGL context to render in, and new resources will have to be created in this context). It is also convenient because it makes it easy for the mesh to fall back to the vertex array render path whenever vertex buffers are not available or not desired.
Sounds good, but does it work?
First, the good news. There is a drastic improvement in the speed of rendering large meshes. This is excellent, since it was the motivation for this work.
Now, some indifferent news (not really bad). There was no speed improvement when rendering the default Croquet spaces using vertex buffers for all meshes. Some possible explanations are:
- we are overflowing the GPU memory (64MB on my laptop) and therefore OpenGL must send the data across the AGP bus anyway (essentially resulting in the vertex array model)
- for small meshes, the benefits of vertex buffers are outweighed by the overhead of managing resource names
- the bottlenecks are elsewhere for rendering the types of Croquet scenes that are currently typical
Preliminary benchmarking and profiling suggests that the last option is the most likely. However, I would have to study the issue more deeply before being willing to bet large sums of money on this opinion.That sounds wonderful, but I really must go.
Me too. Thanks for listening.