一、什么是圖形API
OpenGL是一個跨編程語言、跨平臺的編程圖形程序接口,它講計算機的資源抽象成為一個OpenGL的對象,對這些資源的操作抽象為一個個OpenGL指令。
OpenGL ES 是OpenGL三維圖形API的子集,針對手機、PDA(掌上電腦)和游戲主機等嵌入式設備而設計,去除了很多不必要的和性能較低的API接口。
DirectX是由很多API組成的,DirectX并不是一個單純的圖形API。更重要的是DirectX是屬于Windows上的一個多媒體處理框架,且不支持Windows以外的平臺,不屬于跨平臺框架。按照性質分類,可以分為:1、顯示部分2、聲音部分3、輸入部分4、網絡部分。
Metal是蘋果為游戲開發者推出的新的平臺技術,旨在解決3D渲染,該技術能夠為3D圖像提高10倍的渲染性能。2014年到2018年apple將系統內部從OpenGL ES到Matel,并于2018年宣布棄用OpenGL ES。
二、OpenGL名詞解析
1、紋理
紋理可以理解問圖片,在渲染圖形時為了使場景更加逼真,需要在頂點圍成的區域中填充圖片,這個圖片就是所謂的紋理,紋理只是OpenGL里的對圖片的稱呼。
2、OpenGL狀態機
狀態機描述了一個對象在其生命周期內所經歷的各種狀態、狀態間的轉變、發生轉變的原因、條件,及轉變中所執行的活動。
也可以說狀態機是一種行為,描述對象在其生命周期中響應事件所經歷的狀態序列以及對狀態事件的響應。
特點:(1).有記憶功能,能記住當前的狀態;(2).可以接收輸入,根據輸入的內容和自己原先的狀態,修改自己當前的狀態,且可以有對應的輸出。(3).當進入特殊狀態(停機狀態)的時候,便不再接收輸入,停止工作。
OpenGL是一個狀態機,記錄自己的狀態,除非用戶輸入命令讓她改變自己的狀態,OpenGL 接收輸入的一些方法:
可以使用glColor*函數來選擇一種顏色,以后繪制的所有物體都是這種顏色,除非再次使用glColor*函數重新設定。
可以使用glTexCoord*函數來設置一個紋理坐標,以后繪制的所有物體都是采用這種紋理坐標,除非再次使用glTexCoord*函數重新設置。
可以使用glBlendFunc函數來指定混合功能的源因子和目標因子,以后繪制的所有物體都是采用這個源因子和目標因子,除非再次使用glBlendFunc函數重新指定。
可以使用glLight*函數來指定光源的位置、顏色,以后繪制的所有物體都是采用這個光源的位置、顏色,除非再次使用glBlendFunc函數重新指定
3、OpenGL 上下文(Context)
在應用程序中調用OpenGL指令前,首先需要創建OpenGL的上下文。上下文是一個非常大的狀態機,保存了OpenGL中的各種狀態,這也是OpenGL指令執行的基礎。
OpenGL函數式面向過程的函數,本質上是對OpenGL上下文這個龐大的狀態機的某個狀態或者對象進行操作,當然,前提是把這個對象設置為當前對象。因此,通過對OpenGL指令的封裝是可以將OpenGL的調用封裝成一個面向對象的圖形API。
OpenGL上下文是一個龐大的狀態機,切換上下文的開銷很大,但是不同的繪制模塊可能需要獨立的狀態管理。因此,在應用程序中創建多個不同的上下文,在不同的線程中調用不同的上下文,這些上下文之間共享紋理,緩沖區等資源。會比反復切換上下文,或大量修改渲染狀態更加高效。
4、渲染
將圖形、圖像數據轉換成3D空間圖像的操作叫做渲染。
5、頂點數組和頂點緩沖區
頂點數據就是圖像的輪廓,OpenGL中的圖像都是由圖元組成。在OpenGL ES中,有三種類型的圖元:點,線,三角形。
在調用繪制方法的時候,直接由內存傳入頂點數據,也就是說這部分數據之前時存儲在內存當中的,被稱作頂點數組。
提前分配一塊顯存,將頂點數據預先傳入顯存當中,能夠讓性能更高效。這部分顯存被稱作頂點緩沖區。
6、管線
管線是一個抽象的概念,OpenGL下渲染圖形,會經歷一個一個節點,這樣的操作可以理解為管線。之所以叫管線是因為顯卡在處理數據的時候是按照一個固定的順序來的,且嚴格執行這個順序。
7、固定管線/存儲著色器
在早起的OpenGL 版本,封裝了多種著色器程序塊,內置了一段包含光照、坐標轉換、裁剪等諸多功能的著色器(shader)程序,幫助開發者完成圖形的渲染。開發者只需傳入參數調用即可完成圖形的渲染。
由于OpenGL使用場景非常豐富,固定管線或者存儲著色器無法完成每一個業務,將相關部分開放成可編程。
8、光柵化
光柵化就是把頂點數據轉換成片元的過程,具有將圖片轉換成一個個柵格組成的圖像。特點是每個元素對應幀緩沖區的一個像素。
光柵化是一種將幾何圖元變為二維圖像的過程,包括兩部分工作:1.決定窗口坐標中的那些整型柵格區域被基本圖元占用;2.分配一個顏色值和一個深度值到各個區域,從而產生片元。
光柵化是一個將模擬信號轉化為離散信號的過程:把物體的數學描述和顏色信息轉換成屏幕上用于對應位置的像素和填充像素的顏色。
9、著色器程序(shader)
將固定渲染管線架構變成了可編程渲染管線。
OpenGL在實際調用繪制函數之前,還需要指定一個由shader編譯成的著色器程序。常見的著色器程序有頂點著色器,片段著色器/像素著色器,幾何著色器,曲面細分著色器。片段著色器和像素著色器只是在OpenGL和DirectX中的不同叫法。直到OpenGL ES3.0,依然只支持頂點著色器和片段著色器。
OpenGL在處理shader是,和其他編譯器一樣,通過編譯、鏈接等步驟,生成著色器程序。著色器程序同時包含頂點著色器和片段著色器的運算邏輯。
OpenGL繪制過程:首先由頂點著色器對傳入的頂點數據進行運算-->通過圖元裝配將頂點轉換成圖元-->然后進行光柵化,將圖元這種矢量圖轉換成柵格化數據-->將柵格化數據傳入片段著色器進行運算。片段著色器對柵格化數據中的每一個像素進行運算,并決定像素的顏色。
9.1、頂點著色器
頂點著色器是OpenGL中用于計算頂點屬性的程序。
一般來說典型的需要計算的頂點屬性主要包括頂點坐標轉換,逐頂點關照運算等等。頂點坐標由自身坐標系轉換到歸一化坐標系的運算,就是在這里發生的。
頂點著色器是逐頂點運算的程序,也就是說每個頂點數據都會只從一次頂點著色器(并行),且頂點著色器運算過程中過無法訪問其他頂點的數據。
9.2、片元著色器程序
片段著色器是OpenGL中用于計算片段(像素)顏色的程序。一般用來處理圖形中每個像素點的顏色計算和填充。
片段著色器是逐像素運算的程序,也就是說每個像素都會執行一次片元著色器(并行)。
10、GLSL
OpenGL 著色語言是用來在OpenGL中著色的語言,也就是開發人員寫的短小的自定義程序,是在圖形卡的GPU上執行,代替了固定的渲染管線的一部分,是渲染管線中不同層次具有可編程性。GLSL的著色器代碼分成兩個部分:頂點著色器和片段著色器。
11、混合
在測試階段,如果像素依然沒有被剔除,那么像素的顏色將會和幀緩沖區中附著的顏色混合。混合的算法可以通過OpenGL的函數進行指定,但是OpenGL提供的混法算法有限,可以通過著色器實現更復雜的混合算法,性能會比原生的差。
12、變換矩陣
可以用于圖形的平移,縮放,旋轉變換等
13、投影矩陣
將3D坐標轉換成為二維屏幕坐標,實際線條也將在二維坐標下進行繪制。
13、渲染上屏/交換緩沖區
渲染緩沖區一般映射的是系統的資源,就像窗口,如果將圖像直接渲染到窗口對應的渲染緩沖區,則可以將圖像顯示到屏幕上。*每個窗口只有一個緩沖區,如果在繪制過程中屏幕進行了刷新,窗口可能顯示出不完整的圖像。
為了解決這個問題,常規的OpenGL程序至少會有兩個緩沖區。顯示在屏幕上的稱為屏幕緩沖區,沒有顯示的稱為離屏緩沖區。在一個緩沖區渲染完成后,通過屏幕緩沖區和離屏緩沖區交換,實現圖像在屏幕上的顯示。
由于顯示器是逐行刷新的,為了防止緩沖區交換的時候,屏幕上下的區域分屬兩個不同的幀,所以交換動作會等待屏幕刷新完成的信號,這個信號叫做垂直同步信號,緩沖區交換過程在兩次屏幕刷新之間進行。
在使用雙緩沖區和垂直同步信號后,需要在緩沖區交換完成后才會進行下一幀的渲染,這樣幀率無法達到硬件允許的最高水平。為了解決這個問題,引入了三緩沖區技術。有兩個離屏緩沖區,垂直同步發生時,屏幕緩沖區和最近完成的離屏緩沖區交換。