I’m just started learning OpenGL and this is my first project besides tutorials. I’m trying to load a huge enginering model:
The data is structured in a way that I thought I could use instancing for very good performance, because many items are simple primitives (cylinder, torus, cones, etc) with different transformation matrices. So I structured my data this way:
[INDENT] VBO -> vertices
VBO -> indices
Instance 1.1 [INDENT] VBO -> object color VBO -> transformation matrix Instance 1.2 VBO -> object color VBO -> transformation matrix Instance 1.n VBO -> object color VBO -> transformation matrix[/INDENT][/INDENT]
[INDENT]VBO -> vertices
VBO -> indices
Instance n.1 [INDENT]VBO -> object color VBO -> transformation matrix Instance n.n VBO -> object color VBO -> transformation matrix[/INDENT][/INDENT]
The model has ~50k unique primitives and ~120k instances, so in general each primitive has 2 instances. But in practice, some have 10 and some have only 1. I end up with 50k VAOs and then call dlDrawElementsInstanced for each VAO.
The model is being draw at only 3 fps. I gues it’s because of the number of glDraw calls (50k for the triangles and 50k for the outlines). The shaders are very simple, not even lightning is being applied.
To be sure of that I changed the way I organize the buffers: I put everything in a single buffer, but to do that I had to pass the color and transformations matrices as vertex attributes to each vertex. I know this isn’t right but I had to test if the problem was the number of glDraw calls. I couldn’t even load the model this way because the buffers get way to big and I get out of memory. So I tested this theory on a smaller model that was taking 50ms to render in the instanced way. With a single VAO for everything and only a single glDrawElements call the model is taking less than 1ms to render.
I know that putting everything in a single VAO and passing the trasnformations for every vertex is not the correct way of doing this. Now I also know that instancing isn’t the tool for this due the very few intances for each mesh. So the question is, what would be the correct way to setup the buffers to minimize the number of glDraw calls?
I think that it would be perfect to store all in a single VAO (so I could call glDrawElements a single time) but use something like the glVertexAttribDivisor used in instancing to inform the shaders when to use the next shaders. But not exactly because I had to manually inform when to use the next matrix, in way like glPrimitiveRestartIndex works.