Sign in to follow this  
NightCabbage

2d D3DXMatrixOrthoLH layers, depth, order

Recommended Posts

NightCabbage    100
Hey all have been looking around for a while but I can't seem to find any answers to this question. I'm using a D3DXMatrixOrthoLH projection matrix for a 2d game. I'm drawing textured quads as sprites. I would like to be able to order / layer these sprites based on their Z values (or something else if it's better). But when I do a translation on the sprite and move its Z value in front or behind the other sprite, there is no change. They are just rendered in order, completely disregarding their Z values. My ortho matrix is set up like this: D3DXMatrixOrthoLH(&matOrtho, (float)resWidth, (float)resHeight, 1.0f, 10.0f); Thanks!

Share this post


Link to post
Share on other sites
NightCabbage    100
Quote:
Original post by Matruz
Have you enabled the z stencil buffer?


Yup, I tried that - using this:

dxDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
dxDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

(I think it's on be default anyway? not sure)

Share this post


Link to post
Share on other sites
NightCabbage    100
Aha! You were right :D

I missed the following:

dx_PresParams.EnableAutoDepthStencil = TRUE;
dx_PresParams.AutoDepthStencilFormat = D3DFMT_D16;

So I assume that now my 16-bit z-buffer will be distributed between the values 1.0 and 10.0, given that's what I supplied when I created my Orth projection?

eg. D3DXMatrixOrthoLH(&matOrtho, (float)resWidth, (float)resHeight, 1.0f, 10.0f);

Any reason for the 1.0f and 10.0f?

Couldn't you just use 0.0f and 1.0f?

Share this post


Link to post
Share on other sites
Matruz    122
Quote:
(I think it's on be default anyway? not sure)


Nope, its not. I once had a similar problem.

What kind of game you are making, is it a sidescroller?

Share this post


Link to post
Share on other sites
NightCabbage    100
Quote:
Original post by NightCabbage
Any reason for the 1.0f and 10.0f?

Couldn't you just use 0.0f and 1.0f?


Yep, basically I'm just making an engine right now, and I'll be making a side-scroller, and a top down game with the same engine. Not sure which I'll do first. But they'll both only have a few layers of depth.

D3DXMatrixOrthoLH(&matOrtho, (float)resWidth, (float)resHeight, 1.0f, 10.0f);

So what numbers are good to use for the near and far z-buffer range?

As for layers... say if 2 sprites have the same z-index, is tehre a chance that they could flicker between the 2, given they're on the same layer?

Should I give them slightly different z-index values?
eg. 1.00 and 1.01

Or, providing the draw order stays the same, I imagine they should always be drawn the same way each frame...

So say if I wanted about 20 "layers", and I'm going between 1.0 and 10.0, I could just use these z values for the layers:

1.0
1.5
2.0
2.5
3.0
...
9.0
9.5
10.0

?


-EDIT-

Also, should I be using D3DXMatrixOrthoOffCenterLH instead?

Share this post


Link to post
Share on other sites
Evil Steve    2017
First, I'm fairly sure you can't use 0.0f for the near clip plane (Try it and see if the debug runtimes complain). I forget why, but it's something to do with the projection matrix not being invertable if zNear = 0.0f.

Quote:
Original post by NightCabbage
So what numbers are good to use for the near and far z-buffer range?
For a 16-bit Z-buffer, you have 65536 unique Z values, with ~70% of those values used in the first ~30% of the Z range (I.e. it's not linear, because you'll notice Z-fighting close up a lot more than you'll notice it far away). I wouldn't use anything more than 1.0f -> 1000.0f with a 16-bit Z-buffer.
However, there's very little reason to use a 16-bit Z-buffer, a 24-bit or 32-bit (If it's available) would be preferable, and then there should be no problem using 1.0f -> 10000.0f or more.

Quote:
Original post by NightCabbage
As for layers... say if 2 sprites have the same z-index, is tehre a chance that they could flicker between the 2, given they're on the same layer?
Yes, You'll see a sort of tearing effect (Check Google images for "z-fighting" to see what I mean) if two triangles have the same Z value.

Quote:
Original post by NightCabbage
Should I give them slightly different z-index values?
eg. 1.00 and 1.01

Or, providing the draw order stays the same, I imagine they should always be drawn the same way each frame...

So say if I wanted about 20 "layers", and I'm going between 1.0 and 10.0, I could just use these z values for the layers:
If you're making an engine, I'd accept Z values from 0 to 1000 or so, and then convert that to your Z range internally (I.e. if you have 1.0f -> 100.0f, multiply each Z value by 0.099 to convert from "engine coordinates" to D3D coordinates. That'll also allow you to change your Z-buffer range at a later date if you want, while still keeping the engine interface the same.

Quote:
Original post by NightCabbage
Also, should I be using D3DXMatrixOrthoOffCenterLH instead?
If you need it, yes. D3DXMatrixOrthoLH gives you a coordinate space with (0, 0) in the centre of the screen. If you want (0, 0) to be the top left, you'll need to use D3DXMatrixOrthoOffCenterLH to do that.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by NightCabbage
What is support for 24 or 32 bit z-buffers like these days?
The cardcaps spreadsheet with the SDK will show you (Samples\C++\Direct3D\ConfigSystem\CardCaps.pdf or CardCaps.xls). It shows D3DFMT_D24S8 is supported on all DX9 level hardware, D3DFMT_D24X8 is supported on almost all, and D3DFMT_D32 isn't widely supported at all.
If you want to do things "Properly", you should try several formats and see what's supported, choosing the best format available.

Quote:
Original post by NightCabbage
Steve - did you write these tutorials:
http://thetavern.servebeer.com/?p=articles&a=D3DTutorial1

They're excellent :D

Exactly what I'm after!
I did, glad you like them [smile]. I should be adding to them reasonably soon, when I stop being so lazy...

Share this post


Link to post
Share on other sites
NightCabbage    100
Ah, ok that makes sense.

16-bit = old
24-bit = normal
32-bit = unsupported

So I should test for these 2:

D3DFMT_D24S8
D3DFMT_D24X8

Any of those two better than the other for 2d rendering?

So, just learning about stencil buffers now...

Is it correct that they're basically a mask for what's rendered?

Would I need this? And if so, wouldn't I then be relying on it, so if it wasn't available, my game wouldn't work?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by NightCabbage
16-bit = old
24-bit = normal
32-bit = unsupported

So I should test for these 2:

D3DFMT_D24S8
D3DFMT_D24X8
In my code, I check for D3DFMT_D32 first, since it has the highest precision and will give fewest artefacts. If it's not supported, then I move on to D3DFMT_D24S8 then D3DFMT_D24X8, and then the lower resolution formats.

Quote:
Original post by NightCabbage
Any of those two better than the other for 2d rendering?
If you're not using a stencil buffer, then no - there's going to be no relevant difference. I suppose it's plausible that D3DFMT_D24X8 may be minutely better performance, since the driver can use the extra 8 bits for anything it wants, rather than having to keep the data valid for the stencil buffer.

Quote:
Original post by NightCabbage
So, just learning about stencil buffers now...

Is it correct that they're basically a mask for what's rendered?

Would I need this? And if so, wouldn't I then be relying on it, so if it wasn't available, my game wouldn't work?
More or less. You can use it for rendering "windows" - you'd render your stencil shape - say a star for example - to just the stencil buffer. Then, in a second pass you render your scene, telling D3D to only render pixels where it's written to the stencil buffer. That way, you'll get your scene cut out in a star shape.
There's several other uses for stencil buffers, including a few shadowing methods, but they're not relevant for a 2D game.
The SDK Docs have a section on stencil buffer techniques, which would be worth a quick read over if you're interested.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by NightCabbage
Just out of interest...

Do you know if the portals in Portal, Prey, Quake 3, Serious Sam, etc. use Stencils or Render Targets to draw the alternate scene visible in the portal?
I don't know for sure, but I'd assume that they either use a stencil technique, or they use render-to-texture to render the portal contents to a texture which is then applied to the portal geometry.
You might be able to find out if you run the game through PIX and look at the various D3D calls - any stencil ops should be pretty obvious.

Share this post


Link to post
Share on other sites
smjones    150
Hey Steve,
Just wanted to pipe in and say that your posts are very helpful. I was doing a quick search for setting up the projection transform for a 2D game engine I am writing and was not sure how to move the 0,0 from the center of the screen to the top, left (yes, I still like manipulating sprites in screen space :) )

Here's the code I used after discovering D3DXMatrixOrthoOffCenterLH from your post.


// 2D Coordinate space (not-screen space) with center at left,top
D3DXMatrixOrthoOffCenterLH(&g_mtxProjection, 0.0f, (float)nViewWidth, (float)nViewHeight, 0.0f, -1.0f, 1000.0f);
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &g_mtxProjection );

You also explained the Z near and far values which was a bit of a mystery to me. Unfortunately the DX SDK docs as very lacking in detail. :(
Yes my Z far value is huge and will get trimmed down to perhaps 100.0f or maybe even 1.0f. I will have layers in my engine, perhaps up to 256 for a nice big but round value.

I need to sit down and go through the DX SDK but it seems more appropriate to go through it as needed. But then I find I don't often know the names of what I'm looking for. Thanks for your research!

Steve

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this