2. Terrain Loading

Jump To:

heightfield.h Source
heightfield.cpp Source

main.cpp Source
Download

Heightfield.H File:

Our first changes will take place in our heightfield.h file. First we need to include the windows.h header file because we are using the BYTE variable type specified within the windows.h file for loading in from our heightfield.raw image file.

// #include <windows.h>

We then need to declare a variable with the BYTE variable which I am calling hHeightField like so:

// BYTE hHeightField[1024][1024];

1.
2.

3.
4.
5.
6.
7.
8.
9.
10.
11.

    #include <windows.h>

class SwiftHeightField {
public:
bool Create(char *hFileName, const int hWidth, const int 
hHeight);

void Render(void);

BYTE hHeightField[1024][1024];

};

Heightfield.CPP File:

First off here, just as above we are including another header file, only this one is stdio.h and it is used to output our loaded in data to the console window to show that we have actually loaded in some data.

// #include <stdio.h>

Then we are going to play with our Create function. First off we need to declare a FILE variable, which I am just calling fp as so:

// FILE *fp;

We then need to actually open our heightfield.raw file into our fp variable with the following line:

// fp = fopen(hFileName, "rb");

I am using the expression "rb" which stands for read as binary so we are actually reading data in, and not writing it out. Once we have opened our file, we need to read in the data. We are reading the data into our hHeightField variable starting at the start of the file, and going until it reaches the position hWidth * hHeight, which in this case is 1024 * 1024, which equals 1048576. (That’s gonna be alot of vertices ^_^).

// fread(hHeightField, 1, hWidth * hHeight, fp);

Finally we just need to close the file, which is simple with the line:

// fclose(fp);

The next 5 lines make up a look which will go through each piece of data we read in to our hHeightField variable and print it to the console window.

// for (int hMapX = 0; hMapX < hWidth; hMapX++){
// for (int hMapZ = 0; hMapZ < hHeight; hMapZ++){
// printf("%d, %d, %d\n", hMapX, hMapZ, hHeightField[hMapX][hMapZ]);
// }

// }

1.
2.
3.
4.
5.
6.

7.
8.
9.
10.
11.
12.
13.
14.
15.

16.
17.
18.
19.
20.
21.
22.
23.
24.

25.

    #include “heightfield.h”

bool SwiftHeightField::Create(char *hFileName, const 
int hWidth, const int hHeight){

FILE *fp;

fp = fopen(hFileName, “rb”);

fread(hHeightField, 1, hWidth * hHeight, fp);

fclose(fp);

for (int hMapX = 0; hMapX < hWidth; hMapX++){

for (int hMapZ = 0; hMapZ < hHeight; hMapZ++){
printf(“%d, %d, %d\n“, hMapX, hMapZ, hHeightField[hMapX][hMapZ]);

}
}

return true;
}

void SwiftHeightField::Render(void){

}

Main.CPP File:

Hehe, this is a simple change. All we need to do here is change our Create call to load in the file, heightfield.raw. So our Create line looks like:

// hField.Create("heightfield.raw", 1024, 1024);

Check out the next tutorial on rendering the heightfield here 🙂

If you have any questions, just email me at swiftless@gmail.com

1.
2.
3.
4.
5.
6.
7.
8.

9.
10.
11.
12.
13.
14.
15.
16.
17.

18.
19.
20.
21.
22.
23.
24.
25.
26.

27.
28.
29.
30.
31.
32.
33.
34.
35.

36.
37.
38.
39.
40.
41.
42.
43.
44.

45.
46.
47.
48.
49.
50.
51.
52.
53.

54.
55.
56.
57.
58.
59.
60.
61.
62.

63.
64.
65.
66.
67.
68.
69.
70.
71.

72.
73.
74.
75.
76.
77.
78.
79.
80.

81.
82.
83.
84.
85.
86.
87.
88.
89.

90.
91.
92.
93.
94.
95.
96.
97.
98.

99.
100.
101.
102.
103.
104.
105.
106.
107.

108.
109.
110.
111.
112.
113.
114.
115.
116.

117.
118.
119.
120.
121.
122.
123.
124.
125.

126.
127.
128.

    #include <GL/glew.h>
#include <GL/gl.h>

#include <GL/glext.h>
#include <GL/GLUT.h>

#include <math.h>

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <fstream>

#include <assert.h>

#include “heightfield.h”

#pragma comment(lib,“glew32.lib”)

float xpos = 851.078, ypos = 351.594, zpos = 281.033, xrot = 758, yrot = 238,
 angle=0.0;

float lastx, lasty;

float bounce;
float cScale = 1.0;

SwiftHeightField hField;

void camera (void) {
int posX = (int)xpos;

int posZ = (int)zpos;

glRotatef(xrot,1.0,0.0,0.0);
glRotatef(yrot,0.0,1.0,0.0);

glTranslated(xpos,ypos,zpos);
}

void display (void) {

glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
camera();

hField.Render();

glutSwapBuffers();
}

void Init (void) {
glEnable(GL_DEPTH_TEST);

hField.Create(“heightfield.raw”, 1024, 1024);
}

void mouseMovement(int x, int y) {

int diffx=xlastx;
int diffy=ylasty;
lastx=x;

lasty=y;
xrot += (float) diffy;
yrot += (float) diffx;

}

void keyboard (unsigned char key, int x, int y) {

if (key == ‘w’)
{
float xrotrad, yrotrad;

yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);

xpos += float(sin(yrotrad)) * cScale;
zpos = float(cos(yrotrad)) * cScale;

ypos = float(sin(xrotrad)) ;
bounce += 0.04;

}

if (key == ‘s’)
{
float xrotrad, yrotrad;

yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);

xpos = float(sin(yrotrad)) * cScale;
zpos += float(cos(yrotrad)) * cScale;

ypos += float(sin(xrotrad));
bounce += 0.04;

}

if (key == ‘d’)
{
float yrotrad;

yrotrad = (yrot / 180 * 3.141592654f);
xpos += float(cos(yrotrad)) * cScale;

zpos += float(sin(yrotrad)) * cScale;
}

if (key == ‘a’)
{
float yrotrad;

yrotrad = (yrot / 180 * 3.141592654f);
xpos = float(cos(yrotrad)) * cScale;

zpos = float(sin(yrotrad)) * cScale;
}

}

void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0);

glMatrixMode (GL_MODELVIEW);
}

int main (int argc, char **argv) {

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);

glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(“A basic OpenGL Window);

Init();
glutDisplayFunc(display);
glutIdleFunc(display);

glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(mouseMovement);

glutMainLoop ();
return 0;
} 

Download:

Download heightfield.h Source Code for this Tutorial

Download heightfield.cpp Source Code for this Tutorial

Download main.cpp Source Code for this Tutorial

Download heightfield.raw for this Tutorial

  • March 25, 2010
  • 1