鄧卓堯++李學聰



摘 要:隨著移動設備性能的日漸提高,越來越多的三維模型應用出現在移動平臺上。對于一些比較大型的三維模型而言,其解析和繪制是一個較為復雜的過程,現有的算法需要大量的解析運算,效率不高。該文基于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]??偟膩碚f,當前虛擬現實技術的主要研究方向是重偏硬件平臺而輕軟件算法,所以如果能在模型文件的解析速度上取得突破,這對虛擬現實技術的發展和推廣就顯得尤為重要。
該文基于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.