Featured Posts

8. Bump Mapping in GLSL8. Bump Mapping in GLSL Introduction Bump mapping is essential in todays computer games, and computer graphics in general. Would you like to know the best thing about it? It is extremely simple to implement. Bump mapping works...

Read more

Swiftless GLSL Shader DeveloperSwiftless GLSL Shader Developer Swiftless GLSL Shader Developer   Version 0.1a Currently Swiftless GLSL Shader Developer is in it's first public release, and is currently in alpha status, meaning it is not complete and may contain...

Read more

Wordpress Optimization Wordpress Website Optimizations Introduction Wordpress itself is a fairly wonderful tool. Since switching to it, I find it is a lot quicker to make changes to my website and it is also quicker to get...

Read more

36. OpenGL Framebuffers36. OpenGL Framebuffers Introduction Frame buffers are one of those mythical things that we have all heard of, but many beginner OpenGL developers avoid because there is not much information about them, and they can be confusing...

Read more

1. Terrain Class1. Terrain Class Terrain is one of those things that so far, hasn't been perfectly recreated in computer graphics. But it is almost there! Looking over a beautiful landscape can be one of the most amazing feelings in the...

Read more

  • Prev
  • Next

3. Terrain Rendering

Posted on : 25-03-2010 | By : Swiftless | In : Terrain

Tags: , , , , ,

2

Jump To:

heightfield.h Source
heightfield.cpp Source
main.cpp Source

Download

Heightfield.H File:

In our heightfield.h file, we are going to declare some private variables inside our class, these are going to hold the height and the width of our heightfield, globally within the class:

// private:

// int hmHeight;
// int hmWidth;

1.
2.
3.
4.

5.
6.
7.
8.
9.
10.
11.
12.
13.

14.

  #include <windows.h>

class SwiftHeightField {
    
private:
    
int hmHeight;
    

int hmWidth;
    
public:
    
bool Create(char *hFileName, const int hWidth, const int hHeight);
    

    
void Render(void);
    

    
BYTE hHeightField[1024][1024];

};

Heightfield.CPP File:

To render our terrain, we are going to need to call OpenGL commands from within this source file, so we need include gl.h:

// #include <gl/gl.h>

To get the height and width of our heightfield, we then copy the height and width inside the Create function, to our global variables:

// hmHeight = hHeight;
// hmWidth = hWidth;

Now we move onto our Render function. Yay, we are about to start seeing some results :-)

To start off, I am going to just render our terrain as a bunch of points in space. To do this, we need our glBegin(GL_POINTS) and glEnd() Inside of thse calls, I am placing a loop that will create a vertex at every point along the X and the Z axis at their respective Y positions. So our code goes from nothing, to this:

// void SwiftHeightField::Render(void){
// glBegin(GL_POINTS);
// glEnd();
// }

And then to this:

// void SwiftHeightField::Render(void){

// glBegin(GL_POINTS);
// for (int hMapX = 0; hMapX < hmWidth; hMapX++){
// for (int hMapZ = 0; hMapZ < hmHeight; hMapZ++){
// glVertex3f(hMapX, hHeightField[hMapX][hMapZ], hMapZ);
// }

// }
// glEnd();
// }

Upon running this program, you should find that a window is displayed with a black background, and a bunch of white spots in space. These spots are the vertices of our terrain and are the building blocks of everything to come :-)

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.

  #include <stdio.h>
#include <gl\gl.h>

#include “heightfield.h”

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

hmHeight = hHeight;
    
hmWidth = hWidth;
    

    
FILE *fp;
    

    
fp = fopen(hFileName, “rb”);
    

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

    
fclose(fp);
    

    
return true;
}

void SwiftHeightField::Render(void){
    

glBegin(GL_POINTS);
    
for (int hMapX = 0; hMapX < hmWidth; hMapX++){
        

for (int hMapZ = 0; hMapZ < hmHeight; hMapZ++){
            
glVertex3f(hMapX, hHeightField[hMapX][hMapZ], hMapZ);
        

}
    
}
    
glEnd();
}

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 with triangle strips instead of points 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=x-lastx;
    
int diffy=y-lasty;
    
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

VN:F [1.9.3_1094]
Please rate so I know where to improve the site. 1 means needs a lot of improvement, 10 means perfect. If you leave a low rating, please state why. I don't want people just coming to bash the site.
Rating: 7.5/10 (2 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)
Improve the web with Nofollow Reciprocity.