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