www.pudn.com > PROGRAM.ZIP > DemToGLDlg.cpp, change:2001-08-15,size:25274b


// DemToGLDlg.cpp : implementation file 
// 
#include "stdafx.h" 
#include "DemToGL.h" 
#include "DemToGLDlg.h" 
 
#include "math.h" 
#include <gl\gl.h> 
#include <gl\glu.h> 
#include <gl\glaux.h> 
 
#define Terrain	1 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
	char * SumPointStr; 
	char * iDemXStr; 
	char * iDemYStr; 
	 
	int * m_pDemH;		//------分配所需内存区							 
	int * m_pDemY; 
	int * m_pDemX; 
	float * Normals; 
 
	typedef struct tagDEMFILEHEADER{	//定义DEM数据的头文件格式 
		int map[6]; 
		int iDemY;						//DEM格网Y方向上的点数 
		int iDemX;						//DEM格网X方向上的点数 
		float sx; 
		float sy; 
		float interval;					//DEM格网点的采样间隔 
	}DEMFILEHEADER; 
	DEMFILEHEADER DemHeader; 
 
	int m_iDemX,m_iDemY; 
	int SumPointOfDem; 
	int SumFaceOfDem; 
	float m_interval; 
 
	CString tempfilename; 
	 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
 
// Dialog Data 
	//{{AFX_DATA(CAboutDlg) 
	enum { IDD = IDD_ABOUTBOX }; 
	//}}AFX_DATA 
 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CAboutDlg) 
	protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
	//}}AFX_VIRTUAL 
 
// Implementation 
protected: 
	//{{AFX_MSG(CAboutDlg) 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
	//{{AFX_DATA_INIT(CAboutDlg) 
	//}}AFX_DATA_INIT 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAboutDlg) 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
	//{{AFX_MSG_MAP(CAboutDlg) 
		// No message handlers 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CDemToGLDlg dialog 
 
CDemToGLDlg::CDemToGLDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CDemToGLDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CDemToGLDlg) 
	m_souce = _T(""); 
	m_destname = _T(""); 
	m_MessageToUser = _T(""); 
	m_facenum = _T("0"); 
	m_vertexnum = _T("0"); 
	m_xinterval = _T("0"); 
	m_xnum = _T("0"); 
	m_yinterval = _T("0"); 
	m_ynum = _T("0"); 
	m_MessageToUser2 = _T(""); 
	m_MessageToUser3 = _T(""); 
	m_inputx = _T(""); 
	m_inputy = _T(""); 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CDemToGLDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CDemToGLDlg) 
	DDX_Control(pDX, IDC_PROGRESS3, m_Progress3); 
	DDX_Control(pDX, IDC_PROGRESS2, m_Progress2); 
	DDX_Control(pDX, IDC_PROGRESS1, m_Progress); 
	DDX_Text(pDX, IDC_EDITSOUSE, m_souce); 
	DDX_Text(pDX, IDC_EDITDEST, m_destname); 
	DDX_Text(pDX, IDC_Message, m_MessageToUser); 
	DDX_Text(pDX, IDC_EDITFACENUM, m_facenum); 
	DDX_Text(pDX, IDC_EDITVERTEXNUM, m_vertexnum); 
	DDX_Text(pDX, IDC_EDITXINTERVAL, m_xinterval); 
	DDX_Text(pDX, IDC_EDITXNUM, m_xnum); 
	DDX_Text(pDX, IDC_EDITYINTERVAL, m_yinterval); 
	DDX_Text(pDX, IDC_EDITYNUM, m_ynum); 
	DDX_Text(pDX, IDC_Message2, m_MessageToUser2); 
	DDX_Text(pDX, IDC_Message3, m_MessageToUser3); 
	DDX_Text(pDX, IDC_EDITINPUTX, m_inputx); 
	DDX_Text(pDX, IDC_EDITINPUTY, m_inputy); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CDemToGLDlg, CDialog) 
	//{{AFX_MSG_MAP(CDemToGLDlg) 
	ON_WM_SYSCOMMAND() 
	ON_WM_PAINT() 
	ON_WM_QUERYDRAGICON() 
	ON_BN_CLICKED(IDC_Begin, OnBegin) 
	ON_BN_CLICKED(ID_Browse, OnBrowse) 
	ON_BN_CLICKED(IDC_Dest, OnDest) 
	ON_EN_CHANGE(IDC_EDITDEST, OnChangeEditdest) 
	ON_EN_CHANGE(IDC_EDITSOUSE, OnChangeEditsouse) 
	ON_EN_CHANGE(IDC_EDITINPUTX, OnChangeEditinputx) 
	ON_EN_CHANGE(IDC_EDITINPUTY, OnChangeEditinputy) 
	ON_BN_CLICKED(IDC_Start, OnStart) 
	ON_BN_CLICKED(IDC_FourCut, OnFourCut) 
	ON_BN_CLICKED(IDC_EightCut, OnEightCut) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CDemToGLDlg message handlers 
 
void CDemToGLDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
void CDemToGLDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // device context for painting 
 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
 
		int cxIcon = GetSystemMetrics(SM_CXICON); 
		int cyIcon = GetSystemMetrics(SM_CYICON); 
		CRect rect; 
		GetClientRect(&rect); 
		int x = (rect.Width() - cxIcon + 1) / 2; 
		int y = (rect.Height() - cyIcon + 1) / 2; 
 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		CDialog::OnPaint(); 
	} 
//对话框控件是一种子窗口,首先得到待绘图控件的窗口指针pWnd。 
	CWnd *pWnd=GetDlgItem(IDC_ViewPort); 
 
//通过该窗口控件的指针,得到该窗口的设备文本——pDC。 
	CDC *pDC=pWnd->GetDC(); 
 
//更新控件内的显示 
	pWnd->Invalidate(); 
	pWnd->UpdateWindow(); 
 
//绘制OpenGL场景 
	DrawScene(); 
 
//释放有限的CDC资源 
	pWnd->ReleaseDC(pDC); 
} 
 
HCURSOR CDemToGLDlg::OnQueryDragIcon() 
{ 
	return (HCURSOR) m_hIcon; 
} 
 
void CDemToGLDlg::OnChangeEditdest()  
{ 
	UpdateData(true); 
} 
 
void CDemToGLDlg::OnChangeEditsouse()  
{ 
	UpdateData(true);	 
} 
 
void CDemToGLDlg::OnCancel()  
{ 
/*	if(m_pDemX!=NULL)		delete[] m_pDemX; 
	if(m_pDemY!=NULL)		delete[] m_pDemY; 
	if(m_pDemH!=NULL)		delete[] m_pDemH; 
	if(Normals!=NULL)		delete[] Normals;*/ 
	CDialog::OnCancel(); 
} 
 
void CDemToGLDlg::OnChangeEditinputx()  
{ 
	UpdateData(true); 
} 
 
void CDemToGLDlg::OnChangeEditinputy()  
{ 
	UpdateData(true);	 
} 
 
BOOL CDemToGLDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
	ASSERT(IDM_ABOUTBOX  0xF000); 
 
	CMenu* pSysMenu = GetSystemMenu(FALSE); 
	if (pSysMenu != NULL) 
	{ 
		CString strAboutMenu; 
		strAboutMenu.LoadString(IDS_ABOUTBOX); 
		if (!strAboutMenu.IsEmpty()) 
		{ 
			pSysMenu->AppendMenu(MF_SEPARATOR); 
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
		} 
	} 
 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	m_MessageToUser  = "请选择或输入一个Dem数据文件……"; 
	m_MessageToUser2 = "输入完后按“开始执行”……"; 
	m_MessageToUser3 = "Dem数据文件切割……"; 
	m_Progress.SetRange(0,100); 
	m_Progress2.SetRange(0,100); 
	m_Progress3.SetRange(0,100); 
 
	UpdateData(false); 
 
	//  初始化VC与OpenGL的接口 
	SetOpenGLInterface(); 
	InitOpenGL();	 
	InitViewPort(); 
 
	return TRUE;   
} 
 
void CDemToGLDlg::OnBrowse()						//------选择某一Dem数据文件 
{ 
	char szFilter[]="DEM数据 (*.dem)|*.dem|All Files (*.*)|*.*|"; 
	CFileDialog  file(TRUE,NULL,"*.dem",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter); 
	if(file.DoModal()==IDOK){ 
		m_souce=file.GetPathName(); 
 
		if(!ReadDEM()){ 
			MessageBox("读文件出错!","出错信息",MB_OK); 
			return; 
		} 
		int precision,decimal,sign; 
		precision=0; 
		char * tempstr; 
		tempstr=new char [20]; 
		itoa(SumPointOfDem,tempstr,10); 
		m_vertexnum = (CString)tempstr; 
 
		itoa(SumFaceOfDem,tempstr,10);	 
		m_facenum	= (CString)tempstr; 
		tempstr=_fcvt(m_interval, precision, &decimal, &sign ); 
		m_yinterval = (CString)tempstr+"米"; 
		m_xinterval = (CString)tempstr+"米"; 
		m_xnum		= (CString)iDemXStr; 
		m_ynum		= (CString)iDemYStr; 
		//delete tempstr; 
	}//end of filedlg==IDOK 
	if(m_destname=="") 
		m_MessageToUser="请选择或输入目标文件名……"; 
	else 
		m_MessageToUser="请单击‘开始转化’进行转化……"; 
	 
	UpdateData(false); 
} 
 
void CDemToGLDlg::OnDest()							//-------选择或输入某一目标文件 
{ 
	char szFilter[]="OpenGL源程序 (*.cpp,*.h)|*.cpp;*.h|All Files (*.*)|*.*|"; 
	CFileDialog  file(TRUE,NULL,"*.h",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter); 
	if(file.DoModal()==IDOK) 
		m_destname=file.GetPathName(); 
		 
	if(m_souce=="") 
		m_MessageToUser="请选择或输入Dem数据文件名……"; 
	else 
		m_MessageToUser="请单击‘开始转化’进行转化……"; 
	UpdateData(false); 
} 
 
void CDemToGLDlg::OnBegin()							//---------开始转化文件 
{ 
	if(m_souce==""){ 
		MessageBox("请选择源文件后再按开始!","提示信息"); 
		return; 
	} 
	if(m_destname==""){ 
		MessageBox("请选择目标文件后再按开始!","提示信息"); 
		return; 
	} 
	 
	BeginWaitCursor(); 
 
	m_Progress.SetPos(15); 
	m_MessageToUser="正在写入Dem数据……"; 
	UpdateData(false); 
 
	WriteDataToGL(); 
	EndWaitCursor(); 
	 
	m_Progress.SetPos(100); 
	m_MessageToUser="文件转化完毕……"; 
	UpdateData(false); 
 
	return; 
} 
 
bool CDemToGLDlg::ReadDEM() 
{ 
	CFile file(m_souce,CFile::modeRead); 
	DWORD length=file.GetLength(); 
	if (file.Read((LPSTR)&DemHeader, sizeof(DEMFILEHEADER)) 
		!= sizeof(DEMFILEHEADER)){					//---------读入DEM头文件 
		MessageBox("文件头信息错误!","提示信息"); 
		return false; 
	} 
	 
	m_iDemX=DemHeader.iDemX;						//------从文件头中取数据 
	m_iDemY=DemHeader.iDemY; 
	m_interval=DemHeader.interval; 
	 
	m_pDemX=new int[m_iDemX*m_iDemY];				//X坐标 
	m_pDemY=new int[m_iDemX*m_iDemY];				//Y坐标 
	m_pDemH=new int[length-sizeof(DEMFILEHEADER)];	//Z坐标 
	SumPointStr=new char [10]; 
	iDemXStr=new char[10]; 
	iDemYStr=new char[10]; 
	SumPointOfDem= m_iDemX*m_iDemY; 
	SumFaceOfDem = 2*(m_iDemX-1)*(m_iDemY-1); 
	 
	itoa(SumPointOfDem,SumPointStr,10); 
	 
	itoa(m_iDemX,iDemXStr,10); 
	itoa(m_iDemY,iDemYStr,10); 
 
	if (file.ReadHuge(m_pDemH, length-sizeof(DEMFILEHEADER))  
		!= length-sizeof(DEMFILEHEADER) ) 
		return false; 
	 
	int i,j; 
	for(i=0;i<m_iDemY;i++){						//-----标定格网点的X、Y坐标 
		for(j=0;j<m_iDemX;j++){ 
			m_pDemX[m_iDemY*i+j]=DemHeader.interval*j; 
			m_pDemY[m_iDemY*i+j]=DemHeader.interval*i; 
		}	 
	}				 
	// --- 至此Dem数据已经放在了m_pDemX,m_pDemY,m_pDemH中。 --- // 
	// ---         下面是将坐标原点移动到地形的中心。        --- // 
	float X0=(m_iDemX/2)*m_interval,Y0=(m_iDemY/2)*m_interval; 
 
	for(int s=0;s<m_iDemY;s++) 
		for(int t=0;t<m_iDemX;t++){ 
			m_pDemX[s*m_iDemY+t]-=X0; 
			m_pDemY[s*m_iDemY+t]-=Y0; 
		} 
	file.Close(); 
	GetVertexNormal(); 
	InitTerrainList(); 
	OnPaint(); 
	return true; 
} 
 
void CDemToGLDlg::GetVertexNormal() 
{ 
	int x[2],y[2],z[2]; 
	int width,i,j; 
	width=m_iDemX; 
	Normals=new float [3*SumPointOfDem]; 
	float normal[3],rate; 
 
	for(i=0;i<m_iDemX-1;i++){ 
	for(j=0;j<m_iDemY-1;j++){ 
		x[0]=m_pDemX[(i+1)*width+j]-m_pDemX[i*width+j];//计算格网点(i,j) 
		x[1]=m_pDemX[i*width+(j+1)]-m_pDemX[i*width+j];//组成的矩形格网 
 
		y[0]=m_pDemY[(i+1)*width+j]-m_pDemY[i*width+j];//上的向量(X0,Y0,Z0) 
		y[1]=m_pDemY[i*width+(j+1)]-m_pDemY[i*width+j];//、向量(X1,Y1,Z1), 
 
		z[0]=m_pDemH[(i+1)*width+j]-m_pDemH[i*width+j];//以便利用二者来求取顶 
		z[1]=m_pDemH[i*width+(j+1)]-m_pDemH[i*width+j];//点(i,j)的法向量。 
	 
		normal[0]=y[1]*z[0]-z[1]*y[0];		//求两个向量的差积 
		normal[1]=z[1]*x[0]-x[1]*z[0];		//(X1,Y1,Z1)X(X0,Y0,Z0), 
		normal[2]=x[1]*y[0]-y[1]*x[0];		//从而确定顶点(i,j)的法向量。 
	 
		rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); 
		normal[0]/=rate;					//将法向量单位标准化。 
		normal[1]/=rate; 
		normal[2]/=rate; 
 
		Normals[(i*m_iDemX+j)*3+0] = normal[0]; 
		Normals[(i*m_iDemX+j)*3+1] = normal[1]; 
		Normals[(i*m_iDemX+j)*3+2] = normal[2]; 
	} 
	} 
	 
	for(i=0;i<m_iDemX;i++){ 
		Normals[((i+1)*m_iDemX-1)*3+0] = 0;		//格网点最后一列 
		Normals[((i+1)*m_iDemX-1)*3+1] = 1;		//的法向量 
		Normals[((i+1)*m_iDemX-1)*3+2] = 0; 
	} 
 
	for(j=0;j<m_iDemY;j++){ 
		Normals[((m_iDemX-1)*m_iDemY+j)*3+0] =1;//格网点最后一行 
		Normals[((m_iDemX-1)*m_iDemY+j)*3+1] =0;//的法向量 
		Normals[((m_iDemX-1)*m_iDemY+j)*3+2] =0; 
	} 
} 
 
void CDemToGLDlg::WriteDataToGL() 
{ 
	FILE * CppFile; 
	CString StrWrite; 
	char * WriteTemp; 
	int i,j,k,m; 
 
	WriteTemp=new char [400]; 
	CppFile=fopen(m_destname,"w"); 
	StrWrite="//这是从Dem数据转化来的OpenGL程序\r";		// --\r\n表示回车换行 
	StrWrite+="#define GG	15\r"; 
	int Length=StrWrite.GetLength(); 
	for(k=0;k<Length;k++) 
		WriteTemp[k]=StrWrite.GetAt(k); 
	WriteTemp[k]='\0'; 
	fwrite(WriteTemp,sizeof(char),Length,CppFile); 
	StrWrite="double vdata["+(CString)SumPointStr+"][3]={\r"; 
	Length=StrWrite.GetLength(); 
	for(k=0;k<Length;k++) 
		WriteTemp[k]=StrWrite.GetAt(k); 
	WriteTemp[k]='\0'; 
	fwrite(WriteTemp,sizeof(char),Length,CppFile);	//以上写入GL文件的标志部分 
 
	for(m=0;m<SumPointOfDem;m++)					//---以下为写入顶点坐标				 
	{ 
		StrWrite="{"; 
		Length=StrWrite.GetLength(); 
		for(k=0;k<Length;k++) 
			WriteTemp[k]=StrWrite.GetAt(k); 
		WriteTemp[k]='\0'; 
		fwrite(WriteTemp,sizeof(char),Length,CppFile); 
		 
		itoa(m_pDemX[m],WriteTemp,10); 
		StrWrite=(CString)WriteTemp; 
		Length=StrWrite.GetLength(); 
		for(k=0;k<Length;k++) 
			WriteTemp[k]=StrWrite.GetAt(k); 
		WriteTemp[k]=','; 
		WriteTemp[k+1]='\0'; 
		fwrite(WriteTemp,sizeof(char),Length+1,CppFile); 
 
		itoa(m_pDemY[m],WriteTemp,10); 
		StrWrite=(CString)WriteTemp; 
		Length=StrWrite.GetLength(); 
		for(k=0;k<Length;k++) 
			WriteTemp[k]=StrWrite.GetAt(k); 
		WriteTemp[k]=','; 
		WriteTemp[k+1]='\0'; 
		fwrite(WriteTemp,sizeof(char),Length+1,CppFile); 
 
		itoa(m_pDemH[m],WriteTemp,10); 
		StrWrite=(CString)WriteTemp; 
		Length=StrWrite.GetLength(); 
		for(k=0;k<Length;k++) 
			WriteTemp[k]=StrWrite.GetAt(k); 
		WriteTemp[k]='\0'; 
		fwrite(WriteTemp,sizeof(char),Length,CppFile); 
 
		if(m!=SumPointOfDem-1){ 
			StrWrite="},\r"; 
		} 
		else{ 
			StrWrite="}\r"; 
		} 
		Length=StrWrite.GetLength(); 
		for(k=0;k<Length;k++) 
			WriteTemp[k]=StrWrite.GetAt(k); 
		WriteTemp[k]='\0'; 
		fwrite(WriteTemp,sizeof(char),Length,CppFile);	 
	} 
 
	StrWrite="};\rdouble ndata["+(CString)SumPointStr+"][3]={\r"; 
	Length=StrWrite.GetLength(); 
	for(k=0;k<Length;k++) 
		WriteTemp[k]=StrWrite.GetAt(k); 
	WriteTemp[k]='\0'; 
	fwrite(WriteTemp,sizeof(char),Length,CppFile); 
	 
	m_Progress.SetPos(50); 
	m_MessageToUser="正在计算并写入法向量……"; 
//	UpdateData(false); 
 
	float normal[3]; 
	int     decimal,sign; 
	int     precision = 2; 
 
	for(i=0;i<m_iDemX;i++){ 
		for(j=0;j<m_iDemY;j++){ 
			normal[0]=Normals[(i*m_iDemY+j)*3+0]; 
			normal[1]=Normals[(i*m_iDemY+j)*3+1]; 
			normal[2]=Normals[(i*m_iDemY+j)*3+2]; 
 
			StrWrite="{"; 
			Length=StrWrite.GetLength(); 
			for(k=0;k<Length;k++) 
				WriteTemp[k]=StrWrite.GetAt(k); 
			WriteTemp[k]='\0'; 
			fwrite(WriteTemp,sizeof(char),Length,CppFile); 
 
			if(normal[0]!=0.0){ 
				WriteTemp=_fcvt(normal[0], precision, &decimal, &sign ); 
				StrWrite=(CString)WriteTemp; 
			 
				if(decimal=0) 
					StrWrite.Insert(0,"0."); 
				else 
					StrWrite.Insert(decimal,"."); 
				if(sign!=0) 
					StrWrite=(CString)"-"+StrWrite; 
			} 
			else 
				StrWrite="0.0"; 
		 
			Length=StrWrite.GetLength(); 
			for(k=0;k<Length;k++) 
				WriteTemp[k]=StrWrite.GetAt(k); 
			WriteTemp[k]=','; 
			WriteTemp[k+1]='\0'; 
			fwrite(WriteTemp,sizeof(char),Length+1,CppFile); 
 
			if(normal[1]!=0.0){ 
				WriteTemp=_fcvt(normal[1], precision, &decimal, &sign ); 
				StrWrite=(CString)WriteTemp; 
			 
				if(decimal=0) 
					StrWrite.Insert(0,"0."); 
				else 
					StrWrite.Insert(decimal,"."); 
				if(sign!=0) 
					StrWrite=(CString)"-"+StrWrite; 
			} 
			else 
				StrWrite="0.0"; 
 
			Length=StrWrite.GetLength(); 
			for(k=0;k<Length;k++) 
				WriteTemp[k]=StrWrite.GetAt(k); 
			WriteTemp[k]=','; 
			WriteTemp[k+1]='\0'; 
			fwrite(WriteTemp,sizeof(char),Length+1,CppFile); 
 
			if(normal[2]!=0.0){ 
				WriteTemp=_fcvt(normal[2], precision, &decimal, &sign ); 
				StrWrite=(CString)WriteTemp; 
			 
				if(decimal=0) 
					StrWrite.Insert(0,"0."); 
				else 
					StrWrite.Insert(decimal,"."); 
				if(sign!=0) 
					StrWrite=(CString)"-"+StrWrite; 
			} 
			else 
				StrWrite="0.0"; 
 
			Length=StrWrite.GetLength(); 
			for(k=0;k<Length;k++) 
				WriteTemp[k]=StrWrite.GetAt(k); 
			WriteTemp[k]='\0'; 
			fwrite(WriteTemp,sizeof(char),Length,CppFile); 
			 
			if((i==(m_iDemX-1))&&(j==(m_iDemY-1))){ 
				StrWrite="}\r"; 
			} 
			else{ 
				StrWrite="},\r"; 
			} 
			Length=StrWrite.GetLength(); 
			for(k=0;k<Length;k++) 
				WriteTemp[k]=StrWrite.GetAt(k); 
			WriteTemp[k]='\0'; 
			fwrite(WriteTemp,sizeof(char),Length,CppFile); 
		} 
	} 
	 
	StrWrite =	"};\r\r//-----下面是地形的显示列表-----//\r"; 
	StrWrite+=	"glNewList(DRAW_TERRAIN,GL_COMPILE);\r"; 
	StrWrite+=	"	for(k=0;k<SumPointOfDem;k++){\r"; 
	StrWrite+=	"		glBegin(GL_TRIANGLE_STRIP);\r\r"; 
	StrWrite+=	"			glNormal3fv(ndata[k]);\r"; 
	StrWrite+=	"			glVertex3f(vdata[k]);\r\r"; 
	StrWrite+=	"			glNormal3fv(ndata[k+"+(CString)iDemXStr+"]);\r"; 
	StrWrite+=	"			glVertex3fv(vdata[k+"+(CString)iDemXStr+"]);\r\r"; 
	StrWrite+=	"			glNormal3fv(ndata[k+1]);\r"; 
	StrWrite+=	"			glVertex3f(vdata[k+1]);\r\r"; 
	StrWrite+=	"			glNormal3fv(ndata[k+"+(CString)iDemXStr+"+1]);\r"; 
	StrWrite+=	"			glVertex3f(vdata[k+"+(CString)iDemXStr+"+1]);\r\r"; 
	StrWrite+=	"		glEnd(); \r	}\r"+ 
	StrWrite+=	"glEndList();\r"; 
	Length=StrWrite.GetLength(); 
	for(k=0;k<Length;k++) 
		WriteTemp[k]=StrWrite.GetAt(k); 
	WriteTemp[k]='\0'; 
	fwrite(WriteTemp,sizeof(char),Length,CppFile); 
 
	fclose(CppFile); 
	 
	return; 
} 
 
		// --- 以上是DEM转化为OpenGL源程序的代码,下面是提取粗糙数据 --- // 
 
void CDemToGLDlg::OnStart()  
{ 
	if(m_souce==""){ 
		m_MessageToUser2="请选择或输入Dem数据文件名……"; 
		MessageBox("请先选择DEM数据文件!","提示信息"); 
		UpdateData(false); 
		return; 
	} 
	if((m_inputx=="")||(m_inputy=="")){ 
		m_MessageToUser2="请输入采样间隔的幂倍数……"; 
		MessageBox("请输入采样间隔的幂倍数!","提示信息"); 
		UpdateData(false); 
		return; 
	} 
	int x_interval,y_interval,m_iDemNewX,m_iDemNewY; 
	int i,j; 
	DEMFILEHEADER	DemHeaderNew; 
	DemHeaderNew=DemHeader; 
	x_interval	= atoi(m_inputx); 
	y_interval	= atoi(m_inputy); 
	m_iDemNewX	= m_iDemX/x_interval; 
	m_iDemNewY	= m_iDemY/y_interval; 
 
	int * m_h; 
	m_h=new int [m_iDemNewX*m_iDemNewY]; 
	//原文件的数据都在m_pDemH中,DemHeader中存放文件头// 
	// --- 写文件头 --- // 
	DemHeaderNew.interval*=x_interval; 
	for(i=0;i<m_iDemNewX;i++){ 
		for(j=0;j<m_iDemNewY;j++){ 
			m_h[i*m_iDemNewY+j]=m_pDemH[2*(i*m_iDemY+j)]; 
		} 
	} 
 
	DemHeaderNew.iDemX=m_iDemNewX; 
	DemHeaderNew.iDemY=m_iDemNewY; 
 
	tempfilename=m_souce; 
	int index=tempfilename.Find(".dem"); 
	tempfilename.Insert(index,"cc"); 
	CFile file(tempfilename,CFile::modeCreate | CFile::modeWrite ); 
 
	file.Write((LPSTR)&DemHeaderNew, sizeof(DEMFILEHEADER));	// --- 读入DEM头文件 
	file.Write((LPSTR)m_h,m_iDemNewX*m_iDemNewY*4);						 
	file.Close(); 
	CString MessageStr="文件已经存在"+tempfilename; 
	MessageStr+="中!"; 
	MessageBox(MessageStr,"提示信息"); 
	return; 
} 
 
					// --- 上面是提取粗糙数据,下面是等切分 --- // 
 
void CDemToGLDlg::OnFourCut()  
{ 
	if(m_souce==""){ 
		m_MessageToUser2="请选择或输入Dem数据文件名……"; 
		MessageBox("请先选择DEM数据文件!","提示信息"); 
		UpdateData(false); 
		return; 
	} 
// --- 写入第一份地形 
	int m_iDemNewX,m_iDemNewY; 
	int i,j; 
	DEMFILEHEADER	DemHeaderNew; 
	DemHeaderNew=DemHeader; 
 
	m_iDemNewX	= m_iDemX/2; 
	m_iDemNewY	= m_iDemY/2; 
 
	int * m_h; 
	m_h=new int [m_iDemNewX*m_iDemNewY]; 
	//原文件的数据都在m_pDemH中,DemHeader中存放文件头// 
	// --- 写文件头 --- // 
 
	for(i=0;i<m_iDemNewX;i++){ 
		for(j=0;j<m_iDemNewY;j++){ 
			m_h[i*m_iDemNewY+j]=m_pDemH[i*m_iDemY+j]; 
		} 
	} 
 
	DemHeaderNew.iDemX=m_iDemNewX; 
	DemHeaderNew.iDemY=m_iDemNewY; 
 
	CString tempfilename1=m_souce; 
	int	index=tempfilename1.Find(".dem"); 
	tempfilename1.Insert(index,"01"); 
	CFile file01(tempfilename1,CFile::modeCreate | CFile::modeWrite ); 
 
	file01.Write((LPSTR)&DemHeaderNew, sizeof(DEMFILEHEADER));	// --- 写入DEM头文件 
	file01.Write((LPSTR)m_h,m_iDemNewX*m_iDemNewY*4);						 
	file01.Close(); 
 
// --- 写入第二份地形 
	for(i=0;i<m_iDemNewX;i++){ 
		for(j=0;j<m_iDemNewY;j++){ 
			m_h[i*m_iDemNewY+j]=m_pDemH[i*m_iDemY+m_iDemNewY+j]; 
		} 
	} 
 
	tempfilename=m_souce; 
	index=tempfilename.Find(".dem"); 
	tempfilename.Insert(index,"02"); 
	CFile file02(tempfilename,CFile::modeCreate | CFile::modeWrite ); 
 
	file02.Write((LPSTR)&DemHeaderNew, sizeof(DEMFILEHEADER));	// --- 写入DEM头文件 
	file02.Write((LPSTR)m_h,m_iDemNewX*m_iDemNewY*4);						 
	file02.Close(); 
// --- 写入第三份地形 
	for(i=0;i<m_iDemNewX;i++){ 
		for(j=0;j<m_iDemNewY;j++){ 
			m_h[i*m_iDemNewY+j]=m_pDemH[(i+m_iDemNewX)*m_iDemY+j]; 
		} 
	} 
 
	tempfilename=m_souce; 
	index=tempfilename.Find(".dem"); 
	tempfilename.Insert(index,"03"); 
	CFile file03(tempfilename,CFile::modeCreate | CFile::modeWrite ); 
 
	file03.Write((LPSTR)&DemHeaderNew, sizeof(DEMFILEHEADER));	// --- 写入DEM头文件 
	file03.Write((LPSTR)m_h,m_iDemNewX*m_iDemNewY*4);						 
	file03.Close(); 
// --- 写入第四份地形 
	for(i=0;i<m_iDemNewX;i++){ 
		for(j=0;j<m_iDemNewY;j++){ 
			m_h[i*m_iDemNewY+j]=m_pDemH[(i+m_iDemNewX)*m_iDemY+m_iDemNewY+j]; 
		} 
	} 
 
	tempfilename=m_souce; 
	index=tempfilename.Find(".dem"); 
	tempfilename.Insert(index,"04"); 
	CFile file04(tempfilename,CFile::modeCreate | CFile::modeWrite ); 
 
	file04.Write((LPSTR)&DemHeaderNew, sizeof(DEMFILEHEADER));	// --- 写入DEM头文件 
	file04.Write((LPSTR)m_h,m_iDemNewX*m_iDemNewY*4);						 
	file04.Close(); 
 
	CString MessageStr; 
	MessageStr="文件已经存在"+tempfilename1; 
	MessageStr+=" ~ 04.dem中!"; 
	MessageBox(MessageStr,"提示信息"); 
	return; 
} 
 
void CDemToGLDlg::OnEightCut()  
{ 
	if(m_souce==""){ 
		m_MessageToUser2="请选择或输入Dem数据文件名……"; 
		MessageBox("请先选择DEM数据文件!","提示信息"); 
		UpdateData(false); 
		return; 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
//以下是显示DEM地形的程序 
void CDemToGLDlg::InitOpenGL() 
{ 
	GLfloat light_ambient[]={0.0,0.0,0.0,1.0}; 
	GLfloat light_diffuse[]={1.0,1.0,1.0,1.0}; 
	GLfloat light_specular[]={1.0,1.0,1.0,1.0}; 
	GLfloat light_position[]={.0,.0,1.0,0.0}; 
	GLfloat light_model_ambient[]={0.4,0.4,0.4,1.0}; 
	GLfloat local_view[]={0.0}; 
 
	glLightfv(GL_LIGHT0,GL_POSITION,light_position); 
	glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); 
	glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); 
	glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular); 
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_model_ambient); 
	glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,local_view); 
 
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0); 
	glEnable(GL_DEPTH_TEST); 
	glDepthFunc(GL_LESS); 
 
	glClearColor(0.1,0.1,0.5,0.0); 
} 
 
 
void CDemToGLDlg::InitViewPort() 
{ 
	CRect rect; 
 
	CWnd *pWnd=GetDlgItem(IDC_ViewPort); 
//  得到绘图客户区的大小 
	pWnd->GetClientRect(rect); 
 
	int w=rect.right-rect.left; 
	int h=rect.bottom-rect.top; 
 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
//	glOrtho(-10000.0,10000.0,-10000.0,10000.0,-20000.0,20000.0); 
	gluPerspective(90.0,w/h,1.0,10000.0); 
	glViewport(0,0,w,h); 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
} 
 
void CDemToGLDlg::SetOpenGLInterface() 
{ 
	PIXELFORMATDESCRIPTOR pfd={ 
		sizeof(PIXELFORMATDESCRIPTOR), 
		1, 
		PFD_DRAW_TO_WINDOW| 
		PFD_SUPPORT_OPENGL| 
		PFD_DOUBLEBUFFER, 
		PFD_TYPE_RGBA, 
		24, 
		0,0,0,0,0,0, 
		0, 
		0, 
		0, 
		0,0,0,0, 
		32, 
		0, 
		0, 
		PFD_MAIN_PLANE, 
		0, 
		0,0,0 
	}; 
//对话框控件是一种子窗口,首先得到待绘图控件的窗口指针pWnd。 
	CWnd *pWnd=GetDlgItem(IDC_ViewPort); 
 
//通过该窗口控件的指针,得到该窗口的设备文本——pDC。 
	CDC *pDC=pWnd->GetDC(); 
 
	int iFormat=ChoosePixelFormat(pDC->m_hDC,&pfd); 
	BOOL     rt=SetPixelFormat(pDC->m_hDC,iFormat,&pfd); 
 
	m_hGlrc=wglCreateContext(pDC->m_hDC); 
	wglMakeCurrent(pDC->m_hDC,m_hGlrc); 
} 
 
void CDemToGLDlg::InitTerrainList() 
{ 
	GLfloat mat_ambient[]={0.3,0.3,0.3,1.0}; 
	GLfloat mat_diffuse[]={0.9,0.9,0.7,1.0}; 
	GLfloat mat_specular[]={1.0,1.0,1.0,1.0}; 
	GLfloat mat_shininess[]={50.0}; 
	 
	glNewList(Terrain,GL_COMPILE); 
		glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); 
		glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); 
		glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); 
		glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); 
		for(int i=0;i<m_iDemX-1;i++){ 
			for(int j=0;j<m_iDemY-1;j++){ 
				glBegin(GL_TRIANGLE_STRIP); 
 
					glNormal3d(Normals[(i*m_iDemY+j)*3+0], 
							   Normals[(i*m_iDemY+j)*3+1], 
							   Normals[(i*m_iDemY+j)*3+2]); 
					glVertex3d(m_pDemX[i*m_iDemY+j], 
							   m_pDemY[i*m_iDemY+j], 
							   m_pDemH[i*m_iDemY+j]); 
 
					glNormal3d(Normals[((i+1)*m_iDemY+j)*3+0], 
							   Normals[((i+1)*m_iDemY+j)*3+1], 
							   Normals[((i+1)*m_iDemY+j)*3+2]); 
					glVertex3d(m_pDemX[(i+1)*m_iDemY+j], 
							   m_pDemY[(i+1)*m_iDemY+j], 
							   m_pDemH[(i+1)*m_iDemY+j]); 
 
					glNormal3d(Normals[(i*m_iDemY+j+1)*3+0], 
							   Normals[(i*m_iDemY+j+1)*3+1], 
							   Normals[(i*m_iDemY+j+1)*3+2]); 
					glVertex3d(m_pDemX[i*m_iDemY+j+1], 
							   m_pDemY[i*m_iDemY+j+1], 
							   m_pDemH[i*m_iDemY+j+1]); 
 
					glNormal3d(Normals[((i+1)*m_iDemY+j+1)*3+0], 
							   Normals[((i+1)*m_iDemY+j+1)*3+1], 
							   Normals[((i+1)*m_iDemY+j+1)*3+2]); 
					glVertex3d(m_pDemX[(i+1)*m_iDemY+j+1], 
							   m_pDemY[(i+1)*m_iDemY+j+1], 
							   m_pDemH[(i+1)*m_iDemY+j+1]); 
 
				glEnd(); 
			} 
		} 
	glEndList(); 
} 
 
void CDemToGLDlg::DrawScene() 
{ 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
	glLoadIdentity(); 
	glPushMatrix(); 
	  glTranslatef(0.0,0.0,-5000.0); 
	   
	  glCallList(Terrain); 
	glPopMatrix(); 
 
	glFlush(); 
	SwapBuffers(wglGetCurrentDC()); 
}