Thread: GL terrain demo preview.

  1. #1
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704

    GL terrain demo preview.

    Decided to do a terrain engine, and to make things interesting, do one in GL(which i dont know). With a few tutorials, and a little inginuity I've created this beast:
    http://amithran.hybd.net/tdemo_preview.jpg
    Im sure a lot of you are thinking "12 fps!!! WOW, AMAZING, ASTOUNDINGLY -- sucky". Well heres the deal, I've implimented NO frame savers. I plan to add Occlusion culling, CLOD, and a few ideas of my own. I expect pretty high performance when im done. I also still have to convert my GL_TRIANGLE's into some sort of face list, to save on vertexs. Lots of improvements here.

    The terrain generation is completly my own, it wasnt takin from any tutorial. The texturing methods however, have been adapted from a few.

    Planned Additions:
    -weeds, trees, flowers and other small randomly generated sprites to pretty-fy the landscape.
    -sky box, for nice cloudy days.
    -sun system, that rotates around the world on a timer + ambiant moon lighting. These include visible sun and moon art.
    -water
    -collision
    -physics
    -game ? probably not. Just a demo.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  2. #2
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    It looks really nice. The quality of everything seems quite high. How are the vertices stored/calculated? Is it just from a model file, or is it generated from some sort of a gray scale picture like gametutorials does it? I suggest you read this post I made, it explains how you can use vertex arrays to increase speed and decrease the amount of vertices used without having to use GL_TRIANGLE_STRIP (you can still use GL_TRIANGLE without having to convert to some sort of face list)
    it's a good method to use. Are you going to implement some kind of binary or quad/octree and frustum culling to speed up rendering? I'm sure you can make that sucker fast!
    read this

  3. #3
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    that looks good. im working on something similar right now (for a game) but im not as far into it as your are ( no textureing yet ) here's what mine looks like so far.

  4. #4
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    I totally mean no offense Perspective (I hope you don't get mad at me) but this is his thread meant to show off his work, not for others to show off theirs.

    EDIT: why don't you start your own thread to show off your work?

  5. #5
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    I don't mind perspective's post. Its nice to see other peoples work (as long as it pertains to the subject).

    I would like to compare notes with you perspective; like what method do you use to generate the terrain? These are my two functions (VERY messy):

    Code:
    //This method is to create simi random terrain patches.
    void Terrain::Init(float width, float height, int rows, int cols, float tscale)
    {
    	m_vertices = new sVERTEX*[rows];
    	for( int r = 0; r < rows; r++ )
    		m_vertices[r] = new sVERTEX[cols];
    
    	m_rows = rows;
    	m_cols = cols;
    	m_width = width;
    	m_height = height;
    	m_scale = tscale;
    	m_isProc = false;
    	
    	float tdist = m_width/m_cols;
    	float tdist2 = m_height/m_rows;
    	/*
    	0_1_2
    	|/|/|
    	3 4 5
    	*/
    	int disp = 0;
    	float max = 1.0f;
    	int center = m_rows/2;
    	// initial
    	for( r = 0; r < m_rows; r++ ){
    		for( int c = 0; c < m_cols; c++ ) {
    			m_vertices[r][c].X = r*tdist;
    			if( rand()%3 >= 2 ) 
    				m_vertices[r][c].Y = ((float)(rand()%10)/10)*max;
    			else
    				m_vertices[r][c].Y = 0.0f;
    
    			m_vertices[r][c].Z = c*tdist2;
    		}
    	}
    	// smooth, rolling hills :)
    	for( r = 0; r < m_rows; r++ ){
    		for( int c = 0; c < m_cols; c++ ) {
    			//if( !(m_vertices[r][c].Y > 0.0f) ) {
    			if( 1 ) {
    				float sum = 0;
    				int avgc = 0;
    				
    				if( r > 1 ) {
    					if(m_vertices[r-1][c].Y != 0.0f ) {
    						sum += m_vertices[r-1][c].Y;
    						avgc++; }
    				}
    				if( r < m_rows-1 ) {
    					if(m_vertices[r+1][c].Y != 0.0f ) {
    						sum += m_vertices[r+1][c].Y;
    						avgc++;}
    				}
    				if( c > 1 ) {
    					if(m_vertices[r][c-1].Y != 0.0f ) {
    						sum += m_vertices[r][c-1].Y;
    						avgc++; }
    				}
    				if( c < m_cols-1 ) {
    					if(m_vertices[r][c+1].Y != 0.0f ) {
    						sum += m_vertices[r][c+1].Y;
    						avgc++;}
    				}
    
    				if((r>1)&&(c>1)) {
    					if(m_vertices[r-1][c-1].Y != 0.0f ) {
    						sum += m_vertices[r-1][c-1].Y;
    						avgc++; }
    				}
    				if((r<m_rows-1)&&(c<m_cols-1)) {
    					if(m_vertices[r+1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r+1][c+1].Y;
    						avgc++;}
    				}
    				if((r>1)&&(c<m_cols-1)) {
    					if(m_vertices[r-1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r-1][c+1].Y;
    						avgc++; }
    				}
    				if((r<m_rows-1)&&(c>1)) {
    					if(m_vertices[r+1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r+1][c-1].Y;
    						avgc++; }
    				}
    
    				m_vertices[r][c].Y = ((float)sum/avgc)/1.2;
    			}
    		}
    	}	
    
    };
    
    
    // This is for heightmap based creation of terrain
    
    bool Terrain::Init(char* heightMapFilename, int width, int height, float heightDivider, float scale)
    	{
    	FILE* file;
    	unsigned char* heightMap;
    
    	m_vertices = new sVERTEX*[height];
    	for( int r = 0; r < height; r++ )
    		m_vertices[r] = new sVERTEX[width];
    
    	m_rows = width;
    	m_cols = height;
    	m_width = width;
    	m_height = height;
    	m_scale = 1.0f;
    	m_pScale = scale;
    	m_isProc = true;
    	
    	float tdist = (m_width/m_cols)*m_pScale;
    	float tdist2 = (m_height/m_rows)*m_pScale;
    
    
    	file= fopen(heightMapFilename, "rb");
    	if(file==NULL)
    		return false;
    
    	heightMap= new unsigned char	[width*height];
    	if(heightMap==NULL)
    		return false;	// didnt allocate
    
    
    	fread(heightMap, 1, width*height, file);
    
    		for( r = 0; r < m_rows; r++ ){
    			for( int c = 0; c < m_cols; c++ ) {
    				m_vertices[r][c].X = r*tdist;
    					int a = heightMap[(r*height)+c];
    					m_vertices[r][c].Y = (a/4);
    				m_vertices[r][c].Z = c*tdist2;
    			}
    		}		
    		for( r = 0; r < m_rows; r++ ){
    			for( int c = 0; c < m_cols; c++ ) {
    				float sum = 0;
    				int avgc = 0;
    				if(r > 1) {
    					sum+= m_vertices[r-1][c].Y;
    					avgc++;
    				}
    				if(r < m_rows-1) {
    					sum+= m_vertices[r+1][c].Y;
    					avgc++;
    				}
    				sum /= avgc;
    				if( m_vertices[r][c].Y < sum/2) {
    					m_vertices[r][c].Y = sum;
    				}
    				
    			}
    		}
    
    
    	fclose(file);
    	int b = m_vertices[5][2].Y;
    	char* text = cus_printf("y: %i", b);
    	SetError( text );
    
    	if(heightMap)
    		delete[] heightMap;
    
    	
    	
    	// smooth, rolling hills :)
    	for( r = 0; r < m_rows; r++ ){
    		for( int c = 0; c < m_cols; c++ ) {
    			//if( !(m_vertices[r][c].Y > 0.0f) ) {
    			if( 1 ) {
    				float sum = 0;
    				int avgc = 0;
    				
    				if( r > 1 ) {
    					if(m_vertices[r-1][c].Y != 0.0f ) {
    						sum += m_vertices[r-1][c].Y;
    						avgc++; }
    				}
    				if( r < m_rows-1 ) {
    					if(m_vertices[r+1][c].Y != 0.0f ) {
    						sum += m_vertices[r+1][c].Y;
    						avgc++;}
    				}
    				if( c > 1 ) {
    					if(m_vertices[r][c-1].Y != 0.0f ) {
    						sum += m_vertices[r][c-1].Y;
    						avgc++; }
    				}
    				if( c < m_cols-1 ) {
    					if(m_vertices[r][c+1].Y != 0.0f ) {
    						sum += m_vertices[r][c+1].Y;
    						avgc++;}
    				}
    
    				if((r>1)&&(c>1)) {
    					if(m_vertices[r-1][c-1].Y != 0.0f ) {
    						sum += m_vertices[r-1][c-1].Y;
    						avgc++; }
    				}
    				if((r<m_rows-1)&&(c<m_cols-1)) {
    					if(m_vertices[r+1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r+1][c+1].Y;
    						avgc++;}
    				}
    				if((r>1)&&(c<m_cols-1)) {
    					if(m_vertices[r-1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r-1][c+1].Y;
    						avgc++; }
    				}
    				if((r<m_rows-1)&&(c>1)) {
    					if(m_vertices[r+1][c+1].Y != 0.0f ) {
    						sum += m_vertices[r+1][c-1].Y;
    						avgc++; }
    				}
    
    				m_vertices[r][c].Y = (sum/avgc)/1.2;
    			}
    		}
    	}		
    
    	
    	return true;
    };
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  6. #6
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    Originally posted by Silvercord
    It looks really nice. The quality of everything seems quite high. How are the vertices stored/calculated? Is it just from a model file, or is it generated from some sort of a gray scale picture like gametutorials does it? I suggest you read this post I made, it explains how you can use vertex arrays to increase speed and decrease the amount of vertices used without having to use GL_TRIANGLE_STRIP (you can still use GL_TRIANGLE without having to convert to some sort of face list)
    it's a good method to use. Are you going to implement some kind of binary or quad/octree and frustum culling to speed up rendering? I'm sure you can make that sucker fast!
    read this
    I do believe the method you spoke of in that thread is (as i Know it in D3D) vertex buffers. However in my D3D application I was able to use vertex buffers in combination with face lists. I plan on trying to implement the same methods in conjunction.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  7. #7
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    I think I understand most everything that's going on, it looks like good code to me (it's not messy imo, but it's a lot to read at once for me), but I have a few questions on some things. What kind of file is passed onto the heightmap version of the loader? What do you mean in the first version of Init when you say it 'generates semi smooth terrain patches', it looks like it just generates terrain randomly (which is still cool). What is the difference between d3d vertex buffers and vertex indexing? What exactly do you mean by face list? I would like to point out that I don't think 'vertex list' is any kind of convention special to a specific api. Do you calculate texture coordinates for the triangles yourself? If so, how do ya do that I've always wondered.

    well as long as you don't mind then to perspective: I think yours looks very nice as well. I'd also like to know what methods you use Perspective. I'm going to be making a terrain viewer type thing for a school project, but it cannot be done randomly, in fact I'm going to build every aspect of the terrain in milkshape3d (it has to exactly mirror a watershed that is a part of my problem in chemistry). The reason I asked about the texture coordinates is that milkshape3d calculates all of that stuff for you, and it is only a matter of reading it in and setting it with OpenGL, which isn't nearly as complicated as calculating it myself.

    All right well keep up the good work everyone.

    EDIT:

    This is probably a noob question but I have to ask, what exactly is being tested when you do if(1).

    Code:
    //if( !(m_vertices[r][c].Y > 0.0f) ) {
    			if( 1 ) { //? :(
    				float sum = 0;
    				int avgc = 0;
    Last edited by Silvercord; 03-23-2003 at 01:14 PM.

  8. #8
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    So many questions, so many.

    Bottom up:
    You'll notice a lot of my code is commented out. Thats becuase when I encounter a problem where the syntax works, but the effect is flawed rather then alter what I have, generally I make a copy of the code snippet to work with, a reference if you will. I wont usualy delete a commented snippet until I'm SURE I wont need it again.
    An artifact of this method are the debugging lines. Hense the "messy" code.

    By face list, i mean triangle list. Also, conventions of 3d vertex/face handling are better left explained by a more seasoned DX/GL programmer. As I'm still a novice, and my 'understanding' or 'comprehension' of what one thing is or does is not garanteed to correct. Most of my programming knowledge comes from self teaching, by viewing other's code and logically understanding it, and transposing to my needs. This is so for DX, GL Api's, and even the c++ language itself.

    I use a .RAW file format for the hieght map.

    The 'semi smooth' is so becuase of the random+smoothing method i use. How ever, it is not capable of the smooth, OR abruptness of a HeightMap generated technique. So its 'semi'.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  9. #9
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    >>>>
    I don't mind perspective's post. Its nice to see other peoples work (as long as it pertains to the subject).

    I would like to compare notes with you perspective; like what method do you use to generate the terrain? These are my two functions (VERY messy):
    >>>>

    yeah, i thought it would be ok to post that as it was related to the discussion. i didnt mean to step on anyone's toes (and i guess i didnt )

    your methods are interesting and far more sophistocated than what im doing. my methods of generation have no random aspect (other than my lacking artistic talent with black and white bitmaps) i just read in a bitmap, use its dimensions as the terrain dimensions (scaled of course) then use the color value to determine the height. that way you can just use an airbrush type tool in a photoshop type program and you get nice smooth hills.

    >>>>
    I totally mean no offense Perspective (I hope you don't get mad at me) but this is his thread meant to show off his work, not for others to show off theirs.

    EDIT: why don't you start your own thread to show off your work?
    >>>>

    no offense taken. to be honest, i didnt think it deserved its own thread!!... (yet)

    i plan on implementing a 'scalable' feature. the user will be able to controll smoothness by keyboard input and watch the terrain transform in real time. maybe then it will be worth a thread of its own! lol

  10. #10
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704

    Update, yey.

    http://amithran.hybd.net/tdemo_preview2.jpg

    MUCH imporvement with simple Frustum Culling. The fps still dips to a minimum of 30 if you fanagle the the camera into a complex vew of the terrain. Why? Becuase I havent implimented backface culling. I expect that to provide another large boost.

    I've researched Octrees now. I will impliment it, as well. However, that for the time being will only be a slight improvement, as it will only less the number of vertices to be checked. It will be much more important when I start generating Larger landscapes.



    EDIT: Oh, I thought I'd make it more clear that the vertice and face counts are TOTALS and not neccesarily viewable. The first screen shot tells how many there are in all the terrain. The second shot only shows a small portion of that, whats in the view frustum.
    Last edited by dbgt goten; 03-23-2003 at 06:25 PM.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  11. #11
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,743
    hmm...very nice...i like it...

    I am also doing something very similar right now. It is going along nicely. I am interested in knowing what you are using as your textures...I got some simple stuff on the internet that I am using right now for mine. I like your texturing better than mine though
    My Website

    "Circular logic is good because it is."

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Continous LOD Terrain Source... Released!
    By Perspective in forum Game Programming
    Replies: 13
    Last Post: 04-17-2006, 11:21 PM
  2. Small terrain demo
    By VirtualAce in forum Game Programming
    Replies: 13
    Last Post: 04-04-2004, 07:11 PM
  3. terrain fly thru preview
    By Perspective in forum Game Programming
    Replies: 9
    Last Post: 04-19-2003, 08:42 PM
  4. OpenGL terrain demo (EDITOR)
    By Jeremy G in forum Game Programming
    Replies: 2
    Last Post: 03-30-2003, 08:11 PM
  5. Dx, Sdl, Open-gl
    By dayknight in forum Game Programming
    Replies: 26
    Last Post: 12-28-2002, 02:17 PM