一种基于OpenGL构建的飞行仿真系统设计

时间:2011-06-27

 

  虚拟现实(Virtual Reality,简称VR,又译作灵境、幻真)是近年来出现的高新技术,也称灵境技术或人工环境。VR是一项综合集成技术,涉及计算机图形学、人机交互技术、传感技术、人工智能等领域,它用计算机生成逼真的三维视、听、嗅觉等感觉,使人作为参与者通过适当装置,自然地对虚拟世界进行体验和交互作用。使用者进行位置移动时,电脑可以立即进行复杂的运算,将的3D世界影像传回产生临场感。虚拟现实中的"现实"是泛指在物理意义上或功能意义上存在于世界上的任何事物或环境,它可以是实际上可实现的,也可以是实际上难以实现的或根本无法实现的。而"虚拟"是指用计算机生成的意思。因此,虚拟现实是指用计算机生成的一种特殊环境,人可以通过使用各种特殊装置将自己"投射"到这个环境中,并操作、控制环境,实现特殊的目的,即人是这种环境的主宰。

  OpenGL? 是行业领域中为广泛接纳的 2D/3D 图形 API, 其自诞生至今已催生了各种计算机平台及设备上的数千应用程序。OpenGL? 是独立于视窗操作系统或其它操作系统的,亦是网络透明的。在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL? 帮助程序员实现在 PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL.

  经过近几年来的发展,虚拟现实技术及设备被很多领域应用,而飞行仿真是重要的应用领域之一。本文所研究的飞行仿真系统采用新型六维控制器(六自由度鼠标)作为输入设备,监视器作为输出设备,以OpenGL作虚拟环境生成器,构成一套高性能计算机处理系统来实现高度仿真的飞行模拟器运动。

  1  构建应用程序框架

  应用Visual C++ 6.0建立一个基于MFC的应用程序框架,并将VC库文件opengl32.lib、glu32.lib和glaux.lib包含在应用程序中。

  为使OpenGL函数库的调用有效,首先应设置渲染窗口。OpenGL的渲染处理完全不同于Windows的图形设备接口GDI.要使Windows的窗口格式为OpenGL所接受,需进行下列设置。

  1.1 建立图形操作描述表

  OpenGL作图窗口必须设置为WM_CLIPSIBLINGS和WM_CLIPCHILDREN风格。

  在Windows98/2000系统下,窗口程序首先要处理设备描述表(Device Contexts,DC),它包括若干在窗口上如何显示图形的信息。而在OpenGL程序中,必须创建图形操作描述表(Rending Context,RC),这是DC中专用于OpenGL的一种。但是RC不同于其他的DC,它只需要一个句柄就可以任意调用OpenGL函数,而其他DC调用每个GDI函数时都需要一个句柄。

  使用时先通过wglCreateContext()函数创建一个RC,然后调用wglMakeCurrent()函数启动它,就可在所定义的窗口内调用OpenGL函数绘制飞行器了。

  m_pDC=new CClientDC(this);

  hrc=wglCreateContext(m_pDC->GetSafeHdc( ));

  wglMakeCurrent(m_pDC->GetSafeHdc( ),hrc);

  1.2 设置像素格式

  OpenGL内部用浮点数来表示和处理颜色,红绿蓝和Alpha值这四种成份每种的值为1.0,值为0.0.在256色模式下,OpenGL把一个像素颜色的内部值按线性关系转换为8比特(Bit)来输出到屏幕上,其中红色占位的3比特,绿色占中间的3比特,蓝色占位的2比特,Windows将这个8比特值看作逻辑调色板的索引值。例如OpenGL的颜色值(1.0,0.14,0.6667)经过转换后二进制值为10001111(红色为111,绿色为001,蓝色为10),即第143号调色板,该调色板指定的颜色的RGB值应与(1.0,0.14,0.6667)有相同的比率,为(255,36,170),如果不是该值,那么显示出来的颜色就会有误差。

  像素格式指定设备的绘图属性,包括绘图界面的颜色表示模式、颜色位数、累积缓存区、深度缓存区和模板缓存区的位数。每个OpenGL显示设备都支持某一特定的像素格式。像素格式用PIXELFORMATDESCRIPTOR结构来表示,通过设置这一结构的成员值使之支持OpenGL.建立了图形操作描述表并初始化PIXELFORMATDESCRIPTOR结构后,应以此结构为变量调用ChoosePixelFormat( )函数为设备描述表选择像素格式,调用SetPixelFormat( )将其设置为当前像素格式。

  int pixelformat;

  pixelformat=ChoosePixelFormat(m_pDC->GetSafeHdc( ),&pfd);

  SetPixelFormat(m_pDC->GetSafeHdc( ),pixelformat,&pfd);

  2  绘制场景

  2.1 准备工作

  开始绘制场景之前,需要用背景颜色刷新显存。飞行器在天空的背景中飞行,因此应将清除颜色缓冲区的颜色设为淡蓝色,然后刷新颜色缓冲区和深度缓冲区。

  glClearColor(0.75,0.75,1.0,1.0);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  准备工作还要考虑计算机屏幕是二维的,要用它显示逼真的三维物体就要用到图形变换技术。同时程序还要保证,当用户随意改变窗口大小时,飞行器不会变形失真。因此需要定义初始的坐标变换。视图类的OnSize事件对这些问题进行处理。

  2.2 设置光照效果

  创建三维立体的场景时,添加光线效果对于飞行器的真实感非常重要。OpenGL的光照模型将光照成分划分为四个独立的部分:发射光、环境光、散射光和镜面反射光。OpenGL独立计算这四种光照成分,然后将其结果叠加,从而得到终的效果。

  设置光照应分二步进行。首先使用glLightfv( )函数设置光源的属性和值,创建系统光源。本文定义了四个GLfloat数组sunposition、suncolor、sunambient和sunspecular,分别作为光源位置、光源的散射光亮度、环境光亮度和镜面反射光亮度的属性值。然后用glEnable(GL_LIGHTING)启动OpenGL的光照处理功能。再用glEnable(GL_LIGHT0)打开设置的光源。

  3  绘制飞行器

  飞行器是一个较为复杂的三维图形对象,它需要使用二次曲面和多边形镶嵌工具来创作,并通过OpenGL的纹理映射技术给飞行器穿上漂亮的外衣。

  3.1 飞行器构造原理

  按照组成飞行器对象的几何形体的特点,可将飞行器构造用二次曲面(quadric)和多边形(polygon)表示。具体来说,机头用锥形表示;机体是柱形;尾部的发动机用锥形的柱体来表示;飞行器的顶棚可以用一个拉长的球体来表示,把球体的透明度设为0.65,使之具有玻璃的效果,这些部分是二次曲面。例如机体绘制命令为:

  gluCylinder(quadric,0.25,0.25,3.5,20,2);

  而机翼和机尾的各个部分都是多边形的,应使用多边形镶嵌工具来绘制。例如机尾绘制命令为:

  gluTessBeginPolygon(tess,NULL);

  gluTessBeginContour(tess);

  for (i=0;i<6;i ++)

  gluTessVertex(tess,tail[i],tail[i]);

  gluTessEndContour(tess);

  gluTessEndPolygon(tess);

  3.2 程序实现方法

  程序实现应用了显示列表技术。OpenGL的显示列表是事先存储的用于稍后执行的一组OpenGL命令序列。分析了飞行器的几何形体构造、设置完绘制命令并进行纹理贴图美化飞行器外表后,就可将各个部分的构造程序代码编辑到显示列表里存储起来了。

  F16Body=glGenLists(1);

  glNewList(F16Body,GL_COMPILE);

  调用函数glEndList( ),标志一个显示列表的结束。

  在视图类的DrawScene( )事件的适当位置用函数glCall-

  List(F16Body)调用显示列表,从而按照预先定义的顺序执行飞行器模型的绘制。

  4  六维鼠标控制的飞行仿真系统总体设计

  4.1 六维鼠标的工作原理

  现实中飞行器是可以进行三维移动以及三维旋转运动的,因此在飞行仿真系统中就需要一种可以实现上述运动模式的输入控制设备。这里选择了一种新型并联结构六维控制器,即六维鼠标。

  该六维鼠标基于力控制原理,通过集成A/D转换器的动态应变仪与计算机的COM1口(串行口1)相连,采用串行通信机制。操作者握住鼠标,向所要移动或转动的方向用力,鼠标将受到的六维力传递到内部的微型六维力敏感元件,接着通过鼠标内部机制生成与该力成正比的电压信号,并将电压信号放大后采集进计算机,利用力Jacobian矩阵求出鼠标受到的空间作用力情况[3].六维鼠标的控制系统软件实现将三个力分量分别乘以某个大于零的系数,生成飞行器作空间直线运动的位移分量,从而控制仿真系统中飞行器的平移运动;将三个力矩分量经过一定算法的变换后产生飞行器绕X、Y、Z三个坐标轴转动的角位移,从而控制飞行器的旋转运动, 在算法中应用到了六维鼠标的标定矩阵G6×6.具体变换算法请查阅文献3.图1描述了六维鼠标的工作原理流程。

 

 

  4.2 仿真系统总体设计

  六维鼠标和计算机之间采用串口通信,所以在程序设计中选用了MSComm控件。该控件通过串行端口传送和接收数据,从而为应用程序实现串行通信功能[4].MSComm控件将通信的大部分底层操作都封装在控件内部,应用程序只需获取和设置相应的控件属性即可,简化了编程的复杂度。在Visual C++ 6.0中使用该控件的基本流程如图2所示。

 


  本仿真系统中当控件插入工程后,应将串口初始化及打开命令放在视图类的OnCreate()事件中。在应用程序建立时就打开串口,准备接收鼠标数据。

  应用MSComm控件的OnComm( )事件作为对六维鼠标输入数据的响应事件,并在事件处理中实现对飞行器的运动控制。首先检测串口的GetCommEvent( )事件,如果该事件返回值为2,表示接收缓冲区内的字符数达到Rthreshold值,发生接收事件(comEvReceive)。接下来编写接收数据的过程,实现将鼠标传输的数据转化为三个平移分量(Xp、Yp、Zp)和三个旋转分量(Xr、Yr、Zr)。将Xp、Yp、Zp、Xr、Yr、Zr六个控制变量传递给DrawScene( )函数,在飞行器绘制之前修改视景坐标系,从而控制飞行器的运动。

  glTranslatef(Xp,0.0f,0.0f);

  glTranslatef(0.0f,Yp/10,0.0f);

  glTranslatef(0.0f,0.0f,-Zp);

  glRotated(Xr-37,1.0,0.0,0.0);

  glRotated(Yr-7,0.0,1.0,0.0);

  glRotated(Zr-2,0.0,0.0,1.0);

  glCallList(F16Body);

  系统总体实现流程如图3所示。


  5  结  论

  本文所开发的飞行器仿真系统使用Visual C++ 6.0作为软件平台,应用OpenGL来开发具有六维运动能力的飞行模拟器和高度真实感的三维地形,以六维鼠标作为飞行器的控制输入设备,通过串行通信机制控制计算机中的仿真系统。用户通过给六维鼠标施加不同方向、不同大小的力来自由控制系统中飞行模拟器的运动,实现飞行器在虚拟地形环境中的三维移动和三维转动,从而实现对真实世界中飞行器运动的仿真。

 


  
上一篇:基于DSP的π/4-DQPSK调制快速位定时捕获算法的设计与实现
下一篇:基于USB2.0总线的TMS320VC5402 HPI自举的实现方案

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料