OpenGL坐標(biāo)系與幾何變換

title: OpenGL坐標(biāo)系
date: 2015-3-14
tags: OpenGL


坐標(biāo)系統(tǒng)

想要弄懂幾何變換碍现,一定要搞清楚OpenGL中的坐標(biāo)系統(tǒng)。
從我們構(gòu)造模型的局部坐標(biāo)系(Local/Object Space)經(jīng)過(guò)一系列處理最終渲染到屏幕坐標(biāo)(Screen Space)下晓勇,這過(guò)程中有6種坐標(biāo)系畜伐。

  • World Coordinates(世界坐標(biāo)系)
  • Object Coordinates(對(duì)象坐標(biāo)系、模型坐標(biāo)系想际、局部坐標(biāo)系或當(dāng)前繪圖坐標(biāo)系)
  • Eye Coordinates(眼坐標(biāo)系或照相機(jī)坐標(biāo)系)
  • Clip Coordinates(裁剪坐標(biāo)系)
  • Normalized Device Coordinates (NDC) (歸一化設(shè)備坐標(biāo)系)
  • Window Coordinates (Screen Coordinates)(屏幕坐標(biāo))

繪制管線如圖所示:



實(shí)際上棉饶,并不存在單獨(dú)的模型變換(Model)和視點(diǎn)變換(View),通常將這兩種變換合稱為ModelView變換涂籽。則OpenGL的頂點(diǎn)變換過(guò)程如圖所示:


世界坐標(biāo)系

世界坐標(biāo)系始終是固定不變的。OpenGL使用右手坐標(biāo),這里有一個(gè)形象的方法:使用右手定則
X 是你的拇指
Y 是你的食指
Z 是你的中指
如果你把你的拇指指向右邊衡蚂,食指指向天空,那么中指將指向你的背后薄榛。我們的觀察方向是Z軸負(fù)半軸的方向讳窟。
進(jìn)行旋轉(zhuǎn)操作時(shí)需要指定的角度θ的方向則由右手法則來(lái)決定,即右手握拳敞恋,大拇指直向某個(gè)坐標(biāo)軸的正方向丽啡,那么其余四指指向的方向即為該坐標(biāo)軸上的θ角的正方向(即θ角增加的方向),圖中用圓弧形箭頭標(biāo)出:
![](http://image-for-blog.qiniudn.com/屏幕快照 2015-03-14 下午4.46.40.png?imageView2/2/w/300)

對(duì)象坐標(biāo)系

這是對(duì)象在被應(yīng)用任何變換之前的初始位置和方向所在的坐標(biāo)系硬猫,也就是當(dāng)前繪圖坐標(biāo)系补箍。該坐標(biāo)系不是固定的,且僅對(duì)該對(duì)象適用啸蜜。在默認(rèn)情況下坑雅,該坐標(biāo)系與世界坐標(biāo)系重合。這里能用到的函數(shù)有g(shù)lTranslatef()衬横,glScalef(), glRotatef()裹粤,當(dāng)用這些函數(shù)對(duì)當(dāng)前繪圖坐標(biāo)系進(jìn)行平移、伸縮蜂林、旋轉(zhuǎn)變換之后遥诉, 世界坐標(biāo)系和當(dāng)前繪圖坐標(biāo)系不再重合。改變以后噪叙,再用glVertex3f()等繪圖函數(shù)繪圖時(shí)矮锈,都是在當(dāng)前繪圖坐標(biāo)系進(jìn)行繪圖,所有的函數(shù)參數(shù)也都是相對(duì)當(dāng)前繪圖坐標(biāo)系來(lái)講的睁蕾。如圖則是對(duì)物體進(jìn)行變換后苞笨,對(duì)象坐標(biāo)系與世界坐標(biāo)系的相對(duì)位置。

眼坐標(biāo)系

模型變換:對(duì)象坐標(biāo)系->世界坐標(biāo)系
視變換:世界坐標(biāo)系->眼坐標(biāo)系

GL_MODELVIEW矩陣是模型變換矩陣和視變換矩陣的組合(Mview*Mmodel)子眶,前面已經(jīng)說(shuō)了瀑凝,并不存在單獨(dú)的模型變換(Model)和視點(diǎn)變換(View)。所以使用GL_MODELVIEW矩陣就可以使對(duì)象從對(duì)象坐標(biāo)系轉(zhuǎn)換到眼坐標(biāo)系臭杰。

為啥要轉(zhuǎn)換到眼坐標(biāo)系呢猜丹?
可以這樣理解,通過(guò)前面的MODEVIEW變換硅卢,這個(gè)世界坐標(biāo)系中的場(chǎng)景已經(jīng)繪制好了射窒。這時(shí)候我們還不能看到場(chǎng)景哦藏杖,因?yàn)槲覀兊挠^察位置還沒(méi)定呢,而且如果我們眼睛(照相機(jī))的位置不同脉顿,那么觀察物體的角度則不同蝌麸,那看到的場(chǎng)景的樣子肯定也不同,所以要有這一步艾疟,把場(chǎng)景與我們的觀察位置對(duì)應(yīng)起來(lái)来吩。

默認(rèn)情況下,眼坐標(biāo)系與世界坐標(biāo)系也是重合的蔽莱。使用函數(shù) gluLookAt()則可以指定眼睛(相機(jī))的位置和眼睛看向的方向弟疆。該函數(shù)的原型如下:

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

函數(shù)參數(shù)中,點(diǎn)(eyex, eyey, eyez)代表眼睛所在位置;
點(diǎn)(centerx, centery,centerz)代表眼睛看向的位置盗冷;
向量(upx, upy, upz)代表視線向上方向,其中視點(diǎn)和參考點(diǎn)的連線與視線向上方向要保持垂直關(guān)系怠苔。
只需控制這三個(gè)量,便可定義新的視點(diǎn)。

tips

使用glTranslatef()仪糖,glScalef(), glRotatef()這些函數(shù)是對(duì)對(duì)象坐標(biāo)系進(jìn)行變動(dòng)柑司;使用void gluLookAt()是對(duì)眼坐標(biāo)系進(jìn)行變動(dòng),兩者可以達(dá)到相同的變換效果锅劝。相當(dāng)于對(duì)象不動(dòng)移動(dòng)相機(jī)攒驰,和相機(jī)不動(dòng)移動(dòng)對(duì)象。比如場(chǎng)景向x軸正方向移動(dòng)1個(gè)單位(相機(jī)不動(dòng))故爵,相當(dāng)于相機(jī)向x軸負(fù)方向移動(dòng)一個(gè)單位(對(duì)象不動(dòng))玻粪,glTranslatef(1.0, 0.0, 0.0) <=> gluLookAt(-1.0, 0.0, 0.0, ..., ... )。

裁剪坐標(biāo)系

眼坐標(biāo)到裁剪坐標(biāo)是通過(guò)投影完成的诬垂。眼坐標(biāo)通過(guò)乘以GL_PROJECTION矩陣變成了裁剪坐標(biāo)劲室。

這個(gè)GL_PROJECTION矩陣定義了視景體( viewing volume),即確定哪些物體位于視野之內(nèi)剥纷,位于視景體外的對(duì)象會(huì)被剪裁掉。除了視景體呢铆,投影變換還定義了頂點(diǎn)是如何投影到屏幕上的晦鞋,是透視投影(perspective projection)還是正交投影(orthographic projection)。
透視投影類似于日常生活看到的場(chǎng)景棺克,遠(yuǎn)處物體看起來(lái)小悠垛,近處看起來(lái)大。使用透視投影函數(shù)glFrustum()和gluPerspective().

void glFrustum(GLdouble left, GLdouble right,
      GLdouble bottom, GLdouble top, 
      GLdouble near, GLdouble far)

far, near是指近裁剪面娜谊,遠(yuǎn)剪裁面離視點(diǎn)的距離(>0),
對(duì)角坐標(biāo), (left, bottom, -near)和(right, top, -near)定義了近裁剪面的左下角和右上角的(x, y, z)坐標(biāo)确买。

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)
正投影把物體直接映射到屏幕上纱皆,不影響它們的相對(duì)大小湾趾。也就是圖像反映物體的實(shí)際大小芭商。函數(shù)glOrtho()創(chuàng)建一個(gè)用于正交投影的平行視景體, 將其與當(dāng)前矩陣相乘。

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)

歸一化設(shè)備坐標(biāo)系

由裁剪坐標(biāo)系下通過(guò)除以W分量得到搀缠。這個(gè)操作稱為透視除法铛楣。NDC坐標(biāo)很像屏幕坐標(biāo),但是還沒(méi)有經(jīng)過(guò)平移和縮放到屏幕像素∫掌眨現(xiàn)在3個(gè)軸上的值范圍均為[-1,1]簸州。

屏幕坐標(biāo)系

通常將屏幕上的設(shè)備坐標(biāo)稱為屏幕坐標(biāo)。設(shè)備坐標(biāo)又稱為物理坐標(biāo),是指輸出設(shè)備上的坐標(biāo)歧譬。設(shè)備坐標(biāo)用對(duì)象距離窗口左上角的水平距離和垂直距離來(lái)指定對(duì)象的位置,是以像素為單位來(lái)表示的,設(shè)備坐標(biāo)的 X 軸向右為正,Y 軸向下為正,坐標(biāo)原點(diǎn)位于窗口的左上角岸浑。
從NDC坐標(biāo)到屏幕坐標(biāo)基本上是一個(gè)線性映射關(guān)系。通過(guò)對(duì)NDC坐標(biāo)進(jìn)行視口變換得到瑰步。這時(shí)候就要用到函數(shù)glViewport()矢洲,該函數(shù)用來(lái)定義渲染區(qū)域的矩形,也就是最終圖像映射到的區(qū)域面氓。

小結(jié)

以上是我對(duì)OpenGL坐標(biāo)系統(tǒng)的學(xué)習(xí)筆記兵钮,主要參考了這篇很詳細(xì)的博文以及其中的鏈接博文。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舌界,一起剝皮案震驚了整個(gè)濱河市掘譬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呻拌,老刑警劉巖葱轩,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異藐握,居然都是意外死亡靴拱,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門猾普,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)袜炕,“玉大人,你說(shuō)我怎么就攤上這事初家≠司剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵溜在,是天一觀的道長(zhǎng)陌知。 經(jīng)常有香客問(wèn)我,道長(zhǎng)掖肋,這世上最難降的妖魔是什么仆葡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮志笼,結(jié)果婚禮上沿盅,老公的妹妹穿的比我還像新娘把篓。我一直安慰自己,他們只是感情好嗡呼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布纸俭。 她就那樣靜靜地躺著,像睡著了一般南窗。 火紅的嫁衣襯著肌膚如雪揍很。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天万伤,我揣著相機(jī)與錄音窒悔,去河邊找鬼。 笑死敌买,一個(gè)胖子當(dāng)著我的面吹牛简珠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虹钮,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼聋庵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了芙粱?” 一聲冷哼從身側(cè)響起祭玉,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎春畔,沒(méi)想到半個(gè)月后脱货,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡律姨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年振峻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片择份。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扣孟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荣赶,到底是詐尸還是另有隱情凤价,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布讯壶,位于F島的核電站料仗,受9級(jí)特大地震影響湾盗,放射性物質(zhì)發(fā)生泄漏伏蚊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一格粪、第九天 我趴在偏房一處隱蔽的房頂上張望躏吊。 院中可真熱鬧氛改,春花似錦、人聲如沸比伏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赁项。三九已至葛躏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悠菜,已是汗流浹背舰攒。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悔醋,地道東北人摩窃。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像芬骄,于是被迫代替她去往敵國(guó)和親猾愿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容