opengl中圖形繪制后,往往需要一系列的變換來達到用戶的目的,而這種變換實現的原理是又通過矩陣進行操作的。opengl中的變換一般包括視圖變換、模型變換、投影變換等,在每次變換后,opengl將會呈現一種新的狀態(這也就是我們為什么會稱其為狀態機)。
首先我們要知道,對于矩陣的操作都是對于矩陣棧的棧頂來操作的。當前矩陣即為矩陣棧的棧頂元素,而對當前矩陣進行平移、旋轉等的變換操作也同樣是對棧頂矩陣的修改。所以我們在變換之前調用glPushMatrix()的話,就會把當前狀態壓入第二層,不過此時棧頂的矩陣也與第二層的相同。
當經過一系列的變換后,棧頂矩陣被修改,此時調用glPopMatrix()時,棧頂矩陣被彈出,且又會恢復為原來的狀態。
函數的作用過程可以用下圖描述,更為直觀。
如上圖,從第一個圖狀態1到第二個圖狀態2調用了glPushMatrix()方法,此時矩陣棧的第一個和第二個的狀態是一樣的,但是平移、旋轉等方法都是對棧頂元素操作的,在經過平移,旋轉之后棧頂的狀態1變為狀態2,此時對狀態2再進行某些繪制,在調用glPopMatrix()彈棧,就相當于在狀態1的情況下繪制了。
那么這么做有什么意義呢?
對于某些復雜的繪制,比如一個3D迷宮,障礙是很多墻壁,墻壁是由很多個立方體構成了,我們需要繪制大量的立方體,但是立方體的位置是分布在不同地方的,如果我們每繪制一個立方體都要移動到相應的位置,無疑是十分困難的,但是如果我們先調用glPushMatrix(),在把所有的立方體都移動到中心,然后在繪制, 在調用glPopMatrix(),把這個立方體彈棧,返回原來的位置,我們就只需要一個簡單的for循環就可以做到。此時,可以簡單的把glPushMatrix()和glPopMatrix()方法理解為移動到指定位置,在移動回來;當然,這兩個方法不僅僅適用于移動。相應的理解就是旋轉相應的角度在旋轉回來。
在opengl場景中一般存在多種矩陣變換操作,而控制這些操作的命令主要用到
glMatrixMode(GLenum mode);
作用:用于指定用哪個矩陣作為當前矩陣,mode用于指定哪一種矩陣棧是其后矩陣操作的目標。
mode可取:
GL_MODELVIEW: 把其后的矩陣操作施加于模型視圖矩陣棧。(默認)
GL_PROJECTION: 把其后的矩陣操作施加于投影矩陣棧。
GL_TEXTURE: 把其后的矩陣操作施加于紋理矩陣棧。
注意上述三種模式分別對應了三種矩陣棧。 所以在場景中存在多種矩陣變換時,glPushMatrix()和glPopMatrix()一般情況下也要結合glMatrixMode(GLenum mode)運用,系統才知道具體操作的是哪個矩陣棧。
注釋:
1.模型視圖矩陣是在對物體進行縮放或者從不同的視角觀察物體的時候所調用的。主要涉及到三個函數:
進行模型和視圖變換,主要涉及到三個函數:
(1)glTranslate(x,y,z),把當前矩陣和一個表示移動物體的矩陣相乘。三個參數分別表示了在三個坐標上的位移值。
(2)glRotate(angle,x,y,z),把當前矩陣和一個表示旋轉物體的矩陣相乘。物體將繞著(0,0,0)到(x,y,z)的直線以逆時針旋轉,參數angle表示旋轉的角度。
(3)glScale(x,y,z),把當前矩陣和一個表示縮放物體的矩陣相乘。x,y,z分別表示在該方向上的縮放比例。
2.投影矩陣是定義一個可視空間,可視空間以外的物體不會被繪制到屏幕上。投影分為正投影和透視投影
**(1)透視投影常見的方法:
gluPerspective
gluLookAt
(2)正投影常見的方法:
glOrtho
**