My terrain Generation function's fubar.
I'm trying to generate terrain from a terragen file. I spent a bit of time creating a *.ter file class that works quite well. The only problem I'm having is when it comes down to me rendering the heights and processing the rows and columns of the actual height data I fall short. I bolded the specific function that handles the generation of the heights and as you see in the pictures (first two are using GL_TRIANGLES, and the last one is using GL_POINTS) they are not coming out anywhere near nice looking. The heights are there, and it looks like, from a stone's throw, terrain, but something must be wrong with how I'm processing the columns.
Code:
#include "globj.h"
//=========================================================================
float rotateAngle1 = 0.0;
float rotateAngle2 = 0.0;
GLuint texture1;
//=========================================================================
GLObj::GLObj() : moveX(0), moveY(0), moveZ(0), rotX(0) {}
GLObj::~GLObj() {}
bool GLObj::init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_STENCIL_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//glEnable(GL_COLOR_MATERIAL);
glClearColor(0.0, 0.0, 0.0, 0.0);
//setupLighting();
if(!setupTerrain())
return false;
return true;
}
void GLObj::setupProjection(int width, int height, double fov)
{
if(height == 0)
height = 1;
float ratio = static_cast<float>(width)/ static_cast<float>(height);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ratio, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
screenWidth = width;
screenHeight = height;
}
void GLObj::setupLighting()
{
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
//distant white light
glEnable(GL_LIGHT0);
float light0Pos[] = {0, 0, 100, 0.0};
float light0Col[] = {1.0, 1.0, 1.0, 1.0};
float light0Spc[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, light0Col);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spc);
glEnable(GL_LIGHT1);
float light1Pos[] = {100, 100, 100, 0.0};
float light1Col[] = {0.2, 0.2, 0.4, 1.0};
float light1Spc[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT1, GL_POSITION, light1Pos);
glLightfv(GL_LIGHT1, GL_AMBIENT_AND_DIFFUSE, light1Col);
glLightfv(GL_LIGHT1, GL_SPECULAR, light1Spc);
}
bool GLObj::setupTerrain()
{
FileError msg = terrain.load("Data/Surface1.ter");
if(msg == FILE_TYPE_MISMATCH || msg == FILE_READ_ERROR)
return false;
return true;
}
void GLObj::prepare(double t) {}
void GLObj::render()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-26 - moveX, -15 + moveY, -255 + moveZ);
glRotatef(15, 1, 0, 0);
glRotatef(rotX, 0, 1, 0);
TerragenFile::index row, col;
glColor3f(0.5, 0.5, 0.5);
glDisable(GL_CULL_FACE);
short int b = terrain.getBHeight();
short int s = terrain.getHScale();
for(row = 0; row < terrain.getY() - 1; ++row)
{
glBegin(GL_TRIANGLE_STRIP);
for(col = 0; col < terrain.getX(); ++col)
{
float height =
(b + terrain[(row * terrain.getX()) + col] * s )/ 65536;
float nextHeight =
(b + terrain[((row + 1) * terrain.getX()) + col] * s )/ 65536;
float x = static_cast<float>(row - terrain.getX()/2);
float z1 = static_cast<float>(col - terrain.getX()/2);
float z2 = static_cast<float>((col + 1) - (terrain.getX()/2));
glVertex3d(x, height, z1);
glVertex3d(x, nextHeight, z2);
}
glEnd();
}
}
the float height and float nextheight values are calculated from the terragen file specification where it is said to calculate the absolute height of a point in the file you use the formula
BaseHeight + Elevation * HeightScale / 65536.