Heightmap issue in c++

Started by
-1 comments, last by o002654a 13 years ago
So I'm a first year student for an HND in computer games programming, and I've choosen for my "Introduction to programming 3D applications" course work, to do a height map application. Idea being read in a height map file and output it to the screen, changing camera angle and other features once that has been done.

Problem is that although the program runs, goes through the functions, and loops itself continously, All I get is my deafult background of white displayed. To test that it was loading and processing through the steps I have it change the background to black when the verticies for the quads are supposed to have been loaded and print statements stating where it currently is in the code. This happens but I have no output quad wise.


[s]The code above is what I have so far, the file being loaded is a .raw file, but I would have prefered a .bmp. A dev.hq tutorial was the best I could find that used a .raw instead, and has been for the most part very useful, and I've grown to understand a lot of what is going on, except for the issue of why it doesn't load. Any suggestions?

[/s]EDIT

I've managed to sort a few of the problems out, the camera for one thing, realised I wasn't using it correctly, still not but at least I can see that file does load and after a lengthy waiting time (about 5~6secs on my laptop) the height map loads.

Now here is the problem as I see it, I'm not laoding one instance of the height map but 256*256 of the instance. I'm supposed to load it once and read the pixals as the Y coordinates, but it seems I'm just placing 256*256 number of Quads that contain the flat image in the .raw file. Good news is that the colour changer that is supposed to read the pixal and assign a green tone to it works, so the quads are at least colourful....completely flat...but colourful. Any suggestions?

Here's the updated code as it is so far:


/* Author James Oland o002654a, some aspects were designed with tutorials from dev-hq.*/

//Include statements
#include <iostream> //since this program reads in and handles a file
#include <Windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <stdio.h>

using namespace std;

//Global variables and definitions
#define windowSize 400
#define imageSize 257 //This is the size of the image (it will need to be equal across its x and y axis to work properly.
#define tileSize 16 //Smaller tiles will take longer to process, but will look smoother, the opposite for larger tiles.
#define heightRatio 1.5f //Smaller ratios will produce a faltter terrain, higher ones will be more mountainous.

const float midPoint = (imageSize * imageSize) / 2.0f;

bool fillRender = true; //Used to switch between wire tiles and filled tiles (these will appear solid).

BYTE getHeightmap[imageSize*imageSize]; // Holds the Heightmap information.

//Prototypes
void init(); //This is where the window has its values inialised.
void display(); //This is where the scene is drawn.
void key(unsigned char key, //Used to store the last key pressed.
int x, int y); //Recoreds the location of the mouse cursor.
void outputText(float x, float y, //Text is output at the x and y location in the scene.
char * text); //The text displayed on the hud is handled here.
void loadFile(LPSTR fileName, //Creates a 8 bit ANSI string pointer for the string inserted in fileName.
int nSize, //Maximum number of items to read the image, this would be the (image size in bytes) - (width of the image * height of the image).
BYTE *pHeightmap); //The pointer to the heightmap.
int heightValues(BYTE *pHeightmap,
int x,
int y);
void setVertexColour(BYTE *pHeightmap,
int x,
int y);
void drawHeightmap(BYTE pHeightmap[]);
void glutIdle();

//Structures
typedef struct {
float x;
float y;
float z;
} point3D;

typedef struct {
point3D pos;
point3D lookAt;
point3D up;
} camera;

camera cam = {0, 200, 1000, 0, 0, 0, 0, 1, 0};

int main(int argc, char* argv[]) {
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(windowSize, windowSize);
glutInitWindowPosition(100, 100);
glutCreateWindow("IP3DA Project: o002654a");
init();
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(glutIdle);

glutMainLoop();
return 0;
}

void init() {
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glColor3f(0.0, 0.0, 0.0);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,
GL_NICEST);

//File load
loadFile("Heightmaps/map_01.raw",
imageSize * imageSize,
getHeightmap);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 0.5f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void display() {
char message[30];
glLoadIdentity(); // reset the matrix
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);

//Code used for drawing anything to the screen goes here, before glFLush is called.
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z, cam.lookAt.x,
cam.lookAt.y, cam.lookAt.z,
cam.up.x, cam.up.y, cam.up.z);

drawHeightmap(getHeightmap);

sprintf(message, "Camera (%.1f, %.1f, %.1f)", cam.pos.x, cam.pos.y, cam.pos.z);
outputText(-0.95, 0.5, message);
glutSwapBuffers();
}

void key(unsigned char key, //key used for keyboard input
int x, int y) { //x and y used for the mouse location
switch(key) {
case 'r': //When 'r' is pressed
fillRender = !fillRender; //Change RenderVariable
break;
case 'w':
cam.pos.y += 5.0f;
break;
case 'a':
cam.pos.x -= 5.0f;
break;
case 's':
cam.pos.y -= 5.0f;
break;
case 'd':
cam.pos.x += 5.0f;
break;
case 'z':
cam.pos.z += 5.0f;
break;
case 'x':
cam.pos.z -= 5.0f;
break;

}
glutPostRedisplay();
}

void glutIdle() {
glutPostRedisplay();
}

void outputText(float x, float y,
char * text) {
int i, length;
length = strlen(text);
glRasterPos2f(x, y);
for (i = 0; i < length; i++) {
glutBitmapCharacter(
GLUT_BITMAP_HELVETICA_12,
text);
}
}

void loadFile(LPSTR fileName,
int nSize,
BYTE *pHeightmap) {
FILE *pFile = fopen (fileName, "rb"); //Open the file in a read only binary format.
if (pFile == NULL) { //Check to see if the file has been opened.
MessageBox(NULL,
"Could not find the heightmap file specified.",
"Error with file load.",
MB_OK); //Display the error message if anything goes wrong loading the file.
exit(1);
}

fread (pHeightmap, 1, nSize, pFile); /*Load the file into the pHeightMap Data Array,
- pHeightmap is the pointer to the block of memory to be stored at,
- 1 is the size of each element to be read in bytes,
- nSize is the count we need to go upto before we stop reading in data,
- and pFile is the pointer to the file object that has been stated as the input stream.*/
if (ferror (pFile)) { //Checks to see if everything was read correctly.
MessageBox(NULL,
"Failed to read the data in the file.",
"Error reading file.",
MB_OK); //Display the error message if anything goes wrong reading from the file.
}
fclose (pFile); //Got to be tidy, it is important to close the file after it has been finished with.
}
//This function returns the heights from the heightmap index.
int heightValues(BYTE *pHeightmap, //Where we are getting the data from.
float x, //The x values.
float z) { //The y values, which will be read in for the z coordinates.
//printf("Entered heightValues function\n");
int col = int(x/tileSize) % imageSize; //The percentage character in these two lines is used to check for out of bound errors.
int row = int(z/tileSize) % imageSize;
//printf("heightValues bounds check ran\n");
//Don't manage to get this far.
//printf("Within heightValues, pHeightmap does not return NULL\n"); //Now we make sure the data is valid.
return pHeightmap[col + (row*imageSize)]; /*If the entry was valid then we return the values. This bit requires a bit of imagination,
although this is only a one dimensional array, imagine the array input is being processed
like so: pHeightmap[x][y]. In essence, thats what we are doing treating the array as if it
were 2D.*/
}

void setVertexColour(BYTE *pHeightmap, //This sets the colour value for a particular index.
float x,
float z) { //we read in the file pointed to, and an x and y variable.
float y = (heightValues(pHeightmap, x + midPoint, z + midPoint) / 256.0f); //Then we define the colours to make lower points darker than higher ones.
glColor3f(0.1f, y, 0.1f); /*This means that the colour we are changing will be green,
glColor3f(1.0f, y, 0.0f); we could actualy make it red, or blue, or even a mix of two or all three values.
glColor3f(0.0f, 0.1f, y); We can even predefine part of the colours for a better tone, so only the green might change.
glColor3f(0.0f, y, y); With lower tones maybe being only Red, but higher ones being red with green added.*/

float scale = 0.1f;
glVertex3f(x * scale, y * 1.8f * scale, z * scale);
}

void drawHeightmap(BYTE pHeightmap[]) { // This Renders The Height Map As Quads
if(fillRender) {
glBegin(GL_QUADS);
}
else {
glBegin(GL_LINES);
}
for (float x = -midPoint; x <= midPoint; x += tileSize) {
for (float z = -midPoint; z <= midPoint; z += tileSize) {
//Get the x, y, z values for the Bottom Left Vertex
//printf("Verticies bottomleft set\n");
setVertexColour(pHeightmap, x, z);
//printf("Verticies topleft set\n");
setVertexColour(pHeightmap, x, z + tileSize);
//printf("Verticies topright set\n");
setVertexColour(pHeightmap, x + tileSize, z + tileSize);
//printf("Verticies bottomright set\n");
setVertexColour(pHeightmap, x + tileSize, z);
}
}
glEnd();
glColor4f(0.0f, 0.0f, 0.0f, 0.0f); //reset the colour back to black so any new objects are black unless we change it again.
}



This topic is closed to new replies.

Advertisement