0
\$\begingroup\$

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:

\$\endgroup\$
  • 1
    \$\begingroup\$ Maybe you can get some inspiration from github.com/MonoGame/MonoGame ? \$\endgroup\$ – Aybe Feb 26 at 1:29
  • \$\begingroup\$ @Aybe Thanks, gonna take a look for sure! Seems like a good source. I was trying to figure out some things from the UE4 source, but that codebase is so huge (and let's be honest: it's ugly here or there) \$\endgroup\$ – csisy Feb 26 at 14:30
  • 1
    \$\begingroup\$ A while ago I wrote something similar: 1drv.ms/u/s!AqAtR29m3cqGyn2b834cdoHAHoHw , sharpmix.com/blog/gla . It's very old and I would certainly do things differently today, however, it was the strict minimum extracted from MonoGame/XNA to somehow abstract the calls as they do. It's small enough that you can quickly grasp the concepts, then check actual MonoGame sources to see how it is now. It used GL (OpenTK) and VS2010 so expect minor adjustments before being able to compile it. Good luck! \$\endgroup\$ – Aybe Feb 26 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.