摘 要:通过对Mesa 3D库的移植及改进在VxWorks中实现了基于OpenGL1的图形API函数,解决了VxWorks下图形驱动开发组件WindML3.0不能使用标准图形API进行图形应用程序开发,不能支持3D图形显示的问题。同时利用硬件双缓冲技术解决了实时显示中画面闪烁、抖动的问题,提高了图形显示的质量
引言
随着嵌入式技术的不断发展,嵌入式系统的功能和结构日趋多样化和复杂化,已不再满足于简单图形的显示,对三维真实感图形的显示以及交互式用户界面提出了更高的要求。VxWorks是由美国风河公司推出的一个嵌入式实时多任务操作系统,当前VxWorks下的图形开发主要使用WindML来完成。虽然WindML支持丰富的显示方式、具有较快的显示速度、开放源代码等优势,但是WindML在以下两个方面的不足也限制了其进一步的发展。
(1) WindML提供的图形API函数根本不能同现有业界标准DirectX或是OpenGL兼容,这在很大程度上影响了代码的可移植性。
(2) WindML现有的图形API函数只支持简单的二维图形显示,根本不支持三维图形,这极大的限制了VxWorks下图形显示的开发,很难满足日益增长的对图形显示方面的要求。因此在WindML3. 0中实现对OpenGLAPI的支持就很有现实意义。
1 VxWorks三维图形引擎的总体架构
图形引擎在操作系统中可以视为一个独立的模块,其实质就是作为显示硬件的驱动程序,为应用程序的编写提供接口函数,同时在该操作系统中协调CPU与显示硬件芯片(GPU)之间的通信以及相应的内存管理等。
从这个意义上说,要在一个操作系统中构建出一个完整的图形引擎至少应该包括以下三大功能模块:与CPU通信模块、图形芯片初始化模块、标准图形库函数模块。与CPU通信模块主要负责提供CPU与GPU之间通信总线的驱动程序。以PCI总线为例,这个模块必须实现查找PCI设备、读写PCI配置空间,以及实现PCI中断控制等功能,协助CPU完成内存映射的任务。图形芯片初始化模块负责初始化图形芯片,包括创建并向系统注册显示设备、完成内存映射、正确设置显示模式、销毁设备等,这个模块必须使GPU处于准备好的状态,随时接收并完成绘制图形的任务。标准图形库函数模块负责在底层硬件上实现符合业界标准的图形库API函数(比如OpenGL或是DirectX) 。
2 Mesa3D的移植及改进
2.1 Mesa3D的移植
Mesa3D是一个兼容OpenGL规范的开放源码的函数库,是目前Linux上提供专业三维图形支持的唯一选择。Mesa3D同时也是一个跨平台的函数库,能够运行在XWindow、XWindow with DGA、BeOS、Linux SVGALib等平台上。从编译原理上来说,Mesa3D的移植就是要将Mesa的源代码(.c文件)编译成模块文件(.o文件) ,使其能成为一个功能模块加入到最终的VxWorks镜像中。
但是Mesa3D并不是专门为VxWorks编写的,因此必须从源代码中选取那些实现OpenGL基本功能的源文件, 同时还应根据系统硬件配置实现Mesa3D库与WindML的接口。最后将所有的文件单独编译生成相应的模块,再链接进入VxWorks镜像文件中。根据笔者的实践,要将Mesa3D移植到WindML3.0并能实现所有的OpenGL API函数,以下文件是必须要加入工程,并且需要根据系统的硬件情况进行修改,具体的修改处理情况如下。
(1) 所有实现OpenGL标准功能的文件。在Mesa3D中,OpenGL按照功能分成以下部分:
- 缓冲区操作文件(如buffer.c、accum.c、stencil.c等)
- 像素操作文件(如drawpix.c)
- 纹理操作文件(如texiformat.c、teximage.c、texstore.c等)
- 光照实现文件(如light.c)
- 基本图元(点、线、多边形)实现文件(如lines.c、polygon.c等)
- 光栅化操作文件(如rastpos.c)
(2) X86下的四个基本文件,
x86.c、common_x86.c、3dnow.c、sse.c。
(3) math下的文件。主要实现了基本的矩阵数学运算,用以提供对坐标变换的支持。
(4) array_cache下的文件。
(5) swrast下的文件。
(6) tnl下的文件。
(1)~(6)下的所有文件将编译生成objMesaGL.o模块, 实现了支持OpenGL1. 2标准的所有API函数
(7) X86下的汇编程序文件。这些汇编程序将编译生成objMesaX86. o模块,实现了x86架构下对CPU的操作。
移植成功的关键在于根据硬件配置编写出Mesa3D与WindML的接口,即创建一个名为Mesa图形上下文的数据结构,并初始化结构中各成员变量,然后将指向该数据结构的指针指向WindML的图形上下文(gc), 这样即可将二者有效的结合起来。同时为了克服Mesa3D显示时画面抖动的问题,应编写出支持硬件双缓冲机制的驱动函数。在实际操作中,还应该通过修改编译规则将生成的所有.o 模块都归入一个.a模块中,以方便VxWorks镜像的链接。
2.2 对Mesa3D库的改进
由于Mesa3D并不是专门为WindML3.0提供的库函数, 因此在实际运行中存在着画面闪烁、抖动、以及明显不连续的情况。为了提高显示质量,必须利用双缓冲技术对移植后的Mesa3D加以改进,使其能符合实时显示的要求。
双缓冲技术是在不改变原有的视频帧缓冲区的基础上,在内存(或显存)中重新开辟一块与屏幕一样大小的缓冲区。这两块缓冲区即组成了显示的前台与后台,在显示的时候将后台的图形数据直接复制到前台,同时在后台绘制下一帧要显示的图像。由于图形的绘制过程是在后台缓冲区中进行的,所以可以有效地消除屏幕闪烁、抖动的问题。笔者通过编写API函数uglMesaPageVisbleSet, uglMesaPageDrawSet在Mesa3D库中实现了双缓冲驱动。其中uglMesaPageVisbleSet用于前台的图像显示; uglMesaPageDrawSet用于在后台绘制图像。这两个函数的关键代码如下。
UGL_STATUS uglMesaPageDrawSet(UGL_UGI_DRIVER * pUgiDriver, UGL_PAGE * pPage)
{
pDriver->genDriver.pDrawPage = pPage;
return(UGL_STATUS_OK) ;
}
UGL_STATUS uglMesaPageVisibleSet(UGL_UGI_DRIVER * pUgiDriver, UGL_PAGE * pPage)
{
/* 设置当前显示页 */
pDriver->genDriver.pVisiblePage = pPage;
/* 获得显示地址 */
displayStart = (UGL_UINT32)((UGL_GEN_DDB *)pPage->pDdb)->image;
displayStart -= (UGL_UINT32)pDriver->genDriver.fbAddress;
displayStart >>= 2;
displayStartHigh = (displayStart & 0xFFFF0000) >> 16;
displayStartLow = displayStart & 0x0000FFFF;
/* 设置当前显示页的起始地址 */
__asm__
(
"movw 0x0080, %%bx\n\t"
"movw %0, %%dx\n \ t"
"movw %1, %%cx"
:: "m" (displayStartHigh), "m" (dis2playStartLow) : "bx", "dx", "cx"
);
(*pDriver->displayStartSet)();
return(UGL_STATUS_OK);
}
为了加速VxWorks下图形的渲染速度,还应在上文中提到的(1)中的所有.C文件中尽量采用硬件加速的方式,即通过GPU来绘制直线、三角形、矩形等基本图元,而不是通过CPU采用软件渲染的方式实现。因篇幅所限,源代码就不在此处一一列出了。
3 测试及功能对比
笔者通过以下测试程序来验证OpenGL图形引擎的绘制功能,测试时使用的GPU为ATI Radeon M9000。笔者采用标准的OpenGL1.3 API函数实现下面的三维齿轮效果图。实拍显示效果如图1所示:
图1 炫彩立方体实拍效果图
移植并改进Mesa3D前后WindML3.0图形渲染功能对比如表1所示。
表1 移植并改进Mesa3D前后功能对比
比较项目 | 改进前 | 改进后 |
---|---|---|
二维图形显示 | 支持 | 支持 |
三维图形显示 | 不支持 | 支持 |
OpenGL1.3 API | 不支持 | 支持 |
支持glu库函数 | 不支持 | 支持 |
支持glut库函数 | 不支持 | 支持 |
画面显示质量画 | 面闪烁不清 | 画面稳定清晰 |
4 结束语
本文通过对Mesa3D库的移植和改进, 解决了WindML3.0不支持3D图形显示及标准OpenGLAPI函数的问题,大大增强了WindML开发的图形程序的通用性和可移植性。同时利用硬件双缓冲技术解决了实时显示时屏幕闪烁、抖动的问题,提高了图形显示的质量。
参考文献:
[ 1 ] VxWorks5. 5 Programmerps Guide [M ]. WindRiverSystem Inc. , 2002.
[ 2 ] WindML 3. 0 Release Note [M ]. WindRiver SystemInc. , 2002.
[ 3 ] WindML DDK Programmerps Guide, 3. 0 [M ]. Win2dRiver System Inc. , 2002.
[ 4 ] Timour Paltashev, Navin Govind, Gheni Abla. Simulation of Hardware Support for OpenGL GraphicsArchitecture, Coding and Computing[ J ]. 2000, 6 ( 6) : 1262128.
[ 5 ] 梁玉红,贾艾晨. 基于OpenGL的拱坝三维数据场的可视化应用研究[ J ]. 四川理工学院学报: 自然科学版, 2007, 20 ( 6) : 67271.