Sign in to follow this  

Terrain Woes

This topic is 4731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Free Image Hosting at www.ImageShack.us Greetings Above is a pic of my terrain rendered in wire frame and then rendered again with a texture. In the textured one, you'll see that in the red circle is a part of the terrain that didn't exist in the wireframe version of it. Any ideas what would be causing it?
bool CHeightmap::Render(float _x, float _y, float scale, bool wireframe)
{
	float startX, startY;
	float curX, curY, curZ;

	startX = (_x - (float)width / 2.0f) * scale;
	startY = (_y - (float)height / 2.0f) * scale;
	if(!wireframe)
	{
		EnableTextures();
		texGrass.Bind();
	}

	glBegin(wireframe ? GL_LINES : GL_QUADS);
		for(int y = 0; y < (signed)height; y++)
		{
			for(int x = 0; x < (signed)width; x++)
			{
				// Bottom left
				glTexCoord2i(0, 0);
				curX = (startX + x) * scale;
				curZ = (startY + y + 1) * scale;
				curY = vertices[(y + 1) * width + x] * scale;
				glVertex3f(curX, curY, curZ);
				// Bottom right
				glTexCoord2i(1, 0);
				curX = (startX + x + 1) * scale;
				curZ = (startY + y + 1) * scale;
				curY = vertices[(y + 1) * width + x + 1] * scale;
				glVertex3f(curX, curY, curZ);
				// Top right
				glTexCoord2i(1, 1);
				curX = (startX + x + 1) * scale;
				curZ = (startY + y )* scale;
				curY = vertices[y * width + x + 1] * scale;
				glVertex3f(curX, curY, curZ);
				// Top left
				glTexCoord2i(0, 1);
				curX = (startX + x) * scale;
				curZ = (startY + y) * scale;
				curY = vertices[y * width + x] * scale;
				glVertex3f(curX, curY, curZ);				
			}
		}
	glEnd();
	DisableTextures();
	return true;
}

You may remeber this code from a while back when I posted a question on why the terrain was invisible. Well now its visible but with a minor problem. Also, if I decrease the scale/zoom out, I see a single line sticking out where the strange part is. Thanks

Share this post


Link to post
Share on other sites
I think the problem is that you are reaching out of the array. Would you like me to show you or would you prefer to find it yourself?

Notice that the problem is visable because of the diffrence between lines and quads and has nothing to do with textures.

Share this post


Link to post
Share on other sites
ok:

for(int y = 0; y < (signed)height; y++)
...
curY = vertices[(y + 1) * width + x] * scale;

so:

if y = height-1 then the index into vertices is height * width + x which is bigger than height * width which I'm guessing is the size of your array.

Share this post


Link to post
Share on other sites
Thankyou sooo much! That fixed it!
Another problem though
Free Image Hosting at www.ImageShack.us

What the hell is going on with the water in the ciricled area?
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
When I turn off blending, you can't see it as much but there is a tiny line runing down the water where it is screwing up.
Thanks.

Share this post


Link to post
Share on other sites
Like already said, changing your geometry would be better...Z fighting occurs when polygons are too close together--rounding errors cause one polygon to be on top in one frame, and the other polygon in the next frame. If you move the polygons away from eachother, things should work fine...

Share this post


Link to post
Share on other sites
You should modify (lower) your 'under sea' terrain to avoid overlapping.
You should remember that Z value for every single pixel is affected by a computational error (depending by the hardware of course) that cannot be totally eliminated. So when you move the scene there are pixels with similar Z values that jumps in front and behind creating the ugly effect!

Share this post


Link to post
Share on other sites
Quote:
Original post by Darobat
I'm kinda lost on what your talking about... What function would I use to do that?


Just move your glVertex3f() calls for the axis that is up, Y or Z whatever you are using, to a value lower than you currently have.

Share this post


Link to post
Share on other sites
Is there any other way to do it? Like give the water priority over it? If I change the water level, all it does is move the glitch to another spot. And if I lower the water level from 2.0 to 1.8, I can't see it, but there isn't anything sticking up from the water where teh glitch was apearing.

Share this post


Link to post
Share on other sites
OK, I just learned that If I resize the window it will move and resize the glitched part of the water. When I resize the window I call gluPerspective(45.0f, (float)width / (float)height, 0.1f, 75.0f);
That makes no glitch in the water but if I chnage the last parameter to 100.0f I can see it again. Also, if I resize the window I can see the glitch again... ?????

Share this post


Link to post
Share on other sites
Yes. As other have said it's a z-fighting/z-precision issue.

When you render a frame, you render the colours AND a Z (depth) value. As with colour, you have a limited number of bytes to store this depth value for each pixel. However, the range of depths you might need to represent changes depending on how you set up your near and far planes. Can you see how if you use (for example) 24 bits to represent a depth which could be from 1 to 1000, you have more accuracy than if you used those same 24 bits to store depth values from 0 to 10,000?

This is a very well documented problem, and it should be easiy to solve once you've done a bit of reading.

Try reading this. It should explain everything.

Share this post


Link to post
Share on other sites
Two tips I wanted to give concerning this topic:
1.) You should really use VBO's. It's just emensely faster which means way bigger terrains etc.
2.) This may not be a must but in my opinion it is best to wrap the API specific code into a wrapper class. Sure if this is a small project it aint that important but its something quite easy to do and it doesnt hurt to start earlier.
Porting to other API's like DirectX will become so much easier. Plus you arent as dependent on other peoples code.
Porting to other platforms can often become easier.
etc.

-CProgrammer

Share this post


Link to post
Share on other sites
Arg, that article completly lost me... :S... I tried adding glDepthRange() but I have no Idea what to set it to, so that it will work with my program. Thanks.

Share this post


Link to post
Share on other sites
ARG This is confusing!! So everytime the player was to move on my terrain do I have to change the z-near/z-far ratio or is there some magical constant ratio that will work for my whole terrain?

Share this post


Link to post
Share on other sites
I'm assuming coordinate units are meters.
Use a 24-bit Z buffer.
Put the near clipping plane at least 1 meter out (2 is better, if you can swing it).
Put the far clipping plane at infinity (make stencil shadows easier). The ratio doesn't matter so much; it's the absolute value of the near plane that matters the most.
Put a collision sphere around your camera that has the same radius as your clipping plane distance, to make sure the camera doesn't clip through anything.
Problem solved, unless you have very special, non-typical requirements.

Share this post


Link to post
Share on other sites
Quote:
Original post by Darobat
ARG This is confusing!! So everytime the player was to move on my terrain do I have to change the z-near/z-far ratio or is there some magical constant ratio that will work for my whole terrain?


No, you don't have to change it every time the player moves - remember the depth values are AFTER projection. Essentially this means the depth is measured from the viewpoint, so it doesn't matter where your player moves; the depth is measured in the camera's space, not worldspace.

If it helps, I use near=1.0, far=23000 and a 24 bit Z buffer.

Share this post


Link to post
Share on other sites
Quote:
Original post by mrbastard
Quote:
Original post by Darobat
ARG This is confusing!! So everytime the player was to move on my terrain do I have to change the z-near/z-far ratio or is there some magical constant ratio that will work for my whole terrain?


No, you don't have to change it every time the player moves - remember the depth values are AFTER projection. Essentially this means the depth is measured from the viewpoint, so it doesn't matter where your player moves; the depth is measured in the camera's space, not worldspace.

If it helps, I use near=1.0, far=23000 and a 24 bit Z buffer.

I was being unclear. If by player I mean the player is in first person, so the camera is moving with the player. And also, I know what projection and viewport are but I can't figure them out in your context. Thanks


P.S. I changed it to 1.6f and 23000.0f and I currently don't see and z-fighting so It might be gone. I just gotta move the camera around and see if it appears again.
EDIT: I checked and I think it is gone! Thank you sooo much everyoen who helped me with this!!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Which would be generally faster, for heightmapped terrain?:

A) display list
B) vertex arrays
C) Vertex Buffer Objects (VBOs)

??

Share this post


Link to post
Share on other sites

This topic is 4731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this