PDA

View Full Version : Organising draw calls



Cloudy McStrife
12-01-2015, 11:12 AM
Hey guys.
Whats the best way to organize the draw calls.
What I mean:
I'm currently trying to implement a game engine.
I can draw multiple meshes etc.
But now I want to improve the performance of my engine.
At the moment my draw calls are looking like this.

pseudo code:

drawmesh()
bind_vao();
use_program();
gldrawArrays(...);

I have thought of a way to improve that, but I know there must be a better way.

My thought:

drawmesh()
bind_vao();
draw_all_meshes_using_this_vao();
bind_next_vao();
....

I hope you understand my problem. And sorry for my bad english :P

Thank you :D

GClements
12-01-2015, 12:37 PM
First, any meshes which use the same shader program, uniform values and other GL state can be drawn in a single draw call. You just need to store the attribute data in the same set of buffers rather than using a different set for each mesh.

Where meshes use the same shader program and other GL state but use different uniform values, you may be able to replace uniforms with attributes (or a single attribute which is used as an index into a uniform array).

Multiple textures with the same basic properties (size, filter/repeat modes, etc) can be merged into an array texture. Multiple textures of the same type (2D, cube map, etc) but different properties can be bound to different texture units which are accessed via a uniform array of samplers (indices into arrays of samplers must be dynamically-uniform; in the fragment shader, this basically means that they have to be per-triangle rather than per-fragment).

Where meshes use different shader programs, you may be able to merge the programs into a single "ubershader" which can handle all of the different mesh types.

In the end, you only need to use different draw calls if they require different GL state (e.g. rendering to different FBOs) or need to be rendered in separate passes for other reasons.

But there's a limit to how far you need to take that. If you can render the entire scene in two draw calls, it's not worth expending significant effort so that you only need one draw call.

Cloudy McStrife
12-01-2015, 02:48 PM
First, any meshes which use the same shader program, uniform values and other GL state can be drawn in a single draw call. You just need to store the attribute data in the same set of buffers rather than using a different set for each mesh.


Yeah I thought of that. But then I need to bind different vertex array objects over and over again. (If different mesh types are using the same shader)
I thougt binding a VAO is less performant then glUseProgram.
Please say if I'm wrong :)



Where meshes use the same shader program and other GL state but use different uniform values, you may be able to replace uniforms with attributes (or a single attribute which is used as an index into a uniform array).


That's a great method as long as the attribute doesn't change over time. (Isn't it?)



Where meshes use different shader programs, you may be able to merge the programs into a single "ubershader" which can handle all of the different mesh types.


I thought using an ubershader would be too slow because I always have to use multiple if blocks. (!?)



In the end, you only need to use different draw calls if they require different GL state (e.g. rendering to different FBOs) or need to be rendered in separate passes for other reasons.


So that means I can use one draw call to render multiple meshes?? (As long as they use the same shader I suppose)

Thank you for your reply :)