# 2D z-buffer depth sorting (2D in D3D9 C#)

This topic is 4461 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm creating a tile-based RPG with Direct3D9 and C# using the Sprite interface and have size 32x48 sprites and 32x32 tiles. I would like to draw the sprites based off their y value (bottom draws first) so I can support overlapping sprites. Until I heard of the z-buffer sorting method, I manually compared all sprites and sorted them which is tedious. I enabled the z-buffer and passed the y value as the z value in my draw function and noticed that the buffer only handles values from 0 to 1. I also noticed the higher the z value, the further it's drawn, which is the opposite of what I need. I heard that transparency wouldn't work if I sorted my sprites in this way (not sure if it's true). If anyone knows how to use the z-buffer for 2D, or a better way to accomplish this, I'm all ears. Thanks.

##### Share on other sites
D3DXMATRIX * D3DXMatrixOrthoOffCenterLH(
D3DXMATRIX * pOut,
FLOAT l,
FLOAT r,
FLOAT b,
FLOAT t,
FLOAT zn,
FLOAT zf
);

creates your projection matrix i guess ...

so using z-near and z-far you can set up your z ranges ... im not sure if you can use high values for near, and low values for far range ... try it

if its not working you can do "1 / y = z" ...
( so you are always between 0 and 1, and high y = low z ... )

##### Share on other sites
Since I'm using the D3DX sprite interface, the projection is automatically setup. I also tried the "1 / y" method and it works for plotting y values correctly except for when y = 0, because you can't divide by zero. That results in anything with a z value of 0 not being drawn.

In the process, I noticed Sprite.Clear() has a "Spriteflags" argument which lets me set "SpriteFlags.SortDepthBackToFront" and "SpriteFlags.SortDepthFrontToBack".
Changing these values didn't give me the right effect though, here are some pictures to illustrate. Notice also how the first row of tiles aren't drawn, since their y value is 0.

no sorting:

back to front sorting:

front to back sorting:

##### Share on other sites

zero to bigger than 1 ?

maybe you can catch it before you divide ( dunno if its big overkill )

or you make something like ( 1 / (y + 1) = z ) ...

##### Share on other sites
I tried the new formula "z=1/(y+1)" and that works perfectly. I also solved my other problem. I forgot to change the whole map's z value to 1 to keep it below everything else. So now it works, but it feels like a "hard-coded" solution and I wonder if there's a more proper way of doing this.

##### Share on other sites
That system will work, however, as you said yourself, it will not work when transparency is involved. You will still need to sort objects and render 'furthest' to 'closest'.

At the same time, using the z-buffer for a 2-D game isn't all that great. If you do end up sorting your objects, then the z-buffer becomes effectively useless for this case. Further, sorting can potentially be faster because it is done at the object level whereas z-buffering is done at the pixel level.

##### Share on other sites
I'm not really sure, but you could do this.
  //y == y pos if(monster1.y < monster2.y) //draw monster2 first and so on and so forth.

##### Share on other sites
Actually, transparency works perfectly also if I specify "SpriteFlags.AlphaBlend | SpriteFlags.SortDepthFrontToBack" together. I guess the sprite interface handles it all. I only have one problem now. My sprites arent being drawn when their y position is 0. It seems to be related to the top 16 pixels not being on the screen.

##### Share on other sites
I figured out why my sprites aren't drawing near the top of the screen. I was giving the z-buffer the y value which indicated the top left corner of the object, rather than the bottom of the sprite. The sprite stopped being drawn when the 1/y value became negative, which happened when the top of the object went off screen. So I passed 1 / (y + spriteHeight) and it works fine now.

Thanks for the help everyone.