Return of the SpriteBatch: sorting part 3

Return of the SpriteBatch: sorting part 3

Rate This
  • Comments 2

SpriteSortMode.Texture sorts sprites by texture.

SpriteSortMode.BackToFront and SpriteSortMode.FrontToBack do the obvious thing.

But what is the difference between the Immediate and Deferred sorting modes, and why should you care?

These modes both draw sprites in the same order that you call Draw, without any sorting. Performance will be good if you draw lots of sprites using the same texture in a row, and not so good if each sprite uses a different texture: see part 1 for the reason why.

In all the sort modes except Immediate, calling Begin just sets some flags on the SpriteBatch object. When you call Draw, the sprite is stored in an internal buffer. All the real work happens when you call End:

  • If using anything other than Deferred sorting mode, sorts the sprite buffer as specified.
  • Sends the sprite buffer on to the graphics card, using as few batches as possible (the less times you change texture, the fewer batches will be needed).

Because all the work happens in the End call, you can have many SpriteBatch instances on the go at the same time without any conflicts. You could even do other things like drawing 3D models at the same time as you are adding sprites to a SpriteBatch.

SpriteSortMode.Immediate works quite differently. It sets all the sprite renderstates inside the Begin call. Each time you call Draw, it checks whether the new sprite uses the same texture as the previous one. If they are the same, it just adds the new sprite to the internal buffer. Otherwise it flushes the existing contents of the buffer to the graphics card, then starts a new buffer using the new texture.

One implication of this is that you can only use one SpriteSortMode.Immediate batch at a time. Because it is setting renderstates and drawing polygons as it goes along, you will get conflicts if you try to do anything else with the graphics card (including drawing 3D models) inside an immediate mode SpriteBatch.

Another more interesting implication is that because SpriteSortMode.Immediate sets its renderstates inside the Begin call, if you were to change these renderstates immediately after calling Begin, the sprites will be drawn using your custom state. You can do many interesting things with this:

  • Change the alpha blending renderstates to use blend modes other than the standard SpriteBlendMode options.
  • Set the DepthBufferEnable renderstate to enable the hardware depth buffer. This can be an interesting way of sorting sprites by their layerDepth parameter entirely on the graphics card, allowing you to draw overlapping sprites efficiently in texture order but have them show up on the screen sorted by depth.
  • Change SamplerStates[0].MinFilter and MagFilter to draw sprites with point sampling instead of the default linear filtering.
  • You can use the stencil renderstates to do some cool masking and transition effects.
  • Best of all: you can set a custom pixel shader, or begin an effect that defines a custom pixel shader, to draw sprites using all kinds of fancy shading techniques. The sky is really the limit to what is possible here (you can't easily replace the vertex shader, though, because we use that as a core part of positioning the sprite polygons).
  • I really like this series of articles.

    Are there any source codes available for the concepts explained in the last 5 bullets (for XNA, I mean)?

  • ya how about moving these to video format on the xna site.

Page 1 of 1 (2 items)
Leave a Comment
  • Please add 3 and 3 and type the answer here:
  • Post