Reducing the number of DrawIndexedPrimitive calls

Started by
6 comments, last by kovacsp 18 years, 1 month ago
So currently Graphics is the bottleneck of the game I'm working on. I've scoured the internet looking for optimizations but I'm now pretty sure that the number of draw calls is killing me. Every objects is made out of small blocks in our game and nothing is garunteed to be static (you can destroy everything). I'm making a draw call for every block in the game and this can quickly accumulate to over 800+ draw calls per frame. In order to place all of the blocks in a dynamic vertex buffer, I'd have to perform matrix rotations and scalings on their vertices (they rotate in 3D). This is a pretty big step and want to know if it would be worth it to go from 800-1000 draw calls to maybe 15 with numerous software matrix transformations? Also, any ideas on reducing the number of draw calls?
Advertisement
Geometry instancing might be useful to you.
"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"
hi,

I have the same problem, and was thinking abount the same as you now.
but then, I've found that maybe texture atlasing and occlusion culling (together or separately) may help me reducing the drawprimitive calls enough, and they require less radical changes in my code.
if it doesn't help, I'll take the "huge dynamic vertex buffer with pretransformad geometry" approach too...

kp
------------------------------------------------------------Neo, the Matrix should be 16-byte aligned for better performance!
mm... I do need to look into occlusion culling as that could help a lot. What is texture atlasing? And what is geometry instancing?

Er.... also I need the game to run fine on DX8 Gfx cards... With a minimum pixel shader 1.1 support... Does that out geometry instancing?
You might also try passing the translation, scale and rotation values with each vertex and letting the shaders transform the vertex. If your blocks use different textures, you might try passing a texture index with each vertex and let the shaders choose the texture.

For 800 blocks, that will increase the size of the vertex buffer by about 1 MB. Though doing this will make the vertex buffer much bigger, you only need one draw call to draw all the blocks.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
"I'm making a draw call for every block in the game..."

Yikes! Sounds like you need to perform some frustum culling yourself to avoid drawing objects outside of your camera's field of view.

--------------------------Most of what I know came from Frank D. Luna's DirectX books
Haha, my fault... I am doing the frustum culling.
Anyways, passing rotation, translation, and scaling data with the vertices is not a bad idea at all! That sounds like it might work okay.
Quote:Original post by chippolot
mm... I do need to look into occlusion culling as that could help a lot. What is texture atlasing? And what is geometry instancing?

Er.... also I need the game to run fine on DX8 Gfx cards... With a minimum pixel shader 1.1 support... Does that out geometry instancing?


texture atlasing is when you place some textures into a bigger texture, and UV your mesh to use subsets of that texture. If two materials have the same properties apart from texture, you can use this to render them is one drawprim call (and set the texture atlas as a texture).
Read this article, and you will see.

About instancing: it's when you render multiple instances of an object with different transformations (which you'd do with multiple drawprim calls in an ordinary case). The DX SDK and the NVidia SDK also has sample codes (in the nvidia one, you can even compare speeds with/without instancing).
The downside is that it isn't supported in older cards.

kp
------------------------------------------------------------Neo, the Matrix should be 16-byte aligned for better performance!

This topic is closed to new replies.

Advertisement