PDA

View Full Version : in a 3D world: how to draw a curved ground surfac?



newsb
12-02-2011, 06:49 AM
Hi all,

My question is: in a 3D world: how do I draw a curved ground surface? Currently my 3D world has a flat ground (earth) surface. I want to simulate something like, having the effect of walking on a hill/small mountain, if you understand :-)

Here's my "flat surface" piece of code (called from the display/, so you have an idea about what I've done (it's taken from some opengl book):



void DrawGround(void)
{
GLfloat fExtent = 20.0f; // total length in each direction
GLfloat fStep = 1.0f; // length of each step
GLfloat y = -0.4f; // this is groundLevel / "altitude"
GLfloat iStrip, iRun;

glColor3f(0.60f, .40f, .10f); // red/green/blue
for(iStrip = -fExtent; iStrip <= fExtent; iStrip += fStep)
{
glBegin(GL_TRIANGLE_STRIP);
glNormal3f(0.0f, 1.0f, 0.0f); // All Point up

for(iRun = fExtent; iRun >= -fExtent; iRun -= fStep)
{
glVertex3f(iStrip, y, iRun);
glVertex3f(iStrip + fStep, y, iRun);
}
glEnd();
}
}


Let's say I want to have this ground surface, for my 3D world:

http://www.2shared.com/photo/_YWRnQdJ/surface_ground.html

How do I implement it in a good way? I think I need to learn how to make a curved surface (I guess making the surface out of quadrahedrons doesn't look good)?

Any ideas/suggestions/code pieces are warmly welcome!

BionicBytes
12-02-2011, 10:10 AM
Let's say I want to have this ground surface, for my 3D world
It's called a terrain. You have the start of it coded already - ie create a series of triangle strips.
If you start by reading a grey-scale bitmap as the source of the height image, then you can alter the Y value in your posted routine so that the terrain is displaced by the values in your bitmap.
There are litterally dozens of tutorials on terrains. Start as suggested using immediate mode to get a basic handle on what you are trying to acheive, then move on to vertex arrays as an optimisation of the technique.

newsb
12-03-2011, 09:38 AM
BionicBytes: That's great, thank you very much!

It you (or anyone else) has some small working code pieces (like in my small example above, see the original post), then I would be grateful if you post your terrain code piece here, below...

I'm currently trying to do something myself... I think I need to provide the surface normal (with glNormal3f) and this is really causing me some problems, right now... I've initialized my height map like:



float **hgtmap;

hgtmap = new float*[elems]; // allocate "main" array - "rows"
for(int x=0; x<elems; x++)
{
hgtmap[x] = new float[elems]; // allocate member of "main" - "columns"
for(int z=0; z<elems; z++)
{
hgtmap[x][z] = 0.05f*(float)(rand()%10); // create height map
}
}


How do I calculate the surface normals? I'm doing this, at the moment:



void DrawGround(void)
{
GLfloat xVal, zVal; // xVal = x-coordinate, zVal = z-coordinate
int countX = 0;
int countZ = 0;

glColor3f(0.60f, .40f, .10f); // red/green/blue
// glShadeModel(GL_FLAT); // ??? Need this?
for(xVal = -fExtent; xVal <= fExtent; xVal += fStep)
{
countX += 1;
countZ = 0;

glBegin(GL_TRIANGLE_STRIP);
glNormal3f(0.0f, 1.0f, 0.0f); // surface normal: UP - WRONG?
for(zVal = fExtent; zVal >= -fExtent; zVal -= fStep)
{
countZ += 1;
glVertex3f(xVal, hgtmap[countX-1][countZ-1], zVal);
glVertex3f(xVal + fStep, hgtmap[countX-1][countZ-1], zVal);
} // for(zVal = fExtent; zVal >= -fExtent; zVal -= fStep)
glEnd();
} // for(xVal = -fExtent; xVal <= fExtent; xVal += fStep)

glShadeModel(GL_SMOOTH);
} // end of Drawground function


I can add, that there is a severe problem with my code: There are "holes" in the drawn ground. Finally, I've not added loading the bitmap yet. I guess I can try that, once my surface normals are ok and when I don't have "holes" in my ground/"earth"...

Thanks for any hints/help you can offer!

BionicBytes
12-03-2011, 12:43 PM
I'm concerned by just how you have holes? Do you mean cracks between triangle strip edges ?
Even that should not be happening and each edge of the tri strip should be using the same vertex element. You need to fix this first.
Normals can be calculated afterwards but not using glNormal3f as you need to compute them off line.

newsb
12-03-2011, 08:41 PM
Hi bionicbytes,

With "holes" I mean that I can see the background color (which is blue like the sky in my case). Maybe it is cracks between triangle - not sure, because I have a random elevation of points like shown above...

Could you/somebody else please look at my code above and tell if there are any obvious problems with the way I draw my "random elevated ground" ?

Are you sure it's not because I'm using the wrong normals? I think that could explain the "holes".... And what would be the best approach, in my case to calculate the normals - knowing the height map (as a 2D array)?

Thanks!

mbentrup
12-05-2011, 01:51 AM
You pass the same hgtmap value in both glVertex() calls, you probably want to pass the hgtmap[countX][countZ-1] in the second call to get the height of the adjacent Vertex.

newsb
12-16-2011, 10:37 AM
mbentrup: OMG, thank you very much for your correction about hgtmap...

Sorry for late answer - I thought nobody wanted to reply to me, but then now I checked back for late answers/replies and found your hint/post.

Thank you very much! It now seem to work (although could need a bit of improvement here and there)! I was too blind to see that, I'm glad you too the time to write, I'm grateful about that :-)