摘要:本文是《基于DEM数字高程模型和OpenGL的三维地景仿真处理》系列文章中的第四篇,主要对重绘函数的实现、地景模型的几何变换、高差缩放和网格缩放等内容进行介绍。
关键字:DEM数字高程模型;OpenGL;地景仿真;GIS;VC
引言
在上一篇文章中实现了对数字高程模型(DEM)的建模与场景绘制。本文将在此基础上为其添加人机交互功能,使用户能够随心所欲的设置对地景的观察角度、位置、远近以及对地景高差的缩放等。下面将要给出具体的实现过程:
重绘函数的实现
在本系列的前几篇文章中曾多次提到对ReDraw()函数的调用。该函数用来负责对场景的重绘。通常的做法是先调用glClear()和glLoadIdentity()函数完成屏幕的清空和对矩阵的单位矩阵重置,随后调用glPushMatrix()进行压栈并可在之后执行对场景的旋转、平移、缩放、绘制列表的执行等操作直到glPopMatrix()函数被调用。在glPopMatrix()出栈之后需要通过glFlush()函数强制绘图的完成。由于采取的是双缓存,还需要通过SwapBuffers()交换缓存到当前正在执行的DC上去,这样的处理方式要比单缓存的绘图方式有很好的效果改善。下面给出ReDraw()函数的主要实现代码:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清屏
glLoadIdentity(); // 将矩阵清为单位矩阵
glPushMatrix(); // 压栈
glTranslatef(0.0, 0.0, -5000.0); // 平移到屏幕中心
glRotatef(0.0f, 1.0f, 0.0f, 0.0f); // 旋转
glRotatef(m_fxAngle, 1.0f, 0.0f, 0.0f);
glRotatef(m_fzAngle, 0.0f, 0.0f, 1.0f);
glTranslatef(m_fXOff, m_fYOff, m_fZOff); // 平移
glScalef(m_fScale, m_fScale, m_fScale); // 缩放
if (m_nViewMode == 0 || m_bTexture == FALSE) // 执行显示列表
glCallList(Terrain);
glPopMatrix(); // 出栈
glFlush(); // 强制绘图完成
SwapBuffers(wglGetCurrentDC()); // 交换缓存
其中,glTranslatef()、glRotatef()、glScalef()等函数用以完成对场景的平移、旋转与缩放等几何变换操作。与之类似的还有glTranslated()、glRotated()、glScaled()等,其函数原型分别为:
void glTranslated(GLdouble x, GLdouble y, GLdouble z );
void glTranslatef(GLfloat x, GLfloat y, GLfloat z );
void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void glScaled(GLdouble x, GLdouble y, GLdouble z);
void glScalef(GLfloat x, GLfloat y, GLfloat z);
开始两个函数将目标分别沿X、Y、Z轴平移x、y、z。中间两个函数将目标分别以X、Y、Z轴为轴逆时针旋转x、y、z。最后两个函数将目标分别在X、Y、Z方向上缩放,缩放因子分别为x、y、z。通过改变这几个函数的参数传递将能够很容易的实现用户对地景的平移、旋转与缩放操作。
对地景模型的平移、旋转与缩放处理
用户对地景模型的控制不外呼通过键盘与鼠标来完成。为响应键盘操作,可在WM_KEYDOWN消息响应函数中添加如下的判断处理代码:
switch(nChar) { // 漫游控制
case VK_UP:
m_fYOff = 20; break;
case VK_DOWN:
m_fYOff -= 20; break;
case VK_LEFT:
m_fXOff -= 20; break;
case VK_RIGHT:
m_fXOff = 20; break;
case 87: // W
m_fxAngle ; break;
case 83: // S
m_fxAngle--; break;
case 65: // A
m_fzAngle ; break;
case 68: // D
m_fzAngle--; break;
case 70: // F 前进
m_fScale = 0.05f; break;
case 66: // B 后退
if (m_fScale > 0.05f)
m_fScale -= 0.05f;
break;
default: break;
}
ReDraw(); // 重绘场景
其中,四个方向键将会相应的改变m_fXOff或m_fYOff的值,在ReDraw()执行场景重绘时改变后的参数将传递给glTranslatef()并被执行,从而完成对场景的平移。"W"、"S"、"A"、"D"四键与m_fxAngle和m_fzAngle等表示在各方向上旋转角度的变量相关,在ReDraw()执行场景重绘时这几个参数将传递到glRotatef ()并被执行,完成对场景的旋转。此外,还定义了"F"与"B"键,通过对glScalef ()的传入参数m_fScale的取值设置而实现对场景的缩放控制。
与键盘控制相比,对鼠标控制的响应略显复杂一些。按照通常的使用习惯,应当在鼠标左键按下时开始启动对场景的拖动,直至鼠标左键的释放为止。在此期间,只要鼠标移动,就应当随即执行对场景的重绘,这样才不会使鼠标的拖拽显的生涩。基于上述考虑,在鼠标左键按下发出WM_LBUTTONDOWN消息的响应函数中将控制变量m_LeftButtonDown置位,以开启拖动控制,同时以m_LeftDownPos保存当前的鼠标位置备用:
m_LeftButtonDown = TRUE; // 开始鼠标漫游
m_LeftDownPos = point;
鼠标滑动过程中将不断发出WM_MOUSEMOVE消息,因为我们只需要在按下鼠标左键的同时拖动时执行相关处理,因此在其响应函数中需要首先判断m_LeftButtonDown的状态,如果允许执行拖动处理则将根据当前鼠标位置与先前保存到m_LeftDownPos的前一次鼠标位置计算出应当旋转的角度,并通过ReDraw()函数绘制出角度更改后的场景:
if(m_LeftButtonDown) { // 正在鼠标漫游
m_fzAngle -= (float)(m_LeftDownPos.x - point.x)/3.0f;
m_fxAngle -= (float)(m_LeftDownPos.y - point.y)/3.0f;
m_LeftDownPos = point;
ReDraw(); // 重绘场景
}
一旦鼠标左键释放,WM_LBUTTONUP消息将会发出,在其消息响应函数中需要将控制变量m_LeftButtonDown复位,等待下一次的鼠标拖动:
m_LeftButtonDown = FALSE; // 结束鼠标漫游
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关文章
热点关注
- C 的面试题哦~
- hd7279键盘显示芯片c51代
- C语言的常用库函数使用方
- 什么是迭代跟递归算法?
- c#中父窗口和子窗口之间
- c#结合串口通信类实现串
- c#利用正则表达式实现字
- 用visual c#中轻松浏览
- C语言的常用库函数使用方
- C语言面试题大汇总之华为
- c#.net网络程式研发-sock
- c#实现smtp服务器,使用t
- C语言图像处理
- 如何自画ListView的Item(
- Linux下C语言编程基础知
- C 中对浮点数的格式化显
- 用c#实现由15位身份证号
- Windows Mobile 研发常见
- 在Visual C 中使用fopen
- Linux on POWER 中的 GNU
- uC/OS-II在ARM系统上的移
- C 嵌入式系统中应用
- C/C 中动态链接库的创建
- 关于c#中的datetime类型
- 用c#实现智能设备上的not
- C 中的指针(三) 智能指
- ASP.NET中使用TreeView控
- 使用c#创建sql server的
- C 中的动态多维数组
- c# enum设计和使用的相关
- Visual C /MFC入门教程
- 获取WinNT/Win2k当前用户
- 实现ComboBox输入文字的
- excel 2007单元格及内容
- C语言经典100例(一)
IDC资讯
虚拟主机
域名注册
托管租用
vps主机
智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD



