I am making a simple FPS game engine for my final project in school but I am having trouble understanding why my terrain won't be drawn. It's also quite unfortunate that I was told that the project had to be finished and presented next week like three days ago. Everybody had the idea that we had at least one month to go before that so it was quite suprising, especially to me since I had barely begun my work which isn't good news when you don't know the API you're working with.

Anyways, the terrain is generated as a 3D-plot of the sums of two polynomials, fx and fy. These are also given a definition range, which will then be stretched out to match the definition range of the map.

With my test-map that I generated the x-function is

-x^4 + 2x^3 + 2x^2 - 4x + 1

and the range which the functions is defined for is -1.5 to 2.5

The y-function is

-0.05y^2 + 2

and is defined for the range -7 to 7.

Then the height for a given point is generated as simple as fx(x) + fy(y).

The definition range for the map is -50 and 50. What all that means is for example that fx(-50) would be converted into fx(-1.5) and then applied to the polynomial.

But enough talk, this is how the map looks like when I generated it in Mathematica:

http://img74.imageshack.us/img74/4410/92946098bz7.png

By iterating through -50 to 50 for the x and y and writing it to a file I found that my implementation works, and produces the same heights for a given {x, y} that Mathematica does.

Here's the code for computation, it can get a bit ugly since I've had to hack this together pretty quick.

Since the terrain is constant, I also have a function to generate terrain into an array of heights. Each element is spaced by 1 x and y, which means the spacing of the vertices will also be 1.Code:int world_dim[2]; /* dim = dimension, but is actually more like definition ranges */ double fxdim[2]; double fydim[2]; double* fx = NULL; /* List of coefficients for polynomial functions */ double* fy = NULL; int fxlen = 0; /* Array lengths for previous list */ int fylen = 0; double compute_height (double x, double y) { return compute_x(x) + compute_y(y); } double compute_x (double x) { int i; double val = fx[0]; x = (x - world_dim[0])*(fxdim[1] - fxdim[0])/(world_dim[1] - world_dim[0]) + fxdim[0]; for (i = 1; i < fxlen; i++) val = val*x + fx[i]; return val; } double compute_y (double y) { int i; double val = fy[0]; y = (y - world_dim[0])*(fydim[1] - fydim[0])/(world_dim[1] - world_dim[0]) + fydim[0]; for (i = 1; i < fylen; i++) val = val*y + fy[i]; return val; }

Finally, I there's the function to render the world as well as a function to grab a suitable color for the height (normal height = green grass, high = snow-covered mountain, low = red lava (player dies when height < 0)).Code:double* terrain = NULL; BOOL generate_terrain (void) { int x, y, imax; if (terrain != NULL) free(terrain); imax = world_dim[1] - world_dim[0] + 1; if ((terrain = malloc(sizeof(*terrain)*(imax + 1)*(imax + 1))) != NULL) { for (x = 0; x <= imax; x++) { for (y = 0; y <= imax; y++) { terrain[y*imax + x] = compute_height(x + world_dim[0], y + world_dim[0]); } } return TRUE; } return FALSE; }

Notice that this is when it gets ugly. The world reader module assumes that x and y define the plane and z is the height. The actual OpenGL app uses the default orientation where x and z is the plane, and y is the height.Code:void render_world (void) { double x, y; int ix, iy, imax; double terrain_color[3]; imax = world_dim[1] - world_dim[0] + 1; for (x = world_dim[0], ix = 0; ix < imax; x++, ix++) { glBegin(GL_TRIANGLE_STRIP); for (y = world_dim[0], iy = 0; iy < imax; y++, iy++) { get_color3dv(terrain_color, terrain[iy*imax + ix]); glColor3dv(terrain_color); glVertex3d(x, terrain[iy*imax + ix], y); get_color3dv(terrain_color, terrain[iy*imax + ix + 1]); glColor3dv(terrain_color); glVertex3d(x + 1, terrain[iy*imax + ix + 1], y); } glEnd(); } }

FWIW I used quads at first, but that didn't make a difference.

Now, onto the last piece of code, the render function of the app:

Code:GLvoid render (GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); follow_entity(&player); render_world(); //draw_entities(monsters, draw_monster); render_sky(); /* Draw crosshair */ glPushMatrix(); glLoadIdentity(); glScaled((0.05*HEIGHT)/WIDTH, 0.05, 1.0); glColor3d(0.0, 1.0, 0.0); glLineWidth(2); glBegin(GL_LINES); glVertex2d(-1.0, 0.0); glVertex2d(-0.2, 0.0); glVertex2d( 1.0, 0.0); glVertex2d( 0.2, 0.0); glVertex2d( 0.0, -1.0); glVertex2d( 0.0, -0.2); glVertex2d( 0.0, 1.0); glVertex2d( 0.0, 0.2); glEnd(); glPopMatrix(); glFlush(); }At the start of the game, the player has a x and z pos of 0, the rotations are 0 so the modelview matrix is the identity matrix translated a few units (-3.18, after falling a bit due to gravity) on the y-axis, so I don't think that the camera is being the problem (I should see at least something).Code:#define ENTITY_SIGHT 25 void follow_entity (entity* e) { gluLookAt(e->x, e->y + 0.9*e->sy, e->z, e->x + ENTITY_SIGHT*sin(e->rxz*M_PI/180), e->y + ENTITY_SIGHT*sin(e->ryz*M_PI/180) + 0.9*e->sy, e->z + ENTITY_SIGHT*-cos(e->rxz*M_PI/180), 0.0, 1.0, 0.0); }

What happens is that not even the slightest bit of terrain is generated, no matter how i spin and turn.

EDIT: Attatching the whole project, rename it from .txt to .rar

EDIT: I commented out the skybox rendering (seems like it was in the way) and drew a red quad in front of the player at start. It seems my player movements aren't correct, though I don't know why. Somethings wrong with the gluLookAt() call though, possibly an effect of me handling angles the wrong way as well.

EDIT/UPDATE:Code:GLvoid render (GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); follow_entity(&player); glColor3d(1.0, 0.0, 0.0); glBegin(GL_QUADS); glVertex3d(-0.5, -0.5 + 3.18, -1.0); glVertex3d( 0.5, -0.5 + 3.18, -1.0); glVertex3d( 0.5, 0.5 + 3.18, -1.0); glVertex3d(-0.5, 0.5 + 3.18, -1.0); glEnd(); render_world(); //draw_entities(monsters, draw_monster); //render_sky();

I noticed that gluLookAt() didn't have any effect on the near and far clipping places so tucked in a

glOrtho(-1.0, 1.0, -1.0, 1.0, -ENTITY_SIGHT, ENTITY_SIGHT); before the call, and there seems to be some generated terrain, placed behind the player. Still I have to do something about the camera. Matrices confuse me, and it doesn't help that I have a headache right now.