基于Klimt三维图形程序的优化策略

来源:互联网 发布:沈阳飞客数据恢复 编辑:程序博客网 时间:2024/05/06 19:57
1 优化改进的必要性
    PXA270是一款很优秀的嵌入式处理芯片,在介绍本次设计的硬件环境时我们就可以了解得到,而且在介绍Klimt特性的时候,也多次提到PXA2xx系列处理器,可见PXA270处理器在多媒体处理,特别是三维图像处理方面表现得是非常出色的,加之在演示一般的3D动画时,得到了很流畅很美观的效果,而本人也试过把3D图像程序放到s3c2410的开发板上运行,效果很差,足以见得PXA270的处理能力的强劲。
但在PXA270开发板上运行3D动画程序时,我们同时也发现,在运行一些具有比较复杂的三维图形场景(比如要处理很多图形,或者一些比较复杂的效果)三维动画时,或者提高动画的帧率时,三维动画的显示效果就会不是太流畅。造成这种结果的原因是有多种的,包括硬件,Klimt的结构本省,程序本身,嵌入式GUI等等,对其中一个或多个环节进行优化改进,都有可能使3D图形程序具有更好的显示效果和可用性。3D程序的优化可以提高嵌入式设备有限资源的使用率,可以提高3D图像的显示效果,可以进行更复杂的三维图形应用。可见对基于Klimt的嵌入式进行优化改进具有必要性。
2 硬件的优化
    我们在前面的硬件环境介绍中也说到,其实PXA270处理器如果有某些特定用途的协处理硬件辅助的话,可以表现出更好的性能。前面就介绍了的Intel 7200G显示处理芯片,可以帮助PXA270表现出更好的多媒体特别是三维图形的处理能力,使得PXA270如虎添翼。我们知道,如果一台PC机的CPU处理能力再高,如果它没有一个好的显卡的话,但在面对高质量的3D游戏等三维图像显示时也是无能为力;在嵌入式环境下其实也是同一个道理,我们如果可以给PXA270配备一个诸如Intel 7200G的协处理器的话,那么嵌入式3D图形处理程序将会得到明显的优化。可以处理更复杂的三维效果。
3 软件的优化
3.1 Klimt本身结构的优化
其实影响3D图形程序的效率的原因中,3D图形基础引擎也是一个很重要的原因。任何基于OpenGL或OpenGL|ES的3D图形基础引擎都具有一定的局限性,特别是针对嵌入式平台的,要考虑的因素太多,在某方面性能得到提升的同时,可能另一方面的性能就会受到限制,所以要总体折中考虑。本文前面介绍Klimt架构时也提及,Klimt在试图高效实现某些特性的时候,会带来另外的一些瓶颈。由于Klimt是开源的项目,代码可以任意修改,所以在了解Klimt的基本架构和代码结构之后,我们可以通过修改Klimt的核心源码,经过综合考虑之后,添加或修改自己更加高效的代码、算法或者策略方案。不过这种方法具有较高的难度和需要花费更多时间和精力,在毕业设计比较有限的时间里面,暂时无法完成,不过作为以后的研究探索还是非常有价值的。
3.2 编程代码的优化
Klimt本身提供给开发用户许多可以使用的程序优化策略,开发用户可以在代码设计时对3D程序进行优化。下面是一些基本的策略。
A. 使用顶点数组
从Klimt 0.6.3开始,顶点数组是会被缓存的。使用顶点数组可以减少在变换和光照阶段(Transform and Lighting, TnL stage)中所花费的时间,从而增加三角面的产生率。这对于需要绘制大量多边形的场景是非常重要的。这种方法可以全面将三维图像的表现能力提升50%(具体请参照 teapot 的演示)。从版本0.6.3开始,Klimt就实现了顶点缓冲,它实现了可以通过顶点数组传递顶点信息数据,理论上也可以传递定点格式(fixed point format)的顶点数据。
B. 使用带状连续模式绘制三角形(Triangle Strip)
这是一种在顶点数组中可选的方法,带状的图形编排(使用有一定长度的带状)与使用顶点数组有同样的效果。要注意的是在Klimt中,默认带状长度的最大限制是128,如果需要绘制更长的带状,可以修改MAX_PRIMITIVE_LENGTH 这个宏定义的值。这种方法也可以全面将三维图像的表现能力提升50%。从版本0.6.3开始,Klimt就实现了顶点缓冲,它实现了可以通过顶点数组(即使顶点不是带状格式的)传递顶点信息数据。
C. 关闭纹理矩阵的使用
使用Klimt函数klTweak(KL_TEXTUREMATRIX, GL_FALSE); 把你暂时不需要使用的纹理矩阵设置成不活动状态。这样可以提高三角面的产生率。
D. 关闭透视纹理映射
使用glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 关闭透视纹理映射。许多模块譬如字符透视纹理映射是不需要的。Klimt有许多对使用正方形纹理图像的非透视纹理映射的优化。
E. 关闭正规法线
使用函数klTweak(KL_ENABLE_NORMALIZATION, GL_FALSE); ,在你以正规化格式传递法线参数的时候,把正规法线设置成不活动的。这样可以提高三角面的产生率。
F. 使用表面剔除
使用表面剔除可以大概较少一半的绘制的基元(取决于场景的设置)。Klimt保证可以在屏幕的空间里实现表面的剔除,这就是说,在每个三角面被剔除之前,每个三角面已经被变换,省略和投影。因此表面剔除主要是提高像素填充率和减少三角面的设置时间花费,特别是在使用纹理的时候。
G. 使用小尺寸纹理图像
纹理图像的尺寸对缓冲区的使用有直接的影响。大尺寸的纹理图像会减少像素填充率。
H. 使用 MipMaps 纹理
使用MipMaps 纹理可以提高缓存的使用——特别是纹理映射在绘制的多边形比纹理图像的尺寸小的时候。创建MipMaps 纹理最简单的方法是调用klCreateMipMaps();函数,它可以自动为当前活动的纹理创建MipMap。这种方法可以提高像素填充率。
I. 使用全白绘制纹理的多边形,不在绘制顶点前绘制其他颜色
当不使用光照效果绘制多边形时,调用glColor3f(1.0f, 1.0f, 1.0f); 设置顶点颜色为白色。在这种情况下,纹理的变换没有使用顶点的颜色。这样可以提高像素填充率。
J. 使用定点类型(fixed point)API 函数比与之对应的浮点类型的要好
使用在OpenGL|ES中说明的定点(fixed point)函数可以节省数据从浮点型到内部定点类型的转换过程。
K. 使用平值的明暗处理
每次创建场景的时候,使用glShadeModel(GL_FLAT);激活平直明暗。这样可以提高像素填充率。
L. 关闭光照效果
光照效果是一个花费高昂的操作,特别是在多于一个光源被使用的时候。关闭光照效果可以提高三角面的产生率。
M. 关闭z-testing
使用深度缓冲方法glDisable(GL_DEPTH_TEST); 使得场景不依赖于z-testing。这样可以提高像素填充率。
N. 关闭z-writing
无论什么时候,关闭z-writing是一种明智的做法。这样可以提高像素填充率。
O. 当使用基础场景图像API绘制时,激活播放列表(display lists)
加入你使用基础场景图像API,使用播放列表(display lists) 可以获得图形的加速。虽然播放列表只提供自身镜像加速(主要是节省了数据从浮点型到内部定点类型的转换过程),但他们可以通过移除图像部分旋转的需求来加速场景图像基础库。
3.3 嵌入式GUI的优化
在本文前面介绍嵌入式GUI时我们说道,本设计中使用的嵌入式GUI Qt/Embedded结构太庞大,所以就在图形显示效率上有点逊色。所以也会对Klimt的3D图形程序的效率造成一定的影响。因此,为了提高效率,我们可以考虑把Klimt移植到其他的GUI系统,以提高显示效果。Klimt本身支持的GUI也有很多,另外,由于本身高度可移植性的特点,Klimt很容易移植到其他的GUI上,所以,这也是一种很好的优化方法。
 
Copyright (C) duwchy, Please give source when reprint.