OpenGL學(xué)習(xí)之專有名詞和坐標(biāo)系

一、 OpenGL簡介

  • OpenGL(Open Graphics Library)是一個(gè)跨編程語言、跨平臺(tái)的編程圖形程序接口,它將計(jì)算機(jī)的資源抽象稱為一個(gè)個(gè)OpenGL的對象,對這些資源的操作抽象為一個(gè)個(gè)的OpenGL指令
  • OpenGL ES(OpenGL for Embedded Systems)是 OpenGL 三維圖形 API 的子集,針對手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì),去除了許多不必要和性能較低的API接口。
  • DirectX:是由很多API組成的,DirectX并不是一個(gè)單純的圖形API. 最重要的是DirectX是屬于Windows上一個(gè)多媒體處理API.并不支持Windows以外的平臺(tái),所以不是跨平臺(tái)框架. 按照性質(zhì)分類,可以分為四大部分,顯示部分、聲音部分、輸入部分和網(wǎng)絡(luò)部分.
    • 顯示部分擔(dān)任圖形處理的關(guān)鍵,分為DirectDraw(DDraw)和Direct3D(D3D),前者主要負(fù)責(zé)2D圖像加速。后者則主要負(fù)責(zé)3D效果的顯示,比如CS中的場景和人物、FIFA中的人物等等,都是使用了DirectX的Direct3D。
    • 聲音部分中最主要的API是DirectSound,除了播放聲音和處理混音之外,還加強(qiáng)了3d音效,并提供了錄音功能
  • Metal: Apple為游戲開發(fā)者推出了新的平臺(tái)技術(shù) Metal,該技術(shù)能夠?yàn)?3D 圖像提高 10 倍的渲染性能.Metal 是Apple為了解決3D渲染而推出的框架,在2014年以前蘋果一直沿用OpenGL ES 來解決底層渲染.而后開始慢慢將自身的底層框架的依賴從OpenGL ES遷移到Metal.但其核心的處理思想還是源于OpenGL ES.對于適應(yīng)于OpenGL ES的開發(fā)者而言并沒有太大的改變.

引言:
從2014年到2018年.蘋果才完成了系統(tǒng)內(nèi)部從OpenGL ES過度到Metal.直到WWDC 2018,Apple 宣布 iOS 12 將棄用 OpenGL / CL.

二、OpenGL使用場景

  • 在游戲開發(fā)中,對于游戲場景/游戲人物的渲染
  • 在音視頻開發(fā)中,對于視頻解碼后的數(shù)據(jù)渲染
  • 在地圖引擎,對于地圖上的數(shù)據(jù)渲染
  • 在動(dòng)畫中,實(shí)現(xiàn)動(dòng)畫的繪制
  • 在視頻處理中,對于視頻加上濾鏡效果
  • 等等......

三、OpenGL專業(yè)名詞解析

  • OpenGL 上下文(context)

    在應(yīng)用程序調(diào)用任何OpenGL的指令之前,需要安排首先創(chuàng)建一個(gè)OpenGL的上下文。這個(gè)上下文是一個(gè)非常龐大的狀態(tài)機(jī),保存了OpenGL中的各種狀態(tài),這也是OpenGL指令執(zhí)行的基礎(chǔ)。

    OpenGL的函數(shù)不管在哪個(gè)語言中,都是類似C語言一樣的面向過程的函數(shù),本質(zhì)上都是對OpenGL上下文這個(gè)龐大的狀態(tài)機(jī)中的某個(gè)狀態(tài)或者對象進(jìn)行操作,當(dāng)然你得首先把這個(gè)對象設(shè)置為當(dāng)前對象。因此,通過對OpenGL指令的封裝,是可以將OpenGL的相關(guān)調(diào)用封裝成為一個(gè)面向?qū)ο蟮膱D形API的。

    由于OpenGL上下文是一個(gè)巨大的狀態(tài)機(jī),切換上下文往往會(huì)產(chǎn)生較大的開銷,但是不同的繪制模塊,可能需要使用完全獨(dú)立的狀態(tài)管理。因此,可以在應(yīng)用程序中分別創(chuàng)建多個(gè)不同的上下文,在不同線程中使用不同的上下文,上下文之間共享紋理、緩沖區(qū)等資源。這樣的方案,會(huì)比反復(fù)切換上下文,或者大量修改渲染狀態(tài),更加合理高效的。

  • OpenGL 狀態(tài)機(jī)

    狀態(tài)機(jī)是理論上的一種機(jī)器,我們可以把狀態(tài)機(jī)描述成一個(gè)對象在其生命周期中所經(jīng)歷的各種狀態(tài),狀態(tài)間的轉(zhuǎn)變,發(fā)生轉(zhuǎn)變的動(dòng)因,條件及轉(zhuǎn)變中所執(zhí)行的活動(dòng)。或者說是一種行為,說明對象在其生命周期中響應(yīng)事件所經(jīng)歷的狀態(tài)序列以及那些狀態(tài)事件的響應(yīng)。因此具有以下特點(diǎn):

    1. 有記憶功能,能記住當(dāng)前的狀態(tài)。
    2. 可以接收輸入,根據(jù)輸入的內(nèi)容和自己的原先狀態(tài),修改自己當(dāng)前狀態(tài),并且可以有對應(yīng)輸出
    3. 當(dāng)進(jìn)入特殊狀態(tài)(停機(jī)狀態(tài))的時(shí)候,將不再接收輸入,停止工作。

    在OpenGL中

    1. OpenGL可以記錄自己的狀態(tài)(如當(dāng)前所使用的顏色,是否開啟了混合功能等)
    2. OpenGL中可以接收輸入(當(dāng)調(diào)用OpenGL函數(shù)的時(shí)候,實(shí)際上可以看成OpenGL在接收我們的輸入),我們調(diào)用glColor3f,則OpenGL接收到這個(gè)輸入后會(huì)就修改自己的“當(dāng)前狀態(tài)”這個(gè)狀態(tài)。
    3. OpenGL可以計(jì)入停止?fàn)顟B(tài),不再接收輸入。程序在退出前,OpenGL總會(huì)先停止工作的。

    我們可以使用glColor*函數(shù)來選擇一種顏色,以后繪制的所有物體顏色都是這種顏色,除非再次使用glColor*函數(shù)重新設(shè)置。

    可以使用glColor*函數(shù)來選擇一種顏色,以后繪制的所有物體都是這種顏色,除非再次使用glColor*函數(shù)重新設(shè)定。

    可以使用glTexCoord*函數(shù)來設(shè)置一個(gè)紋理坐標(biāo),以后繪制的所有物體都是采用這種紋理坐標(biāo),除非再次使用glTexCoord*函數(shù)重新設(shè)置。

    可以使用glBlendFunc函數(shù)來指定混合功能的源因子和目標(biāo)因子,以后繪制的所有物體都是采用這個(gè)源因子和目標(biāo)因子,除非再次使用glBlendFunc函數(shù)重新指定。

    可以使用glLight*函數(shù)來指定光源的位置、顏色,以后繪制的所有物體都是采用這個(gè)光源的位置、顏色,除非再次使用glBlendFunc函數(shù)重新指定。

OpenGL是一個(gè)狀態(tài)機(jī),它保持自身的狀態(tài),除非用戶輸入一條命令讓它改變狀態(tài)。

例如:

//獲取是否深度測試/混合
glIsEnabled(GL_DEPTH_TEST);
glIsEnabled(GL_BLEND);

//開啟深度測試/混合
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);

//關(guān)閉深度測試/混合
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
  • 渲染(Rendering)

    將圖形/圖像數(shù)據(jù)轉(zhuǎn)換成3D空間圖像叫做渲染(Rendering)

  • 頂點(diǎn)數(shù)組(VertexArray)和頂點(diǎn)緩沖區(qū)(VertexBuffer)

    畫圖一般是先畫好圖像的骨架,然后在往骨架中填充顏色,對于OpenGL也是一樣的。頂點(diǎn)數(shù)據(jù)就是要畫的骨架,和現(xiàn)實(shí)中不同的是,OpenGL中的圖像都是由圖元組成。在OpenGLES中,有三種類型的圖元:點(diǎn)、線、三角形。這些頂點(diǎn)數(shù)據(jù)一般存儲(chǔ)在內(nèi)存中。開發(fā)者可以選擇函數(shù)指針,在調(diào)用繪制方法的時(shí)候,直接由內(nèi)存?zhèn)魅腠旤c(diǎn)數(shù)據(jù)。這部分被稱為頂點(diǎn)數(shù)組。一般性能高的做法是提前分配一塊顯存,將頂點(diǎn)數(shù)據(jù)預(yù)先傳入到顯存中去,這部分顯存就稱作頂點(diǎn)緩沖區(qū)。

    頂點(diǎn)是指我們在繪制一個(gè)圖形的時(shí)候,他在頂點(diǎn)位置的數(shù)據(jù),而這個(gè)數(shù)據(jù)一般是存儲(chǔ)在內(nèi)存數(shù)組中或者將其緩存到GPU內(nèi)存中。

  • 管線

    OpenGL中渲染圖形一般會(huì)經(jīng)歷一個(gè)一個(gè)的節(jié)點(diǎn),一般我們把這些節(jié)點(diǎn)稱作為管線,可以想象成流水線,每個(gè)任我類似流水線一般執(zhí)行,任務(wù)之間有先后順序。管線是一個(gè)抽象的概念,之所以成為管線是因?yàn)轱@卡在處理數(shù)據(jù)的時(shí)候是按照一個(gè)固定的順序來的,而且嚴(yán)格按照這個(gè)順序執(zhí)行。

  • 固定管線

    在早期OpenGL版本,它封裝了很多著色器程序內(nèi)置的一端包含光照、坐標(biāo)變換、剪裁等等諸多功能的固定shader程序來完成,來幫助開發(fā)者來完成圖形的渲染,而且開發(fā)者只需要傳入相應(yīng)的參數(shù),就能快速的完成圖形的渲染,類似于iOS開發(fā)中封裝的API,我們只需要調(diào)用,就可以實(shí)現(xiàn)相應(yīng)的功能,不需要關(guān)注底層的原理。

    但是OpenGL使用場景非常豐富,固定管線或者存儲(chǔ)著色器無法完成每一個(gè)業(yè)務(wù),這時(shí)我們就需要開放成可編程的。

  • 著色器程序(Shader)

就全面的將固定渲染管線架構(gòu)面成了可編程的渲染管線。因此,OpenGL在實(shí)際調(diào)用繪制函數(shù)之前,我們需要制定一個(gè)shader編譯成的著色器程序。常見的著色器有頂點(diǎn)著色器(VertexShader)片段著色器(fragmentShader)/片元著色器(fragmentShader)/像素著色器(PixelShader)、幾何著色器(GeimetryShader)、曲面細(xì)分著色器(TessellationShader)。直到OpenGL3.0,只支持頂點(diǎn)著色器和片元著色器。

OpenGL在處理shader是,和其他編程一樣。通過編譯、鏈接等步驟,生成了著色器程序(glProgram),著色器程序同時(shí)包含了頂點(diǎn)著色器和片元著色器的運(yùn)算邏輯。在OpenGL進(jìn)行繪制的時(shí)候,首先由頂點(diǎn)著色器對傳入的頂點(diǎn)數(shù)據(jù)進(jìn)行計(jì)算,在進(jìn)行圖元裝配,將頂點(diǎn)轉(zhuǎn)換為圖元。然后進(jìn)行光柵化處理,將圖元這種矢量圖形轉(zhuǎn)換為柵格化數(shù)據(jù)。最后,將柵格化數(shù)據(jù)傳入片元著色器中進(jìn)行運(yùn)算。片元著色器會(huì)對柵格化數(shù)據(jù)的每一個(gè)像素進(jìn)行運(yùn)算,并決定像素的顏色。

  • 頂點(diǎn)著色器(VertexShader)

    一般用于處理每個(gè)圖形的頂點(diǎn)變換的(旋轉(zhuǎn)/平移/投影等)

    頂點(diǎn)著色器是OpenGL中可用于計(jì)算頂點(diǎn)屬性的程序。頂點(diǎn)著色器是逐頂點(diǎn)運(yùn)算的程序。也就是每個(gè)頂點(diǎn)都會(huì)執(zhí)行一次頂點(diǎn)著色器,當(dāng)然這是并行的,并且頂點(diǎn)著色器運(yùn)算過程中無法訪問其他頂點(diǎn)數(shù)據(jù)。

    一般來說典型的粗腰計(jì)算的頂點(diǎn)屬性質(zhì)保包括頂點(diǎn)坐標(biāo)變換、頂點(diǎn)光照運(yùn)算等。頂點(diǎn)坐標(biāo)由自身坐標(biāo)系轉(zhuǎn)換歸一化坐標(biāo)系的計(jì)算,就是在這里發(fā)生的。

  • 片段著色器(fragmentShader)

    一般用于處理圖形中每個(gè)像素的顏色的計(jì)算和填充

    片段著色器是OpenGL中用于計(jì)算片段(像素)顏色的程序。片段著色器是逐像素運(yùn)算的程序,也就是說每個(gè)像素都會(huì)執(zhí)行一次片段著色器,當(dāng)然也是并行的。

  • GLSL(OpenGL Shading Language)

    OpenGL著色語言(OpenGL shading Language)是用來在OpenGL中著色編程的語言,也是開發(fā)者寫的自定義程序,他們實(shí)在圖形的GPU上執(zhí)行的。代替了固定的渲染管線的一部分,使渲染管線中不同層次具有可編程性。比如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等。GLSL(GL Shading Language)的著色器代碼分成2個(gè)部分:Vertex Shader(頂點(diǎn)著色器)和Fragment(片斷著色器)

  • 光柵化(Rasterization)

    是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換成片元的過程。具有將圖形化為一個(gè)個(gè)柵格組成的圖像的作用,特點(diǎn)是每個(gè)元素對應(yīng)幀緩沖中的每一個(gè)像素。

    光柵化就是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換成片元的過程。片元中的每一個(gè)元素對應(yīng)緩沖區(qū)中的一個(gè)像素。

    光柵化其實(shí)就是一種將幾何圖元變成二位圖像的過程。該過程包含了兩個(gè)部分。第一部分:決定窗口坐標(biāo)中那些整型柵格區(qū)域被基本圖元占用;第二部分:分配一個(gè)顏色值和深度值到各個(gè)區(qū)域。

    把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上用于對應(yīng)位置額的像素及用于填充像素的顏色,這個(gè)過程稱作光柵化。

  • 紋理

    紋理我們可以理解為圖片。在渲染圖形中需要編碼填充圖片,為了使得場景更加逼真 而這里使用的圖片就是常說的紋理,但是在OpenGL,我們更常叫紋理

  • 混合(Blending)

    在測試階段之后,如果像素依然沒有被剔除,那么像素的顏色將會(huì)和幀緩沖區(qū)中顏色附著上的顏色進(jìn)行混合,混合的算法可以通過OpenGL的函數(shù)進(jìn)行指定。但是OpenGL提供的混合算法是有限的,如果需要更加復(fù)雜的混合算法,一般可以通過像素著色器進(jìn)行實(shí)現(xiàn),當(dāng)然性能會(huì)比原生的混合算法差一些。

  • 變換矩陣

    例如圖形想發(fā)生平移,縮放,旋轉(zhuǎn)變換.就需要使用變換矩陣.

  • 投影矩陣(Projection)

    用于將3D坐標(biāo)轉(zhuǎn)換為二維屏幕坐標(biāo),實(shí)際線條也將在二維坐標(biāo)下進(jìn)行繪制.

  • 渲染上屏/交換緩沖區(qū)(SwapBuffer)

    渲染緩沖區(qū)一般映射的是系統(tǒng)的資源比如窗口。如果將圖像直接渲染到窗口對應(yīng)的渲染緩沖區(qū),則可以將圖像顯示到屏幕上。

    但是,值得注意的是,如果每個(gè)窗口只有一個(gè)緩沖區(qū),那么在繪制過程中屏幕進(jìn)行了刷新,窗口可能顯示出不完整的圖像。

    為了解決這個(gè)問題,常規(guī)的OpenGL程序至少都會(huì)有兩個(gè)緩沖區(qū)。顯示在屏幕上的稱為屏幕緩沖區(qū),沒有顯示的稱為離屏緩沖區(qū)。在一個(gè)緩沖區(qū)渲染完成之后,通過將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實(shí)現(xiàn)圖像在屏幕上的顯示。

    由于顯示器的刷新一般是逐行進(jìn)行的,因此為了防止交換緩沖區(qū)的時(shí)候屏幕上下區(qū)域的圖像分屬于兩個(gè)不同的幀,因此交換一般會(huì)等待顯示器刷新完成的信號(hào),在顯示器兩次刷新的間隔中進(jìn)行交換,這個(gè)信號(hào)就被稱為垂直同步信號(hào),這個(gè)技術(shù)被稱為垂直同步。

    使用了雙緩沖區(qū)和垂直同步技術(shù)之后,由于總是要等待緩沖區(qū)交換之后再進(jìn)行下一幀的渲染,使得幀率無法完全達(dá)到硬件允許的最高水平。為了解決這個(gè)問題,引入了三緩沖區(qū)技術(shù),在等待垂直同步時(shí),來回交替渲染兩個(gè)離屏的緩沖區(qū),而垂直同步發(fā)生時(shí),屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換,實(shí)現(xiàn)充分利用硬件性能的目的。

OpenGL坐標(biāo)系

2D笛卡爾坐標(biāo)系

在二維繪圖中,最為常用的坐標(biāo)系統(tǒng)是笛卡爾坐標(biāo)系統(tǒng). 笛卡爾坐標(biāo)由一個(gè)X和一個(gè)Y坐標(biāo)構(gòu)成.X表示水平方向位置,Y表示垂直方向的位置.

2D笛卡爾坐標(biāo)系

3D笛卡爾坐標(biāo)系

將2D笛卡爾坐標(biāo)系系統(tǒng)擴(kuò)展到三維空間中.從水平和垂直方向,增加了深度分量.
增加的深度分量用Z來表示,Z軸同時(shí)垂直于X,Y軸.它代表的是一條從屏幕中心朝向讀者的直線.
為了更好的觀察,我們將Y軸向做旋轉(zhuǎn),把X軸向下和后渲染.否則Z軸將直面我們,我們無法具體觀察到Z軸存在.
現(xiàn)在我們可以用3個(gè)坐標(biāo)(X,Y,Z)來指定三維空間中的一個(gè)位置.

3D笛卡爾坐標(biāo)系

視口

窗口是以像素為單位度量. 在開始在窗口中繪制點(diǎn),線,形狀之前,必須告訴OpenGL 如何把指定坐標(biāo)映射為屏幕坐標(biāo).
坐標(biāo)系統(tǒng)必須從邏輯笛卡爾坐標(biāo)映射到物理屏幕像素坐標(biāo). 這個(gè)映射是通過一種叫做視口(viewPort)的設(shè)置來指定.
在我們代碼中,我們會(huì)通過glViewPort函數(shù)來實(shí)現(xiàn)視口的設(shè)計(jì). 視口就是窗口內(nèi)部用于繪制裁剪區(qū)域的客戶區(qū)域.

視口
視口

投影:從3D到2D

不管我們覺得自己的眼睛看到的三維立體圖像多么真實(shí).屏幕上像素實(shí)際上只有二維的. 我們的手機(jī)屏幕本身就是二維的,我們是無法真實(shí)去呈現(xiàn)立體圖形.

那么OpenGL 是如何將笛卡爾坐標(biāo)系映射成可以在屏幕上顯示的二維坐標(biāo)的?
在這里需要用到投影.我們需要指定投影空間,指定在窗口顯示的視景體(Viewing Volume).并指定如何對它進(jìn)行變換.

舉例子: 類似于立體圖像站在鏡子前.
投影分為2種.

  • 第一種正投影(Orthographics Projection)或平行投影. 使用正投影時(shí),需要指定一個(gè)正方形/長方形的視景體. 在視景體以外的任何物體都不會(huì)被繪制. 并且使用正投影所以實(shí)際大小相同的物體在屏幕上都具有相同的大小.不管它們是否存在遠(yuǎn)近問題. 正投影比較適合平面圖形/2D圖形渲染時(shí)使用.
  • 第二種透視投影(Perspective Projection).它在3D開發(fā)中更為常見. 同樣需要指定視景體的.而這個(gè)視景體并不是類似于正方體,看起來像平截體. 透視投影一般會(huì)使用于3D圖像渲染.因?yàn)樗鼤?huì)更加逼真.
投影方式

左手坐標(biāo)系和右手坐標(biāo)系

左手/右手坐標(biāo)系

注意OpenGL中坐標(biāo)系 OpenGL中的物體、世界、照相機(jī)坐標(biāo)系都屬于右手坐標(biāo)系,而規(guī)范化設(shè)備坐標(biāo)系使用左手坐標(biāo)系。籠統(tǒng)地說OpenGL使用右手坐標(biāo)系是不合適的。

坐標(biāo)系

OpenGL 希望每次頂點(diǎn)著色后,我們的可見頂點(diǎn)都為標(biāo)準(zhǔn)化設(shè)備坐標(biāo)(Normalized Device Coordinate,NDC)。也就是說每個(gè)頂點(diǎn)的z,y,z都應(yīng)該在?1到1之間,超出這個(gè)范圍的頂點(diǎn)將是不可見的。

通常情況下我們會(huì)自己設(shè)定一個(gè)坐標(biāo)范圍,之后再在頂點(diǎn)著色器中將這些坐標(biāo)變換為表轉(zhuǎn)化設(shè)備坐標(biāo)。然后這些標(biāo)化設(shè)備坐標(biāo)傳入光柵器(Rasterizer),將它們變換為屏幕上的二維坐標(biāo)和像素。

將坐標(biāo)變換為標(biāo)準(zhǔn)化設(shè)備坐標(biāo),接著再轉(zhuǎn)化為屏幕坐標(biāo)的過程通常是分步進(jìn)行的,也就是類似于流水線那樣子。在流水線中,物體的頂點(diǎn)在最終轉(zhuǎn)化為屏幕坐標(biāo)之前還會(huì)被變換到多個(gè)坐標(biāo)系統(tǒng)(Coordinate System)。將物體的坐標(biāo)變換到幾個(gè)過渡坐標(biāo)系(Intermediate Coordinate System)的優(yōu)點(diǎn)在于,在這些特定的坐標(biāo)系統(tǒng)中,一些操作或運(yùn)算更加方便和容易,這一點(diǎn)很快就會(huì)變得很明顯。對我們來說比較重要的總共有5個(gè)不同的坐標(biāo)系統(tǒng)

  • 局部空間(Local Space,或者稱為物體空間(Object Space))
  • 世界空間(World Space)
  • 觀察空間(View Space,或者稱為視覺空間(Eye Space))
  • 裁剪空間(Clip Space)
  • 屏幕空間(Screen Space)

就是一個(gè)頂點(diǎn)在最終被轉(zhuǎn)化為片段之前需要經(jīng)歷的所有不同狀態(tài).為了將坐標(biāo)從一個(gè)坐標(biāo)系變換到另一個(gè)坐標(biāo)系,我們需要用到幾個(gè)變換矩陣,最重要的幾個(gè)分別是模型(Model)、觀察(View)、投影(Projection)三個(gè)矩陣。物體頂點(diǎn)的起始坐標(biāo)再局部空間(Local Space),這里稱它為局部坐標(biāo)(Local Coordinate),它在之后會(huì)變成世界坐標(biāo)(world Coordinate),觀測坐標(biāo)(View Coordinate),裁剪坐標(biāo)(Clip Coordinate),并最后以屏幕坐標(biāo)(Screen Corrdinate)的形式結(jié)束

在3D圖形學(xué)中常用的坐標(biāo)系:

  • 世界坐標(biāo)系
  • 物體坐標(biāo)系
  • 攝像機(jī)坐標(biāo)系
  • 慣性坐標(biāo)系

世界坐標(biāo)系: 世界坐標(biāo)系是系統(tǒng)的絕對坐標(biāo)系,在沒有建立用戶坐標(biāo)系之前畫面上所有的點(diǎn)的坐標(biāo)都可以在該坐標(biāo)系的原點(diǎn)來確定各自的位置.世界坐標(biāo)系始終是固定不變的

物體坐標(biāo)系: 每個(gè)物體都有他們獨(dú)立的坐標(biāo)系.當(dāng)物理移動(dòng)或者改變方向時(shí).該物體相關(guān)聯(lián)的坐標(biāo)系將隨之移動(dòng)或改變方向

物體坐標(biāo)系是以物體本身而言,比如,我先向你發(fā)指令,“向前走一步”,是向您的物體坐標(biāo)體系指令。我并不知道你會(huì)往哪個(gè)絕對的方向移動(dòng)。比如說,當(dāng)你開車時(shí),有人會(huì)說向左轉(zhuǎn),有人說向東。但是,向左轉(zhuǎn)是物體坐標(biāo)系的概念,而向東則是世界坐標(biāo)系中的。

在某種情況下,我們可以理解物體坐標(biāo)系為模型坐標(biāo)系。因?yàn)槟P晚旤c(diǎn)的坐標(biāo)都是在模型坐標(biāo)系中描述的。

攝像機(jī)(照相機(jī))坐標(biāo)系:在坐標(biāo)系的范疇里,攝像機(jī)坐標(biāo)系和照相機(jī)坐標(biāo)系都是一樣的意義。照相機(jī)坐標(biāo)系是和觀察者密切相關(guān)的坐標(biāo)系。照相機(jī)坐標(biāo)系和屏幕坐標(biāo)系相似,差別在于照相機(jī)坐標(biāo)系處于3D空間中,而屏幕坐標(biāo)系在2D平面里。

攝像機(jī)坐標(biāo)系

慣性坐標(biāo)系: 指的是世界坐標(biāo)系到物體坐標(biāo)系的"半途". 慣性坐標(biāo)系的原點(diǎn)和物體坐標(biāo)原點(diǎn)重合,但慣性坐標(biāo)系的軸平行于世界坐標(biāo)系的軸.

為什么要引入慣性坐標(biāo)系?因?yàn)槲矬w坐標(biāo)系轉(zhuǎn)換到慣性坐標(biāo)系只需要旋轉(zhuǎn),從慣性坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)系只需要平移.

OpenGL坐標(biāo)系

坐標(biāo)變換的全局圖

坐標(biāo)轉(zhuǎn)換圖

在上面的圖中,注意,OpenGL只定義了裁剪坐標(biāo)系、規(guī)范化設(shè)備坐標(biāo)系和屏幕坐標(biāo)系,而局部坐標(biāo)系(模型坐標(biāo)系)、世界坐標(biāo)系和照相機(jī)坐標(biāo)系都是為了方便用戶設(shè)計(jì)而自定義的坐標(biāo)系,它們的關(guān)系如下圖所示

  • 圖中左邊的過程包括模型變換、視變換,投影變換,這些變換可以由用戶根據(jù)需要自行指定,這些內(nèi)容在頂點(diǎn)著色器中完成;

  • 圖中右邊的兩個(gè)步驟,包括透視除法、視口變換,這兩個(gè)步驟是OpenGL自動(dòng)執(zhí)行的,在頂點(diǎn)著色器處理后的階段完成。

將坐標(biāo)系統(tǒng)組合在一起

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

OpenGL 然后對裁剪坐標(biāo)執(zhí)行透視除法從而將它們變換到標(biāo)準(zhǔn)化設(shè)備坐標(biāo)。OpenGL 會(huì)使用 glViewPort 內(nèi)部的參數(shù)來將標(biāo)準(zhǔn)化設(shè)備坐標(biāo)映射到屏幕坐標(biāo),每個(gè)坐標(biāo)都關(guān)聯(lián)了一個(gè)屏幕上的點(diǎn)。這個(gè)過程稱為視口變換

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,739評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,702評論 2 370

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