OpenGL / OpenGL ES 下專業名詞解析

圖形API簡介

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

引言:

從2014年到2018年.蘋果才完成了系統內部從OpenGL ES過度到Metal.直到WWDC 2018,Apple 宣佈 iOS 12 將棄用 OpenGL / CL.

Apps built using OpenGL ES will continue to run in iOS 12, but Open GL ES is deprecated in iOS 12. Games and graphics-intensive apps that previously used OpenGL ES should now adopt Metal.

OpenGL / OpenGL ES 下專業名詞解析

但值得注意的是:

  • 首先蘋果自身的系統遷移上是花費了4年時間做這樣的籌備.
  • 其次在沒有推出Metal 蘋果對於OpenGL ES是高度集成且配合相應圖層和GLKit 來輔助開發者能快速使用OpenGL ES
  • OpenGL ES的棄用,只是針對蘋果內部系統底層API依賴而言,並不是想讓iOS開發者從此不使用OpenGLES. OpenGL ES只是角色變成第三方.畢竟它的跨平臺以及穩定,是很難讓現有的開發放棄.而這2點Metal 目前很難給到
  • 4.最後,如果大家想要融入到項目組,而目前大多數類似百度地圖,高德地圖和音視頻處理的項目組已經是非常龐大的項目了,暫時不會遷移到Metal.所以我們如果只會metal從實際場景中並不夠.
  • 5.所以我們學習會從OpenGL->OpenGL ES->Metal

圖形API目的是解決什麼問題

簡單來說就是實現圖形的底層渲染.

比如在遊戲開發中,對於遊戲場景/遊戲人物的渲染

比如在音視頻開發中,對於視頻解碼後的數據渲染

比如在地圖引擎,對於地圖上的數據渲染

比如在動畫中,實現動畫的繪製

比如在視頻處理中,對於視頻加上濾鏡效果

等等....

OpenGL 專業名詞解析

  • OpenGL 上下文(context)
  • 在應用程序調用任何OpenGL的指令之前,需要安排首先創建一個OpenGL的上下文。這個上下文是一個非常龐大的狀態機,保存了OpenGL中的各種狀態,這也是OpenGL指令執行的基礎。
  • OpenGL的函數不管在哪個語言中,都是類似C語言一樣的面向過程的函數,本質上都是對OpenGL上下文這個龐大的狀態機中的某個狀態或者對象進行操作,當然你得首先把這個對象設置為當前對象。因此,通過對OpenGL指令的封裝,是可以將OpenGL的相關調用封裝成為一個面向對象的圖形API的。
  • 由於OpenGL上下文是一個巨大的狀態機,切換上下文往往會產生較大的開銷,但是不同的繪製模塊,可能需要使用完全獨立的狀態管理。因此,可以在應用程序中分別創建多個不同的上下文,在不同線程中使用不同的上下文,上下文之間共享紋理、緩衝區等資源。這樣的方案,會比反覆切換上下文,或者大量修改渲染狀態,更加合理高效的。
  • OpenGL 狀態機
  • 狀態機是理論上的一種機器.這個非常難以理解.所以我們把這個狀態機這麼理解.狀態機描述了一個對象在其生命週期內所經歷的各種狀態,狀態間的轉變,發生轉變的動因,條件及轉變中所執行的活動。或者說,狀態機是一種行為,說明對象在其生命週期中響應事件所經歷的狀態序列以及對那些狀態事件的響應。因此具有以下特點:
  1. 有記憶功能,能記住其當前的狀態;
  2. 可以接收輸入,根據輸入的內容和自己的原先狀態,修改自己當前狀態,並且可以有對應輸出;
  3. 當進入特殊狀態(停機狀態)的時候,變不再接收輸入,停止工作;

類推到OpenGL 中來,可以這麼理解:

  1. OpenGL可以記錄自己的狀態(如當前所使用的顏色、是否開啟了混合功能等);
  2. OpenGL可以接收輸入(當調用OpenGL函數的時候,實際上可以看成OpenGL在接收我們的輸入),如我們調用glColor3f,則OpenGL接收到這個輸入後會修改自己的“當前顏色”這個狀態;
  3. OpenGL可以進入停止狀態,不再接收輸入。在程序退出前,OpenGL總會先停止工作的。

可以使用glColor*函數來選擇一種顏色,以後繪製的所有物體都是這種顏色,除非再次使用glColor*函數重新設定。

可以使用glTexCoord*函數來設置一個紋理座標,以後繪製的所有物體都是採用這種紋理座標,除非再次使用glTexCoord*函數重新設置。

可以使用glBlendFunc函數來指定混合功能的源因子和目標因子,以後繪製的所有物體都是採用這個源因子和目標因子,除非再次使用glBlendFunc函數重新指定。

可以使用glLight*函數來指定光源的位置、顏色,以後繪製的所有物體都是採用這個光源的位置、顏色,除非再次使用glBlendFunc函數重新指定。

OpenGL是一個狀態機,它保持自身的狀態,除非用戶輸入一條命令讓它改變狀態。

例如:

OpenGL / OpenGL ES 下專業名詞解析

  • 渲染
  • 將圖形/圖像數據轉換成3D空間圖像操作叫做渲染(Rendering).
  • 頂點數組(VertexArray)和頂點緩衝區(VertexBuffer)
  • 畫圖一般是先畫好圖像的骨架,然後再往骨架裡面填充顏色,這對於OpenGL也是一樣的。頂點數據就是要畫的圖像的骨架,和現實中不同的是,OpenGL中的圖像都是由圖元組成。在OpenGLES中,有3種類型的圖元:點、線、三角形。那這些頂點數據最終是存儲在哪裡的呢?開發者可以選擇設定函數指針,在調用繪製方法的時候,直接由內存傳入頂點數據,也就是說這部分數據之前是存儲在內存當中的,被稱為頂點數組。而性能更高的做法是,提前分配一塊顯存,將頂點數據預先傳入到顯存當中。這部分的顯存,就被稱為頂點緩衝區。
  • 頂點指的是我們在繪製一個圖形時,它的頂點位置數據.而這個數據可以直接存儲在數組中或者將其緩存到GPU內存中.
  • 管線
  • 在OpenGL 下渲染圖形,就會有經歷一個一個節點.而這樣的操作可以理解管線.大家可以想象成流水線.每個任務類似流水線般執行.任務之間有先後順序. 管線是一個抽象的概念,之所以稱之為管線是因為顯卡在處理數據的時候是按照一個固定的順序來的,而且嚴格按照這個順序。就像水從一根管子的一端流到另一端,這個順序是不能打破的
  • 固定管線/存儲著色器
  • 在早期的OpenGL 版本,它封裝了很多種著色器程序塊內置的一段包含了光照、座標變換、裁剪等等諸多功能的固定shader程序來完成,來幫助開發者來完成圖形的渲染. 而開發者只需要傳入相應的參數,就能快速完成圖形的渲染. 類似於iOS開發會封裝很多API,而我們只需要調用,就可以實現功能.不需要關注底層實現原理.
  • 但是由於OpenGL 的使用場景非常豐富,固定管線或存儲著色器無法完成每一個業務.這時將相關部分開放成可編程.
  • 著色器程序Shader
  • 就全面的將固定渲染管線架構變為了可編程渲染管線。因此,OpenGL在實際調用繪製函數之前,還需要指定一個由shader編譯成的著色器程序。常見的著色器主要有頂點著色器(VertexShader),片段著色器(FragmentShader)/像素著色器(PixelShader),幾何著色器(GeometryShader),曲面細分著色器(TessellationShader)。片段著色器和像素著色器只是在OpenGL和DX中的不同叫法而已。可惜的是,直到OpenGLES 3.0,依然只支持了頂點著色器和片段著色器這兩個最基礎的著色器。
  • OpenGL在處理shader時,和其他編譯器一樣。通過編譯、鏈接等步驟,生成了著色器程序(glProgram),著色器程序同時包含了頂點著色器和片段著色器的運算邏輯。在OpenGL進行繪製的時候,首先由頂點著色器對傳入的頂點數據進行運算。再通過圖元裝配,將頂點轉換為圖元。然後進行光柵化,將圖元這種矢量圖形,轉換為柵格化數據。最後,將柵格化數據傳入片段著色器中進行運算。片段著色器會對柵格化數據中的每一個像素進行運算,並決定像素的顏色
  • 頂點著色器VertexShader
  • 一般用來處理圖形每個頂點變換(旋轉/平移/投影等)
  • 頂點著色器是OpenGL中用於計算頂點屬性的程序。頂點著色器是逐頂點運算的程序,也就是說每個頂點數據都會執行一次頂點著色器,當然這是並行的,並且頂點著色器運算過程中無法訪問其他頂點的數據。
  • 一般來說典型的需要計算的頂點屬性主要包括頂點座標變換、逐頂點光照運算等等。頂點座標由自身座標系轉換到歸一化座標系的運算,就是在這裡發生的。
  • 片元著色器程序FragmentShader
  • 一般用來處理圖形中每個像素點顏色計算和填充
  • 片段著色器是OpenGL中用於計算片段(像素)顏色的程序。片段著色器是逐像素運算的程序,也就是說每個像素都會執行一次片段著色器,當然也是並行的。
  • GLSL(OpenGL Shading Language)
  • OpenGL著色語言(OpenGL Shading Language)是用來在OpenGL中著色編程的語言,也即開發人員寫的短小的自定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執行的,代替了固定的渲染管線的一部分,使渲染管線中不同層次具有可編程性。比如:視圖轉換、投影轉換等。GLSL(GL Shading Language)的著色器代碼分成2個部分:Vertex Shader(頂點著色器)和Fragment(片斷著色器)
  • 光柵化Rasterization
  • 是把頂點數據轉換為片元的過程,具有將圖轉化為一個個柵格組成的圖象的作用,特點是每個元素對應幀緩衝區中的一像素。
  • 光柵化就是把頂點數據轉換為片元的過程。片元中的每一個元素對應於幀緩衝區中的一個像素。
  • 光柵化其實是一種將幾何圖元變為二維圖像的過程。該過程包含了兩部分的工作。第一部分工作:決定窗口座標中的哪些整型柵格區域被基本圖元佔用;第二部分工作:分配一個顏色值和一個深度值到各個區域。光柵化過程產生的是片元
  • 把物體的數學描述以及與物體相關的顏色信息轉換為屏幕上用於對應位置的像素及用於填充像素的顏色,這個過程稱為光柵化,這是一個將模擬信號轉化為離散信號的過程
  • 紋理

紋理可以理解為圖片. 大家在渲染圖形時需要在其編碼填充圖片,為了使得場景更加逼真.而這裡使用的圖片,就是常說的紋理.但是在OpenGL,我們更加習慣叫紋理,而不是圖片.

  • 混合(Blending
  • 在測試階段之後,如果像素依然沒有被剔除,那麼像素的顏色將會和幀緩衝區中顏色附著上的顏色進行混合,混合的算法可以通過OpenGL的函數進行指定。但是OpenGL提供的混合算法是有限的,如果需要更加複雜的混合算法,一般可以通過像素著色器進行實現,當然性能會比原生的混合算法差一些。
  • 變換矩陣(Transformation)
  • 例如圖形想發生平移,縮放,旋轉變換.就需要使用變換矩陣.
  • 投影矩陣Projection
  • 用於將3D座標轉換為二維屏幕座標,實際線條也將在二維座標下進行繪製.
  • 渲染上屏/交換緩衝區(SwapBuffer)
  • 渲染緩衝區一般映射的是系統的資源比如窗口。如果將圖像直接渲染到窗口對應的渲染緩衝區,則可以將圖像顯示到屏幕上。
  • 但是,值得注意的是,如果每個窗口只有一個緩衝區,那麼在繪製過程中屏幕進行了刷新,窗口可能顯示出不完整的圖像。
  • 為了解決這個問題,常規的OpenGL程序至少都會有兩個緩衝區。顯示在屏幕上的稱為屏幕緩衝區,沒有顯示的稱為離屏緩衝區。在一個緩衝區渲染完成之後,通過將屏幕緩衝區和離屏緩衝區交換,實現圖像在屏幕上的顯示。
  • 由於顯示器的刷新一般是逐行進行的,因此為了防止交換緩衝區的時候屏幕上下區域的圖像分屬於兩個不同的幀,因此交換一般會等待顯示器刷新完成的信號,在顯示器兩次刷新的間隔中進行交換,這個信號就被稱為垂直同步信號,這個技術被稱為垂直同步。
  • 使用了雙緩衝區和垂直同步技術之後,由於總是要等待緩衝區交換之後再進行下一幀的渲染,使得幀率無法完全達到硬件允許的最高水平。為了解決這個問題,引入了三緩衝區技術,在等待垂直同步時,來回交替渲染兩個離屏的緩衝區,而垂直同步發生時,屏幕緩衝區和最近渲染完成的離屏緩衝區交換,實現充分利用硬件性能的目的。


分享到:


相關文章: