Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've got a problem drawing a 3D model to a RenderTarget2D in XNA 4. When the model is drawn to a render target, and then the render target is later drawn to the screen it appears distorted. (See right image below)

However, if I draw directly to the backbuffer, then everything appears correctly (See left image)

I'm resetting all the states before doing the 3D drawing. (BlendState, DepthStencilState, SamplerStates and RasterizerState)

Example of problem

This is my draw method. I first draw to the render target. Then I use a spritebatch to draw this to the screen (offset to the right for this example). Finally yfor direct comparison I reset the states again and draw the 3d model a second time directly to the back buffer (using the exact same DrawModel() method) and it works fine.

    protected override void Draw(GameTime gameTime)
    {
        // First set to use a render target.
        GraphicsDevice.SetRenderTarget(_playerBufferRenderTarget);
        GraphicsDevice.Clear(Color.Black);

        // Reset all the states as appropriate for 3d drawing.
        GraphicsDevice.BlendState = BlendState.Opaque;
        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;
        GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

        // Draw the model (to the rendertarget)
        DrawModel();

        // Go back to the backbuffer.
        GraphicsDevice.SetRenderTarget(null);
        GraphicsDevice.Clear(Color.Black);

        // Now draw the rendertarget to the screen as a sprite (Offset to the right).
// (This looks wrong)
        spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, null, null, null);
        spriteBatch.Draw(_playerBufferRenderTarget, new Vector2(300, 0), null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
        spriteBatch.End();

        // Again, reset the states.
        GraphicsDevice.BlendState = BlendState.Opaque;
        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;
        GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

        // Now draw the model again, but this time directly to the back buffer.
// (This works).
        DrawModel();

        base.Draw(gameTime);
    }

I create the RenderTarger2D within the LoadContent() method.

_playerBufferRenderTarget = new RenderTarget2D(this.GraphicsDevice, 800, 500);

This is the DrawModel method for reference although this is basically copied directly from an MSDN sample:

    private void DrawModel()
    {
        Matrix[] transforms = new Matrix[_playerModel.Bones.Count];
        _playerModel.CopyAbsoluteBoneTransformsTo(transforms);

        foreach (ModelMesh mesh in _playerModel.Meshes)
        {
            foreach (BasicEffect effect in mesh.Effects)
            {
                effect.EnableDefaultLighting();
                effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation) * Matrix.CreateTranslation(modelPosition);
                effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
                effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(90.0f), aspectRatio, 1.0f, 10000.0f);
            }

            mesh.Draw();
        }
    }

I've included a link to the Player.fbx model file. Is it possible that this could be caused by something I've done wrong when creating the model.

share|improve this question
    
Looks like overdraw due to the lack of depth buffer. –  arul Feb 26 '12 at 20:34
    
@arul - Spot on. I changed my RenderTarget creation to specify DepthFormat.Depth24Stencil8 and it's working perfectly. (Post it as and answer and I'll accept it) –  Simon P Stevens Feb 26 '12 at 20:40

1 Answer 1

up vote 3 down vote accepted

Looks like overdraw due to the lack of depth buffer.

You can specify the depth buffer when you create the RenderTarget2D:

 = new RenderTarget2D(this.GraphicsDevice, 800, 500, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
share|improve this answer
    
Thanks very much. Problem solved. –  Simon P Stevens Feb 26 '12 at 20:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.