Try to use the same
Begin/End block as much as possible in order to maximize the amount of sprites that are batched and reduce the actual number of Draw calls made to the graphics device. In general, you only really need to use a different
Begin/End block when you want to change some of the parameters to
I'll start with the second question:
Secondly, and this question is a a bit more subjective but, which design is generally preferable?
Take a look at the longest version of
public void Begin (
In general, as long as I don't need to change any of these parameters I try to use the same
Begin/End block for all of my
Draw operations. The reason should become evident when I address your other question later, but to sum it up, it's to reduce the amount of calls (render stage changes and draw operations) made to the graphics device.
Conversely, whenever I start a new
Begin/End block it's usually for a very specific reason. For instance, I might use separate blocks when:
- I need a group of sprites to be drawn with additive blending instead of alpha blending.
- I have a group of sprites that use a view matrix for camera movement, but there's another group of sprites that should always be drawn on top as an overlay, so the view matrix shouldn't affect them.
- I have different layers of sprites with parallax and implement parallax by passing a different view matrix to each layer.
- I need to use different shaders for different groups of sprites.
All of these cases fall under the general case above - one of the parameters to
SpriteBach.Begin needs to be changed.
As for the first question:
What are the performance implications of calling SpriteBatch.Begin/End in all these separate classes so often (once per class per drawing update) versus just calling it the one time each update.
The main implication is that you won't be taking advantage of the
SpriteBatch class that way - in particular you might end up with many more render stage changes and draw operations happening on the graphics device than what is really needed.
The reason for this is that the
SpriteBatch is not just a class for rendering sprites; it also tries to group as many sprites as it can into a single graphics device operation. For instance, if you draw ten sprites in a row using the same texture with the default
SpriteBatch parameters, the class will actually store the vertices for all of those sprites in the same vertex buffer, and submit it to the graphics device only once.
Begin/End for each
Draw call then you'd get ten individual draw calls instead of just one. The performance implications should be clear from that.
Also the bit about using the same texture is important - as soon as you change to another texture it needs to stop batching, submit all previous vertices that have been batched so far, and start with an empty vertex buffer for the next sprites. This is why to get the best performance when using
SpriteBatchyou should use spritesheets and group as many sprites as you can in the same texture (since changing source rectangle does not count as a change of texture).