5
\$\begingroup\$

In my 2D XNA game, I render all my sprites with a single sprite batch using SpriteSortMode.BackToFront and BlendState.AlphaBlend.

I'm adding a particle system based on the App Hub particles sample. Since this uses SpriteSortMode.Deferred and BlendState.Additive, I will need to have two SpriteBatch.Begin / SpriteBatch.End pairs: one for 'regular' sprites, and one for particles.

In my top-down shooter, If I want to have explosions appear under planes, but above the ground, then I believe I will have to have three Begin/End pairs, first to draw everything under the explosions, then to draw the explosions, then to draw everything above the explosions. If I want to have particle effects at multiple different depths, then I'm going to need even more Begin/Endpairs.

This is all easy to code, but I'm wondering if there is an alternative way to handle this?

\$\endgroup\$
2
  • \$\begingroup\$ Using Immediate for the sorting mode allows changing the BlendState between a Begin and End pair. Immediate is slower than the rest in basic situations; however, it can be the fastest if it prevents multiple Begin/End pairs. \$\endgroup\$ May 10, 2012 at 17:58
  • \$\begingroup\$ @ClassicThunder Thanks! That works, and is fast enough for me right now. \$\endgroup\$
    – Ergwun
    May 12, 2012 at 14:22

2 Answers 2

1
\$\begingroup\$

Try to render the first batch with SpriteSortMode.FrontToBack and DepthStencilState.Default

Then render the particles with SpriteSortMode.Deferred, BlendState.Additive and DepthStencilState.DepthRead...

I think it should works...

\$\endgroup\$
2
  • \$\begingroup\$ That almost works, except my sprites have transparency, and the transparent parts also hide particles underneath. \$\endgroup\$
    – Ergwun
    May 11, 2012 at 12:46
  • \$\begingroup\$ Draw trasnparent part without writing depth, or draw the transparent parts at the end... or you can also clip colors by an alpha range in the shader ... you have to decide what to do with trasnaprent objects, but you have no many options \$\endgroup\$
    – Blau
    May 11, 2012 at 13:01
0
\$\begingroup\$

You are not specifying whether you are using entity component system or not. However, there is another way of approaching the problem instead of trying to solve it directly on top of the underlying toolkit.

Either case, if you have Artemis-like entity component system(ECS) available, you can easily achieve this layering by having individual component system for each layer. These layers, then automatically get called in right order and the entities drawn on screen will appear as specified.

BackgroundSystem backgroundSystem = new BackgroundSystem(0, world);
ExplosionSystem explosionSystem = new ExplosionSystem(1, world);
PlaneSystem planeSystem = new PlaneSystem(2, world);

In this example, lower number in the constructor means being drawn earlier. Now when these systems are added to the ECS, and the render is done, their render functions will be called in the specified order rendering background on the bottom, explosions on top and planes on top of explosions.

If you don't want to submit to using ECS, you can achieve similar by wrapping your SpriteBatch in a class, for example Renderer that implements rendering queue, and abstracting your rendering code into Drawables or something similar.

Each Drawable has a member layer, which acts as a hint to the Renderer. This can be an enumeration or an integer that is used to sort all drawables so that once rendering is done, they are drawn from bottom to top.

The good thing about this is that you can hide details of each drawable or component and simplify your rendering code.

\$\endgroup\$

You must log in to answer this question.

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