[.net] Z-Buffer or Culling problem...?
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.
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.
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement