Skip to main content
gamedev.net
🔒 Locked

Heightmap Bug

Started by CodeFish Dec 19, 2002 at 3:38 PM 5 replies 200+ views
Original Post
CodeFish
CodeFish
I''ve been working with heightmaps, and using tutorial 34 as an example. I''ve stumbled across what I think is a bug in my code, and I can''t see a clean way around it. After looking at tutorial 34, I think the bug is in there too. Say I have a map that is 1024 x 1024, and I''m going to have my segments 16 units apart in the x and z. My for loop would look something like this: for( GLuint nRow=0; nRow<1024; nRow+=16 ) { for( GLuint nCol=0; nCol<1024; nCol+=16 ) { // plot the quad glVertex3f( nCol, Height(nCol, nRow), nRow ); glVertex3f( nCol, Height(nCol, nRow+16), nRow+16 ); glVertex3f( nCol+16, Height(nCol+16, nRow+16), nRow+16 ); glVertex3f( nCol+16, Height(nCol+16, nRow), nRow ); } } This will loop 0-1008 in rows and cols, and NOT do the 1024''s, which is what we want (because the 1008''s are our last row). However, when asking Height() to return us our position, we''re passing in x+16 and z+16, which on the extremes are going to be 1008+16=1024. Our raw data (8-bit heightmap) has pixels from 0-1023 (1024 pixels across). By asking for pixel 1024, we''re actually asking for the first pixel of the next line. Now in the tutorial, there''s a MOD (%) cap to make sure this is not going to happen, however in this case that just means we''re using the first pixel of our current line, which could be drastically different from our previous pixel, giving us sharp edges (picture a gradient from low to high, when you reach the highest point, you''re going to make a quad to the lowest point on the end). The problem is in the very first quad we lay, it goes from 0-16, which is actually 17 pixels of data. Now we can''t start at -1, cause that''s worse than overflowing, but we can''t drop one off of our increment (16), because then we''d have more segments than we wanted. The only solution I have so far is change the check in Height(). Instead of MODding our values, check against our width minus 1, and set it to that if it''s greater. That way, we''ll get the last pixel on the line we want instead of the first pixel of the next line. Not the best solution, but fast. Maybe the tutorial is doing something that I missed, if so please let me know!
CodeFish
CodeFish
Thanks for the reply.

I think you misunderstood me. If you were to do what you have posted, you would not render the last row and col because you''re only going to less than 1008, and you''re last row and col starts at 1008. My issue was with overextending the HeightMap data. By reading pixel 1024, I''m in effect reading the first pixel of the next line, not the last pixel of my current line. Is that any clearer?
CodeFish
CodeFish
So your map in that case is 1008 x 1008? I still don''t understand (sorry!).

If I want my map to be 1024 x 1024, and I have heightmap data that is 1024 x 1024 pixels, and I''m drawing in segments of 16, I need to draw the 1008 row so that my map is indeed 1024 x 1024.

nCol = 992;
nRow = 0;

I draw that quad, it will extend from (992, 0), to (1008, 16). My map is currently 1008 wide, I need one more quad. So

nCol = 1008 (still < 1024);
nRow = 0;

I draw the quad that extends from (1008, 0), to (1024, 16). My map is now 1024 wide (the desired width). However, when I ask for height information at pixel 1024, it''s the next line of my image (zero offset, images are 0-1023 in width).

The next loop nCol == 1024, which is not less than 1024, so we break and begin our next row.

Is that any clearer?

Topic Locked

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

Sign in to reply to this topic.