Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Normal generation for terrain

Started by Harry Hunt Mar 3, 2010 at 2:42 PM 1 replies 1.4k views
Original Post
Harry Hunt
Harry Hunt
Hi everybody! I'm playing around with OpenGL and .NET and I've run into some difficulties (being a DirectX kind of guy). Basically what I want to do is render a heightmapped terrain. I generate the terrain as follows:
for (int y = 0; y < patchHeight; y++)
{
	for (int x = 0; x < patchWidth; x++)
	{
		Vertex vertex = new Vertex();
		vertex.x = x * quadSize;
		vertex.y = -(y * quadSize);
		vertex.z = HeightForCoordinate(x, y);
		patch[y * patchWidth + x] = vertex;
	}
}
and render it like this:
for (int y = 0; y < patchHeight - 1; y++)
{
	for (int x = 0; x < patchWidth - 1; x++)
	{
		Vertex topLeft = patch[y * patchWidth + x];
		Vertex topRight = patch[y * patchWidth + x + 1];
		Vertex bottomLeft = patch[(y + 1) * patchWidth + x];
		Vertex bottomRight = patch[(y + 1) * patchWidth + x + 1];

		GL.Begin(BeginMode.TriangleStrip);
		GL.Vertex3(bottomLeft.x, bottomLeft.y, bottomLeft.z);
		GL.Normal3(bottomLeft.normal);

		GL.Vertex3(topLeft.x, topLeft.y, topLeft.z);
		GL.Normal3(topLeft.normal);

		GL.Vertex3(bottomRight.x, bottomRight.y, bottomRight.z);
		GL.Normal3(bottomRight.normal);

		GL.Vertex3(topRight.x, topRight.y, topRight.z);
		GL.Normal3(topRight.normal);
		GL.End();
	}
}
The z-value is within the range of 0.0 to 1.0. This works as expected. Now I want to generate normals for my terrain and I do so using the method described here.
for (int y = 0; y < patchHeight; y++)
{
	for (int x = 0; x < patchWidth; x++)
	{
		int xPred = Math.Max(0, x - 1);
		int xSucc = Math.Min(patchWidth - 1, x + 1);
		int yPred = Math.Max(0, y - 1);
		int ySucc = Math.Min(patchHeight - 1, y + 1);

		float sx = patch[y * patchWidth + xPred].z - patch[y * patchWidth + xSucc].z;
		float sy = patch[yPred * patchWidth + x].z - patch[ySucc * patchWidth + x].z;
		patch[y * patchWidth + x].normal = new Vector3(sx, sy, 2.0f * quadSize);
		patch[y * patchWidth + x].normal.Normalize();
	}
}
For some reason however, this looks really broken: I've re-read the form post explaining the algorithm a couple of times but I can't figure out what I'm doing wrong. So I was hoping that someone in here might be able to point me in the right direction. Thanks a lot in advance!
karwosts
karwosts

GL.Vertex3(bottomLeft.x, bottomLeft.y, bottomLeft.z);GL.Normal3(bottomLeft.normal);GL.Vertex3(topLeft.x, topLeft.y, topLeft.z);GL.Normal3(topLeft.normal);GL.Vertex3(bottomRight.x, bottomRight.y, bottomRight.z);GL.Normal3(bottomRight.normal);GL.Vertex3(topRight.x, topRight.y, topRight.z);GL.Normal3(topRight.normal);

[/quote]

You are calling glVertex and glNormal in the wrong order.

To set the normal, texcoord, color for a vertex, call glNormal, glTexcoord first, then call glVertex.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Harry Hunt
Harry Hunt
That was exactly it! Thanks a bunch!
Guess I should stick to DirectX ;-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.