1

I'm using XNA 3.1

I have recently created a 2D Heads Up Display (HUD) by using Components.Add(myComponent) to my game. The HUD looks fine, showing a 2D map, crosshairs and framerate counter. The thing is, whenever the HUD is on screen the 3D objects in the game no longer draw correctly.

Something further from my player might get drawn after something closer, the models sometimes lose definition when I walk past them. When I remove the HUD all is drawn normally.

Are their any known issues regarding this that I should be aware of? How should I draw a 2D HUD over my 3D game area?

This is what it looks like without a GameComponent:

two 3D objects, the one further away is correctly rendered behind the closer one

And here's how it looks with a GameComponent (in this case it's just some text offscreen in the upper left corner that shows framerate), notice how the tree in the back is appearing in front of the tree closer to the camera:

two 3D objects, the one further away is rendered on top of the closer one

Lucius
  • 3,705
  • 2
  • 22
  • 41
PaulG
  • 6,920
  • 12
  • 54
  • 98
  • 1
    Somewhere in your HUD rendering code a pipeline state is changed that is not restored afterwards. Make sure *all necessary states* are set when you draw the models. This includes blend/rasterizer/depth stencil states, viewports, shaders, samplers, input layouts, depth buffer and render targets. Could you provide a screenshot to narrow down the problem? – Lucius Feb 18 '13 at 15:00
  • Thanks for the response. I will provide screenshots as soon as I get back from work. – PaulG Feb 18 '13 at 15:10
  • Try `GraphicsDevice.DepthStencilState = DepthStencilState.Default;` before you draw the models. – Lucius Feb 19 '13 at 00:39
  • I'm using XNA 3.1, should have mentioned that. Don't think I have those properties available. – PaulG Feb 19 '13 at 00:51
  • 1
    `GraphicsDevice.RenderState.DepthBufferEnable = true` and `GraphicsDevice.RenderState.DepthBufferWriteEnable = true` are the XNA 3.1 equivalent. – Lucius Feb 19 '13 at 01:00
  • Thanks! Works great, do I have to do this every frame? Also, create an answer so I can vote for it. Thanks a lot! – PaulG Feb 19 '13 at 01:02
  • 1
    Yes, `SpriteBatch.Begin` disables the depth buffer, so you have to reenable it for every frame. Glad I could help you! I will post an answer tomorrow, so this can get closure. – Lucius Feb 19 '13 at 01:07

1 Answers1

1

You have to enable the depth buffer:

// XNA 3.1
GraphicsDevice.RenderState.DepthBufferEnable = true;
GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

// XNA 4.0
GraphicsDevice.DepthStencilState = DepthStencilState.Default;

SpriteBatch.Begin alters the state of the graphics pipeline:

In both versions depth buffering is disabled, that's what causes the issue.

Again, I cannot stress this enough:

Always make sure that ALL render states are correctly set before drawing any geometry.

  • BlendState
  • DepthStencilState
  • RasterizerState
  • Viewports
  • RenderTargets
  • Shaders
  • SamplerStates
  • Textures
  • Constants

Educate yourself on the purpose of each state and each stage in the rendering pipeline. If in doubt, try resetting everything to default.

Lucius
  • 3,705
  • 2
  • 22
  • 41