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());
}