高海芳,王天雷,邱杰,康獻(xiàn)民,4,王大承,4
?
基于OpenGL的3DS模型的導(dǎo)入與控制
高海芳1,王天雷2,邱杰3,康獻(xiàn)民1,4,王大承1,4
(1. 五邑大學(xué) 機(jī)電工程學(xué)院,廣東 江門 529020;2. 五邑大學(xué) 信息工程學(xué)院,廣東 江門 529020;3. 國(guó)家摩托車及配件質(zhì)量監(jiān)督檢驗(yàn)中心,廣東 江門 529000;4. 五邑大學(xué) 摩托車研究院,廣東 江門 529020)
研究了在VC++6.0環(huán)境下利用OpenGL導(dǎo)入3DS模型的兩種方法,并給出了具體實(shí)現(xiàn)過(guò)程和技術(shù)要點(diǎn),兩種導(dǎo)入方法比較結(jié)果說(shuō)明:讀入3DS文件類的方法優(yōu)于文件轉(zhuǎn)換法,導(dǎo)入的模型圖的失真度很小,并可方便實(shí)現(xiàn)平移、旋轉(zhuǎn)、縮放、拾取等人機(jī)交互控制.
OpenGL;3DS模型;人機(jī)交互
OpenGL是SGI公司開發(fā)的一套高性能的圖形處理系統(tǒng),是圖形硬件的軟件界面[1]. 通過(guò)OpenGL,程序員可以創(chuàng)建人機(jī)交互的應(yīng)用程序,實(shí)現(xiàn)具有逼真效果的三維圖形圖像,但是利用OpenGL繪制復(fù)雜的三維模型的工作量和難度較大;而利用3DS MAX可靈活繪制復(fù)雜的三維模型及動(dòng)畫,但不能實(shí)現(xiàn)人機(jī)交互;因此,越來(lái)越多的圖形、圖像制作者選擇利用OpenGL與3DS MAX的優(yōu)勢(shì),即使用3DS MAX對(duì)復(fù)雜模型建模,再將它導(dǎo)入OpenGL中編程,實(shí)現(xiàn)交互式的動(dòng)畫.
3DS模型文件由許多Chunk組成,每個(gè)Chunk包括一個(gè)頭和一個(gè)主體,Chunk是相互嵌套的,這就決定了必須以遞歸的方式讀取它們. Chunk的頭又由2部分組成:ID是一個(gè)整型數(shù),表示Chunk的含義;Chunk的長(zhǎng)度是一個(gè)長(zhǎng)整型數(shù)(以字節(jié)為單位,包括頭),包含了下一個(gè)Chunk的相對(duì)位置信息[2-3]. 3DS模型文件中有一個(gè)基本Chunk,其ID是4D4D,基本Chunk又稱為主Chunk,主Chunk包括3D編輯器Chunk和關(guān)鍵幀Chunk. 3DS模型文件中3個(gè)主要的Chunk ID信息見表1.
表1 3DS模型文件中的3個(gè)主要的Chunk ID信息
文件轉(zhuǎn)換是指直接采用VIEW3DS等軟件將3DS文件轉(zhuǎn)換為OpenGL所需要的C文件. 具體實(shí)現(xiàn)過(guò)程如下:1)將VIEW3DS軟件在開始菜單的運(yùn)行程序中運(yùn)行;2)將需要轉(zhuǎn)換的3DS文件拖入即可得到一個(gè)后綴名為.h和.gl的文件;3)將這2個(gè)文件拷貝到已編好的OpenGL框架程序中,并在工程菜單中加入這2個(gè)文件;4)在視類的執(zhí)行文件中添加該頭文件,如#include "BASE.h",并添加成員變量int Model,在初始化函數(shù)中添加代碼:Model =GL3DS_initialize_BASE(),在繪制場(chǎng)景函數(shù)中添加代碼:glCallList(Model1),編譯運(yùn)行程序即可得到圖1所示的模型圖.該方法使用簡(jiǎn)單,但模型在導(dǎo)入過(guò)程中丟失了部分材質(zhì)及紋理,有明顯的失真;由于模型以一個(gè)數(shù)據(jù)文件存放,也不便于控制.
圖1 文件轉(zhuǎn)換法導(dǎo)入的模型圖
由于3DS模型文件中的編輯Chunk、顏色Chunk、材質(zhì)Chunk、紋理Chunk最重要,對(duì)3DS模型起關(guān)鍵性的作用,因此建立讀入3DS文件的類就是怎樣讀入這些關(guān)鍵的Chunk. 在VC++6.0的MFC框架中定義一個(gè)名為3DSload的類,用于3DS文件的讀入與重繪,該類中主要定義了幾個(gè)結(jié)構(gòu)體及主要函數(shù).
1)主要結(jié)構(gòu)體:
a. 顏色結(jié)構(gòu)體
typedef struct {
GLfloat red; 顏色的紅色分量
GLfloat green; 顏色的綠色分量
GLfloat blue; 顏色的藍(lán)色分量
GLfloat alpha;
}OUTGL_RGB;
b. 頂點(diǎn)結(jié)構(gòu)
typedef struct {
GLfloat u,v; 紋理坐標(biāo)
GLfloat nx,ny,nz; 法向量
GLfloat x,y,z; 坐標(biāo)值
}OUTGL_VERTEX;
c. 對(duì)象結(jié)構(gòu)體M3DSObject用于存取讀入的內(nèi)容
typedef struct{
GLuint NumVertex;
OUTGL_VERTEX *VertexLists;
GLuint NumPolygon;
GLuint strip;
POLYGONLIST *PolygonLists;
}M3DSObject;
2)主要函數(shù):
M3DSObject* Load3DSObject(char *filename); 讀取3DS文件函數(shù)
void Draw3DSObject(M3DSObject *object);3DS模型重繪函數(shù)
void Unitize3DSObject(M3DSObject *object);3DS模型歸一化函數(shù)將3DS模型歸一化,即將模型平移到原點(diǎn),并縮放到每個(gè)坐標(biāo)均在[-1,1]的立方體中.
3DSload類編寫完成后即可按下面的步驟導(dǎo)入3DS模型:
1)在MFC的文檔類中添加成員變量M3DSObject *m_Real3DS1用于存取導(dǎo)入的模型.
2)添加OnOpenDocument的消息響應(yīng)函數(shù). 為了能夠?qū)攵鄠€(gè)模型并便于控制,采用顯示列表的方法加載模型. 在OnOpenDocument的消息響應(yīng)函數(shù)中添加源程序:
BOOL CRead3DSDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
glNewList(1,GL_COMPILE);創(chuàng)建顯示列表
m_Real3DS1=Load3DSObject("BASE.3DS");導(dǎo)入第一個(gè)名為BASE.3DS的模型
Draw3DSObject(m_Real3DS1);調(diào)用3DSload類的成員函數(shù)重繪3DS模型
glEndList();
...
glNewList(7,GL_COMPILE);
m_Real3DS2=Load3DSObject("6.3DS");
Draw3DSObject(m_Real3DS2);
glEndList();
}
3)在視圖類中添加成員函數(shù)DrawWithOpenGL()重繪導(dǎo)入模型.
4)在視圖類中響應(yīng)OnPaint()函數(shù),并在該函數(shù)下調(diào)用DrawWithOpenGL()函數(shù)顯示3DS模型.
編譯運(yùn)行程序即可得到如圖2所示的 6軸機(jī)器人模型. 由圖2可知:由于采用創(chuàng)建顯示列表的方法分別導(dǎo)入機(jī)器人的各個(gè)關(guān)節(jié),容易對(duì)每個(gè)關(guān)節(jié)實(shí)施控制,所以導(dǎo)入的機(jī)器人模型不存在失真. 但是該方法操作比較復(fù)雜,要求編程者對(duì)3DS模型結(jié)構(gòu)有較好的了解,并且有一定的VC++基礎(chǔ).
圖2 3DS文件類讀入方法導(dǎo)入的 6軸機(jī)器人模型圖
由3DS文件類的讀入方法導(dǎo)入的3DS模型能很容易地實(shí)現(xiàn)平移、旋轉(zhuǎn)、縮放和拾取等人機(jī)交互控制.
模型圖平移采用函數(shù)glTranslatef(m_xTranslation, m_yTranslation, m_zTranslation)實(shí)現(xiàn),其中3個(gè)參數(shù)對(duì)應(yīng)3個(gè)坐標(biāo)軸. 模型圖旋轉(zhuǎn)采用函數(shù)glRotatef(m_Rotation,x,y,z),其中m_Rotation表示旋轉(zhuǎn)角度,、、的取值為0或1[4],取1表示該軸即為旋轉(zhuǎn)軸. 例如:glRotatef(30.0f,1.0f,0.0f,0.0f)表示繞軸旋轉(zhuǎn)30o. 通過(guò)平移與旋轉(zhuǎn)可對(duì)圖2中機(jī)器人模型的各個(gè)關(guān)節(jié)進(jìn)行控制,實(shí)現(xiàn)如圖3所示的效果. 為實(shí)現(xiàn)實(shí)時(shí)控制,采用鼠標(biāo)右鍵與Ctrl鍵組合實(shí)現(xiàn)旋轉(zhuǎn)控制,鼠標(biāo)右鍵與Shif鍵組合實(shí)現(xiàn)平移控制. 其實(shí)現(xiàn)過(guò)程如下:
圖3 平移與旋轉(zhuǎn)后的3DS模型圖
1)定義一個(gè)Bool型變量m_RButtonDown,判斷鼠標(biāo)右鍵是否按下:變量為真表示按下,為假表示松開.
2)定義一個(gè)Cpoint變量存取鼠標(biāo)右鍵按下的位置,該點(diǎn)的位置與鼠標(biāo)平移后松開的位置即可表示為旋轉(zhuǎn)與平移控制函數(shù)的參數(shù)(由于通過(guò)響應(yīng)鼠標(biāo)按下的消息所獲得的點(diǎn)是,平面內(nèi)的二維點(diǎn),而平移函數(shù)中軸方向的參數(shù)是沒(méi)有辦法獲得的,所以通過(guò)鼠標(biāo)右鍵移動(dòng)只能使導(dǎo)入的3DS模型在,平面內(nèi)移動(dòng)).
3)通過(guò)if語(yǔ)句:if(m_ReftButtonDown&&(nFlags&MK_SHIFT/MK_CTRL))判斷是旋轉(zhuǎn)控制還是平移控制.
模型圖縮放采用函數(shù)glScalef(m_xScaling,m_yScaling,m_zScaling)實(shí)現(xiàn),其中3個(gè)參數(shù)對(duì)應(yīng)于3個(gè)坐標(biāo)軸的縮放比例. 采用一個(gè)Slider控件控制縮放,縮放函數(shù)的參數(shù)可通過(guò)Slider控件的移動(dòng)獲得,一般將函數(shù)glScalef(m_xScaling,m_yScaling,m_zScaling)中的3個(gè)參數(shù)設(shè)為大小一樣.
在OpenGL程序中拾取是在投影變換(Projection Transformation)階段利用投影變換中歸一化視體操作來(lái)實(shí)現(xiàn)的. 拾取時(shí),我們用一個(gè)選擇框來(lái)選擇物體;設(shè)置模型圖拾取控制函數(shù)gluPickMatrix (,,width,height,viewport[4]),其中,是鼠標(biāo)點(diǎn)擊到窗口上的坐標(biāo),width和height就是以(,)為中心的拾取框的寬度和高度,viewport是當(dāng)前窗口的大??;初始化名稱堆棧函數(shù)glSelectBuffer (SIZE,selectBuf),SIZE表示堆棧大小,selectBuf表示堆棧名稱,初始化對(duì)象名稱函數(shù)glInitNames(),加載對(duì)象名稱glLoadName(GLuint name),name為整型數(shù),表示加載對(duì)象名稱. 具體實(shí)現(xiàn)模型圖拾取控制的流程如圖4所示.
圖4 實(shí)現(xiàn)模型圖拾取控制的流程
將3DS模型導(dǎo)入OpenGl軟件中,降低了OpenGl復(fù)雜建模的難度,可以得到較真實(shí)的三維復(fù)雜物體模型. 采用在OpenGL程序中引入3DS數(shù)據(jù)模型文件的方法得到了較好的三維效果,同時(shí)可以進(jìn)行人機(jī)交互處理,成果可用于機(jī)器人仿真軟件開發(fā)、3D游戲開發(fā)等領(lǐng)域.
[1] 李新,李?yuàn)檴? 3DS模型在OpenGL中的讀取和重繪[J]. 首都師范大學(xué)學(xué)報(bào):自然科學(xué)版,2008, 29(2): 101-104.
[2]OpenGL體系結(jié)構(gòu)審核委員會(huì). OpenGL編程指南[M]. 4版. 鄧鄭祥. 北京:人民郵電出版社,2005.
[3]WRIGHT R S, APCHAK J B. OpenGL超級(jí)寶典[M]. 徐波. 北京:人民郵電出版社,2005.
[4] 張正波,牟彥,黃華,等. OpenGL實(shí)現(xiàn)3DS文件中的模型自由旋轉(zhuǎn)[J]. 計(jì)算機(jī)工程與應(yīng)用,2005, 41(13): 98-100.
[責(zé)任編輯:孫建平]
Import and Control of 3DS Models Based on OpenGL
GAOHai-fang1,WANGTian-lei2,QIUJie3,KANGXian-min1,4,WANGDa-cheng1,4
Two methods for importing the 3DS model using OpenGL in the VC + +6.0 environment are studied and the specific implementation procedures and technical points are given. A comparison of the two methods shows that the 3DS file-class method is better than the file conversion method as it causes less model diagram distortion and can easily achieve such human-computer interaction as translation, rotation, scaling and picking up.
OpenGL; 3DS model; human-computer interaction
1006-7302(2010)03-0005-32
TP311
A
2010-03-15
廣東省教育部產(chǎn)學(xué)研合作專項(xiàng)項(xiàng)目(2008B090500081)
高海芳(1984—),男,湖南常德人,碩士研究生,研究方向:自動(dòng)化控制,E-mail: gaohaitian125@163.com;王大承,教授,碩士生導(dǎo)師,通信作者,研究方向:智能控制與測(cè)試、特種加工、摩托車設(shè)計(jì),E-mail:dcwang@wyu.edu.cn.