James Monger
James Monger

Reputation: 10685

XNA draw order issues

I've been trying to apply a desaturation and white noise effect to my XNA project, and I've managed to do it but now I'm encountering some issues with the draw order.

In the code below, the commented out lines are what is causing the issue. If they are commented, the draw order problem is fixed, but then the screen isn't desaturated. When they're uncommented, the screen is desatured as I wish but the draw order problem occurs.

//GraphicsDevice.SetRenderTarget(scaleupTarget);
GraphicsDevice.Clear(Color.SeaGreen);            

DrawModel(building_a_mdl, (Matrix.Identity * Matrix.CreateTranslation(100, -14, -100)), building_a_tex);

/*GraphicsDevice.SetRenderTarget(null);
scaleupEffect.Parameters["RandomOffset"].SetValue((float)rng.NextDouble());
GraphicsDevice.Textures[1] = noiseTexture;
spriteBatch.Begin(
    SpriteSortMode.Texture,
    BlendState.AlphaBlend,
    SamplerState.PointClamp,
    null,
    null,
    scaleupEffect);
spriteBatch.Draw(scaleupTarget, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, upScaleAmount, SpriteEffects.None, 0.0f);
spriteBatch.End();*/

With the issue With the issue

Upvotes: 0

Views: 408

Answers (2)

Zerratar
Zerratar

Reputation: 1249

Try the following code:

    RenderTarget2D scaleupTarget = null;

    protected override void Draw(GameTime gameTime)
    {                        
            if (scaleupTarget == null)
            {
                    // be sure to keep the depthformat when creating the new renderTarget2d
                    scaleupTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth24);                
            }        
            GraphicsDevice.SetRenderTarget(scaleupTarget);
            GraphicsDevice.Clear(ClearOptions.Target, Color.SeaGreen, 1.0f, 0);
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;

            // Setup the rasterState, 
            // if CullMode.None; works, try with 
            // CullMode.CullCounterClockwiseFace
            // afterwards
            var rs = new RasterizerState();
            rs.CullMode = CullMode.None;
            rs.FillMode = FillMode.Solid;

            // Set the GraphicsDevice to use the new RasterizeState
            GraphicsDevice.RasterizerState = rs;

            DrawModel(building_a_mdl, (Matrix.Identity * Matrix.CreateTranslation(100, -14, -100)), building_a_tex);

            scaleupEffect.Parameters["RandomOffset"].SetValue((float)rng.NextDouble());
            GraphicsDevice.Textures[1] = noiseTexture;

            GraphicsDevice.SetRenderTarget(null);

            // SpriteBatch.Begin will set the GraphicsDevice.DepthStencilState to None.
            spriteBatch.Begin(
                    SpriteSortMode.Texture,
                    BlendState.AlphaBlend,
                    SamplerState.PointClamp,
                    null,
                    null,
                    scaleupEffect);
            spriteBatch.Draw(scaleupTarget, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, upScaleAmount, SpriteEffects.None, 0.0f);            
            spriteBatch.End();

            // Set back to the original depthstate before you continue.
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
    }

Upvotes: 1

Steve H
Steve H

Reputation: 5529

I suspect that even though you tried to change the DepthStencilState, it still holds the key to your issue.

The process of calling SpriteBatch.Begin() turns off depth buffer test since it's not needed for the 2d rendering of the SpriteBatch.Draw() calls. Then the next frame, it's still turned off when you go to draw your 3d stuff and you get the problem you are experiencing.

So just before drawing 3d stuff, make sure your DepthStencilState is set back to Default.

GraphicsDevice.Clear(Color.SeaGreen);

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

DrawModel(building_a_mdl, (Matrix.Identity * Matrix.CreateTranslation(100, -14, -100)), building_a_tex);

See this link for reference: http://blogs.msdn.com/b/shawnhar/archive/2010/06/18/spritebatch-and-renderstates-in-xna-game-studio-4-0.aspx

Upvotes: 0

Related Questions