Please note that this is purely an architectural/design question. And sorry for the long post, there are a lot of "thinking out loud" here.
I'm working on a simple graphics engine (as a universtiy research project) and I'm stuck with a decision. I'm trying to abstract every low level API call (so there is no direct gl/d3d call in the high level of code) making the "engine" basically graphics-API-independent.
Let's say I have a class that can represent the source of any geometry (eg. positions, normals, texcoords, etc). The attributes provided can vary from geometry to geometry, there is no guarantee that every geometry contains all of the possible attributes.
I also have the traditional Scene/GameObject/Component/etc classes: a GameObject can be added to the Scene and a GameObject can contain any number of Components.
Lastly, there are multiple Renderers that iterate over a certain set of "things" and use the RenderDevice to issue graphics commands (like setting states, creating resources, executing draw calls, etc).
I'm wondering where I should create/store the actual vertex buffer(s), etc. As far as I know, it is the best to have the least amount of different vertex layouts. Also, the vertex layout is tightly coupled to the shader (especially in DX11+) so it seems logical that the renderer specifies a vertex struct with a layout descriptor. And this was my initial idea.
However, this means that only the renderer knows how to align/store data interleaved from the individual components of the geometry source. And this means that the renderer should create the actual vertex buffers. (This would also help with static batching, since the batching logic depends on the actual rendering task).
However with this approach a "GeometrySource" might be stored in multiple vertex buffers. For example the ShadowMapRenderer requires only the position component of the geometry. Also it can batch every static geometry into a single vertex buffer since there will be no state/uniform/etc changes between the draw calls.
My very first approach (years ago) was that the GeometrySource self-contained a vertex buffer with a vertex layout descriptor. However there are multiple problems with this approach:
- every (even the smallest one) geometry would be stored in separate buffers which would cause a big driver overhead
- in the modern graphics APIs (eg. DX11+) the vertex layout is tightly coupled to the shader that will be used to render that geometry (see)
- the vertex layout should be checked before rendering (does the buffer provide every necessary attribute with the right format?)
So I don't think that this approach would be beneficial. What is a sensible alternative?
Also, there are multiple stack*** posts, but unfortunately, I couldn't find my answer in these: