OpenGL學習07 OpenGL矩陣

2021-06-27 14:42:42 字數 4835 閱讀 9243

關於矩陣的概念和矩陣的計算本篇就不再多說了,不了解的同學可以翻一下大學數學了!

矩陣(matrix)是一種很強大的數學工具,特別實在計算機圖形處理中,它可以極大的簡化變數之間的複雜關係的乙個或多個方程式的求解。例如:空間中有乙個點座標x、y、z,如果當這個點圍繞任意點以任意方向旋轉一定的座標之後,想知道它的新位置,就需要使用矩陣。

(1)變換管線

從原始頂點資料通往螢幕座標的路是相當漫長的。圖1提供了這個過程的流程圖。

圖1,來至opengl超級寶典

首先,把頂點轉換成乙個1 x 4的矩陣,前3個值分別是x、y、z,第4個是縮放因子,可以在接受4個引數的定製函式中手工使用這個值,這個值是w座標,他在預設情況下為1.0,很少炫耀修改它。

接著,把頂點與模型檢視矩陣相乘,產生經過變換的視覺座標。

然後,將這個視覺座標與投影矩陣相乘,產生裁剪座標。這樣就有效的清除了可視區域之外的所有資料。這個裁剪座標隨後除以w值,產生規範化的裝置座標。w值可能會被投影矩陣或者模型檢視矩陣所修改,具體取決與頂點所發生的變換(opengl和高層矩陣函式隱藏了這些細節)。

最後,把這個座標通過視口變換對映到乙個2d平面上。

(2)模型檢視矩陣

模型檢視矩陣是乙個4 x 4的矩陣,代表經過變換的座標系統,我們可以用這個座標系統放置物體並設定方向。為圖元所提供的頂點按照單列單矩陣的形式使用,並與模型檢視矩陣相乘,產生與視覺座標相對應的經過變換的新座標。

a)移動

使用glut的函式庫建立乙個立方體,**如下:

void glutwirecube(gldouble size);

此時乙個邊長size個單位的立方體就會出現在原點居中的位置。如果希望在繪製這個立方體之前把它沿著y軸方向移動n個單位,可以把模型檢視矩陣乘以乙個表示沿y軸方向上移動n個單位的矩陣,然後執行繪製任務。

opengl提供了乙個高層函式,可以實現這個操作,**如下:

void gltranslatef (glfloat x, glfloat y, glfloat z);

這個函式接受三個引數,分別是x、y、z方向的移動數量。然後,它建立乙個適當的矩陣,並執行乘法操作。下面是上述操作的偽**:

gltranslatef(0.0f, 50.0f, 0.0f);

glutwirecube(50.0f);

圖2為移動前後的效果(圖形旋轉):

圖2

b)旋轉之前程式中一直在使用旋轉功能,但我們僅僅只是會使用它,但還不知道旋轉的原理。opengl高層提供了乙個可以設定旋轉矩陣的函式,如下:

void glrotatef (glfloat angle, glfloat x, glfloat y, glfloat z);

函式中接受4個引數,angle為旋轉的角度,x、y、z為組成向量(x,y,z)為旋轉圍繞的軸。簡單點來講就是原點(0,0,0)和(x,y,z)組成一條直線,物理圍繞這條直線旋轉angle角度,下面是上述操作的偽**:

glrotatef(45.0f, 1.0f, 1.0f, 1.0f);

glutwirecube(50.0f);

圖3為旋轉前後的效果:

圖3

c)縮放縮放變換根據指定的因子沿3個軸對物體的所有頂點驚醒拉伸或收縮,從而改變物體的大小。同樣opengl高層提供了縮放的函式,如下:

void glscaled (gldouble x, gldouble y, gldouble z);

函式接受3個引數,x、y、z分別為x、y、z方向的縮放比例因子,當縮放因子為1.0時,該方向大小不變;當縮放因子大於1.0時,該方向會被放大;當縮放因子小於1.0時,該方向會被縮小;下面是上述操作的偽**:

glscaled(1.5f, 1.0f, 0.5f);

glutwirecube(50.0f);

圖4為縮放前後的效果(圖形被旋轉):

圖4

(3)單位矩陣模型檢視矩陣變換是累積的,每次呼叫乙個變換函式時,都會建立乙個新矩陣,並把它與當前的模型檢視矩陣相乘,得到乙個新矩陣作為當前模型檢視矩陣。

可以通過在模型檢視矩陣中載入單位矩陣來實現把模型檢視矩陣重置到原點目標。單位矩陣表示沒有反生變換,載入單位矩陣的效果相當於在繪圖時所指定額所有座標都處於視覺座標中。所謂的單位矩陣就是矩陣對角線元素均為1,其餘元素為0的矩陣。當這種矩陣與任意的頂點矩陣相乘時,其結果就是頂點矩陣,不會發生任何變化。如圖5所示:

圖5,來至opengl超級寶典

下面**為載入單位矩陣:

glmatrixmode(gl_projection);

glloadidentity();

第一行**指定了當前操作的矩陣是模型檢視矩陣。在設定了當前操作矩陣之後,他就將一直保持為活動矩陣,知道對他進行修改。第二行**在當前矩陣中載入單位矩陣。

(4)矩陣堆疊

在場景中放置每個物體時,並不一定都要使用單位矩陣對模型檢視矩陣重置。常常需要儲存當前變換狀態,然後放置了一些物體之後再進行恢復到這個狀態。當一開始就報模式檢視變換為自己經常使用的檢視變換矩陣時,這種方法非常方便。

為了方便這個過程,opengl中維護了乙個矩陣堆疊,它既可以用於模型檢視矩陣,也可以用於投影矩陣,矩陣堆疊的工作方式就像普通堆疊一樣。我們可以把當前的矩陣壓入矩陣堆疊中,對它進行儲存,然後再修改當前矩陣。從矩陣堆疊中彈出相當於恢復原來的那個矩陣。

堆疊的深度最大值獲取:

glgetintegerv(gl_max_modelview_stack_depth, &stack_deep);

矩陣堆疊操作函式:

glpushmatrix();

glpopmatrix();

glpushmatrix函式會將當前使用的模型檢視矩陣壓入堆疊;glpopmatrix函式會將棧頂的矩陣彈出,作為當前模型檢視矩陣使用。

(5)矩陣高階操作

這些對變換(移動、縮放、旋轉)進行包裝的opengl高層函式對於許多變換問題是極為簡單的。但是,為了獲得真正強大的功能和靈活性,必須花時間掌握直接使用矩陣。

opengl在表示乙個4x4的矩陣是並沒有使用浮點型的二維陣列,而是使用了乙個包含16個浮點值的一維陣列表示。這個方法和許多數學函式庫使用的方法不同,後者常常使用二維陣列來表示矩陣。例如,下面兩個例子中,opengl更傾向於使用前者。

glfloat matrix[16];

glfloat matrix[4][4];

opengl也可以使用第二種型別表示形式,但是第一種是更高效的表示方式。這16個元素代表乙個4x4的矩陣,如圖6所示。當我們按列逐個遍歷陣列的元素是,就稱之為列主序的矩陣順序。在記憶體中,用二維陣列表示4x4矩陣是以行主序儲存的。

圖6,來至opengl超級寶典

真正的奧秘在於這16個值表示空間中乙個特定的位置和三個軸的方向。這4個列的每個列都表示乙個4元素的向量。為了簡單期間,我們把注意力集中在前3個元素中。第4列的那個向量包含了經過變換的座標系統的x、y、x值。當我們在單位矩陣上呼叫gltranslate函式時,他所完成的任務就是把我們提供的x、y、z值放在這個矩陣的底12、13、14位置上。

前3列只是方向向量,便是空間中x、y、z軸的方向。在絕大多數情況下,這3個向量相互之間呈90度垂直(正交),如圖7所示;

最令人吃驚的事情是如果乙個4x4的矩陣包含乙個不同的座標系統的位置和方向。那麼,把乙個頂點(以乙個列矩陣或向量的形式)與這個矩陣相乘,其結果就是乙個變換到該座標的新頂點。這意味著空間中任何位置以及自己所需要的任何方向都可以通過乙個4x4的矩陣進行唯一的定義,並且,如果把乙個物體的所有頂點與這個矩陣相乘,就可以把整個物體變換到空間指定的位置和方向。

圖7,來至opengl超級寶典

opengl提供了載入矩陣的方法:

void glloadmatrixd (const gldouble *m);

void glloadmatrixf (const glfloat *m);

絕大多數opengl實現使用float而不是double型別儲存和操作管線資料。因此,如果在程式中使用double,可能會產生效能上的影響,因為16位浮點數必須轉換成單精度浮點數。下面**顯示把乙個陣列載入成單位矩陣;

glfloat matrix[16] =   ;

glmatrixmode(gl_modelview);

glloadmatrixf(matrix);

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學習07 繪製立方體

opengl在繪製場景之前,需要先產生或者說定義乙個場景,這個產生目標場景檢視的過程類似於照相機拍照的過程。1.把照相機固定在三角架上,並讓它對準場景 檢視變換 2.對場景進行安排,使各個物體在 中的位置是我們所希望的 模型變換 3.選擇照相機鏡頭,並調整放大倍數 投影變換 4.確定最終 的大小。例...