Here's the problems you are having:
- Sorting for sprite batches only applies within that batch. At
End
, everything in the batch gets drawn to screen and becomes pixels. The default depth state for SpriteBatch
does not read the depth buffer.
- State objects (eg:
SamplerState
) are read-only once they are used. In this case, you're accessing the state that the graphics device is currently using. You can create a new state of your own, if you like - or use different existing ones.
Here's what you need to do:
Fortunately you don't have to create a custom SamplerState
, as you can just use the built-in SamplerState.LinearWrap
. Pass it into SpriteBatch.Begin
like so:
spriteBatch.Begin(SpriteSortMode.Deferred,
null, SamplerState.LinearWrap, null, null);
(Note the use of Deferred
- this is the default. You should only use Immediate
if you actually need that behaviour, as it is much, much slower. Passing null
in for state objects causes SpriteBatch
to use the default state object for that state.)
Then it's a simple matter of tiling your sprites. The trick to do this with SpriteBatch.Draw
is the source rectangle parameter. You can specify a source rectangle that extends beyond the edge of your texture. If, for example, you wanted to draw your sprite tiled 3 times horizontally and 2 times vertically, here's how:
spriteBatch.Draw(myTexture, myPosition,
new Rectangle(0, 0, myTexture.Width * 3, myTexture.Height * 2),
Color.White);
Then, to draw a non-tiled sprite, simply don't specify a source rectangle.
It is worth noting the reason for the existence of TextureAddressMode.Clamp
: If you draw a tile with Wrap
, and then position or scale your sprite it so that a pixel in the sprite's texture does not perfectly line up with a pixel on the screen, you will find that your sprite gets a fringe where blending is happening between two pixels on the opposite sides of the texture. Clamp
prevents blending from doing this by extending the edge pixels of the texture out to infinity. To avoid this problem you must either have pixel-perfect sprite positioning, or ensure that your art assets look reasonable if it happens.
It's also worth noting that this wrapping technique precludes the use of texture atlases. So, if you have many different tile types, it can be better for performance to just draw the tile multiple times. (Details)