www.pudn.com > WaveSimulation.rar > Terrian.cpp


// Terrian.cpp: implementation of the CTerrian class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Terrian.h" 
#include "Bezier.h" 
#include "mydefine.h" 
#include "Input.h" 
#include "Bezier.h" 
#include "Texture.h" 
 
 
#include  
#include  
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
CTerrian::CTerrian() 
{ 
	memset((float *)m_TerrianArray,0,sizeof(m_TerrianArray)); 
} 
 
CTerrian::~CTerrian() 
{ 
 
} 
 
void CTerrian::DrawTerrain() 
{	 
	int i; 
	 
	g_cInput.SetGLState(); 
 
	float xsacle = 5.0f; 
	float xoffset = (TERRIAN_COL_NUM / 2.0f);// 
	float zscale = 2.0f; 
	float zoffset = 9.5f; 
 
//	FILE *fp; 
//	fp = fopen("a.txt","w"); 
 
 
	GLfloat TextureCorx = 0.0f,TextureCory = 0.0f; 
	g_cTexture.UseTexture(1); 
 
	for(i = 0; i < TERRIAN_ROW_NUM - 1; i++) 
	{ 
		for(int j = 0; j < TERRIAN_COL_NUM - 1; j++) 
		{ 
			float	pointarray[3][3]; 
			float	result[3]; 
			pointarray[0][0] = (j - xoffset) / xsacle; 
			pointarray[0][1] = m_TerrianArray[i][j]; 
			pointarray[0][2] = (i) / zscale - zoffset ; 
				 
			pointarray[1][0] = (j + 1 - xoffset) / xsacle; 
			pointarray[1][1] = m_TerrianArray[i + 1][j+1]; 
			pointarray[1][2] = (i + 1) / zscale - zoffset; 
			 
			pointarray[2][0] =(j + 1 - xoffset) / xsacle; 
			pointarray[2][1] = m_TerrianArray[i ][j+1] ; 
			pointarray[2][2] = (i) / zscale - zoffset; 
 
 
			calcNormal(pointarray,result); 
			glNormal3fv( result ); 
 
			glBegin(GL_TRIANGLES); 
				CompTextCor(pointarray[0], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[0] ); 
 
				CompTextCor(pointarray[1], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[1] ); 
 
				CompTextCor(pointarray[2], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[2] ); 
			glEnd(); 
 
 
			pointarray[0][0] = (j - xoffset) / xsacle; 
			pointarray[0][1] =m_TerrianArray[i ][j] ; 
			pointarray[0][2] = (i) / zscale - zoffset; 
				 
			pointarray[1][0] = (j - xoffset) / xsacle; 
			pointarray[1][1] = m_TerrianArray[i + 1][j]; 
			pointarray[1][2] = (i + 1) / zscale - zoffset; 
			 
			pointarray[2][0] =(j + 1 - xoffset) / xsacle; 
			pointarray[2][1] = m_TerrianArray[i + 1][j+1]; 
			pointarray[2][2] =(i + 1) / zscale - zoffset; 
 
 
			calcNormal(pointarray,result); 
			glNormal3fv( result ); 
 
			glBegin(GL_TRIANGLES); 
				CompTextCor(pointarray[0], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[0] ); 
 
				CompTextCor(pointarray[1], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[1] ); 
 
				CompTextCor(pointarray[2], TextureCorx,TextureCory); 
				glTexCoord2f(TextureCorx, TextureCory); 
				glVertex3fv( pointarray[2] ); 
			glEnd(); 
 
//			fprintf(fp,"(%5.3f,%5.3f)   %5.3f  ",vertexarray[0],vertexarray[2],vertexarray[1]); 
		} 
//		fwrite("\n",sizeof(char),1,fp); 
//		fwrite("\n",sizeof(char),1,fp); 
//		fwrite("\n",sizeof(char),1,fp); 
	} 
//	fclose(fp); 
 
} 
 
float CTerrian::GetPositionHeight(float x,float z) 
{ 
	float xscale = 5.0f; 
	int xoffset = -(TERRIAN_COL_NUM / 2.0f) ; 
	float zscale = 2.0f; 
	float zoffset = -9.5f; 
 
	float xstep  = 1 / xscale; 
 
	float zstep  = 1 / zscale; 
 
	int xIndex,zIndex; 
	xIndex =  floor( x * xscale - xoffset ); 
	zIndex =  floor((z - zoffset) * zscale );  
 
	float dx,dz,odx,odz; 
	dx  = x - ( (xIndex + xoffset) / xscale );  
		dx  = (xstep - dx) / xstep;  
	dz  = z - ( (zIndex / zscale) + zoffset ); 
		dz  = (zstep - dz) / zstep; 
	odx = 1 - dx; 
	odz = 1 - dz; 
 
	float value00,value01,value10,value11; 
 
	value00 = m_TerrianArray[zIndex][xIndex]; 
	value01 = m_TerrianArray[zIndex][xIndex + 1]; 
	value10 = m_TerrianArray[zIndex + 1][xIndex]; 
	value11 = m_TerrianArray[zIndex + 1][xIndex + 1]; 
 
	float result = 0.0f; 
	result = value00 * dz * dx + value01 * dz * odx +  
			 value10 * odz * dx + value11 * odz * odx; 
	return -result; 
} 
 
int CTerrian::InitTerrian() 
{ 
//////////////use bezier curve to generate the terrian 
	float x1,y1,x2,y2,x3,y3,x4,y4; 
	float slopek1,slopek4; 
 
	x1 = -1.0f;	y1 = -1.0f; 
 
	x4 = 0.05f;	y4 = 0.05f; 
 
	slopek1 = -0.2f;	slopek4 = 0.0f; 
 
	float a = 0.20f; 
	x2 = a * x1 + (1 - a) * x4;	y2 = y1 + slopek1 * ( x2 - x1 ); 
	 
	a = 0.90f; 
	x3 = (1 - a) * x1 + a * x4;	y3 = y4 - slopek4 * (x4 - x3); 
 
	CBezier terrianbezier; 
	terrianbezier.Init(x1,y1,x2,y2,x3,y3,x4,y4); 
 
	float result[2]; 
	for(int i = 0; i < TERRIAN_ROW_NUM; i++) 
	{ 
		terrianbezier.ComputeBezier( (float)(TERRIAN_ROW_NUM - i )/ TERRIAN_ROW_NUM,result); 
		m_TerrianArray[i][0] = result[1] * 30.0f; 
	} 
/////////////////////////////basic terrain  
	for(i = 0 ; i < TERRIAN_ROW_NUM ; i++) 
		for(int j = 0; j < TERRIAN_COL_NUM ; j++) 
			m_TerrianArray[i][j] = m_TerrianArray[i][0]; 
 
/////////////////////////////advanced terrain 
//	CreateHill(0.0f,15.0f,3.0f,10.0f,5.0f); 
	return 1; 
} 
 
void CTerrian::TestTerrianDraw() 
{ 
	 
//	FILE *fp; 
//	fp = fopen("b.txt","w"); 
	float deep; 
	for(float x = -9.0f; x < 9.0f; x+= 0.2f) 
	{ 
		for(float z = -7.0f; z < 80.0f; z+= 0.5f) 
		{ 
			deep = GetPositionHeight(x,z); 
			glBegin(GL_POINTS); 
			glVertex3f(x,-deep,z); 
			glEnd(); 
//			fprintf(fp,"(%5.3f,%5.3f)   %5.3f  ",x,z,-deep); 
		} 
///		fwrite("\n",sizeof(char),1,fp); 
//		fwrite("\n",sizeof(char),1,fp); 
//		fwrite("\n",sizeof(char),1,fp); 
	} 
//	fclose(fp); 
} 
 
void CTerrian::CreateHill(float positionx, float positionz, float xwidth, float zwidth, float ywidth) 
{ 
	float xscale = 5.0f; 
	int xoffset = -(TERRIAN_COL_NUM / 2.0f) ; 
	float zscale = 2.0f; 
	float zoffset = -9.5f; 
	float xstep  = 1 / xscale; 
	float zstep  = 1 / zscale; 
 
 
	float leftx = positionx - xwidth / 2.0f; 
	float rightx = leftx + xwidth; 
	int leftIndex = floor( leftx * xscale - xoffset ); 
	int rightIndex = floor( rightx * xscale - xoffset ); 
	int middleIndex = (leftIndex + rightIndex) / 2; 
	for(int i = leftIndex; i < rightIndex; i++) 
	{ 
//		int i = 47; 
		float currentx = leftx + xstep * (i - leftIndex); 
		float ratio =  ( ( (rightIndex - leftIndex) / 2.0f) - fabs( i - middleIndex) ) / ( (  rightIndex - leftIndex) / 2.0f ) ; 
		float currentlength = ratio * zwidth ; 
 
		float zbegin,zend; 
		zbegin = positionz - currentlength / 2; 
		zend = zbegin + currentlength; 
 
		int zbeginIndex,zendIndex; 
		zbeginIndex = floor((zbegin - zoffset) * zscale );  
		zendIndex   = floor((zend - zoffset) * zscale ); 
		 
		float centery = GetPositionHeight(currentx,positionz); 
 
		if(zbeginIndex != zendIndex) 
		{ 
			float z1,y1,z2,y2,z3,y3,z4,y4; 
 
 
			z1 = zbegin;	y1 = -GetPositionHeight(currentx,z1); 
			z4 = zend;		y4 = -GetPositionHeight(currentx,z4); 
			z2 = 0.75f * z1 + 0.25f * z4;	y2 = ratio * (ywidth - centery) + centery; 
			z3 = 0.25f * z1 + 0.75f * z4;	y3 = y2; 
 
			CBezier modelbezier; 
			modelbezier.Init(z1,y1,z2,y2,z3,y3,z4,y4); 
////////////////////////////////////	 
			modelbezier.Result(); 
//			modelbezier.DrawBezier(); 
//////////////////////////////////// 
			for(int j = zbeginIndex; j < zendIndex; j++) 
			{ 
				float currentz = zbegin + (j - zbeginIndex) * zstep; 
				m_TerrianArray[j][i] = modelbezier.Findy(currentz); 
 
			}//endfor 
		}//endif 
	}//endfor 
}//end 
 
void CTerrian::CompTextCor(float *Point, float &textcorx, float &textcory) 
{ 
 
}