opengl學(xué)習(xí)腳印opengl坐標(biāo)變換.doc_第1頁
opengl學(xué)習(xí)腳印opengl坐標(biāo)變換.doc_第2頁
opengl學(xué)習(xí)腳印opengl坐標(biāo)變換.doc_第3頁
opengl學(xué)習(xí)腳印opengl坐標(biāo)變換.doc_第4頁
opengl學(xué)習(xí)腳印opengl坐標(biāo)變換.doc_第5頁
免費(fèi)預(yù)覽已結(jié)束,剩余6頁可下載查看

下載本文檔

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

文檔簡(jiǎn)介

1、OpenGL 學(xué)習(xí)腳印OpenGL坐標(biāo)變換OpenGL 學(xué)習(xí)腳印 : OpenGL坐標(biāo)變換寫在前面本節(jié)內(nèi)容翻譯和整理自http:/www.songho.ca songho 的博客 OpenGL Transformation 內(nèi)容 ,以供自己和初學(xué)者熟悉 OpenGL 中坐標(biāo)變換的整個(gè)過程。通過本節(jié),你可以了解到:OpenGL 坐標(biāo)變換過程理解 OpenGL 矩陣計(jì)算概覽幾何數(shù)據(jù)例如頂點(diǎn)位置和法向量在光柵化操作之前,都要通過 Vertex Operation 和 Primitive Assembly OpenGL 流水線操作 (在 OpenGL pipeline 節(jié)描述 )。 OpenGL 頂點(diǎn)

2、變換 Object Coordinates( 對(duì)象坐標(biāo)系或模型坐標(biāo)系 )這是對(duì)象的局部坐標(biāo)系統(tǒng),是對(duì)象在被應(yīng)用任何變換之前的初始位置和方向所在的坐標(biāo)系。要對(duì)對(duì)象實(shí)行變換,可以使用glRotatef(), glTranslatef(), glScalef()等函數(shù)。EyeCoordinates(眼坐標(biāo)系或照相機(jī)坐標(biāo)系)由 GL_MODELVIEW 矩陣和模型坐標(biāo)系中坐標(biāo)相乘的結(jié)果。在 OpenGL 中使用 GL_MODELVIEW 矩陣來使對(duì)象從模型坐標(biāo)系轉(zhuǎn)換到眼坐標(biāo)系。GL_MODELVIEW 矩陣是模型變換和視變換矩陣的組合 (Mview*Mmodel) 。模型變換從對(duì)象坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)

3、系,而視變換從世界坐標(biāo)系轉(zhuǎn)換到眼坐標(biāo)系。注意:OpenGL 中并沒有單獨(dú)的視變換矩陣。 因此,要想模擬變換照相機(jī)或者進(jìn)行視變換, 那么場(chǎng)景 (3D 對(duì)象和光照 )必須以視變換矩陣的逆矩陣進(jìn)行變換。換言之, OpenGL 將照相機(jī)定義在位于眼坐標(biāo)系下朝向 -Z 軸,位于點(diǎn) (0,0,0) 的位置,而不能進(jìn)行變換。法向量同樣從對(duì)象坐標(biāo)系變換到眼坐標(biāo)系來用于光照計(jì)算。注意:法向量的轉(zhuǎn)換方式和頂點(diǎn)不同。它用法向量乘以GL_MODELVIEW 矩陣的逆矩陣的轉(zhuǎn)置矩陣。 請(qǐng)參考 Normal Vector Transformation 獲取更多細(xì)節(jié)。 Clip Coordinates( 裁剪坐標(biāo)系 )眼坐

4、標(biāo)通過乘以GL_PROJECTION變成了裁剪坐標(biāo)。這個(gè) GL_PROJECTION 矩陣定義了視見體 ( viewing volume,frustum) ,頂點(diǎn)式如何投影到屏幕上的 ( 透視投影還是正交投影 perspective or orthogonal) 。稱作裁剪坐標(biāo)系的是因?yàn)椋?jīng)過變換后的頂點(diǎn) (x,y,z) 將與 w相比較來進(jìn)行裁剪。請(qǐng)參考下面ProjectionMatrix 部分獲取更多細(xì)節(jié)。Normalized DeviceCoordinates (NDC) (歸一化設(shè)備坐標(biāo)系)由裁剪坐標(biāo)系下通過除以 W 分量得到。這個(gè)操作稱為透視除法。 NDC 坐標(biāo)很像屏幕坐標(biāo), 但是還沒

5、有經(jīng)過平移和縮放到屏幕像素?,F(xiàn)在 3 個(gè)軸上的值范圍均為 -1,1 。Window Coordinates (Screen Coordinates)(屏幕坐標(biāo) )通過對(duì) NDC 坐標(biāo)進(jìn)行視口變換得到。NDC 坐標(biāo)通過平移和縮放來適應(yīng)渲染的屏幕。屏幕坐標(biāo)最終傳遞給繪制流水線中的光柵化處理部分來變成片元。glViewport()用來定義渲染區(qū)域的矩形,這是最終圖像映射到的區(qū)域。另外, glDepthRange()用來確定屏幕坐標(biāo)中的Z 值。屏幕坐標(biāo)通過上面兩個(gè)函數(shù)的給定參數(shù)來進(jìn)行計(jì)算:glViewport(x, y, w, h);glDepthRange(n, f);這個(gè)公式由NDC 坐標(biāo)和屏幕坐

6、標(biāo)之間的線性關(guān)系來獲得的:OpenGL 變換矩陣OpenGL 使用 4x4 矩陣來進(jìn)行變換。注意,這 16 個(gè)元素的矩陣,實(shí)際上按列主序的方式以1D形式存儲(chǔ)。如下圖所示 :如果想當(dāng)做通常的行主序格式使用,你需要將其轉(zhuǎn)置。OpenGL當(dāng)中,有四類型的矩陣:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE,和GL_COLOR可以通過glMatrixMode()函數(shù)來指定當(dāng)前矩陣類型,例如使用模視矩陣,則可以選擇GL_MODELVIEW,調(diào)用glMatrixMode(GL_MODELVIEW)。Model-ViewMatrix (GL_MODELVIEW)模視矩陣GL_MO

7、DELVIEW矩陣將模型變換矩陣和視變換矩陣組合成一個(gè)矩陣。為了轉(zhuǎn)換相機(jī),你需要對(duì)整個(gè)場(chǎng)景執(zhí)行相反的變換。 gluLookAt() 函數(shù)專門用來設(shè)定視變換。矩陣最后一列元素 (m12,m13,m14)用于執(zhí)行平移變換,glTranslatef() 。元素 m15 是齊次坐標(biāo)系下坐標(biāo),特別用于投影變換。(m0, m1,m2), (m4, m5, m6) and (m8,m9,m10) 這 3 個(gè)元素集,用于歐幾里得和仿射變換,例如glRotatef() 用于旋轉(zhuǎn), glScalef() 用于縮放。注意: 這三個(gè)元素集實(shí)際上代表3 個(gè)正交坐標(biāo)軸 :(m0, m1,m2): +X axis,left

8、 vector, (1, 0, 0) by default(m4, m5,m6): +Y axis,up vector, (0, 1, 0) by default(m8, m9,m10) : +Z axis,forward vector, (0, 0, 1) by default如下圖所示 :我們可以從角度和lookat 向量來直接構(gòu)造GL_MODELVIEW,而不是用 OpenGL 來操作 4 列的GL_MODELVIEW矩陣。這里有一些有用的代碼來構(gòu)造GL_MODELVIEW矩陣 :Angles to AxesLookat toAxesMatrix4 class注意 :如果多個(gè)變換應(yīng)用到一

9、個(gè)頂點(diǎn)時(shí),OpenGL 以逆序的方式執(zhí)行多個(gè)相乘操作。 舉例來說,如果頂點(diǎn)先由MA變換,再由MB變換,那么OpenGL先執(zhí)行MBx MA操作,再乘以頂點(diǎn)。因此,在代碼中,后執(zhí)行的變換先出現(xiàn),而先執(zhí)行的變換后出現(xiàn):cpp view plaincopyprint?/ Note that the object will be translated first then rotated glRotatef(angle, 1, 0, 0); rotate object angle degree around X-axis glTranslatef(x, y, z); / move object to (

10、x, y, z) drawObject(); <span style=font-size:14px;><code class=codeblock/style=margin-left:30px;></code></span>Projection Matrix (GL_PROJECTION)投影矩陣GL_PROJECTION用于定義視錐。視錐決定了哪些對(duì)象以及對(duì)象的哪些部分會(huì)被裁減掉。同時(shí),它也決定了3D 場(chǎng)景是如何被投影到屏幕上的。OpenGL使用兩個(gè)函數(shù)來進(jìn)行投影變換。glFrustum() 用于進(jìn)行透視投影 ,glOrtho()用于進(jìn)行正交 (

11、平行 )投影。這兩個(gè)函數(shù)都需要 6各參數(shù)來指定裁剪平面的:left,right,bottom, top, near and far planes。兩個(gè)函數(shù)原型如下 :void glFrustum(GLdoubleleft,GLdouble right,GLdoublebottom,GLdoubletop,GLdoublenearVal,GLdoublefarVal);void glOrtho(GLdoubleleft, GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublenearVal,GLdoublefarVal);8個(gè)頂點(diǎn)如下圖所示 :遠(yuǎn)裁剪面

12、 (far) 的頂點(diǎn)可以通過相似三角形的比例計(jì)算出來(補(bǔ)充 : 實(shí)際上通過函數(shù)gluFrustum指定時(shí),參數(shù)都是指的近裁面的 l,r,t,b ,遠(yuǎn)裁剪面可以計(jì)算出來),例如,遠(yuǎn)裁剪面的 left 參數(shù)可以如下計(jì)算:對(duì)于正交投影, 這個(gè)比例是1,因此遠(yuǎn)裁剪面的left,right, bottom和top和近裁剪面的一樣,如下圖所示:gluPerspective() and gluOrtho2D()函數(shù)使用時(shí)需要更少的參數(shù)。gluPerspective()只需要四個(gè)參數(shù),F(xiàn)OV 視角,寬高比,以及遠(yuǎn)近裁剪面的距離。函數(shù)原型為:voidgluPerspective(GLdoublefovy,GLd

13、oublezNear,GLdoublezFar);轉(zhuǎn)換為同等的glFrustum() 的代碼如下 :GLdoubleaspect,從 gluPerspective()cpp view plaincopyprint?/ This creates a symmetricfrustum./ It converts to 6 params (l, r, b, t, n, f) forglFrustum()/ from given 4 params (fovy, aspect, near,far) void makeFrustum(double fovY, double aspectRatio,doub

14、le front, double back)const doubleDEG2RAD = 3.14159265 / 180;double tangent =tan(fovY/2 * DEG2RAD);/ tangent of half fovYdouble height = front * tangent;/ half height ofnear planedouble width = height * aspectRatio;/ half width of near plane/ params: left, right,bottom, top, near, farglFrustum(-widt

15、h, width,-height, height, front, back);補(bǔ)充 : 關(guān)于 gluPerspective函數(shù)計(jì)算視錐利用 gluPerspective函數(shù)指定視錐如下圖所示:注意到視錐的對(duì)稱性,利用三角形的相似性,可以推算如下圖所示 :其中 top : n = tan(fov/2) ,bottom= -top,left = -right =>top= height/2 =n*tan(fov/2)height為近裁剪面高度=>right=width/2 =aspect*height/2=aspect*n*tan(fov/2)width 為近裁剪面寬度注意上述代碼中w

16、idth,height均為實(shí)際值的一半。注意 :這里使用 gluPerspective函數(shù)構(gòu)造的是一個(gè)對(duì)稱的視錐,如果你想要構(gòu)造非對(duì)稱視錐必須直接使用glFrustum() 函數(shù)。例如,你想要把一個(gè)寬場(chǎng)景繪制到兩個(gè)相連的屏幕上,你可以將視錐分割為左右兩個(gè)非對(duì)稱的視錐,然后在每個(gè)視錐中渲染場(chǎng)景,如下圖所示:Texture Matrix(GL_TEXTURE)紋理矩陣紋理坐標(biāo) (s,t,r,q) 在進(jìn)行任何紋理映射前乘以GL_TEXTURE 。默認(rèn)情況下,它是一個(gè)單位陣,因此紋理會(huì)被映射到物體的位置,那個(gè)你指定紋理坐標(biāo)的位置。通過修改 GL_TEXTURE ,你可以滑動(dòng)、旋轉(zhuǎn)、拉伸以及收縮紋理。

17、cpp view plaincopyprint?/ rotate texture aroundX-axisglMatrixMode(GL_TEXTURE);glRotatef(angle, 1, 0, 0)Color Matrix (GL_COLOR)顏色矩陣顏色分量 (r,g,b,a) 乘以 GL_COLOR矩陣。可以用于顏色空間轉(zhuǎn)換和顏色分量交換。 GL_COLOR 矩陣被經(jīng)常使用,并且需要 GL_ARB_imaging 拓展。其他的矩陣操作 glPushMatrix() :push the current matrix into the current matrix stack.glPo

18、pMatrix() :pop the current matrix from the current matrix stack.glLoadIdentity() :set the current matrix to the identity matrix.glLoadMatrixfd(m) :replace the current matrix with the matrixm.glLoadTransposeMatrixfd(m) :replace the current matrix with the row-major ordered matrixm.glMultMatrixfd(m) :multiply the current matrix by the matrixm, and update th

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論