?? terrain.cpp
字號:
#include <windows.h>
#include <gl/Gl.h>
#include <gl/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "define.h"
#include "bmpLoader.h"
#include "terrain.h"
Terrain::Terrain(void)
{
TerrainImage.data = NULL;
TextureLoaded = false;
WorldHeight = 0;
WorldLength = 0;
WorldWidth = 0;
MaxColor = 0;
MinColor = 0;
V = NULL;
}
Terrain::~Terrain(void)
{
if (TextureLoaded) glDeleteTextures (1,&TerrainTextureImage);
if (V) {
delete [] V;
glDeleteLists(TerrainList,1);
}
}
bool Terrain::LoadTerrainHeight(char *filename)
{
if(ImageLoad(filename, &TerrainImage)) {
V = new Point[TerrainImage.sizeX * TerrainImage.sizeY];
for(unsigned int i = 0 ; i < TerrainImage.sizeX * TerrainImage.sizeY ; i++) {
unsigned int Temp = (unsigned int) TerrainImage.data[3 * i] << 16 | (unsigned int) TerrainImage.data[3 * i + 1] << 8 | (unsigned int) TerrainImage.data[3 * i + 2];
if ( Temp > MaxColor ) MaxColor = Temp;
if ( Temp < MinColor ) MinColor = Temp;
}
WorldWidth = TerrainImage.sizeX;
WorldLength = TerrainImage.sizeY;
WorldHeight = WorldHeight ? WorldHeight : 15;
for(unsigned int i = 0 ; i < TerrainImage.sizeX; i++) {
for(unsigned int j = 0 ; j < TerrainImage.sizeY; j++) {
unsigned int Temp = (unsigned int) TerrainImage.data[3 * (i * TerrainImage.sizeY + j)] << 16 | (unsigned int) TerrainImage.data[3 * (i * TerrainImage.sizeY + j) + 1] << 8 | (unsigned int) TerrainImage.data[3 * (i * TerrainImage.sizeY + j) + 2];
V[i * TerrainImage.sizeX + j].P[0] = (float) -WorldWidth / 2.0f + i * (float) WorldWidth / (float) TerrainImage.sizeX;
V[i * TerrainImage.sizeX + j].P[1] = (float) WorldHeight / (float) ( MaxColor - MinColor ) * (float) ( Temp - MinColor );
V[i * TerrainImage.sizeX + j].P[2] = (float) -WorldLength / 2.0f + j * (float) WorldLength / (float) TerrainImage.sizeY;
}
}
free(TerrainImage.data);
TerrainList = glGenLists(1);
GLfloat vN[3];
float deltaTexX = 1.0f / (float) TerrainImage.sizeX,
deltaTexY = 1.0f / (float) TerrainImage.sizeY;
glNewList(TerrainList,GL_COMPILE);
glBegin(GL_QUADS);
for(unsigned int i = 0 ; i < TerrainImage.sizeX - 1; i++)
for(unsigned int j = 0 ; j < TerrainImage.sizeY - 1; j++) {
GetNormalVector(V[( i + 1 ) * WorldWidth + j].P,
V[i * WorldWidth + j].P,
V[i * WorldWidth + ( j + 1 )].P,
vN);
glTexCoord2f( i * deltaTexX , j * deltaTexY );
glNormal3fv(vN);
glVertex3fv(V[i * WorldWidth + j].P);
glTexCoord2f( ( i + 1 ) * deltaTexX , j * deltaTexY );
//glNormal3fv(vN);
glVertex3fv(V[( i + 1 ) * WorldWidth + j].P);
glTexCoord2f( ( i + 1 ) * deltaTexX,( j + 1 ) * deltaTexY);
//glNormal3fv(vN);
glVertex3fv(V[( i + 1 ) * WorldWidth + ( j + 1 )].P);
glTexCoord2f( i * deltaTexX , ( j + 1 ) * deltaTexY);
//glNormal3fv(vN);
glVertex3fv(V[i * WorldWidth + ( j + 1 )].P);
}
glEnd();
glEndList();
return true;
}
return false;
}
void Terrain::LoadTerrainTexture(char *filename)
{
Image iTemp;
glEnable(GL_TEXTURE_2D);
glGenTextures(1,&TerrainTextureImage);
glBindTexture(GL_TEXTURE_2D,TerrainTextureImage);
ImageLoad(filename, &iTemp);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,iTemp.sizeX,iTemp.sizeY,GL_RGB,GL_UNSIGNED_BYTE,iTemp.data);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
free(iTemp.data);
TextureLoaded = true;
glDisable(GL_TEXTURE_2D);
}
void Terrain::Draw()
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TerrainTextureImage);
glCallList(TerrainList);
glDisable(GL_TEXTURE_2D);
}
int Terrain::GetWorldLength()
{
return WorldLength;
}
int Terrain::GetWorldWidth()
{
return WorldWidth;
}
int Terrain::GetWorldHeight()
{
return WorldHeight;
}
void Terrain::GetNormalVector(const GLfloat *v1,
const GLfloat *v2,
const GLfloat *v3,
GLfloat *vN)
{
vN[0] = (v2[1] - v1[1]) * (v3[2] - v1[2]) - (v2[2] - v1[2]) * (v3[1] - v1[1]);
vN[1] = (v2[2] - v1[2]) * (v3[0] - v1[0]) - (v2[0] - v1[0]) * (v3[2] - v1[2]);
vN[2] = (v2[0] - v1[0]) * (v3[1] - v1[1]) - (v2[1] - v1[1]) * (v3[0] - v1[0]);
GLfloat fLength = 1.0f / (GLfloat) sqrt(vN[0] * vN[0] + vN[1] * vN[1] + vN[2] * vN[2]);
vN[0] *= fLength;
vN[1] *= fLength;
vN[2] *= fLength;
}
float Terrain::GetPositionHeight(float x,float z)
{
int X = WorldWidth / 2 + x , Z = WorldLength / 2 + z;
int n = X * WorldWidth + Z;
return V[n].P[1];
}
void Terrain::SetWorldHeight(int Height)
{
WorldHeight = Height;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -