Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render multiple models in OpenGL with a single draw call

Tags:

opengl

shader

3d

I built a 2D graphical engine, and I created a batching system for it, so, if I have 1000 sprites with the same texture, I can draw them with one single call to openGl.

This is achieved by putting in a single vbo vertex array all the vertices of all the sprites with the same texture.

Instead of "print these vertices, print these vertices, print these vertices", I do "put all the vertices toghether, print", just to be very clear. Easy enough, but now I'm trying to achieve the same thing in 3D, and I'm having a big problem.

The problem is that I'm using a Model View Projection matrix to place and render my models, which is the common approach to render a model in 3D space.

For each model on screen, I need to pass the MVP matrix to the shader, so that I can use it to transform each vertex to the correct position.

If I would do the transformation outside the shader, it would be executed by the cpu, which I not a good idea, for obvious reasons.

But the problem lies there. I need to pass the matrix to the shader, but for each model the matrix is different.

So I cannot do the same I did with 2d sprites, because changing a shader uniform requires a draw every time.

I hope I've been clear, maybe you have a good idea I didn't have or you already had the same problem. I know for a fact that there is a solution somewhere, because in engine like Unity, you can use the same shader for multiple models, and get away with one draw call

like image 545
Ryno Avatar asked Jun 14 '15 21:06

Ryno


1 Answers

There exists a feature exactly like what you're looking for, and it's called instancing. With instancing, you store n matrices (or whatever else you need) in a Uniform Buffer and call glDrawElementsInstanced to draw n copies. In the shader, you get an extra input gl_InstanceID, with which you index into the Uniform Buffer to fetch the matrix you need for that particular instance.

You can read more about instancing here: https://www.opengl.org/wiki/Vertex_Rendering#Instancing

like image 82
orost Avatar answered Sep 28 '22 02:09

orost