Page 1 of 1

SpriteBatch with a z cord

Posted: Fri Nov 27, 2015 9:55 pm
by Relazy
Hello. I have made a fairly competent game so far, and I am looking into using spriteBatches for additional performance, however I am limited by the fact that I have a z map on my maps (ordered map of when to draw what which is dynamic).
So my question is:
How do I use sprite batches alongside a z map assuming that the z cord can change while in game?
Is there a way to manage the draw order between two sprite batches?

I have been pondering about this for a while now and there is a possible solution that I have figured:
Sample all of the images at load on single z cord and put them all on a image data and use it as a sprite batch.
However as you may guess this isn't an optimal solution as:

:| greatly extends the load time

:| consumes more RAM

:halloween: prevents the change of z cord at run time.

:halloween: draws all of the quads on the map, instead of drawing only what is visible

Is there any other better option for me and is it worth it, assuming that I am drawing the same quad of an image more than 10 times and am only drawing images that are on the screen? :?

Re: SpriteBatch with a z cord

Posted: Sun Nov 29, 2015 9:42 am
by T-Bone
It sounds to me like spritebatches might not be the right tool for the job. The code will probably get quite messy, and the performance improvements won't be that large if objects change z values often.

Re: SpriteBatch with a z cord

Posted: Sun Nov 29, 2015 2:45 pm
by zorg
Hopefully i'm not too wrong about what i'm about to write... so, here goes nothing :3

I had this exact problem before, sprite batches being used as image atlas + sprite instances with quads, and you don't have control over the order which one batch draws out the sprites.

Now, one solution would be to have as much spritebatches as you have depth layers (if you only use integers for z ordering), though i do assume that you have all drawables of relevance (ones that can have their z order modified) on one atlas, else you'll need more than one spritebatch per layer.

When you add a sprite to a batch, it returns its id, which can be used to dynamically remove them from a batch, and add them to another, when their z order changes.

Now, depending on your game, you might want to have another kind of ordering, namely y axis based, when more objects on one z depth are drawn, and depending on "camera" perspective, you might see that some sprites occlude others wrong.
I tried experimenting with re-sorting the spritebatch positions of sprites whose y positions were changed, but i never did a benchmark whether this is a good idea or not...
I also didn't check whether the insertion order in spritebatches (when you call :add) is the same as the draw order, so that last idea may be useless :3

Re: SpriteBatch with a z cord

Posted: Thu Dec 03, 2015 4:48 am
by slime
A spritebatch draws its sprites in the same order as they were added.

Clearing and re-adding everything to a spritebatch every frame (if necessary) will still be faster than drawing each quad or image individually.

Re: SpriteBatch with a z cord

Posted: Fri Dec 04, 2015 6:02 pm
by Relazy
T-Bone wrote:It sounds to me like spritebatches might not be the right tool for the job. The code will probably get quite messy, and the performance improvements won't be that large if objects change z values often.
Yeah, I fear this might be the case as I sort items on screen at run time.
slime wrote:A spritebatch draws its sprites in the same order as they were added.
Clearing and re-adding everything to a spritebatch every frame (if necessary) will still be faster than drawing each quad or image individually.
The problem with this is that I have large maps, so there are cases when all I need to draw is about 20 quads which the player is viewing in a map that contains 500 + Quads. So is it more efficient to draw all 500 quads from one sprite batch or to draw 20 quads from one image?

My main problem with spritebatches is that if I have two of them that have varying z-cords for example:
Batch1:
BackgroundTree: [1,1,1]
tree: [1,1,2]
ForegroundTree:[1,1,3]

Batch2:
BackgroundClouds: [1,1,2]
Clouds: [1,1,3]
ForegroundClouds:[1,1,4]

How can I make sure that the Tree is drawn before the Clouds are drawn and that the Background clouds are drawn atop of Background tree?