www.gusucode.com > 与三维有关的一个VC++图形处理程序-源码程序 > 与三维有关的一个VC++图形处理程序-源码程序/code/DemToGLDlg.cpp

    // DemToGLDlg.cpp : implementation file
// Download by http://www.NewXing.com
#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());
}