5
\$\begingroup\$

In XNA 3.1 is there any other way to disable depth in 3D Worlds using DirectX models other than

GraphicsDevice.RenderState.DepthBufferEnable = false;

?

The reason for my question is I have quite a huge program which offers a 3D World with a couple of 3D DirectX models inside. Depth was never an issue since it ever worked fine but since a few days after doing some modifications my models are all depth-translucent i.e. depth-buffering and/or culling seems to be disabled.

But in my whole source code I never touch any of the options related to Depth or Culling which means I never turn these settings on explicitly nor turn it off somewhere.

So I am searching for some other statement maybe related to the GraphicsDevice that implicitly turns depth off - but I can't find it.

(Sorry that I don't post any source code but I have too much source code and I simply don't know where to search)

UPDATE:

These are a couple of simple objects seen with correct depth. These are a couple of simple objects seen with correct depth.

These are the same objects in their current state. These are the same objects in their current state.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Well, first, are you aware that the Z buffer doesn't work for transparent polygons? The bottom line is that since you now have depth-translucent objects, this becomes a depth-sorting issue. \$\endgroup\$ Oct 31, 2012 at 13:56
  • 1
    \$\begingroup\$ You should probably post a picture. And my hunch is your culling order got reversed, try flipping that to eliminate the possibility. \$\endgroup\$ Oct 31, 2012 at 14:03
  • \$\begingroup\$ @LaurentCouvidou My model has indeed transparent parts but I have transparency disabled in XNA (by not enabling it explicitly) so that these parts appear opaque. \$\endgroup\$ Oct 31, 2012 at 14:03
  • \$\begingroup\$ @KlashnikovKid preparing picture, hold on ... \$\endgroup\$ Oct 31, 2012 at 14:04
  • \$\begingroup\$ @KlashnikovKid Images added ... \$\endgroup\$ Oct 31, 2012 at 14:18

3 Answers 3

5
\$\begingroup\$

It does look like the spritebatch overlay drawing is changing your cullmode renderstate setting.

In 3.1 you can tell the spritebatch to save and restore the renderstate with the SaveStateMode parameter;

SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);

From MSDN;

However, there are cases where render states can change automatically. A common example is the rendering of sprites and 3D objects on the same graphics device. In this case, the SpriteBatch object changes various render states when you call End. If you try any 3D rendering after this step, the results can be unpredictable.

For this reason, you should restore several key render states to their former settings before you try to render any 3D objects. The following code demonstrates this approach.

    GraphicsDevice.RenderState.DepthBufferEnable = true;
    GraphicsDevice.RenderState.AlphaBlendEnable = false;
    GraphicsDevice.RenderState.AlphaTestEnable = false;

More from MSDN

SpriteBatch.Begin sets the following render states.

  • CullMode
  • DepthBufferEnable
  • AlphaBlendEnable
  • AlphaTestEnable

  • AlphaBlendOperation

  • SourceBlend
  • DestinationBlend
  • SeparateAlphaBlendEnabled
  • AlphaFunction
  • ReferenceAlpha

Begin sets the following sampler states.

  • AddressU
  • AddressV
  • MagFilter
  • MinFilter
  • MipFilter
  • MipMapLevelOfDetailBias
  • MaxMipLevel

If Begin is called with SaveStateMode set to None, then these states must be reset by the caller if they are used elsewhere. Calling Begin with SaveStateMode set to SaveState will reset these values properly, but may adversely affect performance.

\$\endgroup\$
4
  • \$\begingroup\$ I removed every single call to the Spritebatch.Begin() method (of which I had many) BUT unfortunately nothing has changed: I still have no depth in my model. \$\endgroup\$ Oct 31, 2012 at 22:41
  • \$\begingroup\$ Please see my answer below. Nevertheless i marked your answer as correct because it gave some valuable insight into these things that helped me lot. Thank you for that! \$\endgroup\$ Oct 31, 2012 at 23:42
  • \$\begingroup\$ Just going by your screenshots it looks definitely like a culling issue. Are you usuing primitive to draw the boxes. Did you by any chance change the order in your vertex lists? \$\endgroup\$
    – Ken
    Nov 1, 2012 at 8:41
  • \$\begingroup\$ The boxes are DirectX models which are drawn in the very standard way as it should be done in XNA (loading Model from Content; iteration over all modelMeshes; iteration over all effects per mesh; setting worldCoordinates, projection and view; and drawing each mesh) ... Nevertheless I did find the faulty statement which was the cause for my trouble -> see my answer below. And again thank you for your comment - you did help me a lot ! \$\endgroup\$ Nov 1, 2012 at 9:49
4
\$\begingroup\$

Are you using a SpriteBatch to render your overlay in the second image? If so, SpriteBatch in 3.1 sets render states when drawing (including disabling the depth buffer) that you need to restore before drawing in 3D. See this article for the exact states changed.

\$\endgroup\$
1
  • \$\begingroup\$ I removed every single call to the Spritebatch.Begin() method (of which I had many) BUT unfortunately nothing has changed: I still have no depth in my model. \$\endgroup\$ Oct 31, 2012 at 22:48
1
\$\begingroup\$

Thank you for all the comments and efforts.

After having cut my whole program into pieces I found the error which was in fact a silly one. For some reason I set the depth of my main viewport I am using to render the models to

_mainViewport.MaxDepth = 2.0f;

which was the cause why my models showed no depth!

After setting the MaxDepth value to 1.0f my models were displayed correctly again.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .