OpenGL座標系與幾何變換
title: OpenGL座標系
date: 2015-3-14
tags: OpenGL
座標系統
想要弄懂幾何變換,一定要搞清楚OpenGL中的座標系統。
從我們構造模型的區域性座標系(Local/Object Space)經過一系列處理最終渲染到螢幕座標(Screen Space)下,這過程中有6種座標系。
- World Coordinates(世界座標系)
- Object Coordinates(物件座標系、模型座標系、區域性座標系或當前繪圖座標系)
- Eye Coordinates(眼座標系或照相機座標系)
- Clip Coordinates(裁剪座標系)
- Normalized Device Coordinates (NDC) (歸一化裝置座標系)
- Window Coordinates (Screen Coordinates)(螢幕座標)
繪製管線如圖所示:
實際上,並不存在單獨的模型變換(Model)和視點變換(View),通常將這兩種變換合稱為ModelView變換。則OpenGL的頂點變換過程如圖所示:
世界座標系
世界座標系始終是固定不變的。OpenGL使用右手座標,這裡有一個形象的方法:使用右手定則
X 是你的拇指
Y 是你的食指
Z 是你的中指
如果你把你的拇指指向右邊,食指指向天空,那麼中指將指向你的背後。我們的觀察方向是Z軸負半軸的方向。
進行旋轉操作時需要指定的角度θ的方向則由右手法則來決定,即右手握拳,大拇指直向某個座標軸的正方向,那麼其餘四指指向的方向即為該座標軸上的θ角的正方向(即θ角增加的方向),圖中用圓弧形箭頭標出:
![](http://image-for-blog.qiniudn.com/螢幕快照 2015-03-14 下午4.46.40.png?imageView2/2/w/300)
物件座標系
這是物件在被應用任何變換之前的初始位置和方向所在的座標系,也就是當前繪圖座標系。該座標系不是固定的,且僅對該物件適用。在預設情況下,該座標系與世界座標系重合。這裡能用到的函式有glTranslatef(),glScalef(), glRotatef(),當用這些函式對當前繪圖座標系進行平移、伸縮、旋轉變換之後, 世界座標系和當前繪圖座標系不再重合。改變以後,再用glVertex3f()等繪圖函式繪圖時,都是在當前繪圖座標系進行繪圖,所有的函式引數也都是相對當前繪圖座標系來講的。如圖則是對物體進行變換後,物件座標系與世界座標系的相對位置。
眼座標系
模型變換:物件座標系->世界座標系
視變換:世界座標系->眼座標系
為啥要轉換到眼座標系呢?
可以這樣理解,通過前面的MODEVIEW變換,這個世界座標系中的場景已經繪製好了。這時候我們還不能看到場景哦,因為我們的觀察位置還沒定呢,而且如果我們眼睛(照相機)的位置不同,那麼觀察物體的角度則不同,那看到的場景的樣子肯定也不同,所以要有這一步,把場景與我們的觀察位置對應起來。
預設情況下,眼座標系與世界座標系也是重合的。使用函式 gluLookAt()則可以指定眼睛(相機)的位置和眼睛看向的方向。該函式的原型如下:
void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz);
函式引數中,點(eyex, eyey, eyez)代表眼睛所在位置;
點(centerx, centery,centerz)代表眼睛看向的位置;
向量(upx, upy, upz)代表視線向上方向,其中視點和參考點的連線與視線向上方向要保持垂直關係。
只需控制這三個量,便可定義新的視點。
tips
使用glTranslatef(),glScalef(), glRotatef()這些函式是對物件座標系進行變動;使用void gluLookAt()是對眼座標系進行變動,兩者可以達到相同的變換效果。相當於物件不動移動相機,和相機不動移動物件。比如場景向x軸正方向移動1個單位(相機不動),相當於相機向x軸負方向移動一個單位(物件不動),glTranslatef(1.0, 0.0, 0.0) <=> gluLookAt(-1.0, 0.0, 0.0, ..., ... )。
裁剪座標系
眼座標到裁剪座標是通過投影完成的。眼座標通過乘以GL_PROJECTION矩陣變成了裁剪座標。
透視投影
類似於日常生活看到的場景,遠處物體看起來小,近處看起來大。使用透視投影函式glFrustum()和gluPerspective().
void glFrustum(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near, GLdouble far)
far, near是指近裁剪面,遠剪裁面離視點的距離(>0),
對角座標, (left, bottom, -near)和(right, top, -near)定義了近裁剪面的左下角和右上角的(x, y, z)座標。
void gluPerspective(GLdouble fovy, GLdouble aspect,
GLdouble near, GLdouble far)
fovy視角,aspect = w/h
![](http://image-for-blog.qiniudn.com/螢幕快照 2015-03-14 下午7.44.25.png?imageView2/2/w/320)正投影
把物體直接對映到螢幕上,不影響它們的相對大小。也就是影象反映物體的實際大小。函式glOrtho()建立一個用於正交投影的平行視景體, 將其與當前矩陣相乘。
void glOrtho(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near, GLdouble far);
![](http://image-for-blog.qiniudn.com/螢幕快照 2015-03-14 下午7.44.35.png?imageView2/2/w/320)
歸一化裝置座標系
由裁剪座標系下通過除以W分量得到。這個操作稱為透視除法。NDC座標很像螢幕座標,但是還沒有經過平移和縮放到螢幕畫素。現在3個軸上的值範圍均為[-1,1]。螢幕座標系
通常將螢幕上的裝置座標稱為螢幕座標。裝置座標又稱為物理座標,是指輸出裝置上的座標。裝置座標用物件距離視窗左上角的水平距離和垂直距離來指定物件的位置,是以畫素為單位來表示的,裝置座標的 X 軸向右為正,Y 軸向下為正,座標原點位於視窗的左上角。
從NDC座標到螢幕座標基本上是一個線性對映關係。通過對NDC座標進行視口變換得到。這時候就要用到函式glViewport(),該函式用來定義渲染區域的矩形,也就是最終影象對映到的區域。
小結
以上是我對OpenGL座標系統的學習筆記,主要參考了這篇很詳細的博文以及其中的連結博文。
相關文章
- OpenGL中的座標變換、矩陣變換矩陣
- OpenGL入門第三課--矩陣變換與座標系統矩陣
- OpenGL ES on iOS --- 座標系統與矩陣轉換iOS矩陣
- 齊次座標與投影幾何
- OpenGL 座標系統詳解
- Python pytorch 座標系變換與維度轉換PythonPyTorch
- pose座標變換
- 地心地固座標系(ECEF)與站心座標系(ENU)的轉換
- 理解SVG transform座標變換SVGORM
- Core Graphics框架 :仿射變換與齊次座標框架
- 理解SVG座標系統和變換: transform屬性SVGORM
- ROS TF :使用 TF 設定機器人 釋出座標變換 使用座標變換 將感測器資料轉換為機器人座標系下ROS機器人
- ogre, dx, opengl座標矩陣矩陣
- Qt - 座標系及轉換QT
- 三維空間座標系變換-旋轉矩陣矩陣
- 理解SVG座標系統和變換: 建立新視窗SVG
- 【計算幾何】求線段相交交點座標
- ArcGIS地圖投影與座標系轉換的方法地圖
- GIS中的座標系定義與轉換 (轉)
- 理解SVG座標系和變換:視窗,viewBox和preserveAspectRatioSVGView
- 計算機圖形學(四)_幾何變換_1_基本的二維幾何變換(一)計算機
- 向量和矩陣的座標變換7矩陣
- opencv 圖片幾何變換-縮放OpenCV
- MoseEvent 中的幾種座標系
- svg06——svg中座標變換與順序的關係SVG
- 計算機圖形學(四)_幾何變換_1_基本的二維幾何變換(二)_旋轉計算機
- 計算機圖形學(四)_幾何變換_1_基本的二維幾何變換(三)_縮放計算機
- 雷達座標變換及其相關運算
- OpenGL模型檢視變換、投影變換、視口變換模型
- 向量和矩陣的座標變換(下標記法)7矩陣
- ogre世界座標魚螢幕座標相互轉換
- 利用齊次座標進行二維座標轉換
- 計算機視覺—圖片幾何變換(2)計算機視覺
- OpenGL 使用矩陣變換改變檢視矩陣
- [WebGL入門]十三,minMatrix.js和座標變換矩陣WebJS矩陣
- 座標系定義和相互轉換演算法演算法
- MathNet Ray3D座標系下轉換3D
- Go版本的各座標系互相轉換的工具Go