2
\$\begingroup\$

I've recently started learning how to program in 3D with XNA and I've been trying to implement a Terrain3D class(a very simple height map). I've managed to draw a simple terrain, but I'm getting a weird bug where I can see through the terrain. This bug happens when I'm looking through a hill from the map. Here is a picture of what happens:

I was wondering if this is a common mistake for starters and if any of you ever experienced the same problem and could tell me what I'm doing wrong. If it's not such an obvious problem, here is my Draw method:

public override void Draw()
{
    Parent.Engine.SpriteBatch.Begin(SpriteBlendMode.None, 
        SpriteSortMode.Immediate, SaveStateMode.SaveState);

    Camera3D cam = (Camera3D)Parent.Engine.Services.GetService(typeof(Camera3D));
    if (cam == null)
        throw new Exception("Camera3D couldn't be found. Drawing a 3D terrain requires a 3D camera.");

    float triangleCount = indices.Length / 3f;

    basicEffect.Begin();

    basicEffect.World = worldMatrix;
    basicEffect.View = cam.ViewMatrix;
    basicEffect.Projection = cam.ProjectionMatrix;
    basicEffect.VertexColorEnabled = true;

    Parent.Engine.GraphicsDevice.VertexDeclaration = new VertexDeclaration(
        Parent.Engine.GraphicsDevice,
        VertexPositionColor.VertexElements);

    foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
    {
        pass.Begin();
        Parent.Engine.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, 
            VertexPositionColor.SizeInBytes);
        Parent.Engine.GraphicsDevice.Indices = indexBuffer;
        Parent.Engine.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
            0, 0, vertices.Length, 0, (int)triangleCount);
        pass.End();
    }

    basicEffect.End();

    Parent.Engine.SpriteBatch.End();
}

Parent is just a property holding the screen that the component belongs to. Engine is a property of that parent screen holding the engine that it belongs to.

If I should post more code(like the initialization code), then just leave a comment and I will.

\$\endgroup\$
9
  • \$\begingroup\$ In all honesty the screenshot isn't showing a great deal cos of the colour of the white part. A wireframe screenshot would probably do it better justice. \$\endgroup\$
    – Ray Dey
    Feb 13, 2011 at 2:07
  • \$\begingroup\$ Well when I put the wireframe it just looks like there is no problem... mmm I really don't know how to show it properly... \$\endgroup\$ Feb 13, 2011 at 2:10
  • \$\begingroup\$ What about some basic lighting? That might give it a better sense of depth. \$\endgroup\$
    – Ray Dey
    Feb 13, 2011 at 2:17
  • \$\begingroup\$ When I enable the default lighting on the effect used when drawing the terrain, the terrain becomes really really dark and I can't hardly see the brightest parts... I guess I need to define the normals of the triangles for the lighting to work properly? I'm really new to 3D sorry... \$\endgroup\$ Feb 13, 2011 at 2:38
  • \$\begingroup\$ No worries dude, we're all here to learn :) Yeah you'll most likely need to set your normals. Have you just tried darkening the colour from white to a grey and see if that shows it slightly better? \$\endgroup\$
    – Ray Dey
    Feb 13, 2011 at 2:41

2 Answers 2

4
\$\begingroup\$

Sprite batches tend to overwrite some render states. Try to set device.RenderState.DepthBufferWriteEnable = true; and device.RenderState.DepthBufferEnable; manually. Hope that helps.

\$\endgroup\$
2
  • \$\begingroup\$ Plus what Steve H says. \$\endgroup\$
    – Dave O.
    Feb 13, 2011 at 3:42
  • \$\begingroup\$ Problem solved! Thank you very much. :) That's the Z-Buffer right? I think I've read about it before but I forgot to use it. \$\endgroup\$ Feb 13, 2011 at 3:46
5
\$\begingroup\$

You should end your spriteBatch before doing any 3d drawing. Always keep 2d and 3d drawing separate.

By the way, why are you even beginning & ending the spritebatch if you're not drawing any 2d?

Within a spritbatch begin/end, XNA sets various renderstates for 2d drawing. Often these aren't best for 3d drawing... especially if you're using XNA 3.1. In 3.1, SpriteBatch.Begin disables the depthbuffer... which is needed for 3d drawing and could factor into your issue.

Also, if the problem turns out to be what's known as Z-fighting (it is hard to tell from the screen shot), increase your nearclip value when setting up your camera's projection matrix.

\$\endgroup\$
1
  • \$\begingroup\$ The spriteBatch thing was a stupid mistake from me. Thanks for pointing it out! :) \$\endgroup\$ Feb 13, 2011 at 3:43

You must log in to answer this question.

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