国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

OpenGL顯示3DS模型若干問題的研究

2010-07-07 06:52:36胡平平劉建明王晶杰
圖學(xué)學(xué)報 2010年4期
關(guān)鍵詞:關(guān)鍵幀頂點(diǎn)紋理

胡平平, 劉建明, 王晶杰

(1. 北京信息科技大學(xué),北京 100192;2. 國網(wǎng)信息通信有限公司,北京 100761)

OpenGL是一個著名的開放式三維圖形開發(fā)函數(shù)庫,它提供的函數(shù)不僅可以創(chuàng)建基本的 3D物體原形還能夠很方便地對 3D物體進(jìn)行各種操作和變換,得到逼真的 3D顯示效果,這使它成為一個非常流行的 3D圖形瀏覽開發(fā)工具。但OpenGL卻不適于創(chuàng)建復(fù)雜的不規(guī)則 3D物體。3DS是Autodesk公司存儲3D模型數(shù)據(jù)的一種文件格式,許多流行的 3D建模軟件和圖形格式轉(zhuǎn)換工具都能夠生成 3D模型的 3DS文件,將OpenGL技術(shù)和3DS模型數(shù)據(jù)結(jié)合實(shí)現(xiàn)對3D物體的瀏覽便成為一種廣泛使用的方法。

由于3DS文件的數(shù)據(jù)格式?jīng)]有官方的正式說明文檔,盡管很多文獻(xiàn)[1-3]對用OpenGL讀取、顯示和控制3DS模型數(shù)據(jù)的方法進(jìn)行了介紹,但都側(cè)重于OpenGL編程實(shí)現(xiàn)方法,只涉及了基本的靜態(tài)3DS模型數(shù)據(jù)的使用。各種資源上能夠得到的讀取3DS數(shù)據(jù)的方法基本上一樣,都沒有對動態(tài)數(shù)據(jù)進(jìn)行處理,也沒有考慮數(shù)據(jù)轉(zhuǎn)換的性能。用這些方法顯示含動畫信息的3DS模型時會出現(xiàn)物體位置錯位的現(xiàn)象,即使是靜態(tài)數(shù)據(jù),當(dāng)模型復(fù)雜且數(shù)據(jù)量較大時,其處理速度常常慢到不能實(shí)用的地步。

本文從OpenGL顯示3D模型的數(shù)據(jù)處理過程出發(fā),結(jié)合3DS文件數(shù)據(jù)的組織結(jié)構(gòu),扼要介紹了如何由3DS文件構(gòu)造OpenGL顯示數(shù)據(jù)的方法。重點(diǎn)討論了法線向量在OpenGL顯示中的兩種應(yīng)用效果和由3DS數(shù)據(jù)生成法線向量的方法,給出了一種高效的法線向量求解算法,該算法的速度比現(xiàn)有方法快一至兩個數(shù)量級,極大地提高了數(shù)據(jù)轉(zhuǎn)換的性能。本文還介紹了3DS模型中和動畫有關(guān)的關(guān)鍵幀數(shù)據(jù)的使用方法,解決了現(xiàn)有方法在顯示帶動畫信息的3DS模型時物體位置不正確的問題。

1 OpenGL和3DS數(shù)據(jù)的關(guān)系

1.1 OpenGL的數(shù)據(jù)處理過程

OpenGL顯示三維物體的一般過程是:保存當(dāng)前變換矩陣、設(shè)置新的視景體和新的變換矩陣、設(shè)置每一個三維物體的數(shù)據(jù)、恢復(fù)當(dāng)前變換矩陣。設(shè)置三維物體數(shù)據(jù)的過程是由一系列嵌入在glBegin()和glEnd()調(diào)用之間的OpenGL函數(shù)調(diào)用構(gòu)成的,其過程如下所示:

對每一個三維物體:

若該物體沒有紋理或各面有相同紋理映射則glBegin();

對物體的每一個面:

若該面有紋理映射則設(shè)置紋理;

若該物體不同面有不同的紋理則glBegin();

設(shè)置以面為單位的面法線向量;

設(shè)置紋理或材質(zhì)的顏色;

對每一個面的所有頂點(diǎn):

設(shè)置以頂點(diǎn)為單位的頂點(diǎn)法線向量;

若該面有紋理則設(shè)置頂點(diǎn)的紋理坐標(biāo);

設(shè)置頂點(diǎn)坐標(biāo);

若該物體不同面有不同的紋理則glEnd();

若該物體沒有紋理或各面有相同紋理映射glEnd();

在上面的過程中,以面為單位的法線向量設(shè)置和以頂點(diǎn)為單位的法線向量設(shè)置是兩種不同的方式,下文將詳細(xì)介紹。如果物體沒有紋理映射或各面的紋理映射相同,則 glBegin()和 glEnd()以物體為單位,否則應(yīng)該以每一個面為單位,這樣不同的面才能顯示不同的紋理。

1.2 3DS文件數(shù)據(jù)的組織結(jié)構(gòu)

關(guān)于3DS文件的格式,文獻(xiàn)[4]和文獻(xiàn)[5]有較詳細(xì)的介紹,此處僅列出和OpenGL顯示數(shù)據(jù)有關(guān)部分的組織結(jié)構(gòu):

3DS文件數(shù)據(jù):

文件版本數(shù)據(jù)(ID=0x0002);

編輯數(shù)據(jù)(ID=0x3D3D):

. 材質(zhì)數(shù)據(jù)(ID=0xAFFF);

. . 材質(zhì)名稱數(shù)據(jù)(ID=0xAFFF);

. . 材質(zhì)顏色數(shù)據(jù)(ID=0xA010/20/30);

. . 材質(zhì)紋理數(shù)據(jù)(ID=0xA300);

. 物體數(shù)據(jù)(ID=0x4000):

. 物體名稱數(shù)據(jù);

. 物體頂點(diǎn)數(shù)據(jù)(ID=0x4110);

. 物體面數(shù)據(jù)(ID=0x4120);

. . 面材質(zhì)數(shù)據(jù)(ID=0x4130);

. . 面材質(zhì)名稱;

. . 同材質(zhì)面索引數(shù)據(jù);

. 物體轉(zhuǎn)換矩陣數(shù)據(jù)(ID=0x4160);

關(guān)鍵幀數(shù)據(jù)(ID=0xB000):

關(guān)鍵幀名稱(ID=0xB00A);

關(guān)鍵幀起止幀數(shù)據(jù)(ID=0xB008);

物體關(guān)鍵幀數(shù)據(jù)(ID=0xB002);

物體關(guān)鍵幀標(biāo)識數(shù)據(jù)(ID=0xB030);

物體關(guān)鍵幀名稱和層次數(shù)據(jù)

(ID=0xB010/11);

物體關(guān)鍵幀支點(diǎn)坐標(biāo)數(shù)據(jù)(ID=0xB013);

物體關(guān)鍵幀移動數(shù)據(jù)(ID=0xB020);

物體關(guān)鍵幀轉(zhuǎn)動數(shù)據(jù)(ID=0xB021);

物體關(guān)鍵幀縮放數(shù)據(jù)(ID=0xB022);

1.3 OpenGL顯示數(shù)據(jù)和3DS數(shù)據(jù)的關(guān)系

從上面的介紹可知,OpenGL顯示處理是以物體為單位進(jìn)行的,3DS的數(shù)據(jù)則按照類型組織,對應(yīng)于OpenGL中同一個物體的數(shù)據(jù)要從3DS文件中不同類型的數(shù)據(jù)獲得,具體方法是:

物體的頂點(diǎn)和面數(shù)據(jù):直接來自3DS的物體頂點(diǎn)數(shù)據(jù)(x,y,z坐標(biāo)值)和物體面數(shù)據(jù)(該面所用頂點(diǎn)的索引號和方向)。

物體的材質(zhì)數(shù)據(jù):由3DS物體面數(shù)據(jù)的面材質(zhì)名稱數(shù)據(jù)得到材質(zhì)名稱,再由該材質(zhì)名稱到3DS材質(zhì)數(shù)據(jù)中找到對應(yīng)的材質(zhì)顏色和紋理數(shù)據(jù)。而物體面數(shù)據(jù)的同材質(zhì)面索引數(shù)據(jù)則指出哪些面使用這個材質(zhì)。

物體的位置數(shù)據(jù):該數(shù)據(jù)由物體頂點(diǎn)數(shù)據(jù)、物體轉(zhuǎn)換矩陣數(shù)據(jù)和關(guān)鍵幀數(shù)據(jù)共同決定,前兩種數(shù)據(jù)從物體數(shù)據(jù)中直接得到,后一個則來自物體對應(yīng)的關(guān)鍵幀數(shù)據(jù)。具體生成方法,在本文后面介紹。

物體的法線向量數(shù)據(jù):由上述得到的物體頂點(diǎn)和面數(shù)據(jù)通過計(jì)算得到,具體方法見下文。

2 OpenGL中法線向量的作用和求解方法

2.1 法向量的作用和效果

OpenGL顯示三維物體時,需要為每一個頂點(diǎn)設(shè)置法線向量,法線向量不僅為OpenGL光照處理確定每一個面的正反提供依據(jù),而且還影響到物體的顯示效果[6-7]。OpenGL法向量的設(shè)置有兩種方法:以面為單位和以頂點(diǎn)為單位,前一種方法每個面的所有頂點(diǎn)使用相同的法向量,后一種方法每個面的不同頂點(diǎn)有不同的法向量(又稱平均法向量)。圖1和圖2是同一個3D模型用兩種法向量設(shè)置方法的顯示效果圖。

從上面的效果圖可以看出,以頂點(diǎn)為單位的法向量方法顯示的物體比較平滑,這也是OpenGL顯示3DS模型時最常用的方法。

圖1 法向量以面為單位的顯示效果

圖2 法向量以頂點(diǎn)為單位的顯示效果

2.2 現(xiàn)有的法向量求解方法

3DS模型并沒有直接提供OpenGL顯示用的法向量數(shù)據(jù),這些數(shù)據(jù)要從3DS模型的面數(shù)據(jù)中求解得到。3DS模型的面是由3個頂點(diǎn)和一個方向碼構(gòu)成的三角面片,讀入3DS模型的面數(shù)據(jù)后,首先要統(tǒng)一各個面的方向(必要時要根據(jù)方向碼調(diào)整3個頂點(diǎn)的順序),然后按特點(diǎn)順序由三角形的兩個邊向量的叉積求出該三角形的法向量。如果采用以面為單位的法向量方法,則構(gòu)成三角形的3個頂點(diǎn)的法向量就是該三角形的法向量;如果采用以頂點(diǎn)為單位的法向量方法,由于同一個頂點(diǎn)可能為不同的三角形共用,此時一個頂點(diǎn)的法向量就是使用該頂點(diǎn)的所有三角形法向量的平均向量?,F(xiàn)有的頂點(diǎn)法向量求解方法如下所示:

對每一個三維物體:

對物體的每一個面:

計(jì)算該面的法向量并歸一化;

對物體的每一個頂點(diǎn):

在物體所有面中尋找用到該頂點(diǎn)的面并將該面的法向量疊加;

疊加法向量平均并歸一化后作為該頂點(diǎn)的法向量;

該方法在求某一個頂點(diǎn)的法向量時,要遍歷物體所有面的3個頂點(diǎn),其運(yùn)算量是:頂點(diǎn)數(shù)量X面數(shù)量X3,由于是先求出所有面的法向量然后再使用,因此,計(jì)算過程中還要為每一個面設(shè)置一個法向量存儲空間。

2.3 改進(jìn)的法向量求解方法

3D物體模型中,一個頂點(diǎn)可能被多個面使用,但用到某一個頂點(diǎn)的面占全部面的比例往往很小。一般情況下,簡單模型的比例最大約10%,復(fù)雜大型模型的比例最大約1%,可見現(xiàn)有算法為求某一個頂點(diǎn)的法向量而遍歷所有面的處理大部分是不必要的。鑒于此,可以對頂點(diǎn)法向量的求解方法改進(jìn)為如下所示:

對每一個三維物體:

將該物體所有頂點(diǎn)的法向量設(shè)置為0;

對物體的每一個面:

計(jì)算該面的法向量;

將該面的法向量疊加到該面 3個頂點(diǎn)的法向量中;

對物體的每一個頂點(diǎn):

將頂點(diǎn)的法向量除以其疊加次數(shù)并歸一化;

上述新方法在求頂點(diǎn)的法向量時避免了對不使用該頂點(diǎn)的面的判斷處理,且新方法不用為每一個面設(shè)置一個法向量存儲空間,只需為每一個頂點(diǎn)設(shè)置一個疊加計(jì)數(shù)器變量,由于計(jì)數(shù)器變量所使用的空間只是法向量的1/6〔計(jì)數(shù)器為兩字節(jié)整數(shù),法向量為3個浮點(diǎn)數(shù),用12字節(jié)〕,而頂點(diǎn)的數(shù)量最多是面數(shù)量的3倍,故新方法使用的變量空間最多是現(xiàn)有方法的1/2。

2.4 兩種法向量求解方法的比較

新頂點(diǎn)法向量的求解方法在使用變量空間上至少節(jié)省一半,而計(jì)算量的節(jié)省情況則和 3D模型的具體情況有關(guān)。只有當(dāng)使用每一個頂點(diǎn)的面的數(shù)量和面的總數(shù)量相等時,現(xiàn)有算法才不存在無用的處理,此時兩種算法的處理量幾乎相等,但該情況意味著每一個頂點(diǎn)被所有的面共用,這是不可能存在的,因此新算法的處理量總是小于現(xiàn)有方法。

表1是兩種處理方法對幾種典型模型的實(shí)際處理時間對比,可以看出,模型的數(shù)據(jù)量越大,尤其是頂點(diǎn)被共用的面的數(shù)量相對于面的總數(shù)量越小,新方法的改進(jìn)效果就越明顯。對于一般模型數(shù)據(jù),新方法的速度平均是現(xiàn)有方法的幾倍至幾十倍,而對大型模型,速度提高的效果非常明顯,約為幾百倍。

表1 兩種法向量求解方法的計(jì)算時間比較

3 3DS模型關(guān)鍵幀數(shù)據(jù)的使用方法

不帶動畫信息的3DS模型中各物體的頂點(diǎn)數(shù)據(jù)可以直接作為這些物體的實(shí)際位置坐標(biāo)數(shù)據(jù),但當(dāng)3DS模型帶動畫信息時,模型中各物體的實(shí)際位置一般由頂點(diǎn)數(shù)據(jù)和關(guān)鍵幀數(shù)據(jù)共同決定,如果僅按頂點(diǎn)數(shù)據(jù)顯示物體,則模型中的物體可能會顯示在錯誤的位置上。

3DS模型中每一個物體的關(guān)鍵幀信息由物體的名稱或關(guān)鍵幀的層次結(jié)構(gòu)決定。關(guān)鍵幀的層次關(guān)系是一個樹狀結(jié)構(gòu),當(dāng)某一個物體是根節(jié)點(diǎn)或根節(jié)點(diǎn)的葉節(jié)點(diǎn)時,其位置信息僅由它自己的關(guān)鍵幀數(shù)據(jù)決定;否則該物體的位置信息要由它自己的關(guān)鍵幀數(shù)據(jù)和它所有父節(jié)點(diǎn)的關(guān)鍵幀數(shù)據(jù)共同決定。

3DS模型中各種關(guān)鍵幀數(shù)據(jù)塊的結(jié)構(gòu)在文獻(xiàn)[4]和文獻(xiàn)[5]中有一定的介紹,但這些數(shù)據(jù)的具體含義和使用方法都沒有介紹。下面僅對與物體位置有關(guān)的關(guān)鍵幀數(shù)據(jù)含義和使用方法做一個簡單介紹,至于如何利用關(guān)鍵幀數(shù)據(jù)在OpenGL環(huán)境中顯示可以運(yùn)動的3DS模型,由于篇幅所限,此處不做介紹。

3.1 物體關(guān)鍵幀數(shù)據(jù)的確定方法

3DS模型中每一個關(guān)鍵幀數(shù)據(jù)都有自己的名稱,該名稱在名稱層次塊(0xB010)中,如果其中的名稱不是“DUMMY”,則該關(guān)鍵幀數(shù)據(jù)就屬于名稱與之匹配的物體,否則,該關(guān)鍵幀數(shù)據(jù)屬于一個虛物體,該物體是一個父節(jié)點(diǎn),它的實(shí)際名稱在后面的虛名稱塊(0xB011)中,而該父節(jié)點(diǎn)的關(guān)鍵幀數(shù)據(jù)為其所有子節(jié)點(diǎn)共用,它所含子節(jié)點(diǎn)的關(guān)鍵幀數(shù)據(jù)位于其后,由子節(jié)點(diǎn)關(guān)鍵幀數(shù)據(jù)的層次號決定。

在關(guān)鍵幀數(shù)據(jù)中,每一個物體的關(guān)鍵幀數(shù)據(jù)(0xB002)都有一個位于名稱層次塊(0xB010)中的層次號,層次號是由該關(guān)鍵幀的層次關(guān)系和它在關(guān)鍵幀數(shù)據(jù)中出現(xiàn)的位置決定的,其編排方法是:根關(guān)鍵幀的層次號為-1,其它關(guān)鍵幀的層次號由0開始遞增或保持不變。層次號保持不變,說明這些關(guān)鍵幀屬于同一個層次;層次號增加則表示該關(guān)鍵幀是上一個節(jié)點(diǎn)的子節(jié)點(diǎn);層次號減小,則說明該關(guān)鍵幀是一個新的父節(jié)點(diǎn),該節(jié)點(diǎn)的層次同前面與之層次號相同的節(jié)點(diǎn)一樣,每一個父節(jié)點(diǎn)之后新子節(jié)點(diǎn)關(guān)鍵幀的層次號就是該關(guān)鍵幀數(shù)據(jù)出現(xiàn)的實(shí)際位置的順序號(新子節(jié)點(diǎn)關(guān)鍵幀的層次號一定是一個沒有出現(xiàn)過的值)。以后各關(guān)鍵幀的層次號依上述規(guī)律編排,直到所有的關(guān)鍵幀數(shù)據(jù)編排完畢。

3.2 物體位置和關(guān)鍵幀數(shù)據(jù)的關(guān)系

3DS模型中物體的位置由以下數(shù)據(jù)決定:物體的頂點(diǎn)坐標(biāo)數(shù)據(jù)(0x4110)、轉(zhuǎn)換矩陣數(shù)據(jù)(0x4160)中的源點(diǎn)坐標(biāo)和物體關(guān)鍵幀數(shù)據(jù)中的支點(diǎn)坐標(biāo)數(shù)據(jù)(0xB013)、移動數(shù)據(jù)(0xB020)、旋轉(zhuǎn)數(shù)據(jù)(0xB021)及縮放數(shù)據(jù)(ID=0xB022)。

3DS模型中不帶動畫信息的物體也有一幀關(guān)鍵幀數(shù)據(jù),只不過其關(guān)鍵幀數(shù)據(jù)的支點(diǎn)坐標(biāo)和旋轉(zhuǎn)關(guān)鍵幀數(shù)據(jù)都是0,縮放數(shù)據(jù)是1。帶動畫信息的物體則按它具有關(guān)鍵幀的多少帶有指定數(shù)量的關(guān)鍵幀數(shù)據(jù)。物體轉(zhuǎn)換矩陣數(shù)據(jù)中的源點(diǎn)坐標(biāo)表示該物體當(dāng)前位置和它被創(chuàng)建時原始位置的位移,該數(shù)據(jù)和物體關(guān)鍵幀數(shù)據(jù)第0幀的移動數(shù)據(jù)相同。物體的頂點(diǎn)坐標(biāo)實(shí)際上就是由物體被創(chuàng)建時的初始位置和大小按照其第0幀關(guān)鍵幀數(shù)據(jù)做變換(平移、旋轉(zhuǎn)和縮放)生成的。而物體關(guān)鍵幀數(shù)據(jù)中的支點(diǎn)坐標(biāo)則是頂點(diǎn)坐標(biāo)表示的位置到當(dāng)前位置的平移量,因此,為了顯示物體正確的當(dāng)前位置,應(yīng)該將物體的頂點(diǎn)坐標(biāo)進(jìn)行調(diào)整,方法是:將物體各頂點(diǎn)坐標(biāo)減去其關(guān)鍵幀數(shù)據(jù)的支點(diǎn)坐標(biāo)。

4 結(jié) 論

本文給出的由3DS模型數(shù)據(jù)求解頂點(diǎn)法向量的新方法和關(guān)鍵幀數(shù)據(jù)的使用均成功地應(yīng)用到作者開發(fā)的多屏同步 3D顯示系統(tǒng)中,不僅實(shí)現(xiàn)了大型3DS模型的快速裝入和帶動畫信息的3DS模型物體位置的正確顯示,還實(shí)現(xiàn)了帶動畫信息的3DS模型物體的運(yùn)動顯示,效果良好。

[1]趙文廣, 李仲學(xué), 李翠平. 面向工程可視化仿真的VC++, OpenGL與3DS集成技術(shù)[J]. 北京科技大學(xué)學(xué)報, 2001, 23(6): 563-565.

[2]殷素峰, 高雪強(qiáng), 楊勝強(qiáng). 在 OpenGL環(huán)境下開發(fā)3DS文件瀏覽器[J]. 工程圖學(xué)學(xué)報, 2005, 26(6):22-25.

[3]尹士偉, 張光年, 郭新宇. 一種控制3DS模型的新方法的研究與實(shí)現(xiàn)[J]. 微計(jì)算機(jī)信息, 2007, 23(3-2):307-308.

[4]Martin van Velsen.3D-Studio File Format(.3ds) [EB/OL].http://www.the-labs.com/Blender/3dsspec.html,1998.10.5.

[5]Jeff Lewis.The Unofficial 3DStudio 3DS File Format[EB/OL].http://www.the-labs.com/Blender/3DS-details.html,1998.10.5.

[6]喬 林, 費(fèi)廣正, 林 杜, 等. OpenGL程序設(shè)計(jì)[M].北京: 清華大學(xué)出版社, 2000. 194-202.

[7][美]Dave Shrieiner, Mason Woo等. OpenGL編程指南(第 4版)[M]. 鄧鄭祥譯.北京:人民郵電出版社,2005. 44-45.

猜你喜歡
關(guān)鍵幀頂點(diǎn)紋理
過非等腰銳角三角形頂點(diǎn)和垂心的圓的性質(zhì)及應(yīng)用(下)
基于BM3D的復(fù)雜紋理區(qū)域圖像去噪
軟件(2020年3期)2020-04-20 01:45:18
使用紋理疊加添加藝術(shù)畫特效
關(guān)于頂點(diǎn)染色的一個猜想
基于改進(jìn)關(guān)鍵幀選擇的RGB-D SLAM算法
TEXTURE ON TEXTURE質(zhì)地上的紋理
Coco薇(2017年8期)2017-08-03 15:23:38
基于相關(guān)系數(shù)的道路監(jiān)控視頻關(guān)鍵幀提取算法
消除凹凸紋理有妙招!
Coco薇(2015年5期)2016-03-29 23:22:15
基于聚散熵及運(yùn)動目標(biāo)檢測的監(jiān)控視頻關(guān)鍵幀提取
論“關(guān)鍵幀”在動畫制作中的作用
武义县| 新巴尔虎左旗| 紫云| 皮山县| 巴林左旗| 鄂伦春自治旗| 溧阳市| 游戏| 甘洛县| 含山县| 馆陶县| 大余县| 江孜县| 杨浦区| 双峰县| 谢通门县| 交口县| 七台河市| 闽清县| 宜黄县| 宜都市| 安仁县| 乐安县| 民权县| 嘉定区| 元氏县| 腾冲县| 灵宝市| 图们市| 应城市| 宁化县| 临漳县| 湘乡市| 彩票| 冷水江市| 黑龙江省| 大英县| 大渡口区| 东丽区| 丽水市| 林州市|