[.net] Z-Buffer or Culling problem...?

Started by
4 comments, last by Glasswalker 19 years, 3 months ago
Hello all, I've been developing a 3-D game in C# using Managed DirectX. I've gotten a heightmap based terrain (a buffered TriangleList of CustomVertex.PositionColoredTextured) in place which the user can move around on, but I now have a problem where some of the far terrain (and even the back side of the terrain) is showing up in front of near terrain. I have enabled AutoDepthStencilling and thought perhaps the 16 bits wasn't enough, but going to D24S8 didn't change anything. Changing the CullMode to None from Counterclockwise also didn't change things. I've tried playing with the Camera objects FarPlane value, but that also changes nothing. Can anyone offer any help? I would swear this was working when I first imported the terrain, and all I've done since then was add a moving camera! Thanks, Glasswalker.
I don't need no stinkin' signature!
Advertisement
Quite frankly, it could be a lot of things. If you could kindly supply us with some code to examine, I'm sure we could give you a much better answer. :)
Alright, the code is a bit extensive at this point but I will try to paste the relevant bits.

Camera Creation:

public Camera()
{
Well.GlobalDevice.Transform.Projection = Matrix.PerspectiveFovLH(this.FOV, this.Aspect, this.NearPlane, this.FarPlane);
Well.GlobalDevice.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 6.5f, 6.0f), new Vector3(0.5f, 0.5f, 0.5f),
new Vector3(0, 1, 0));
velocity = new Vector3(0.0f, 0.0f, 0.0f);
orientationMatrix = Matrix.Translation(0.0f, 0.0f, 0.0f);
Move(0.0f,0.0f,0.0f);
Rotate(0.0f,-12.8f,0.0f);
vectorFrustum = new Vector3[8]; // corners of the view frustum
planeFrustum = new Plane[6]; // planes of the view frustum
}

Camera Movement:

public void UpdateCamera()
{
// Update the position vector
Vector3 vT = velocity;
vT = Vector3.TransformNormal(vT, orientationMatrix);
this.Loc += vT;
// Set the view matrix -- Yaw and Pitch are set elsewhere
Quaternion qR = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0.0f);
orientationMatrix.AffineTransformation(1.25f, new Vector3(0,0,0), qR, this.Loc);
viewMatrix = Matrix.Invert(orientationMatrix);
}

Terrain VertexBuffer Creation:

private void ManageVertexBuffer(string hexName, float elevationFactor)
{
if (this.vertexBuffer != null)
{
verts = (CustomVertex.PositionColoredTextured[])this.vertexBuffer.Lock(0,0);
string fileName = hexName + ".jpg";
System.Drawing.Bitmap heightmap = new System.Drawing.Bitmap(fileName);
for (int i = 0; i < SizeX; i++)
{
for (int j = 0; j < SizeY; j++)
{
int currentIndex = j + (i * SizeX);
int colorToHeight = heightmap.GetPixel(j,i).ToArgb() & 0x000000ff;
int mappedHeight = (colorToHeight * (int)scale);
float localAltitude = mappedHeight * elevationFactor;
this.verts[currentIndex].SetPosition(
new Vector3((float)(j * this.Spacing), (localAltitude),
(float)(i * this.Spacing)));
this.verts[currentIndex].Tu = ((float)j / (float)SizeY);
this.verts[currentIndex].Tv = ((float)i / (float)SizeX);
this.verts[currentIndex].Color = ColorVertex(localAltitude);
}
}
heightmap.Dispose();
// Unlock (and copy) the data
this.vertexBuffer.Unlock();
}
}

And Terrain Rendering:

public void Render(Camera cam)
{
if (this.Valid)
{
Well.GlobalDevice.RenderState.CullMode = Cull.CounterClockwise;
Well.GlobalDevice.VertexFormat = CustomVertex.PositionColoredTextured.Format;

Well.GlobalDevice.SetStreamSource(0, this.vertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.PositionColoredTextured.Format));
Well.GlobalDevice.Indices = this.indexBuffer;
Well.GlobalDevice.SetTexture(0, this.hexTexture);
Well.GlobalDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, this.indices.Length, 0, this.indices.Length / 3);
}
}

Thanks for taking a look. I'm really stuck on this one,
Glasswalker.
I don't need no stinkin' signature!
Are you clearing the z-buffer every frame?
There was bound to be an important snippet I neglected. Yes. I'm clearing the z-buffer:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
try
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0f, 0);
device.Transform.View = this.camera.ViewMatrix;
device.BeginScene();

ProcessInput();
this.camera.Render();
SetupLights();
device.RenderState.ZBufferEnable= false;
device.RenderState.Lighting = false;
DrawSky();
device.RenderState.Lighting = true;
device.RenderState.ZBufferEnable= true;

DrawLand(0.0f, 0.0f, 0.0f);
DrawWater();
debugFont.DrawText(debugText, new Rectangle(5, 5, 0, 0), DrawTextFormat.NoClip, Color.Yellow);

device.EndScene();
device.Present();
this.Invalidate();
}
}

Looking at it a few more times, it appears as though it is culling in reverse -- far objects occluding near ones entirely. Anything else?
Glasswalker.
I don't need no stinkin' signature!
I found the answer myself. I'm sorry for wasting your time, but I had the camera Projection matrix being redefined right after the first render.
Thanks again to those who offered their time,
Glasswalker.
I don't need no stinkin' signature!

This topic is closed to new replies.

Advertisement