📄 dialogdlg.cpp
字号:
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0 )
{ MessageBox("ChoosePixelFormat failed");
return;
}
if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{ MessageBox("SetPixelFormat failed");
return;
}
return;
}
//三维场景的绘制函数
void CDialogDlg::draw_scence()
{
glCallList(no3);//第一步:绘制天空背景
glCallList(no1);//第二步:回到缺省的绘制条件下
glMatrixMode(GL_PROJECTION);
GLsizei nWidth=800;
GLsizei nHeight=600;
GLdouble dAspect=(GLdouble)nWidth/(GLdouble)nHeight;
glLoadIdentity();
gluPerspective(60,dAspect,1.0,20000.0);
glViewport(0,0,nWidth,nHeight);
glMatrixMode(GL_MODELVIEW);
gluLookAt(lookx,looky,lookz,0,9990,860,0,0,1);
glTranslated(px,py,pz);
glCallList(no2);//第三步:绘制三维地形
glFinish();
}
//计算点的规一化法向量,计算方法参见计算机图形学相关书籍
void CDialogDlg::GetVertexNormal(int i,int j, float normal[3])
{
float normal1[3],normal2[3],normal3[3],normal4[3];
GLint x[4],y[4],z[4];
int width,height;
width=m_iDemWidth;
height=m_iDemHeight;
if ((i<height-1)&&(i>0)&&(j>0)&&(j<width-1))
{ x[0]=0;
x[1]=m_pDemX[j-1]-m_pDemX[j];
x[2]=0;
x[3]=m_pDemX[j+1]-m_pDemX[j];
y[0]=m_pDemY[i-1]-m_pDemY[i];
y[1]=0;
y[2]=m_pDemY[i+1]-m_pDemY[i];
y[3]=0;
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];
z[2]=m_pDemH[(i+1)*width+j]-m_pDemH[i*width+j];
z[3]=m_pDemH[i*width+j+1]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
GetShiCha(x[1],y[1],z[1],x[2],y[2],z[2],normal2);
GetShiCha(x[2],y[2],z[2],x[3],y[3],z[3],normal3);
GetShiCha(x[3],y[3],z[3],x[0],y[0],z[0],normal4);
normal[0]=normal1[0]+normal2[0]+normal3[0]+normal4[0];
normal[1]=normal1[1]+normal2[1]+normal3[1]+normal4[1];
normal[2]=normal1[2]+normal2[2]+normal3[2]+normal4[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;
}
if ((i==0)&&(j==0))
{ x[0]=0;
x[1]=m_pDemX[j+1]-m_pDemX[j];
y[0]=m_pDemY[i+1]-m_pDemY[i];
y[1]=0;
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];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
normal[0]=normal1[0];
normal[1]=normal1[1];
normal[2]=normal1[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if ((i==0)&&(j==(width-1)))
{ x[0]=m_pDemX[j-1]-m_pDemX[j];
x[1]=0;
y[0]=0;
y[1]=m_pDemY[i+1]-m_pDemY[i];
z[0]=m_pDemH[i*width+j-1]-m_pDemH[i*width+j];
z[1]=m_pDemH[(i+1)*width+j]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
normal[0]=normal1[0];
normal[1]=normal1[1];
normal[2]=normal1[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if ((i==(height-1))&&(j==0))
{ x[0]=m_pDemX[j+1]-m_pDemX[j];
x[1]=0;
y[0]=0;
y[1]=m_pDemY[i-1]-m_pDemY[i];
z[0]=m_pDemH[i*width+j+1]-m_pDemH[i*width+j];
z[1]=m_pDemH[(i-1)*width+j+1]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
normal[0]=normal1[0];
normal[1]=normal1[1];
normal[2]=normal1[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if ((i==(height-1))&&(j==(width-1)))
{ x[0]=0;
x[1]=m_pDemX[j-1]-m_pDemX[j];
y[0]=m_pDemY[i-1]-m_pDemY[i];
y[1]=0;
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];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
normal[0]=normal1[0];
normal[1]=normal1[1];
normal[2]=normal1[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if (i==0)
{ x[0]=m_pDemX[j-1]-m_pDemX[j];
x[1]=0;
x[2]=m_pDemX[j+1]-m_pDemX[j];
y[0]=0;
y[1]=m_pDemY[i+1]-m_pDemY[i];
y[2]=0;
z[0]=m_pDemH[i*width+j-1]-m_pDemH[i*width+j];
z[1]=m_pDemH[(i+1)*width+j]-m_pDemH[i*width+j];
z[2]=m_pDemH[i*width+j+1]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
GetShiCha(x[1],y[1],z[1],x[2],y[2],z[2],normal2);
normal[0]=normal1[0]+normal2[0];
normal[1]=normal1[1]+normal2[1];
normal[2]=normal1[2]+normal2[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if (i==(height-1))
{ x[0]=m_pDemX[j+1]-m_pDemX[j];
x[1]=0;
x[2]=m_pDemX[j-1]-m_pDemX[j];
y[0]=0;
y[1]=m_pDemY[i-1]-m_pDemY[i];;
y[2]=0;
z[0]=m_pDemH[i*width+j+1]-m_pDemH[i*width+j];
z[1]=m_pDemH[(i-1)*width+j]-m_pDemH[i*width+j];
z[2]=m_pDemH[i*width+j-1]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
GetShiCha(x[1],y[1],z[1],x[2],y[2],z[2],normal2);
normal[0]=normal1[0]+normal2[0];
normal[1]=normal1[1]+normal2[1];
normal[2]=normal1[2]+normal2[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if (j==0)
{ x[0]=0;
x[1]=m_pDemX[j+1]-m_pDemX[j];
x[2]=0;
y[0]=m_pDemY[i+1]-m_pDemY[i];
y[1]=0;
y[2]=m_pDemY[i-1]-m_pDemY[i];
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];
z[2]=m_pDemH[(i-1)*width+j]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
GetShiCha(x[1],y[1],z[1],x[2],y[2],z[2],normal2);
normal[0]=normal1[0]+normal2[0];
normal[1]=normal1[1]+normal2[1];
normal[2]=normal1[2]+normal2[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
if (j==(width-1))
{ x[0]=0;
x[1]=m_pDemX[j-1]-m_pDemX[j];
x[2]=0;
y[0]=m_pDemY[i-1]-m_pDemY[i];
y[1]=0;
y[2]=m_pDemY[i+1]-m_pDemY[i];
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];
z[2]=m_pDemH[(i+1)*width+j]-m_pDemH[i*width+j];
GetShiCha(x[0],y[0],z[0],x[1],y[1],z[1],normal1);
GetShiCha(x[1],y[1],z[1],x[2],y[2],z[2],normal2);
normal[0]=normal1[0]+normal2[0];
normal[1]=normal1[1]+normal2[1];
normal[2]=normal1[2]+normal2[2];
float rate=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
normal[0]/=rate;
normal[1]/=rate;
normal[2]/=rate;
return;}
}
void CDialogDlg::move_scence() //启动场景的漫游,也就是激活定时器
{
SetTimer(1,50,NULL);
CWnd* mywnd;
mywnd=GetDlgItem(IDC_BUTTON4);
mywnd->EnableWindow(true);
mywnd=GetDlgItem(IDC_BUTTON3);
mywnd->EnableWindow(false);
}
void CDialogDlg::readdem()//读取地形文件数据,加载到内存
{
m_pDemH=NULL;
m_pDemX=NULL;
m_pDemY=NULL;
m_iDemWidth=0;
m_iDemHeight=0;
typedef struct tagDEMFILEHEADER{//地形文件的文件头,需要根据不同的地形文件进行相应的修改
int map[6];
int height;
int width;
float sx;
float sy;
float tap;
}DEMFILEHEADER;
DEMFILEHEADER DemHeader;
LPSTR lpstr=(LPSTR)::LockResource(LoadResource(NULL,
FindResource(NULL,MAKEINTRESOURCE(IDR_DEM1),"DEM")));
memcpy((LPSTR)&DemHeader,lpstr,sizeof(DEMFILEHEADER));
// 获取地形文件的相关信息,比如宽度,长度,间距等
m_iDemWidth=DemHeader.width;
m_iDemHeight=DemHeader.height;
m_pDemX = new int[m_iDemWidth];
m_pDemY = new int[m_iDemHeight];
m_pDemH = new int[m_iDemWidth*m_iDemHeight];
for(int i=0;i<m_iDemHeight;i++)
m_pDemX[i]=i*(int)DemHeader.tap*2;
for(int j=0;j<m_iDemWidth;j++)
m_pDemY[j]=j*(int)DemHeader.tap*2;
//加载地形高程信息
lpstr+=sizeof(DEMFILEHEADER);
memcpy(m_pDemH,lpstr, 4*m_iDemWidth*m_iDemHeight);
//加载地形纹理图像
lpstr=(LPSTR)LoadResource(NULL,
FindResource(NULL,MAKEINTRESOURCE(IDB_BITMAP10),RT_BITMAP));
LPSTR lpdibdata=(LPSTR)::FindDIBBits(lpstr);
memcpy(m_pTexForest0,lpdibdata,128*128*3);
//加载天空背景图像
lpstr=(LPSTR)LoadResource(NULL,
FindResource(NULL,MAKEINTRESOURCE(IDB_BITMAP12),RT_BITMAP));
lpdibdata=(LPSTR)::FindDIBBits(lpstr);
memcpy(m_pTexyun,lpdibdata,512*512*3);
GLint* g_fHeight=m_pDemH;
//根据高度和坡度,生成每个高程点对应的颜色,用二维数组存放
for(int x=0; x<=119; x++)
for(int z=0; z<=119; z++)
{
GLfloat gradient = ((GLfloat) (g_fHeight[x*m_iDemWidth+z]-g_fHeight[(x+1)*m_iDemWidth+z])) / 100.0;
if(g_fHeight[x*m_iDemWidth+z]>10)
{
if((g_fHeight[x*m_iDemWidth+z]-g_fHeight[x*m_iDemWidth+z+1])<12 && (g_fHeight[x*m_iDemWidth+z]-g_fHeight[x*m_iDemWidth+z+1])>-12 && (g_fHeight[x*m_iDemWidth+z]-g_fHeight[(x+1)*m_iDemWidth+z])<12 && (g_fHeight[x*m_iDemWidth+z]-g_fHeight[(x+1)*m_iDemWidth+z])>-12)
{
colour[x][z].g =gradient + 0.5;//0.6;
colour[x][z].r = colour[x][z].g*0.2;
colour[x][z].b = colour[x][z].g*0.2;
}
else
{
colour[x][z].r = gradient + 0.75;
colour[x][z].g = colour[x][z].r*0.8;
colour[x][z].b = colour[x][z].r*0.7;
}
}
else if(g_fHeight[x*m_iDemWidth+z]>0){
colour[x][z].g = gradient + 0.75;
colour[x][z].r = colour[x][z].g * 0.2;
colour[x][z].b = 0.2;
}
else {
colour[x][z].r = gradient + 1.0;
colour[x][z].g = colour[x][z].r * 0.75;
colour[x][z].b = colour[x][z].r * 0.5;
}
}
}
void CDialogDlg::OnTimer(UINT nIDEvent) //漫游时进行位置平移
{
// TODO: Add your message handler code here and/or call default
px-=10;
py+=8;
pz-=1;
OnPaint();
CDialog::OnTimer(nIDEvent);
}
void CDialogDlg::stop_move() //停止漫游,也就是关闭定时器
{
// TODO: Add your control notification handler code here
KillTimer(1);
CWnd* mywnd;
mywnd=GetDlgItem(IDC_BUTTON3);
mywnd->EnableWindow(true);
mywnd=GetDlgItem(IDC_BUTTON4);
mywnd->EnableWindow(false);
}
//计算法向量之---求矢量的叉乘
void CDialogDlg::GetShiCha(float x1, float y1, float h1, float x2, float y2, float h2,float normal[3])
{
normal[0]=y1*h2-y2*h1;
normal[1]=x2*h1-x1*h2;
normal[2]=x1*y2-x2*y1;
}
int CDialogDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CSplashWnd::ShowSplashScreen(this);//程序运行开始出现闪现窗口
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -