1. 程式人生 > >7.OpenGL學習之三維觀察

7.OpenGL學習之三維觀察

三維觀察

如果對比紋理對映和以前的程式碼,發現多了呼叫gluLookAt方法語句,如下圖所示。
這裡寫圖片描述
如果沒有這條語句,窗口裡什麼都沒有。這其中涉及到三維觀察或者變換管線,而三維觀察的設定在OpenGL程式設計中非常重要的。變換管線的處理流程如下圖。
這裡寫圖片描述
類比到我們現實生活 理解上圖的意思。如果我們要觀察一個物體,我們可以從不同的位置去觀察它(檢視變換);移動或者旋轉它(模型變換);如果把物體畫下來,我們可以選擇:是否需要一種“近大遠小”的透視效果(投影變換);我們可能只希望看到物體的一部分,而不是全部(剪裁);我們可能希望把整個看到的圖形畫下來,但它只佔據紙張的一部分,而不是全部(視口變換)。

模型檢視變換
上圖中輸入(初始化頂點資料)是在模型座標(或區域性座標)中得到的,相對於世界座標。該位置要經過模型變換才能得到世界座標系的位置,關係如下:
這裡寫圖片描述
模型座標系中的點Pm可以通過下面公式獲得在世界座標系中的位置。
這裡寫圖片描述
不同位置觀察物體,決定了採用哪種檢視座標系(或者叫相機座標系)。下面公式計算世界座標系的點在檢視座標系中的位置。
這裡寫圖片描述
變換示意圖如下。在OpenGL中,模型變換和檢視變換是在GL_MODELVIEW狀態下一起設定的。任何對相機位置和方向的改變都要更新模型檢視矩陣。
這裡寫圖片描述
gluLookAt(eye.x, eye,y, eye.z, look.x, look.y, look.z, up.x, up.y, up.z)就是設定檢視座標系的,引數是相對於世界座標而言。如果沒有呼叫gluLookAt(),那麼照相機就被設定為預設的位置和方向。在預設情況下,照相機位於原點,指向z軸的負方向,朝上向量為(0,1,0)。

投影變換

投影變換將在模型檢視變換之後應用到頂點上。這種投影實際上定義了視景體並建立了裁剪平面。投影一般分為正投影和透視投影。正投影大多在進行2D繪製使用。glOrtho(left, right, bottom, top, near, far)建立一個平行六面體的視景圖,它在x方法上從left到right延伸,在y方向上從bottom到top延伸,在z方向上從near到far延伸。
透視投影所顯示的場景與現實生活中更加接近,遠處的物體看起來比近處同樣大小的物體更小些。
設定視景體可以使用gluPerspective 和glFrustum,二者都能達到相同的效果。下圖中,兩個藍色平面之間為可見區域,如果物體不在兩平面之間,在軟體裡是看不見該物體。另外函式的引數是相對於檢視座標而言的。
gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
這裡寫圖片描述


void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);
這裡寫圖片描述

視口變換

當我們得到了一個場景的二維投影,它將被對映到螢幕上某處的視窗上。這種到物理視窗的對映是我們最後要做的變換,稱為視口變換。在OpenGL使用下面函式進行設定。
glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
這裡寫圖片描述
對於二維繪圖而言,世界視窗由函式gluOrtho2D()設定,它的原型是
void gluOrtho2D(GLdouble left, GLdouble right, GLdouble buttom, GLdouble top);
對於三維情況,視口的設定通過glViewport()函式,它的原型是:
void glViewport(GLint x, GLint y, GLint width, GLint height);
設定視口的左下角,以及寬度和高度。

示例演示

1、眼睛在Z軸上,gluLookAt(0, 0, 16, 0, 0, 0, 0, 1, 0)

這裡寫圖片描述

2、眼睛沿Z軸向原點靠近,gluLookAt(0, 0, 8, 0, 0, 0, 0, 1, 0),物體變大

這裡寫圖片描述

3、如果不呼叫gluLookAt函式,由於程式中glFrustum(-x, +x, -1.0, +1.0, 4.0, 20.0),此時在檢視座標系裡物體在xmin = -1,xmax = 1,ymin = -1,ymax = 1,zmin = -1,zmax = 1 的立方體區域裡,處於視景體之外,所以看不見物體。

這裡寫圖片描述

4、眼睛在X軸上,gluLookAt(8, 0, 0, 0, 0, 0, 0, 1, 0)。程式中繞X軸旋轉。

這裡寫圖片描述