鄧卓堯++李學(xué)聰
摘 要:隨著移動(dòng)設(shè)備性能的日漸提高,越來(lái)越多的三維模型應(yīng)用出現(xiàn)在移動(dòng)平臺(tái)上。對(duì)于一些比較大型的三維模型而言,其解析和繪制是一個(gè)較為復(fù)雜的過(guò)程,現(xiàn)有的算法需要大量的解析運(yùn)算,效率不高。該文基于OBJ文件格式提出了一種分步多線(xiàn)程的模型解析算法,在不影響模型質(zhì)量的前提下大大提高了模型在移動(dòng)設(shè)備上的解析速度。
關(guān)鍵詞:OpenGL ES 移動(dòng)平臺(tái) obj模型 分步多線(xiàn)程 模型解析
中圖分類(lèi)號(hào):TP391.9 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2017)05(a)-0005-03
近年來(lái),隨著VR/AR技術(shù)的大熱,三維模型在移動(dòng)設(shè)備上的應(yīng)用已經(jīng)從簡(jiǎn)單分析顯示模型轉(zhuǎn)到由大量三維模型構(gòu)成的大型集群式三維場(chǎng)景顯示,而這對(duì)嵌入式手持設(shè)備的性能要求也是指數(shù)式增長(zhǎng)的。
根據(jù)“全球VR技術(shù)標(biāo)準(zhǔn)”所明確VR產(chǎn)品三大關(guān)鍵技術(shù)標(biāo)準(zhǔn)——低于20 ms延時(shí)、75 Hz以上屏幕刷新率及1K以上陀螺儀刷新率,各大廠商隨之先后發(fā)布自己研發(fā)的VR設(shè)備,但和理想的體驗(yàn)效果還有一段距離[1]??偟膩?lái)說(shuō),當(dāng)前虛擬現(xiàn)實(shí)技術(shù)的主要研究方向是重偏硬件平臺(tái)而輕軟件算法,所以如果能在模型文件的解析速度上取得突破,這對(duì)虛擬現(xiàn)實(shí)技術(shù)的發(fā)展和推廣就顯得尤為重要。
該文基于OBJ模型文件,根據(jù)其文件結(jié)構(gòu)不對(duì)稱(chēng)性,提出了分步多線(xiàn)程的解析方法,最后在Android設(shè)備上利用OpenGL加以實(shí)現(xiàn),相比于傳統(tǒng)的頂點(diǎn)索引算法解析方法,該文方法的明顯優(yōu)勢(shì)在于:在不犧牲模型質(zhì)量的前提下大幅度地提高了其解析速度,并使在嵌入式手持設(shè)備上加載大型模型文件變得可能。
1 OBJ文件的結(jié)構(gòu)
OBJ文件格式是Alias|Wavefront公司為3D建模而開(kāi)發(fā)的一種文件輸出標(biāo)準(zhǔn)。它以非常簡(jiǎn)單明了的語(yǔ)法定義了對(duì)象的幾何特征和其他屬性,并支持在應(yīng)用程序中讀取或模型的轉(zhuǎn)換[2]。OBJ文件中不同的數(shù)據(jù)類(lèi)型通過(guò)其關(guān)鍵字區(qū)分排列,其主要關(guān)鍵字如表1所示。
2 模型解析繪制的通用方法和其有缺點(diǎn)
在Android系統(tǒng)中顯示OBJ文件格式的3D模型,可以使用OpenGL ES引擎。由于一般來(lái)說(shuō)嵌入式系統(tǒng)的CPU、內(nèi)存等都比PC差,而且對(duì)能耗有著特殊的要求,許多嵌入式設(shè)備并沒(méi)有浮點(diǎn)運(yùn)算協(xié)處理器,所以Khronos針對(duì)嵌入式系統(tǒng)對(duì)標(biāo)準(zhǔn)的OpenGL系統(tǒng)進(jìn)行了維護(hù)和改動(dòng),形成Android OpenGL ES的標(biāo)準(zhǔn)接口來(lái)支持3D圖形功能[3]。
在Android中使用OpenGL顯示3D模型,主要通過(guò)GLSurface View的視圖來(lái)實(shí)現(xiàn),我們通常要在onSurfaceCreated()方法之前完成模型數(shù)據(jù)解析的初始化工作。這里以解析OBJ文件為例,OBJ文件結(jié)構(gòu)的主框架是先存儲(chǔ)頂點(diǎn)數(shù)據(jù),再存儲(chǔ)面數(shù)據(jù)以及一些其他的模型材質(zhì)數(shù)據(jù),面數(shù)據(jù)和材質(zhì)數(shù)據(jù)都是以頂點(diǎn)數(shù)據(jù)的索引為對(duì)象,調(diào)用時(shí)通過(guò)其索引找到相應(yīng)的頂點(diǎn)數(shù)據(jù)再組成模型的各個(gè)面。在使用時(shí),便可通過(guò)頂點(diǎn)索引算法將這些頂點(diǎn)數(shù)據(jù)組成多邊形。
在Android平臺(tái)上使用OpenGL ES實(shí)現(xiàn)3D繪圖,可以通過(guò)構(gòu)建頂點(diǎn)數(shù)組緩沖區(qū)或使用頂點(diǎn)索引算法。
2.1 構(gòu)建頂點(diǎn)數(shù)組緩沖區(qū)
OpenGL ES在三維空間中繪制圖形是通過(guò)一次性繪制空間中的點(diǎn)序列來(lái)實(shí)現(xiàn)的,這些點(diǎn)給稱(chēng)為頂點(diǎn),因此,在Android上可以利用OpenGL ES通過(guò)構(gòu)建頂點(diǎn)數(shù)組緩沖區(qū)繪制3D模型[4]。在空間坐標(biāo)系中,每個(gè)頂點(diǎn)都有對(duì)應(yīng)的X軸、Y軸和Z軸坐標(biāo)。OpenGL ES支持的基本圖像有:點(diǎn)、線(xiàn)和三角形。普遍常用的是繪制三角形,通過(guò)無(wú)數(shù)的特定形狀特定位置的三角形可以組合成各種復(fù)雜的三維模型。
在繪制過(guò)程中,OpenGL ES為Android提供了glVertex Pointer()方法來(lái)構(gòu)建需要繪制的頂點(diǎn)數(shù)據(jù),使用時(shí)將需要繪制的頂點(diǎn)數(shù)據(jù)存儲(chǔ)在本地緩沖區(qū),再以數(shù)組的形式傳入該方法,設(shè)置著色器語(yǔ)言和貼片數(shù)據(jù),最后通過(guò)glDrawArrays()方法實(shí)現(xiàn)基于頂點(diǎn)數(shù)組的3D模型的繪制。
2.2 頂點(diǎn)索引算法
在解析模型的過(guò)程中,一般最常用的就是頂點(diǎn)索引算法。頂點(diǎn)索引算法的基本思想是基于索引查找,在索引表和主表(即線(xiàn)性表的索引存儲(chǔ)結(jié)構(gòu))上進(jìn)行的查找[5]。索引查找的過(guò)程大致為:首先根據(jù)給定的索引值K1,在索引表上查找出索引值等于K1的索引項(xiàng),以確定K1對(duì)應(yīng)的子表在主表中的開(kāi)始位置和長(zhǎng)度,然后再根據(jù)給定的關(guān)鍵字K2,在對(duì)應(yīng)的子表中查找出關(guān)鍵字等于K2的元素(結(jié)點(diǎn))。頂點(diǎn)索引算法的基本實(shí)現(xiàn)是建立兩個(gè)數(shù)組:一個(gè)數(shù)組用于存儲(chǔ)模型中所有的頂點(diǎn)坐標(biāo)值;另一個(gè)數(shù)組則存儲(chǔ)每個(gè)表面所對(duì)應(yīng)的三個(gè)頂點(diǎn)在第一個(gè)數(shù)組紅的索引。其對(duì)應(yīng)關(guān)系如圖1所示。
2.3 兩種繪圖方法的優(yōu)缺點(diǎn)
基于頂點(diǎn)數(shù)組繪制模型時(shí),可以直接使用頂點(diǎn)數(shù)組的本地緩沖區(qū)作為繪圖參數(shù),繪圖過(guò)程的效率較高,但數(shù)據(jù)重復(fù)率高,浪費(fèi)存儲(chǔ)空間,而且模型數(shù)據(jù)解析的過(guò)程較慢。而基于頂點(diǎn)索引算法繪制模型時(shí),可以通過(guò)建立索引表和主表提高數(shù)據(jù)的復(fù)用率,并節(jié)約內(nèi)存空間。但缺點(diǎn)是必須先建立頂點(diǎn)索引表,再分析出頂點(diǎn)數(shù)據(jù)和面法向量數(shù)據(jù)。
上面討論的兩種方法其模型解析過(guò)程都不能直接使用多線(xiàn)程來(lái)進(jìn)行解析,所以一般的應(yīng)用在解析3D模型的時(shí)候都是使用單線(xiàn)程進(jìn)行解析的,大大影響了模型的解析速度,從而降低應(yīng)用的體驗(yàn)效果?;谶@種情況,目前一般的解決方法是提高設(shè)備的硬件性能或控制模型的大小。在PC端上可以通過(guò)提高CUP、內(nèi)存等硬件條件來(lái)提高模型的解析速度,但是在嵌入式手持設(shè)備上這個(gè)缺點(diǎn)仍然非常突出。而隨著VR技術(shù)的日漸完善,使用大型3D模型又是不可阻擋的趨勢(shì)。
3 分步多線(xiàn)程優(yōu)化方案
為了解決這種問(wèn)題,在這里我們提出了分步多線(xiàn)程解析模型文件的應(yīng)用方法。其核心思想是先用主線(xiàn)程處理好文件中必要的前提數(shù)據(jù),其后基于所整理好的前提數(shù)據(jù)用多線(xiàn)程先解析完頂點(diǎn)數(shù)據(jù),再用多線(xiàn)程根據(jù)面數(shù)據(jù)中保存的頂點(diǎn)索引與整理好的頂點(diǎn)數(shù)據(jù)進(jìn)行配對(duì)組建成模型的每一個(gè)面,最終所有的面組成完整的3D模型。將模型文件中的頂點(diǎn)數(shù)據(jù)和面數(shù)據(jù)分別提取出來(lái),程序如下。
ArrayList
ArrayList
String[] objLines = (new String(objBytes)).split(“\n”);
pickOutData(objLines);
在獲得頂點(diǎn)數(shù)據(jù)和面數(shù)據(jù)的列表后,再使用異步多線(xiàn)程處理頂點(diǎn)數(shù)據(jù)和面數(shù)據(jù):
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();
}
});
至此,我們最后通過(guò)handleFaceData()和faceToNormals()方法解析出3D模型的頂點(diǎn)數(shù)據(jù)和面法向量數(shù)據(jù),接下來(lái)只要使用OpenGL提供的方法即可完成模型的顯示。具體的3D模型異步多線(xiàn)程解析過(guò)程如圖2所示。
4 移動(dòng)平臺(tái)下的OpenGL
在此,我們以Android的移動(dòng)平臺(tái)為例,為了在嵌入式系統(tǒng)上實(shí)現(xiàn)全面可編程的3D圖形,Khronos Group制定了一種業(yè)界標(biāo)準(zhǔn)應(yīng)用程序編程接口——OpenGL ES[4]。它由精心定義的桌面OpenGL子集組成,創(chuàng)造了軟件與圖形加速間靈活強(qiáng)大的底層交互接口,保護(hù)了浮點(diǎn)運(yùn)算和定點(diǎn)運(yùn)算系統(tǒng)描述以及EGL針對(duì)便攜設(shè)備的本地視窗系統(tǒng)規(guī)范。Android便是通過(guò)OpenGL ES的支持實(shí)現(xiàn)3D圖形的操作,這里我們使用OpenGL ES 2.0的接口實(shí)現(xiàn)3D模型的顯示。
將通過(guò)分步多線(xiàn)程解析出來(lái)的頂點(diǎn)數(shù)據(jù)數(shù)組vertices和面數(shù)據(jù)的法向量數(shù)組normals導(dǎo)入OpenGL ES的方法中,繪制模型。我們以加載一個(gè)鏤空錐形模型為例,運(yùn)用我們提出的分步多線(xiàn)程O(píng)BJ模型文件解析技術(shù)加載,在不犧牲模型質(zhì)量的前提下大大提高了模型解析速度,其顯示效果如圖3所示。
5 結(jié)語(yǔ)
OBJ文件結(jié)構(gòu)簡(jiǎn)單,語(yǔ)法明了,能有效支持對(duì)模型進(jìn)行二次修改,但缺點(diǎn)是用一般方法解析文本的過(guò)程較慢,不利于在嵌入式手持設(shè)備上的解析和加載。該文提出了一種基于Android移動(dòng)平臺(tái)OBJ格式的3D模型文件解析優(yōu)化的分步多線(xiàn)程解析法,在不影響模型質(zhì)量和穩(wěn)定性的情況下,有效地提高了模型的解析速度。對(duì)VR技術(shù)的發(fā)展以及在嵌入式設(shè)備上的推廣都有著一定的借鑒意義。
當(dāng)然,我們的工作也存在著許多有待完善的方面,諸如嵌入式設(shè)備中的內(nèi)存空間大小也制約了模型文件的大小,對(duì)STL和3DS的模型文件的解析優(yōu)化也有待研究。最后,感謝在編寫(xiě)本文的過(guò)程中給予了幫助的所有人。
參考文獻(xiàn)
[1] 黎明.虛擬現(xiàn)實(shí)VR(Virtrual Reality)現(xiàn)狀和前景[J].藝術(shù)科技,2016(9):103-104.
[2] 馬杰,王晶,黃秋萍.OpenGL ES在Android平臺(tái)上3D繪圖的兩種方式分析與實(shí)現(xiàn)[J].硅谷,2013(12):80-81.
[3] 黃小鳳,宋瑾鈺,俞成海.基于OpenGL ES的移動(dòng)平臺(tái)的三維模型繪制[J].工業(yè)控制計(jì)算機(jī),2013(1):60-62.
[4] 陳密密.基于頂點(diǎn)索引的三維建模與可視化方法研究[J].影像技術(shù),2011(2):7-10.