OpenGL – Abstraction of VAOs, VBOs, and Models

abstractioncdesignobject-orientedopengl

I have gone down the rabbit hole that is abstracting away a working game engine in OpenGL and C++. Before reaching the other side I'd like to ask about my current design, which is – the more I look at it – eventually in need of a major revision. I have separated windows, input and frame buffers from the concerns, but render operations are becoming a problem.

Currently all types of renderable objects, including frame buffers inherit from a common class: Renderable which has a shader program and a vertex array object. Next in the hierarchy is an Entity (yeah, I'd use better naming..), which has a model matrix, world coordinates, uniforms and associated functions with it.

After that are the specific types of objects. Namely Dummy and Model. They deal with the actual buffers and data. For this example I will focus on Model. It shall load model data from a file, create buffers and draw the model on command. I planned to use a buffer for each attribute and process meshes separately, drawing with index buffers.

I have also separated the concept of a buffer away from the renderable. I use a class for an index buffer and a vertex buffer (or interleaved buffer). The buffer manages data and e.g. binds GL buffers and deals with vertex array pointers and so on.

This all was fine until I asked this question about VAO and VBO granularity on GameDev. Since then more doubts have arisen.

Given that:

  • Only a few VAOs should be used in a whole program
  • Using modern techniques one can switch between the VBOs being used by a VAO when drawing
  • Using a single interleaved buffer for multiple meshes improves performance

I must ask:

  • Is my design sensible?
  • Is using separate classes for buffers a common design pattern?
  • What should be done to accommodate for textures, animations and such in the future?

It seems that particularly when introducing the need of combining multiple meshes and their multiple attributes into a single buffer my design becomes a bit complicated since a buffer needs to know about a VAO and a model needs to provide the buffers with information.

Any insight would be greatly appreciated!

Best Answer

I've had bad experiences with too much abstracted rendering in the past. OpenGL is still very procedural at it's core, and the whole state management is very difficult to debug and extend if you apply a nice modern OO filter and make lots of small objects.

In addition, writing optimized rendering code often forces you to take a global view because the different steps to render a frame and even just the content management/preloading don't map nicely to the approaches used in other parts of an engine.

Therefore, I would separate the functionalities into layers as well as possible, so you can live in a 'looser' OO world with longer methods that deal with OpenGL state, and a nice clean world where you can work in a more abstracted, nice OO context. There's an link to DDD here, with seperate domains designed according to the needs of the domain.

Related Topic