OpenGL學習隨筆 四

2021-04-23 14:25:04 字數 2088 閱讀 8777

久違了,我的blog。這幾天被透視投影卡住了,雖然到現在也沒有完全搞明白,但也還是應該階段性總結一下。

3d影象在2d平面顯示要經過以下幾個步驟,

1. 資料配置環節,配置頂點、顏色等資料,確定了物體的大小和外觀。

2. 指定模型視點變換引數,將物體到3d場景中,並確定我們的觀察點,也就是人眼的位置。

3. 指定投影變換引數,確定投影方式和方向。

4. 指定視口變換引數,將投影結果對映至視口(2d顯示平面)。

以上4步都屬於配置動作,分別用於修改opengl狀態機中的不同配置引數(頂點陣列,變換矩陣等),真正觸發opengl開始工作的是類似gldrawelements這樣的api。記住,opengl就是一堆資料配置和動作。

2,3,4中涉及的各種變換都是通過矩陣來表示的(這裡有太多數學知識,再單獨總結吧),和各種資料快取不同的是,整個opengl似乎只有乙個矩陣堆疊,各種變換是共享的,所以還需要乙個狀態量來表示當前矩陣是用於做什麼變換的。這個狀態量通過glmatrixmode來指定,引數可以是gl_projection, gl_modelview等等。

1. 模型視點變換

模型視點變換,亦可分別稱為視點變換、模型變換,但由於兩者關係比較密切,所以一般會連在一起說。為什麼兩者關係密切呢?因為很多情況下,「人的觀察點不變,改變物體的位置」(模型變換)與「物體不變,改變人的位置」(視點變換)可以達到同樣的效果。

模型變換相關的函式有,glrotate*(旋轉),gltranslate*(平移),glscale*(縮放)等等。。

對於視點變換opengl並沒有提供專門的函式(這更體現了模型視點變換的互換性),但在glu裡提供了glulookat函式。它有三組引數,分別表示人眼所處的位置(eyex, eyey, eyez),人眼所觀察的位置(或者說所聚焦的位置,兩點一線,(centerx, centery, centerz)),以及眼睛與頸部所形成的向量(upx, upy, upz)。

拿拍攝來比喻,僅改變第一組引數表示相機繞物體移動,僅改變第二組引數表示相機原地轉動(在xoz平面),僅改變第三組引數表示相機旋轉(在xoy平面)。如果仍然不能理解,建議去看nate robin opengl教程中的projection演示。

2. 投影變換

投影(projection)的目的是將3d圖形轉換至2d平面顯示。opengl提供了正交投影(orthogonal projection)和透視投影(perspective projection)兩種投影方式。正交的另一種說法是垂直(數學沒學好...),其投影結果不會改變物體的大小。透視投影和人眼的視覺模型,或者說小孔成像比較類似,投影之後遠處的東西看上去會小一些。因此,絕大多數情況下使用的是透視投影。

透視投影的模型定義了乙個視景體,這是乙個平截頭體(倒放的稜臺),所有在這個視景體內的物體才會被顯示出來。由於平截頭體的底面比頂面要大,所以可以理解為,底面經過投影之後縮小成頂面般的大小,也就是人眼模型所要的效果。至於位於視景體內的物體是經過怎樣的運算而最終變成2d平面影象的,這是乙個內部演算法的問題,如開篇所說我還沒有完全掌握......

opengl提供了glfrustum介面來實現透視投影,這個api完全是以視景體模型來定義的,如果覺得用起來不太直接,還有乙個glu的介面 gluperspective。

3. 視口變換

視口可以理解為最終在顯示器上顯示的大小,雖然一般來說就是opengl視窗的大小,但理論上兩者並不一定要相同。視口大小通過glviewport介面來指定。注意每當視窗大小發生改變時都需要重新指定。同時也要注意透視投影的輸出與視口大小之間的關係,gluperspective有個引數是寬高比,通常該值應該等於視口的寬高比,否則會造成影象被縮放。

想要真正掌握這些概念,還需要親自實踐,寫段**來體會一下。

static void display(void)

static void reshape(int w, int h)

一些心得:

1. 試著調整一下glulookat的引數,看看結果是否與你想像中的一致。

2. 可以在display中把x,y,z軸畫出來,以輔助理解

3. 看不到影象,有可能是不在視線範圍內,也有可能是離得太近,甚至還有可能是顏色填錯了,這些心得只有靠自己在實踐中去總結,才能變成自己的財富。

4. 別人的教程寫得再好,只能縮短你學習的過程,但永遠也不能替代自己動手這一環節。

OpenGL學習隨筆 十三

因為工作原因,有一段時間沒玩opengl了。今天開始重新拾起。這一年來接觸了些opengl es的chip provider,感覺大家都開始發力了,mobile 3d產業要爆發了。之前一直在看1.x系列,現在從2.x開始,雖然1.x還有不少內容沒玩過。2.x系列最大的變化就是引入了可程式設計pipe...

OpenGL學習隨筆 七

很多時候,知識難以常握是因為我們只知其表不知其裡,或者說不了解歷史就不能理解現在。所以在學習到一定程度之後一定要去分析和實現opengl,之後才能真正理解和掌握opengl。每天在不斷學習新的內容時,我都會選擇重寫測試 而不是在之前的 上修改,原因是想找出一些思維定勢和盲區。今天嘗試用push和po...

opengl 入門學習 隨筆五

今天開始opengl的學習,下面上第乙個程式!void mydisplay int main int argc,char argv 整個程式表示顯示乙個矩形 這裡有幾個概念稍微介紹一下 1 glclear 表示清除背景,也就是說我們在黑板上清除的效果是顯示全黑,在白紙上清楚顯示的是全白 2 glut...