0
votes

I have been working on a DirectX 10 2D engine witten in c++ using the tutorials on http://rastertek.com/ My sprite system is based up on http://rastertek.com/dx10tut11.html and has been working quite well until I tried to render a background texture that is 1920x1080 in size.

The problem I am having is that the FPS drops down from 3000 to 1800 though if I draw a smaller texture only to about 2800. I know that drawing large textures will always have performance impact but there must be a way to optimize this quite a bit. First I thought that it had something to do with the vertex buffer being dynamic but changing it to a default one didn't optimize the performance. The shader code is as simple as it get's: Calculate the position of the vertices against the view matrices and the pixel shader uses the texture coordinates to draw them. I have been thinking about just using the D3DXSPRITE system included in DirectX 10 but it has been been taken out in DirectX 11 so I decided against it.

So after this long explanation my question is: How can I optimize my code to draw large textures ? Are there any solutions that you would suggest to use ?

1

1 Answers

2
votes

The tutorial in your link indicates that you should disable the Z-buffer when drawing sprites. This is only correct if you are doing alpha-blending. To optimize drawing large sprites, you should enable the Z-buffer, and draw batches (as large as you can) of opaque sprites from front-to-back, while maintaining back-to-front ordering for alpha-blended sprites. This helps avoid overdraw, which is probably the cause of the decrease in framerate you're seeing.

For example, if you have some opaque (Oi) and alpha-blended (Ai) sprites that you want to render in this order:

O1 O2 O3 A1 A2 O4 O5 O6 A3 A4 O7

You should render them this way:

[Z-enable] O3 O2 O1 [Z-disable] A1 A2 [Z-enable] O6 O5 [z-disable] A3 A4 O7

If you want to optimize even further, you can do bounds checking to see whether the sprites overlap. If they don't, you can merge the batches, though this won't help with overdraw since you wouldn't have had any in the first place.

So the above should help you with optimizing performance, but here are some other semi-related tips:

  • Don't focus on optimizing at ridiculous framerates. Instead, try to increase the workload until you're around 60-120 FPS, then optimize. Display drivers are designed to hit 60FPS, and may even scale back performance to save on power if you're rendering faster than that.
  • Unless you have a critical need to target Windows Vista RTM, you should switch to Direct3D 11 (supported on Vista with some Windows Updates applied, and Windows 7+ natively). It's basically the same API, just faster and with better support.
  • Take a look at the DirectX Tool Kit's SpriteBatch implementation. It likely does everything you're looking for, and uses D3D11 at its core.