⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrain.cpp

📁 一個簡單的游戲設計...好好玩的
💻 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 + -