OpenGL學習筆記 OpenGL的變換和矩陣

2021-08-22 15:37:07 字數 2426 閱讀 2555

opengl的變換和矩陣

1)指定矩陣型別

opengl中使用glmatrixmode指定當前要設定的矩陣型別,常用的引數是gl_projection和gl_modelview,還有gl_texture。opengl將視點變換(即攝像機變換)和模型變換(即物體變換和世界變換)合二為一了。glmatrixmode指定的模式一但指定就不會變除非再次呼叫glmatrixmode,所以一般在reshpae裡設定gl_projection之後再使用glmatrixmode指定當前矩陣型別為gl_modelview,那麼以後設定的變換矩陣就都是模型視點矩陣。

2)模型視點矩陣設定順序

在設定模型視點矩陣時,如果使用glulookat設定視點矩陣,必須先呼叫glulookat,然後再設定各個模型變換矩陣。而且由於每幀重新重新整理,矩陣不會自動清除(矩陣設定都是右乘到棧頂),所以每幀一開始要使用glloadidentity將模型視點矩陣設成單位陣,然後用glulookat設定視點矩陣,然後是各模型變換矩陣。

3)變換矩陣設定和執行順序

由於opengl使用的是向量右乘矩陣(向量是列向量,矩陣是列主矩陣),v'=m x v,而每次使用gltranslate*,glscale* ,glrotate*等的時候是將所指定的矩陣右乘到當前矩陣棧棧頂的矩陣上,比如原棧頂矩陣為i,使用gltranslate*指定矩陣t,那麼當前變換矩陣就是ixt,如果再用glscale*指定乙個縮放矩陣s,那麼當前矩陣就是ixtxs,用來變換向量就變成 v' = ixtxsxv,效果就是先縮放再平移,可見指定矩陣的順序是和矩陣變換向量的執行順序相反的。如果這兒在**中先呼叫glscale*,再呼叫gltranslate*,就會變成先平移再縮放,結果是很不一樣的,因為縮放是針對中心點的座標值變化,如果先平移,等於這些點離中心點遠了,再放大就會更加偏離中心點。

示例**:

glpushmatrix();

gltranslatef(10.0f,0.0f,0.0f);

glscalef(2.0f,2.0f,2.0f);

glutwirecube(1.0);

glpopmatrix();

glpushmatrix();

glscalef(2.0f,2.0f,2.0f);

gltranslatef(10.0f,0.0f,0.0f);

glutwirecube(1.0);

glpopmatrix();

同樣對於視點變換和模型變換,由於是先指定視點變換(呼叫glulookat)後指定模型變換,所以實際效果是先模型變換再視點變換,這與一般圖形學上的流水線順序一致。

4)glloadidentity,glpushmatrix/glpopmatrix的使用

在使用glmatrixmode(gl_projection)後要立刻呼叫glloadidentity,glmatrixmode本身不會將棧頂矩陣清成單位陣。在每幀開始要呼叫glloadidentity將模型視點矩陣設成單位陣(否則會累積上一幀矩陣變換的最終效果)。在設定模型變換矩陣時,也可以使用glloadidentity,這會清除之前所有變換矩陣的累積效果重新開始矩陣設定,當然最方便的還是glpushmatrix/glpopmatrix組合,首先他的效率比glloadidentity高,執行glpushmatrix時複製當前的矩陣併入棧(新矩陣位於棧頂,原矩陣被壓入棧中),這樣之後所做的變換就可以累積原來的變換效果,之後呼叫glpopmatrix會將原變換矩陣彈出,這樣就恢復了原來的變換矩陣,不受push/pop之間矩陣變換的影響。這種矩陣棧的結構特別適合層次關係,一般至少支援32層。(投影矩陣支援2層,但一般沒用)

5)模型變換矩陣函式

即gltranslate*,glscale* ,glrotate*,使用這些函式速度比自己設定矩陣並呼叫glmultmatrix*快。

使用glscale*會對光照產生影響,必須再次歸一化法線。(因為opengl會將模型變換應用到法線上)

連續旋轉時應該是記錄旋轉角度並以之呼叫glrotate*,因為多次進行微小旋轉會導致誤差

6)視點變換矩陣

可以用glulookat指定,也可以自己封裝函式實現功能

7)投影變換

投影矩陣一般是在reshape(螢幕尺寸設定或變化的時候)裡呼叫,必須首先呼叫:

glmatrixmode(gl_projection);

glloadidentity();

投影變換定義視景體,opengl會根據視景體進行裁剪(應該是會生成乙個齊次空間透視裁剪矩陣並進行裁剪)

使用glfrustum指定透視投影的視景體,他會生成乙個透視矩陣並將其與當前矩陣相乘

也可以使用gluperspective指定,注意他使用的是fovy和w/h

還可以自己封裝類似函式(要使用glmultmatrix*)

8)視口變換,深度座標

glviewport指定視口

gldepthrange設定深度值範圍,預設為0.0~1.0(書中說這是在視口變換過程對z座標編碼的方式。這應該是opengl設定的齊次透視裁剪空間的z值範圍吧)

OpenGL學習筆記之一 什麼是OpenGL

opengl到底是什麼?制定並維護的規範 specification opengl規範嚴格規定了每個函式該如何執行,以及它們的輸出值。至於內部具體每個函式是如何實現 implement 的,將由opengl庫的開發者自行決定 譯註 這裡開發者是指編寫opengl庫的人 因為opengl規範並沒有規定...

openg離線包 OpenGL離線渲染和緩衝區物件

理論 輸入 影象,點,線。輸出 影象 實現方案 從一般到特殊 1.不支援fbo 主要介紹pc上,移動裝置如果不支援fbo要實現離線渲染那就實在沒轍了。gldrawbuffer gl back glreadbuffer gl back 設定讀寫時後快取區。一般pc都支援雙緩衝機制,如果沒有gl bac...

OpenGL學習筆記

我是一名ios開發者,opengl是乙個比較重要的技術。所以就此開啟我的菜鳥之路。opengl open graphics library 是乙個跨程式設計語 言 跨平台的程式設計圖形程式接 它將計算機的資源抽象稱為乙個個opengl的物件,對這些資源的操作抽象為乙個的opengl指令.direct...