Zbuffer depth, making stuff render above stuff.

Jul 16, 2009 at 9:35 AM
Edited Jul 16, 2009 at 9:39 AM

G'day,

I'm just trying to build a 3D menu system, and want to know how do I get my menu objects ( just colored boxes for now) to render above everything else regardless.

I tried this,

public void Draw(DrawState in_State)

{

 in_State.PushRenderState();

 if (ignoreZDepth)
 {
 in_State.RenderState.DepthColourCull.CullMode = CullMode.None;
 in_State.RenderState.DepthColourCull.DepthWriteEnabled = false;
 }

 // My rendering stuff
 //....

 in_State.PopRenderState();

}

And this simply made my model all garbled and wierd.

 

Any Ideas?

 

P.S, Really nice engine, I'm lovin' it. :P

 

Coordinator
Jul 16, 2009 at 1:55 PM
Edited Jul 16, 2009 at 1:58 PM

Hi. The best way to do this would be to draw everything else, then clear the depth buffer, then draw your menu.

Clearing is a little bit weird in xen, as it changed internally early on.
It's setup so there is a ClearBufferModifier object, which was intended to be added to a draw target (as a draw 'modifier') where it would clear the screen/texture for you before all the drawing took place.
(A draw modifier is a Begin/End draw object, that has BeginDraw() called before all IDraw objects are drawn, and EndDraw() called afterwards - it's not that wonderful...)

Anyway, eventually I merged it into the draw target, so each DrawTarget has an embedded ClearBufferModifier already created and added - which could be accessed with the DrawTarget.ClearBuffer property.

This is great, unless you want to do a one-off clear midway through rendering.
In which case, there are two options,

1> Get the GraphicsDevice and call Clear() yourself (state.BeginGetGraphicsDevice() - yeah... this is a bit nasty too :)

or...

2> Create and store a new ClearBufferModifier object, and manually call Draw() on that (which, funnily enough, will perform the clear). Alternatively, ClearBufferModifier implements IDraw so you can add it to your draw list before the menu.

After creating the ClearBufferModifier, it will default to clear all the buffers, including the colour buffer. So you will want to either set the appropriate property to false, or create it:

new ClearBufferModifier(ClearOptions.DepthBuffer | ClearOptions.Stencil)

like so. (Note, it's best practice to always clear both the depth and stencil at the same time, as the video card internally just flags the buffer as cleared. Whereas otherwise it has to write each depth value manually, as stencil values are interleaved with depth values). 
Hope that helps

Jul 17, 2009 at 3:25 AM

Thanks StatusUnknown! Takes a little getting used, but is simple enough and works a charm if I do this:

            ClearBufferModifier bufferMod;
            public void Draw(DrawState in_State)
            {
                if (ignoreZDepth)
                {
                    if (bufferMod == null)
                        bufferMod = new ClearBufferModifier( ClearOptions.DepthBuffer );

                    in_State.BeginGetGraphicsDevice(StateFlag.None).Clear(ClearOptions.Stencil | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1f, 0);
                }

                in_State.PushRenderState();
                //.... my rendering stuff
          }

Two more questions more out of curiosity if you have the time,

1) When I change new ClearBufferModifier()'s  ClearOptions, it always has the same effect. albeit the desired effect. What am I not seeing?

2) When I change the clear color, it also has no effect, the background just goes black when I use this code. I plan on using a skybox later, but I find this odd. What have I missed?

 

Thanks again for your help, works perfect. :)