6
\$\begingroup\$

I was trying to output some debug information using DrawString when I noticed my model suddenly was being rendered like it was inside-out (like the culling had been disabled or something) and the texture maps weren't applied

I commented out the DrawString method until I only had SpriteBatch.Begin() and .End() and that was enough to cause the model rendering corruption - when I commented those calls out the model rendered correctly

What could this be a symptom of? I've stripped it down to the barest of code to isolate the problem and this is what I noticed.

Draw code below (as stripped down as possible)

        GraphicsDevice.Clear(Color.LightGray);
        foreach (ModelMesh mesh in TIEAdvanced.Meshes)
        {
            foreach (Effect effect in mesh.Effects)
            {
                if (effect is BasicEffect)
                    ((BasicEffect)effect).EnableDefaultLighting();
                effect.CurrentTechnique.Passes[0].Apply();
            }
        }

        spriteBatch.Begin();
        spriteBatch.DrawString(spriteFont, "Camera Position: " + cameraPosition.ToString(), new Vector2(10, 10), Color.Blue);
        spriteBatch.End();

        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        TIEAdvanced.Draw(Matrix.CreateScale(0.025f), viewMatrix, projectionMatrix);
\$\endgroup\$
4
  • \$\begingroup\$ please add your drawing code into question \$\endgroup\$
    – Vodáček
    Jul 4, 2012 at 6:54
  • \$\begingroup\$ I think I've had similar problems, when I generated lots of particles (sprites) with random Z-layers in my scene. Other sprites started blinking, phasing in and out rapidly. Maybe you're also doing something nasty with Z-layers? Let's see your code! \$\endgroup\$
    – Marton
    Jul 4, 2012 at 7:02
  • \$\begingroup\$ Actually I JUST figured it out then - apparently the moment you use the SpriteBatch with .Begin / End it sets the DepthStencilState to None! Adding GraphicsDevice.DepthStencilState = DepthStencilState.Default; after the SpriteBatch call fixed it. This would seem like a very common scenario but I had a hard time finding any information on this subject \$\endgroup\$
    – manning18
    Jul 4, 2012 at 7:03
  • \$\begingroup\$ also recommended thing is to set blend state to opaque: GraphicsDevice.BlendState = BlendState.Opaque; \$\endgroup\$
    – Vodáček
    Jul 4, 2012 at 7:07

2 Answers 2

10
\$\begingroup\$

SpriteBatch will change the following render states. Even if you don't specify any in your Begin call - it will use its own defaults:

GraphicsDevice.BlendState = BlendState.AlphaBlend;
GraphicsDevice.DepthStencilState = DepthStencilState.None;
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

When you want to draw 3D models, you will want to set:

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;

And, if your 3D models have wrapping UV coordinates:

GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

This information comes from this blog post.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ +1 For XNA 3.x users, the blog post you're looking for is here \$\endgroup\$ Jul 4, 2012 at 13:06
  • \$\begingroup\$ Unfortunate, but understandable. I ran into this issue since I made an omnipotent RenderLayer class that contained a list of IDrawable objects, but since it made no distinction between sprites and 3D (I had simply item.Draw() wedged between begin/end), I was hitting some issues. \$\endgroup\$
    – Kyle Baran
    Aug 26, 2014 at 14:54
0
\$\begingroup\$

I also had this problem, but the code

GraphicsDevice.DepthStencilState = DepthStencilState.Default;

resolved the problem.

\$\endgroup\$
1
  • \$\begingroup\$ Can't make any sense out of this. Please revise? \$\endgroup\$ Mar 9, 2013 at 3:46

You must log in to answer this question.

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