Archived

This topic is now archived and is closed to further replies.

omegasyphon

terrain generation

Recommended Posts

There are tutorials on it, but keep in mind terrain generation has nothing to do with OpenGL. OpenGL is merely a rendering API.

That said, try flipcode.com or search the net for +fractal +terrain and that should give you something.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Just load in a heightmap and then build a quad-tree from it. Its really not that hard at all, very very very easy actually. Just continually split your heightmap up into smaller squares. First into 4 squares, then each of those 4 into 4 smaller ones each, etc etc, until its at a level your happy with. Keep each new squares boundaries kept in a node structure, which has joins to its parent node and its 4 children nodes.

Share this post


Link to post
Share on other sites
not to sound sarcastic but if its so easy do u mind showing an example? since all the tutorials i find are about theory but dont really explain how to implement it

Share this post


Link to post
Share on other sites
I'm currently working on a fractal terrain game thing for a project. Here is some code to help you out, it doesn't use quadtree or anything like that but it will produce a random terrain and convert it into a polygon mesh:

    

float randheight( int i ){
return ((rand()%(i*100))/100.0);
}

void recursemap( float map[MAPSIZE][MAPSIZE], int left, int right, int top, int bottom, int depth ){
int newx, newz;

// calculate new center point

newx=((left+right)/2);
newz=((top+bottom)/2);

// calculate the center of each edge

map[left][newz]=(map[left][top]+map[left][bottom]+randheight( (MAPDEPTH+1)-depth )/2.0-1.0)/3.0;
map[right][newz]=(map[right][top]+map[right][bottom]+randheight( (MAPDEPTH+1)-depth )/2.0-1.0)/2.0;
map[newx][top]=(map[left][top]+map[right][top]+randheight( (MAPDEPTH+1)-depth )/2.0-1.0)/2.0;
map[newx][bottom]=(map[left][bottom]+map[right][bottom]+randheight( (MAPDEPTH+1)-depth )/2.0-1.0)/2.0;

// if it is the first iteration generate a height for the center

if( depth==0 ){
map[newx][newz]=randheight( 8 );
} else {
// else base the height for the center on the other edge center heights

map[newx][newz]=(map[left][newz]+map[right][newz]+map[newx][top]+map[newx][bottom]+randheight( ((MAPDEPTH+1)-depth) ))/4.0;
}
// if we have recursed enough times then exit

if( depth==MAPDEPTH ){
return;
} else {
recursemap( map, left, newx, top, newz, depth+1 );
recursemap( map, left, newx, newz, bottom, depth+1 );
recursemap( map, newx, right, top, newz, depth+1 );
recursemap( map, newx, right, newz, bottom, depth+1 );
}
}

void initmap( float map[MAPSIZE][MAPSIZE] ){
// generated random heights for the corners of the map

map[0][0]=randheight( 5 );
map[0][MAPSIZE-1]=randheight( 5 );
map[MAPSIZE-1][MAPSIZE-1]=randheight( 5 );
map[MAPSIZE-1][0]=randheight( 5 );
// recurse through the map

recursemap( map, 0, (MAPSIZE-1), 0, (MAPSIZE-1), 0 );
}



That will generate a fractal landscape.
Next you need to turn it into something that you can use:

  

void map2object( float map[MAPSIZE][MAPSIZE], int mapsize ){
int x, z, vcount, pcount;

vcount=last_vert_num; //(init vcount here)


for( x=0; x<mapsize; x++ ){
for( z=0; z<mapsize; z++ ){
vertices[vcount].x=(float)x;
vertices[vcount].y=map[x][z];
vertices[vcount].z=(float)z;
vcount++;
}
}

pcount=last_poly_num; //(init pcount here)


for( x=0; x<(mapsize-1); x++ ){
for( z=0; z<(mapsize-1); z++ ){
polygons[pcount].p1=(z*mapsize)+x+last_vert_num;
polygons[pcount].p2=(z*mapsize)+x+1+last_vert_num;
polygons[pcount].p3=((z+1)*mapsize)+x+last_vert_num;
pcount++;
polygons[pcount].p1=((z+1)*mapsize)+x+1+last_vert_num;
polygons[pcount].p2=((z+1)*mapsize)+x+last_vert_num;
polygons[pcount].p3=(z*mapsize)+x+1+last_vert_num;
pcount++;
}
}
}



The second chunk of code will take your array of heights and convert them into a vertex array and a polygon array. You would call both of them like this:

  

#define MAPSIZE 17
#define MAPDEPTH 4
float map[MAPSIZE][MAPSIZE]

initmap( map );
map2object( map, MAPSIZE );



MAPSIZE should be a (2^n)+1 where n is the integer MAPDEPTH.

Hope all this helps.

---

Fleejay

Edited by - fleejay on March 25, 2001 1:46:53 PM

Share this post


Link to post
Share on other sites