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) { }