1
\$\begingroup\$

Usually in 3d drawing you want to ideally have fewer larger textures rather than lots of smaller ones, and make sure you render the same kinds of textures at the same time. So there is less texture swapping going on behind the scenes.

This is not a difficult thing to do as most textures are purely used for models or terrains/structures. So you may have a terrain texture, a structures texture and a couple of player/enemy textures. Then just draw the terrain, the structures and any enemies and the player, only requiring a few texture swaps there, and if you are also using some sort of model instancing for the enemies you can get away with some other improvements there.

Anyway now enter the 2d drawing world, rather than applying a texture and then drawing lots of vertices using it you are giving a texture to each draw command. So I am wondering how XNA handles this behind the scenes.

Take for example a top down 2d game, you have a tileset for the level containing many ground sprites, an enemy sprite sheet which may contain anywhere from 10-20 enemies sprites and animations, then possibly a player/equipment sheet which contains anything for them.

Now in this instance if I were to draw my level which was lets say 64x64 tiles (a tile being an x,y,tileSetIndex), and I have a tileset with 8x8 sprites (lets say 32x32 each):

var tileSetSourceRect = someTilesetEntity.GetSourceRectForIndex(tile.tileSetIndex);
mySpriteBatch.Draw(someTilesetEntity.TilesetTexture, tileSetSourceRect , tile.Position, Color.White);

assuming no real optimisations and just looping through every tile would this just retain the tilesetTexture in memory, or is it going to keep removing/adding the texture after every Draw() call? As I do not know how it can manage this unless it keeps some state under the hood between draw calls (maybe thats what Begin/End is for on spriteBatches).

So will I be getting 4096 (64x64 tiles itterated) texture swaps, or will it only do 1 texture swap in this instance?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 1 texture swap. The sprite batch does what it's name implies; It batches draw calls up, so unless you change the texture or similar it'll be one texture swap and one draw call. \$\endgroup\$ Feb 6, 2012 at 10:37

1 Answer 1

1
\$\begingroup\$

Short Answer

In that example, only one texture swap.

Long Answer

Since there was no actual texture change between Draw calls, only source rectangle changes, it would retain the texture and you would only get one set texture operation in total. Also, because there was no texture change, you would have the added benefit that all the vertices generated for the sprites would be batched into the same vertex buffer and submitted only once.

If on the other hand you did change textures between Draw calls, then the result would depend on the SpriteSortMode you chose when calling Begin.

By default it uses SpriteSortMode.Deferred, which has the implication that every time you change a texture it needs to stop batching, render the previous batch contents, and then start batching the new values. This of course requires a texture swap and a new vertex buffer too, but note that this only happens when you call End (hence being called deferred). So in sum, the more texture changes you make, the more it has to work behind the scenes.

On the other hand you can also use SpriteSortMode.Texture which works just like SpriteSortMode.Deferred but sorts sprites by texture before drawing. This will result in the minimum possible amount of draw operations, but can also mess up your draw order.

Finally if you choose SpriteSortMode.Immediate, sprites are drawn immediatly after you issue the Draw call. In this case I'm actually not sure about the details, but I am guessing you'd also get as many texture swaps as there were draw calls, since there's no batching taking place.

Check this answer for more insight on how SpriteBatch works.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the responses, I was hoping this was the case but could find no solid information on this. \$\endgroup\$
    – Grofit
    Feb 6, 2012 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .