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

📄 terrain.cpp

📁 涉及windows游戏编程中的一些源码
💻 CPP
字号:
#include "LOD.h"
#include "MMath.h"
#include "terrain.h"
#include "image.h"

int g_w=0;
void setW(int w)
{
	g_w = w;
}
#define INDEX(x,y)	(y)*g_w+(x)

void CTerrain::SetCamera(CCamera* pcm)
{
     m_camera_info= pcm->GetCameraInfo(); 
}

int CTerrain::LoadMap(char* file_name,float scaleW,float scaleH,float startH)
{
	m_map = ::LoadRPMap(file_name);
	if(m_map._data==NULL)
		return TE_FILE_ERROR;

	if(!Math.IsMagicNumber(m_map._info._height - 1) )
	{
		FreeRPMap(m_map);
		return TE_INVALIDATE_SIZE;
	}

	m_data_array.SetDataInfo(m_map._info._width ,m_map._info._height ,m_map._data);
	m_w = m_map._info._width;
	m_h = m_map._info._height;
	
	m_scale =scaleH;
	setW(m_map._info._width);


    return TE_OK;
}
int CTerrain::LaadFromRAW(char* file_name,float scaleW,float scaleH,float startH)
{
	return 1;
}

int CTerrain::SetTexture(GLuint tex[],int texNumb)
{
	for(int i=0;i<texNumb;i++)
		m_texID[i]=tex[i];
    m_texNum = texNumb;
	return 1;
}

CLOD* CTerrain::GetLODControl()
{
	return m_pLodControl;
}

CLOD* CTerrain::CreateLODCntrl()
{
	m_pLodControl=new CLOD(this);
	return m_pLodControl;
}

float CTerrain::GetHeight(float x,float y)
{
	int xl,xh,yl,yh;
	if (x<0 || x> m_w ||y<0||y>m_h)
		return 0;
	xl = x;
	xh = xl+1;
	yl = y;
	yh = yl+1;
    
	float dx = x - xl ;
	float dy = y - yl ;

	float hll =(    dy  * dx    )  * m_data_array.GetValue(xh,yh);// yh * m_w + xh];   
	float hlh =( (1-dy) * dx    )  * m_data_array.GetValue(xh,yl);// yl * m_w + xh];
    float hhl =(    dy  * (1-dx))  * m_data_array.GetValue(xl,yh);// yh * m_w + xl];
    float hhh =( (1-dy) * (1-dx))  * m_data_array.GetValue(xl,yl);// yl * m_w + xl];

	return (hll+hlh+hhh+hhl) * m_scale;

}
//***************************************************************
//以下是地形的渲染函数,目前该函数为简单的渲染,。
//在以后将加入:
//       LOD, View Frustum Culling,
//       Multi-Texture Maping
//       Water simulate
//***************************************************************
int CTerrain::Render()
{
	
	if(m_pLodControl)
	{
		glDisable(GL_BLEND);
		glEnable(GL_DEPTH_TEST);
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glScalef(1.0,1.0,m_scale);
		m_pLodControl->Render(m_texID); 
		glPopMatrix();
		return 1;	
	}
	else
	{
		MessageBox(NULL,"No LOD Control created,SimNature will exit!","Falt error",MB_OK);
		exit(0);
	}
	
}

CTerrain::CTerrain()
{
//	m_data = NULL;
	m_map._data = NULL;
	m_pLodControl = NULL;
}

void CTerrain::Strecth(float s)
{
	m_scale *= s;
}

void CTerrain::Smooth(int level)
{	
	float h ;
	for(int i=0;i<level;i++)
	{
	for(int x=0;x<m_w;x++)
		for(int y =0;y<m_w;y++)
		{
		  int lx = x-1;
		  if(lx<0) lx= m_w-1;
		  int ly = y-1;
		  if(ly<0) ly= m_h-1;
		  int ux = x+1;
		  if(ux >= m_w)ux =0;
		  int uy = y+1;
		  if(uy >= m_h)uy =0;

          h  =  4 * m_data_array.GetValue( (lx) , y    );
	      h  += 4 * m_data_array.GetValue( (ux) , y    );
		  h  += 4 * m_data_array.GetValue( x    , (uy) );
          h  += 4 * m_data_array.GetValue( x    , (ly) );
		  h  += 2 * m_data_array.GetValue( (lx) , (lx) );
	      h  += 2 * m_data_array.GetValue( (ux) , (ly) );
		  h  += 2 * m_data_array.GetValue( (lx) , (uy) );
          h  += 2 * m_data_array.GetValue( (ux) , (uy) );
		  h  += 6 * m_data_array.GetValue( x    , y    );
		  h /= 30.0;
		  m_data_array.SetValue(x    , y  , h );
		}
	}

}

int CTerrain::GetRawValue(int x, int y)
{
	return  m_data_array.GetValue(x , y)  *  m_scale;
}

void GetNormal(float* p1,float* p2,float* p3,float* out)
{
	float v1[3] = {p2[0]-p1[0],p2[1]-p1[1],p2[2]-p1[2]};
	float v2[3] = {p3[0]-p1[0],p3[1]-p1[1],p3[2]-p1[2]};

	out[0] = v1[1]*v2[2] - v1[2]*v2[1];
	out[1] = v1[2]*v2[0] - v1[0]*v2[2];
	out[2] = v1[0]*v2[1] - v1[1]*v2[0];
}

unsigned char* CTerrain::CaculateLightMap(float light_x,float light_y,float light_h,float scale)
{
	unsigned char* ldata = new unsigned char[ (m_map._info._width) * (m_map._info._height) ]; 

	memset((void*)ldata,0,m_map._info._height * m_map._info._width * sizeof(char)); 
	float n[3];
	float ldir[3] = {light_x,light_y,light_h};
	float llen  = ldir[0]*ldir[0] + ldir[1]*ldir[1] + ldir[2]*ldir[2];
	llen = sqrt(llen);

	float p1[3],p2[3],p3[3];
	int w = m_map._info._width;
	int h = m_map._info._height;

	unsigned char cl;
	for(int x = 0 ; x< w - 1;x++)
		for(int y =0 ;y< h - 1;y++)
		{

			p1[0] = x     ; p1[1] = y     ; p1[2] = m_data_array.GetValue( x    , y    ) * scale;
			p2[0] = x + 1 ; p2[1] = y     ; p2[2] = m_data_array.GetValue( x + 1, y    )  * scale;
			p3[0] = x     ; p3[1] = y + 1 ; p3[2] = m_data_array.GetValue( x    , y + 1)  * scale;
			GetNormal(p1,p2,p3,n);

			float dot = (ldir[0]*n[0] + ldir[1]*n[1] + ldir[2]*n[2])
				        / (sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]) * llen);
			if(dot < 0)
				cl = 0;//( 55 - fabs(dot) * 55);
			else
			{
				cl = dot * 255;
			}
			ldata[x + y* (m_map._info._width)] = cl;
		}

	//光滑亮度图
		for(int i=0;i<0;i++)
		{
			for(int x=0;x<m_w;x++)
				for(int y =0;y<m_w;y++)
				{
					int lx = x-1;
					if(lx<0) lx= m_w-1;
					int ly = y-1;
					if(ly<0) ly= m_h-1;
					int ux = x+1;
					if(ux >= m_w)ux =0;
					int uy = y+1;
					if(uy >= m_h)uy =0;
					
					h  =  4 * ldata[ (lx) + y    * m_w ];
					h  += 4 * ldata[ (ux) + y    * m_w ];
					h  += 4 * ldata[ x    + (uy) * m_w ];
					h  += 4 * ldata[ x    + (ly) * m_w ];
					h  += 2 * ldata[ (lx) + (lx) * m_w ];
					h  += 2 * ldata[ (ux) + (ly) * m_w ];
					h  += 2 * ldata[ (lx) + (uy) * m_w ];
					h  += 2 * ldata[ (ux) + (uy) * m_w ];
					h  += 6 * ldata[ x     + y   * m_w ];
					h /= 30.0;

					h*=1.1;
					if(h>255)
						h=255;
					ldata[ x     + y     * m_w ] = h;
				}
		}
		return ldata;

}

GLuint CTerrain::BuilMainTexture(char *filename, float light_x,float light_y,float light_z,float scale)
{
	IMAGESIZE size;

	//Caculate the light map the light map is the same size as the terrain map
	unsigned char *ldata = CaculateLightMap(light_x,light_y,light_z,scale);

	if(ldata == NULL)
		return -1;

	//Load texture data (Use NeHe's iPicture OLE Picture Loader ,it can load any picture format);
	IMAGEDATA image = ::LoadPictureAsTexture(filename,&size,0);

	//Failed load texture data
	if(image == NULL )
	{
		delete [] ldata;
		return -1;
	}

	//缩放亮度图,使其和纹理的尺寸相同
	float sx =  (m_map._info._width  - 1)  / (size.width - 1);
	float sy =  (m_map._info._height - 1) / (size.height- 1);
	for(int x = 0;x<size.width;x++)
		for(int y=0;y<size.height;y++)
		{
			int lx = sx*x;
			int ly = sy*y;
			
			float st = ldata[lx + m_map._info._width*ly] / 255.;
			st = sqrt(st);
			//调制纹理亮度
			image[ (3*x    ) + size.width * 3 * y] *= (0.9*st);
			image[ (3*x + 1) + size.width * 3 * y] *= (.9*st);

			if(image[ (3*x + 1) + size.width * 3 * y]>255)
				image[ (3*x + 1) + size.width * 3 * y] = 255;

			image[ (3*x + 2) + size.width * 3 * y] *= (0.9*st);
		} 

	//Free light map
	delete[] ldata;
	GLuint texture;
	glGenTextures(1,&texture);
	glBindTexture(GL_TEXTURE_2D,texture);

    glTexImage2D(GL_TEXTURE_2D,0,3,	size.width,	size.height,0,GL_BGR_EXT ,GL_UNSIGNED_BYTE,image);

	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);
	glEnable(GL_TEXTURE_2D);

	FreeImageData(image);
	return texture;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -