OpenGL完全教程 第四章 矩陣變換_第1頁
OpenGL完全教程 第四章 矩陣變換_第2頁
OpenGL完全教程 第四章 矩陣變換_第3頁
OpenGL完全教程 第四章 矩陣變換_第4頁
OpenGL完全教程 第四章 矩陣變換_第5頁
已閱讀5頁,還剩7頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、OpenGL 完全教程 第四章 矩陣變換作者:何詠 日期:2006-2-3 20:52:21 點(diǎn)擊:3468如需轉(zhuǎn)載本文,請聲明作者及出處。第四章 矩陣變換通過前三章的學(xué)習(xí),我們知道了如何使用OpenGL 在3D 空間中繪制基本圖元,并把使用圖元組成模型。然而,在我們繪制完一個物體或一個場景之后,我們總希望從多個角度觀察這個物體,或者在場景中走動。這時,我們需要OpenGL 的另一個功能:變換。OpenGL 為我們提供了許多方面和類型的變換。你可以對投影方式進(jìn)行變換,也可以對物體/模型 進(jìn)行變換。你可以改變自己的位置和方向,也可以改變物體的大小和角度。學(xué)習(xí)本章內(nèi)容,你將了解:OpenGL 中變

2、換的種類使用矩陣描述一個變換基本變換定義和使用自己的變換4.1 OpenGL中的變換變換(Transform,可以使3D 空間中的物體投影到2D 平面上。使用變換,你可以移動、旋轉(zhuǎn)、縮放甚至彎曲一個物體。然而變換并沒有直接修改頂點(diǎn)數(shù)據(jù),取而代之,變換修改了坐標(biāo)系。如果旋轉(zhuǎn)一個坐標(biāo)系,然后再在 旋轉(zhuǎn)后的坐標(biāo)系里繪圖,繪制后的圖形就好像被旋轉(zhuǎn)了。在基本OpenGL 渲染流程中,將進(jìn)行以下變換:視圖變換 :用于指定觀察者的位置和方向;模型視圖變換:移動和變換場景中的模型;投影變換 :對視見空間進(jìn)行裁剪和扭曲;視見區(qū)變換:對最終輸出進(jìn)行縮放。在一個場景中,我們希望改變觀察者的位置和觀察角度。用于改變觀

3、察者方位和角度的變換,就是視圖變換。默認(rèn)情況下(沒有執(zhí)行任何變換時),觀察者位于點(diǎn)(0,0,0,且視線朝著-Z方向。也就是說,只有在z<0的地方繪圖,才有可能被觀察到。此變換用于移動和旋轉(zhuǎn)場景中的物體。使用模型視圖變換完全可以代替視圖變換。道理是很簡單的:比如你想使用視圖變換將觀察者向-Z軸移動10個單位,此時場景中所有的物體都向+Z軸移動了10個單位。這跟你直接使用模型視圖變換將場景中所有物體向+Z方向移動10個單位的效果是完全一樣的。要把3D 場景投影到2D 平面上,就必須執(zhí)行投影變換。投影變換有兩種形式,即平行投影變換和透視投影變換。關(guān)于平行投影和透視投影,在第3中已進(jìn)行了具體的介

4、紹,這里不在復(fù)述?,F(xiàn)在要強(qiáng)調(diào)的是,投影也是一種變換,實(shí)現(xiàn)投影,本質(zhì)上是對場景中所有物體進(jìn)行特殊的變換,使得它們能夠被畫在一個平面上。比如透視投影變換會將場景中所有物體按照遠(yuǎn)近不同進(jìn)行縮放和扭曲,使它們看起來具有立體感。這里又回到了第二章中的主題。視見區(qū)變換就是對投影后的2D 圖象進(jìn)行縮放和剪裁,使它能夠被正確地顯示在窗口上。你可以回到第二章了解視見區(qū)的具體概念。4.2 矩陣矩陣(M a t r ix 是那樣的強(qiáng)大以至于幾乎所有的變換都可以由矩陣來表達(dá)。矩陣是又n 行m 列的數(shù)組成的一個陣列(m、n1)。通過矩陣的乘法運(yùn)算就可以運(yùn)用各種變換。在OpenGL 中,統(tǒng)一使用大小為4×4的矩

5、陣。由于矩陣的運(yùn)算法則和具體數(shù)學(xué)內(nèi)容,和OpenGL 這一主題并沒有太大關(guān)系(使用OpenGL 并不需要了解矩陣是怎樣運(yùn)算的,因?yàn)镺penGL 會幫你完成一切),所以這里不再介紹。但這并不代表這些數(shù)學(xué)知識是不重要的,靈活地運(yùn)用矩陣,可以自己創(chuàng)造出許多OpenGL 沒有提供的變換,并提高運(yùn)算速度。你可以參看線性代數(shù)了解更多內(nèi)容。 在OpenGL 進(jìn)行變換操作時,會首先把頂點(diǎn)轉(zhuǎn)換為1×4的矩陣(第1-3行分別存放頂點(diǎn)的x 、y 、z坐標(biāo),第4行存放w 坐標(biāo),即縮放因子,一般總為1.0),然后將這個點(diǎn)依次乘以模型視圖變換矩陣、投影矩陣、視見區(qū)變換矩陣最后得到因出現(xiàn)在屏幕上的2D 屏幕坐標(biāo),

6、完成變換。幸運(yùn)的是,你不需要任何數(shù)學(xué)基礎(chǔ),哪怕你對矩陣一無所知,也能順利地完成這一流程。因?yàn)镺penGL 已經(jīng)封裝了高級函數(shù),這使得你不用自己動手寫矩陣,就能完成所有的基本變換。稍后就將介紹這些基本函數(shù)。4.3 基本變換對于每一種變換,OpenGL都有自己的函數(shù)用來生成這些變換的矩陣并應(yīng)用它們。下面將一一介紹。這是本章最重要的內(nèi)容。使用模型變換,你就可以完成物體的旋轉(zhuǎn)和移動,并產(chǎn)生移動觀察者的效果。這正是本章的主題。為了能夠完成我們的示例,我們定義以下函數(shù)在原點(diǎn)繪制一個球體。以下函數(shù)涉及到二次曲面的內(nèi)容,這是OpenGL 的另一個高級主題,我們將在今后的章節(jié)中 具體講解,現(xiàn)在我們只用它來繪制球

7、體:pro c e du re DrawS p h ere(R:Sin gl e ; /R 代表球體的半徑v ar S pO bj:GL UQu a d r ic O bj;b e gi nspObj:=gluNe wQu a d r ic;gluQu a d r icN orma l s(S pO bj ,GL U_SMOOT H ;gluQu a d r ic Or i en t a ti on(S pO bj ,GL U_O U T SI D E ;gluS p h ere(S pO bj , R , 50, 50 ;glu De l e t e Qu a d r ic (spObj ;

8、en d ;當(dāng)我們調(diào)用Dra wS p h ere 時,會在原點(diǎn)繪制一個球體?,F(xiàn)在我們想在點(diǎn)(0,10,0上繪制這個球體,就必須在繪制之前將坐標(biāo)系沿+Y 方向平移10個單位。于是我們會寫出這樣的代碼:/建立一個將坐標(biāo)系沿+Y方向平移10個單位的矩陣:./用當(dāng)前模型視圖矩陣乘以這個矩陣:.DrawSphere(5;/繪制一個半徑為5的球體但事實(shí)上,我們不需要這么麻煩。OpenGL為我們提供了這樣一個函數(shù):glTranslatef(x,y,z:Single;其中,x , y ,z 分別表示在X 、Y 、Z軸上平移的量。調(diào)用這個函數(shù)之后,OpenGL會自動生成一個平移矩陣,然后應(yīng)用這個矩陣。因此,我

9、們可以這樣寫代碼:glTranslatef(0,10,0;DrawSphere(5;這樣就能在(0,10,0上繪制一個球體了。與平移類似,OpenGL也為我們提供了一個高級函數(shù)用于旋轉(zhuǎn)物體:glRotatef(Angle,x,y,z:Single;這個函數(shù)將生成并應(yīng)用一個將坐標(biāo)系以向量(x , y ,z為軸,旋轉(zhuǎn)an gl e 個角度的矩陣。如果我們想將一個球體以Y 軸自轉(zhuǎn)50度,就可以調(diào)用:glRotatef(50,0,1,0;DrawSphere(5;縮放變換其實(shí)是將坐標(biāo)系的x 、y 、z軸按不同的縮放因子展寬,從而實(shí)現(xiàn)縮放效果。函數(shù)glScalef(x,y,z:Single;把坐標(biāo)系的X

10、 、Y 、Z軸分別縮放x 、y 、z倍。例如:glScalef(2,2,2;DrawSphere(5;將繪制一個半徑為10的球體。使用變換時,我們應(yīng)該注意的是,變換是疊加在上次變換的基礎(chǔ)上的。也就是說,變換的效果會累積。每次調(diào)用變換函數(shù)時,會生成一個新的函數(shù)來乘以當(dāng)前的模型視圖矩陣,隨后,新的矩陣將成為當(dāng)前的模型變換矩陣,在下次執(zhí)行變換時,會被新的矩陣相乘,因此作用效果將不斷累積。舉個例子就能很明白地說明這一點(diǎn)。例如,你想在(0,10,0)上繪制一個球體,完后在(10,0,0)上繪制另一個,得到如圖4.3-1所示的圖形: 圖4.3-1你可能會寫出如下代碼:/沿Y 軸向上平移10個單位glTra

11、nslatef(0,10,0;/畫第一個球體DrawSphere(5;/沿X 軸向左平移10個單位glTranslatef(10,0,0;/畫第二個球體DrawSphere(5;然而,你不應(yīng)該忘記,變換的作用效果是累積的。在繪制第二個球體時,由于此時坐標(biāo)系已經(jīng)向Y 軸移動了10個單位,再向X 方向移動10個單位之后,新的坐標(biāo)系的原點(diǎn)應(yīng)是絕對坐標(biāo)系中的點(diǎn)(10,10。因此,上述程序?qū)⒗L制出如圖4.3-2所示的圖形。 圖4.3-2你可能會在繪制第二個球體之前調(diào)用gl Trans l a t ef(0,-10,0; 把坐標(biāo)系往回移動10個單位。但這樣會降低代碼的可讀性,還會給CPU 增加額外的運(yùn)算。

12、這個時候,我們可以使用單位矩陣。我們可以調(diào)用gl Loa dId en tity (;函數(shù)將當(dāng)前模型視圖變換矩陣重置到初始狀態(tài),再進(jìn)行新的繪制: procedure RenderScene(;beginglMatrixMode(GL_MODELVIEW;/沿Y 軸向上平移10個單位glTranslatef(0,10,0;/畫第一個球體DrawSphere(5;/加載單位矩陣glLoadIdentity;/沿X 軸向上平移10個單位glTranslatef(10,0,0;/畫第二個球體DrawSphere(5;end ;請看第一行代碼。這里調(diào)用了glM a t r ixM o d e 函數(shù)。這個

13、函數(shù)的作用是通知OpenGL 我們將對模型視圖變換矩陣進(jìn)行操作。也就是要進(jìn)行模型視圖變換。glM a t r ixM o d e 可用參數(shù)如下:GL _PRO JEC T I O N :用于修改投影矩陣GL_MOD E L VIEW :用于修改模型視圖變換矩陣如果每次變換前都把當(dāng)前矩陣恢復(fù)到單位矩陣,也比較麻煩。更多時候,我們希望保存當(dāng)前矩陣,執(zhí)行一些變換之后,把當(dāng)前矩陣恢復(fù)到上次保存時的狀態(tài)。OpenGL 為我們提供了一個“矩陣堆?!睗M足我們的這種要求。我們可以把當(dāng)前矩陣壓入堆棧中,然后執(zhí)行一些變換,再彈出剛才壓入的矩陣,從而把當(dāng)前矩陣恢復(fù)到上次變換之前的狀態(tài)。我們調(diào)用glPushMatri

14、x(;把當(dāng)前矩陣壓入矩陣堆棧,調(diào)用glPopMatrix(;彈出矩陣。我們還可以分別調(diào)用glGet(GL_MAX_MODELVIEW_STACK_DEPTH;glGet(GL_MAX_PROJECTION_STACK_DEPTH;來獲取模型視圖矩陣堆棧和投影矩陣堆棧的最大堆棧深度。一般情況下(在Wi n d o w s 平臺上,模型視圖的最大堆棧深度是32,而投影堆棧的最大深度是2。procedure RenderScene(;beginglMatrixMode(GL_MODELVIEW;/推入矩陣堆棧glPushMatrix;/沿Y 軸向上平移10個單位glTranslatef(0,10,0

15、;/畫第一個球體DrawSphere(5;/恢復(fù)到上次保存時的狀態(tài)glPopMatrix;/沿X 軸向左平移10個單位glTranslatef(10,0,0;/畫第二個球體DrawSphere(5;無論是 2 維數(shù)組還是一維數(shù)組,都是按照列優(yōu)先的順序保存的。如圖 4.4-1 所示。 圖 4.4-1 矩陣定義完后,調(diào)用 glLoadMatrix(M; 可以用矩陣 M 替換當(dāng)前矩陣,調(diào)用 glMultMatrix(M; 用當(dāng)前矩陣乘以矩陣 M。 要說明的是,使用 glLoadMatrix 或 glMultMatrix 的速度沒有 OpenGL 的高級變換函數(shù)快。所以如果不是高級變換 函數(shù)完成不了的

16、變換,就不要使用 glLoadMatrix 或者 glMultMatrix。 4.5 示例程序 這是一個經(jīng)典的示例程序。它演示了太陽系中地月系與太陽之間的運(yùn)動關(guān)系:月球饒地球轉(zhuǎn),整個地月系饒?zhí)?轉(zhuǎn),所有的星球都自轉(zhuǎn)。這個例子很好地展示了矩陣變換的性質(zhì)和矩陣堆棧的作用。為了增加視覺效果,本程序中加 入了光照渲染。 同時,我們也加入了紋理貼圖,這是為了能看星球自轉(zhuǎn)的景象。有關(guān)光照和紋理貼圖的詳細(xì)內(nèi)容,我 們都將會在今后的章節(jié)中具體講解。 以下是渲染過程的代碼: procedure TfrmMain.RenderScene; begin glEnable(GL_CULL_FACE; glClear

17、(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT; glLoadIdentity; glTranslatef(0,0,-110; glRotatef(yDeg,0,1,0; glRotatef(xDeg,1,0,1; RenderLights;/光照處理 /繪制太陽 glColor3ub(255,100,64; glPushMatrix; glRotate(SunSelfAng,0,1,0; DrawSphere(10; glPopMatrix; glPushMatrix;/推入當(dāng)前矩陣 /繪制地月系 glRotatef(EarthCommonAng,0,1,0; glTranslatef(50,0,0; glPushMatrix;/繪制地球 glRotatef(EarthSelfAng,0,1,0; glColor3ub(2

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論