1. 程式人生 > >openGL座標系

openGL座標系

從我們構造模型的區域性座標系(Local/Object Space)經過一系列的處理最終渲染到螢幕座標系(Screen Space)下,這個過程有6種座標系。

一、世界座標系(World Coordinates)

學名:右手笛卡爾座標系統。

在OpenGL中,世界座標系是以螢幕中心為原點(0, 0, 0),且是始終不變的。x軸正方向為螢幕從左向右,y軸正方向為螢幕從下向上,z軸正方向為螢幕從裡向外。長度單位這樣來定:視窗範圍按此單位恰好是(-1,-1)到(1,1),即螢幕左下角座標為(-1,-1),右上角 座標為(1,1)。

進行旋轉操作時需要指定的角度θ的方向則由右手法則來決定,即右手握拳,大拇指直向某個座標軸的正方向,那麼其餘四指指向的方向即為該座標軸上的θ角的正方向(即θ角增加的方向),在上圖中用圓弧形箭頭標出。

座標變換矩陣棧:

用來儲存一系列的變換矩陣,棧頂就是當前座標的變換矩陣,進入OpenGL管道的每個座標(齊次座標)都會先乘上這個矩陣,結果才是對應點在場景中的世界座標。OpenGL中的座標變換都是通過矩陣運算完成的。 
如圖: 

物件座標系(乘以模型檢視矩陣)--->眼睛座標系(乘以投影矩陣)--->裁剪座標系(除以w)--->標準裝置座標系--->裝置座標系

二、物件/模型/區域性/繪圖座標系(object coordinate)

這是物件在被應用任何變換之前的初始位置和方向所在的座標系,也就是當前繪圖座標系。該座標系 不是固定的
,且 僅對該物件適用。在預設情況下,該座標系與世界座標系重合。這裡能用到的函式有 glTranslatef(),glScalef(), glRotatef(),當用這些函式對當前繪圖座標系進行平移、伸縮、旋轉變換之後, 世界座標系和當前繪圖座標系不再重合。改變以後,再用glVertex3f()等繪圖函式繪圖時,都是在當前繪圖座標系進行繪圖,所有的函式引數也都是相對當前繪圖座標系來講的。如圖則是對物體進行變換後,物件座標系與世界座標系的相對位置。

三、眼/照相機座標系(eye coordinate)

模型變換:物件座標系-->世界座標系

檢視變換:世界座標系-->眼睛座標系

GL_MODELVIEW矩陣是模型變換和試圖變換矩陣的組合(view*model),因為沒有單獨的模型變換和檢視變化,所以使用GL_MODELVIEW矩陣可以使物件直接從物件座標系轉換到眼睛座標系。

為什麼要轉換到眼睛座標系?

因為我們的觀察位置沒定,如果我們的眼睛(照相機)的位置不同,那麼觀察物體的角度則不同,看到的樣子也不同,所有要有這一步,把場景與我們的觀察位置對應起來。

預設情況下,眼睛座標系與世界座標系也是重合的。使用gluLookAt()則可以指定眼睛(相機)的位置和眼睛看的方向。該函式的原型如下:

1 void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, 
2                         GLdouble centerx, GLdouble centery, GLdouble centerz,
3                         GLdouble upx, GLdouble upy, GLdouble upz);

函式引數中,點(eyex, eyey, eyez)代表眼睛所在位置;
點(centerx, centery,centerz)代表眼睛看向的位置;
向量(upx, upy, upz)代表視線向上方向,其中視點和物體的連線與視線向上方向要保持。

注:

使用glTranslatef(),glScalef(), glRotatef()這些函式是對 物件座標系進行變動;使用void gluLookAt()是對 眼座標系進行變動,兩者可以達到相同的變換效果。相當於物件不動移動相機,和相機不動移動物件。比如場景向x軸正方向移動1個單位(相機不動),相當於相機向x軸負方向移動一個單位(物件不動),glTranslatef(1.0, 0.0, 0.0) <=> gluLookAt(-1.0, 0.0, 0.0, ..., ... )。

四、裁剪座標系(clip coordinate)

眼座標到裁剪座標是通過投影完成的。眼座標通過乘以GL_PROJECTION矩陣變成了裁剪座標。

投影分為透視投影(perspective projection)和正交投影(orthographic projection)

1>透視投影

類似日常生活看到的場景,遠大近小。透視投影函式有兩個:gluPerspective()和glFrustum()

1 void glFrustum(GLdouble left, GLdouble right,
2       GLdouble bottom, GLdouble top, 
3       GLdouble near, GLdouble far)
1 void gluPerspective(GLdouble fovy,  GLdouble aspect,
2           GLdouble near, GLdouble far) 

far, near是指近裁剪面,遠剪裁面離視點的距離(>0),fovy視角,aspect = w/h

2>正投影

1 void glOrtho(GLdouble left, GLdouble right,
2            GLdouble bottom, GLdouble top, 
3            GLdouble near, GLdouble far);

把物體直接對映到螢幕上,不影響它的相對大小。也就是影象反映物體的實際大小。

五、歸一化裝置座標系(normalized device coordinate)

在裁剪座標系下通過除以w分量得到,這個操作稱為透視除法。得到的座標值均為[-1,1]

六、螢幕座標(screen coordinate)

螢幕座標的x軸向右為正,y軸向下為正,座標原點位於視窗的左上角。是歸一化裝置座標系通過視口變換得到(viewport)

幾何變換

OpenGL中可以使用的幾何變換有平移、旋轉、縮放三種。

glTranslatef(x, y, z);

該函式可以實現平移變換,x、y、z為各座標軸上的平移量。

glRotatef(θ, x, y, z);

該函式實現旋轉變換。θ為旋轉角度,x、y、z為旋轉軸。旋轉方向由右手法則決定(參見第一節“座標系”)。

glScalef(x, y, z);

該函式實現縮放變換。x、y、z為各軸方向的擴大量。若為負值,則沿著座標軸的反方向進行縮放。