Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
TERRAIN.CPP
Package: openglsystem.rar [view]
Upload User: nthssl
Upload Date: 2022-04-05
Package Size: 25357k
Code Size: 9k
Category:
OpenCV
Development Platform:
Visual C++
- #include "terrain.h"
- CTerrain::CTerrain()
- {
- width = 256;
- scanDepth = 80.0;
- terrainMul = 50.0;
- textureMul = 0.25;
- heightMul = 175.0;
- fogColor[0] = 0.75f;
- fogColor[1] = 0.9f;
- fogColor[2] = 1.0f;
- fogColor[3] = 1.0f;
- // CObject attributes
- position = CVector(0,0,0);
- velocity = CVector(0,0,0);
- acceleration = CVector(0,0,0);
- size = sqrt(width*terrainMul*width*terrainMul + width*terrainMul*width*terrainMul);
- BuildTerrain(width, 0.5f);
- }
- CTerrain::CTerrain(int w, float rFactor)
- {
- width = w;
- scanDepth = 80.0;
- terrainMul = 50.0;
- textureMul = 0.25;
- heightMul = 175.0;
- fogColor[0] = 0.75f;
- fogColor[1] = 0.9f;
- fogColor[2] = 1.0f;
- fogColor[3] = 1.0f;
- heightMap = NULL;
- // CObject attributes
- position = CVector(0,0,0);
- velocity = CVector(0,0,0);
- acceleration = CVector(0,0,0);
- size = sqrt(width*terrainMul*width*terrainMul + width*terrainMul*width*terrainMul);
- BuildTerrain(width, rFactor);
- }
- void CTerrain::BuildTerrain(int w, float rFactor)
- {
- width = w;
- heightMap = new float[width*width];
- MakeTerrainPlasma(heightMap, width, rFactor);
- // load texture
- terrainTex[0].LoadTexture("ground.tga");
- glGenTextures(1, &terrainTex[0].texID);
- glBindTexture(GL_TEXTURE_2D, terrainTex[0].texID);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //or GL_CLAMP
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //or GL_CLAMP
- switch (terrainTex[0].textureType)
- {
- case BMP:
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, terrainTex[0].width, terrainTex[0].height,
- GL_RGB, GL_UNSIGNED_BYTE, terrainTex[0].data);
- break;
- case PCX:
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, terrainTex[0].width, terrainTex[0].height,
- GL_RGBA, GL_UNSIGNED_BYTE, terrainTex[0].data);
- break;
- case TGA:
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, terrainTex[0].width, terrainTex[0].height,
- GL_RGB, GL_UNSIGNED_BYTE, terrainTex[0].data);
- break;
- default:
- break;
- }
- }
- void CTerrain::OnCollision(CObject *collisionObject)
- {}
- void CTerrain::OnDraw(CCamera *camera)
- {
- int z, x;
- glEnable(GL_DEPTH_TEST);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogfv(GL_FOG_COLOR, fogColor);
- glFogf(GL_FOG_START, scanDepth * 0.2f);
- glFogf(GL_FOG_END, scanDepth * 2.5);
- glHint(GL_FOG_HINT, GL_FASTEST);
- glEnable(GL_FOG);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER,0.0);
- glDisable(GL_ALPHA_TEST);
- // push/pop objects that move with the camera (e.g. a sun, the sky)
- //glTranslatef(camera->x, camera->y, camera->z);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, terrainTex[0].texID);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glColor3f(1.0, 1.0, 1.0);
- for (z = (int)(camera->position.z / terrainMul - scanDepth), z=z<0?0:z; (z < camera->position.z / terrainMul + scanDepth) && z < width-1; z++)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for (x = (int)(camera->position.x / terrainMul - scanDepth), x=x<0?0:x; (x < camera->position.x / terrainMul + scanDepth) && x < width-1; x++)
- {
- // glColor3f(heightMap[x+z*width], heightMap[x+z*width], heightMap[x+z*width]);
- glTexCoord2f(textureMul * x, textureMul * z);
- glVertex3f((float)x*terrainMul, (float)heightMap[x + z*width]*heightMul, (float)z*terrainMul);
- // glColor3f(heightMap[x+1+z*width], heightMap[x+1+z*width], heightMap[x+1+z*width]);
- glTexCoord2f(textureMul * (x+1), textureMul * z);
- glVertex3f((float)(x+1)*terrainMul, (float)heightMap[x+1 + z*width]*heightMul, (float)z*terrainMul);
- // glColor3f(heightMap[x+(z+1)*width], heightMap[x+(z+1)*width], heightMap[x+(z+1)*width]);
- glTexCoord2f(textureMul * x, textureMul * (z+1));
- glVertex3f((float)x*terrainMul, (float)heightMap[x + (z+1)*width]*heightMul, (float)(z+1)*terrainMul);
- // glColor3f(heightMap[x+1+(z+1)*width], heightMap[x+1+(z+1)*width], heightMap[x+1+(z+1)*width]);
- glTexCoord2f(textureMul * (x+1), textureMul * (z+1));
- glVertex3f((float)(x+1)*terrainMul, (float)heightMap[x+1 + (z+1)*width]*heightMul, (float)(z+1)*terrainMul);
- }
- glEnd();
- }
- }
- // RangedRandom()
- // Returns a random number between v1 and v2
- float CTerrain::RangedRandom(float v1,float v2)
- {
- return v1 + (v2-v1)*((float)rand())/((float)RAND_MAX);
- }
- // NormalizeTerrain()
- // Given a height field, normalize it so that the minimum altitude
- // is 0.0 and the maximum altitude is 1.0
- void CTerrain::NormalizeTerrain(float field[],int size)
- {
- float maxVal,minVal,dh;
- int i;
- /*
- Find the maximum and minimum values in the height field
- */
- maxVal = field[0];
- minVal = field[0];
- for (i=1;i<size*size;i++)
- {
- if (field[i] > maxVal)
- {
- maxVal = field[i];
- }
- else if (field[i] < minVal)
- {
- minVal = field[i];
- }
- }
- /*
- Find the altitude range (dh)
- */
- if (maxVal <= minVal) return;
- dh = maxVal-minVal;
- /*
- Scale all the values so they are in the range 0-1
- */
- for (i=0;i<size*size;i++)
- {
- field[i] = (field[i]-minVal)/dh;
- }
- }
- // FilterHeightBand()
- // Erosion filter -
- // FilterHeightBand applies a FIR filter across a row or column of the height field
- void CTerrain::FilterHeightBand(float *band,int stride,int count,float filter)
- {
- int i,j=stride;
- float v = band[0];
- for (i=0;i<count-1;i++)
- {
- band[j] = filter*v + (1-filter)*band[j];
- v = band[j];
- j+=stride;
- }
- }
- // FilterHeightField()
- // Erosion filter -
- // Erodes a terrain in all 4 directions
- void CTerrain::FilterHeightField(float field[],int size,float filter)
- {
- int i;
- // Erode rows left to right
- for (i=0;i<size;i++)
- {
- FilterHeightBand(&field[size*i],1,size,filter);
- }
- // Erode rows right to left
- for (i=0;i<size;i++)
- {
- FilterHeightBand(&field[size*i+size-1],-1,size,filter);
- }
- // Erode columns top to bottom
- for (i=0;i<size;i++)
- {
- FilterHeightBand(&field[i],size,size,filter);
- }
- // Erode columns bottom to top
- for (i=0;i<size;i++)
- {
- FilterHeightBand(&field[size*(size-1)+i],-size,size,filter);
- }
- }
- // MakeTerrainPlasma()
- // desc: Genereate terrain using diamond-square (plasma) algorithm
- void CTerrain::MakeTerrainPlasma(float field[],int size,float rough)
- {
- int i,j,ni,nj,mi,mj,pmi,pmj,rectSize = size;
- float dh = (float)rectSize/2,r = (float)pow(2,-1*rough);
- // Since the terrain wraps, all 4 "corners" are represented by the value at 0,0,
- // so seeding the heightfield is very straightforward
- // Note that it doesn't matter what we use for a seed value, since we're going to
- // renormalize the terrain after we're done
- field[0] = 0;
- while(rectSize > 0)
- {
- /*
- Diamond step -
- Find the values at the center of the retangles by averaging the values at
- the corners and adding a random offset:
- a.....b
- . .
- . e .
- . .
- c.....d
- e = (a+b+c+d)/4 + random
- In the code below:
- a = (i,j)
- b = (ni,j)
- c = (i,nj)
- d = (ni,nj)
- e = (mi,mj)
- */
- for (i=0;i<size;i+=rectSize)
- for (j=0;j<size;j+=rectSize)
- {
- ni = (i+rectSize)%size;
- nj = (j+rectSize)%size;
- mi = (i+rectSize/2);
- mj = (j+rectSize/2);
- field[mi+mj*size] = (field[i+j*size] + field[ni+j*size] + field[i+nj*size] + field[ni+nj*size])/4 + RangedRandom(-dh/2,dh/2);
- }
- /*
- Square step -
- Find the values on the left and top sides of each rectangle
- The right and bottom sides are the left and top sides of the neighboring rectangles,
- so we don't need to calculate them
- The height field wraps, so we're never left hanging. The right side of the last
- rectangle in a row is the left side of the first rectangle in the row. The bottom
- side of the last rectangle in a column is the top side of the first rectangle in
- the column
- .......
- . .
- . .
- . d .
- . .
- . .
- ......a..g..b
- . . .
- . . .
- . e h f .
- . . .
- . . .
- ......c......
- g = (d+f+a+b)/4 + random
- h = (a+c+e+f)/4 + random
- In the code below:
- a = (i,j)
- b = (ni,j)
- c = (i,nj)
- d = (mi,pmj)
- e = (pmi,mj)
- f = (mi,mj)
- g = (mi,j)
- h = (i,mj)
- */
- for (i=0;i<size;i+=rectSize)
- for (j=0;j<size;j+=rectSize)
- {
- ni = (i+rectSize)%size;
- nj = (j+rectSize)%size;
- mi = (i+rectSize/2);
- mj = (j+rectSize/2);
- pmi = (i-rectSize/2+size)%size;
- pmj = (j-rectSize/2+size)%size;
- // Calculate the square value for the top side of the rectangle
- field[mi+j*size] = (field[i+j*size] + field[ni+j*size] + field[mi+pmj*size] + field[mi+mj*size])/4 + RangedRandom(-dh/2,dh/2);
- // Calculate the square value for the left side of the rectangle
- field[i+mj*size] = (field[i+j*size] + field[i+nj*size] + field[pmi+mj*size] + field[mi+mj*size])/4 + RangedRandom(-dh/2,dh/2);
- }
- // Setup values for next iteration
- // At this point, the height field has valid values at each of the coordinates that fall on a rectSize/2 boundary
- rectSize /= 2;
- dh *= r;
- }
- // Normalize terrain so minimum value is 0 and maximum value is 1
- NormalizeTerrain(field,size);
- }