基于OpenGL的移动设备三维模型解析优化方法
2017-06-21邓卓尧李学聪
邓卓尧++李学聪
摘 要:随着移动设备性能的日渐提高,越来越多的三维模型应用出现在移动平台上。对于一些比较大型的三维模型而言,其解析和绘制是一个较为复杂的过程,现有的算法需要大量的解析运算,效率不高。该文基于OBJ文件格式提出了一种分步多线程的模型解析算法,在不影响模型质量的前提下大大提高了模型在移动设备上的解析速度。
关键词:OpenGL ES 移动平台 obj模型 分步多线程 模型解析
中图分类号:TP391.9 文献标识码:A 文章编号:1672-3791(2017)05(a)-0005-03
近年来,随着VR/AR技术的大热,三维模型在移动设备上的应用已经从简单分析显示模型转到由大量三维模型构成的大型集群式三维场景显示,而这对嵌入式手持设备的性能要求也是指数式增长的。
根据“全球VR技术标准”所明确VR产品三大关键技术标准——低于20 ms延时、75 Hz以上屏幕刷新率及1K以上陀螺仪刷新率,各大厂商随之先后发布自己研发的VR设备,但和理想的体验效果还有一段距离[1]。总的来说,当前虚拟现实技术的主要研究方向是重偏硬件平台而轻软件算法,所以如果能在模型文件的解析速度上取得突破,这对虚拟现实技术的发展和推广就显得尤为重要。
该文基于OBJ模型文件,根据其文件结构不对称性,提出了分步多线程的解析方法,最后在Android设备上利用OpenGL加以实现,相比于传统的顶点索引算法解析方法,该文方法的明显优势在于:在不牺牲模型质量的前提下大幅度地提高了其解析速度,并使在嵌入式手持设备上加载大型模型文件变得可能。
1 OBJ文件的结构
OBJ文件格式是Alias|Wavefront公司为3D建模而开发的一种文件输出标准。它以非常简单明了的语法定义了对象的几何特征和其他属性,并支持在应用程序中读取或模型的转换[2]。OBJ文件中不同的数据类型通过其关键字区分排列,其主要关键字如表1所示。
2 模型解析绘制的通用方法和其有缺点
在Android系统中显示OBJ文件格式的3D模型,可以使用OpenGL ES引擎。由于一般来说嵌入式系统的CPU、内存等都比PC差,而且对能耗有着特殊的要求,许多嵌入式设备并没有浮点运算协处理器,所以Khronos针对嵌入式系统对标准的OpenGL系统进行了维护和改动,形成Android OpenGL ES的标准接口来支持3D图形功能[3]。
在Android中使用OpenGL显示3D模型,主要通过GLSurface View的视图来实现,我们通常要在onSurfaceCreated()方法之前完成模型数据解析的初始化工作。这里以解析OBJ文件为例,OBJ文件结构的主框架是先存储顶点数据,再存储面数据以及一些其他的模型材质数据,面数据和材质数据都是以顶点数据的索引为对象,调用时通过其索引找到相应的顶点数据再组成模型的各个面。在使用时,便可通過顶点索引算法将这些顶点数据组成多边形。
在Android平台上使用OpenGL ES实现3D绘图,可以通过构建顶点数组缓冲区或使用顶点索引算法。
2.1 构建顶点数组缓冲区
OpenGL ES在三维空间中绘制图形是通过一次性绘制空间中的点序列来实现的,这些点给称为顶点,因此,在Android上可以利用OpenGL ES通过构建顶点数组缓冲区绘制3D模型[4]。在空间坐标系中,每个顶点都有对应的X轴、Y轴和Z轴坐标。OpenGL ES支持的基本图像有:点、线和三角形。普遍常用的是绘制三角形,通过无数的特定形状特定位置的三角形可以组合成各种复杂的三维模型。
在绘制过程中,OpenGL ES为Android提供了glVertex Pointer()方法来构建需要绘制的顶点数据,使用时将需要绘制的顶点数据存储在本地缓冲区,再以数组的形式传入该方法,设置着色器语言和贴片数据,最后通过glDrawArrays()方法实现基于顶点数组的3D模型的绘制。
2.2 顶点索引算法
在解析模型的过程中,一般最常用的就是顶点索引算法。顶点索引算法的基本思想是基于索引查找,在索引表和主表(即线性表的索引存储结构)上进行的查找[5]。索引查找的过程大致为:首先根据给定的索引值K1,在索引表上查找出索引值等于K1的索引项,以确定K1对应的子表在主表中的开始位置和长度,然后再根据给定的关键字K2,在对应的子表中查找出关键字等于K2的元素(结点)。顶点索引算法的基本实现是建立两个数组:一个数组用于存储模型中所有的顶点坐标值;另一个数组则存储每个表面所对应的三个顶点在第一个数组红的索引。其对应关系如图1所示。
2.3 两种绘图方法的优缺点
基于顶点数组绘制模型时,可以直接使用顶点数组的本地缓冲区作为绘图参数,绘图过程的效率较高,但数据重复率高,浪费存储空间,而且模型数据解析的过程较慢。而基于顶点索引算法绘制模型时,可以通过建立索引表和主表提高数据的复用率,并节约内存空间。但缺点是必须先建立顶点索引表,再分析出顶点数据和面法向量数据。
上面讨论的两种方法其模型解析过程都不能直接使用多线程来进行解析,所以一般的应用在解析3D模型的时候都是使用单线程进行解析的,大大影响了模型的解析速度,从而降低应用的体验效果。基于这种情况,目前一般的解决方法是提高设备的硬件性能或控制模型的大小。在PC端上可以通过提高CUP、内存等硬件条件来提高模型的解析速度,但是在嵌入式手持设备上这个缺点仍然非常突出。而随着VR技术的日渐完善,使用大型3D模型又是不可阻挡的趋势。
3 分步多线程优化方案
为了解决这种问题,在这里我们提出了分步多线程解析模型文件的应用方法。其核心思想是先用主线程处理好文件中必要的前提数据,其后基于所整理好的前提数据用多线程先解析完顶点数据,再用多线程根据面数据中保存的顶点索引与整理好的顶点数据进行配对组建成模型的每一个面,最终所有的面组成完整的3D模型。将模型文件中的顶点数据和面数据分别提取出来,程序如下。
ArrayList
ArrayList
String[] objLines = (new String(objBytes)).split(“\n”);
pickOutData(objLines);
在获得顶点数据和面数据的列表后,再使用异步多线程处理顶点数据和面数据:
Thread VerticesThread = new Thread(new Runnable() {
ArrayList
@Override
public void run() {
handleVerticesData(alv);
}
});
Thread faceThread = new Thread(new Runnable() {
@Override
public void run() {
handleFaceData();
faceToNormals();
}
});
至此,我们最后通过handleFaceData()和faceToNormals()方法解析出3D模型的顶点数据和面法向量数据,接下来只要使用OpenGL提供的方法即可完成模型的显示。具体的3D模型异步多线程解析过程如图2所示。
4 移动平台下的OpenGL
在此,我们以Android的移动平台为例,为了在嵌入式系统上实现全面可编程的3D图形,Khronos Group制定了一种业界标准应用程序编程接口——OpenGL ES[4]。它由精心定义的桌面OpenGL子集组成,创造了软件与图形加速间灵活强大的底层交互接口,保护了浮点运算和定点运算系统描述以及EGL针对便携设备的本地视窗系统规范。Android便是通过OpenGL ES的支持实现3D图形的操作,这里我们使用OpenGL ES 2.0的接口实现3D模型的显示。
将通过分步多线程解析出来的顶点数据数组vertices和面数据的法向量数组normals导入OpenGL ES的方法中,绘制模型。我们以加载一个镂空锥形模型为例,运用我们提出的分步多线程OBJ模型文件解析技术加载,在不牺牲模型质量的前提下大大提高了模型解析速度,其显示效果如图3所示。
5 结语
OBJ文件结构简单,语法明了,能有效支持对模型进行二次修改,但缺点是用一般方法解析文本的过程较慢,不利于在嵌入式手持设备上的解析和加载。该文提出了一种基于Android移动平台OBJ格式的3D模型文件解析优化的分步多线程解析法,在不影响模型质量和稳定性的情况下,有效地提高了模型的解析速度。对VR技术的发展以及在嵌入式设备上的推广都有着一定的借鉴意义。
当然,我们的工作也存在着许多有待完善的方面,诸如嵌入式设备中的内存空间大小也制约了模型文件的大小,对STL和3DS的模型文件的解析优化也有待研究。最后,感谢在编写本文的过程中给予了帮助的所有人。
参考文献
[1] 黎明.虛拟现实VR(Virtrual Reality)现状和前景[J].艺术科技,2016(9):103-104.
[2] 马杰,王晶,黄秋萍.OpenGL ES在Android平台上3D绘图的两种方式分析与实现[J].硅谷,2013(12):80-81.
[3] 黄小凤,宋瑾钰,俞成海.基于OpenGL ES的移动平台的三维模型绘制[J].工业控制计算机,2013(1):60-62.
[4] 陈密密.基于顶点索引的三维建模与可视化方法研究[J].影像技术,2011(2):7-10.