OpenGL入門(一)-- 快速瞭解OpenGL常見的專業名詞
- 一. 圖形API簡介
- 1. OpenGL
- 2. OpenGL ES
- 3. DirectX
- 4. Metal
- 圖形`API`的左右
- 二. OpenGL 專業名詞解析
- 1. OpenGL 狀態機
- 2. OpenGL 上下文 ( context )
- 3. 渲染(Rendering)
- 4. 頂點數組(VertexArray)& 頂點緩存區(VertexBuffer)
- 5. 管線
- 6. 固定管線 和 可編程管線
- 7. 着色器(shader)
- 8. 頂點着色器(VertexShader)
- 9. 片元着色器(VertexShader)
- 10. GLSL(OpenGL shading Language)
- 11. 光柵化(VertexShader)
- 12. 紋理
- 13. 混合(Blending)
- 14. 變換矩陣
- 15. 投影矩陣
- 16. 渲染上屏/交換緩衝區
- 17. 投影方式
- 18. 視口
- 19. 座標系
據說
OpenGL
很難,所以嘗試一下從入門到放棄的艱辛過程。此係列文章只是對學習到的OpenGL
相關知識做一個簡單的認知與筆記。個人理解,如有錯誤,歡迎指正。
一. 圖形API簡介
1. OpenGL
OpenGL
全稱:Open Graphics Library
,是一個跨平臺的、跨編程語言的編程圖形程序接口。其將計算機的資源抽象稱爲一個個的OpenGL
的對象,對這些資源的操作抽象爲一個個的OpenGL
指令。簡單的說就是一套處理
PC端
圖形圖像渲染的API
。適用於:
PC
端
ps: OpenGL vs OpenCV
OpenGL: 是做渲染,轉換爲位圖渲染顯示。
OpenCV: 是做識別的(比如:人臉識別,身份證、銀行卡識別),與人工智能結合。
2. OpenGL ES
OpenGL ES
全稱:OpenGL for Embedded Systems
,是OpenGL
三維圖形API
的子集。針對移動端(iOS/安卓)、PDA
和遊戲主機等嵌入式設置而設計,去除了許多不必要和性能較低的API
接口。適用於:嵌入式設備
3. DirectX
DirectX
是有很多API
組成,DirectX
並不是一個單純的圖形API
,最重要的是DirectX
是屬於Windows
上一個多媒體處理框架,不支持Windows
以外的平臺,所以不是跨平臺框架,按照性質分類,可以分爲四大部分:顯示部分、聲音部分、輸入部分和網絡部分適用於:
Windows
4. Metal
Metal是
Apple
爲遊戲開發者推出的新的平臺技術,該技術能夠爲3D
圖像提高10倍
的渲染性能,是Apple
爲了解決3D渲染
而推出的框架。
Metal
和OpenGL ES
:
- 2018年之前,
iOS
的底層圖形渲染是CoreAnimation
,是基於OpenGL ES
封裝的上層框架,2018年
之後,底層渲染遷移到了Metal
。OpenGL ES
是第三方框架,不一定契合自己的項目,Metal
可以定製需求,迭代開發
圖形API
的左右
圖形
API
能解決什麼問題?簡單的說,就是實現圖形的底層渲染。
- 比如遊戲開發中,對於遊戲場景遊戲人物的的渲染
- 比如音視頻開發中,對於視頻解碼後的數據渲染
- 比如地圖引擎,對於地圖上的數據渲染
- 比如在動畫中實現動畫的繪製
- 比如在處理視頻中,對於視頻添加濾鏡效果
二. OpenGL 專業名詞解析
1. OpenGL 狀態機
狀態機:理論上是一種機器,描述了一個對象在其生命週期內所經歷的各種狀態,狀態間的轉變,發生轉變的動因,條件轉變中所執行的活動。或者說,狀態機是一種行爲,說明對象在其生命週期中響應事件所經歷的狀態序列以及對那些事件的響應。
簡單的可以理解爲:是一臺可以保存狀態,並根據當前狀態進行輸出的機器。
特點:
- 有記憶功能,能記住其當前的狀態
- 可以接受輸入,根據輸入的內容和自己的原先狀態,修改自己當前的狀態,並且可以有對應輸出
- 當進入特殊狀態(停機狀態)的時候,便不再接受輸入,停止工作。
類推到 OpenGL 中:
OpenGL
可以記錄自己的狀態(如:當前使用的顏色,是否開啓了混合功能等)OpenGL
可以接收輸入(當調用OpenGL
函數的時候,實際上可以看成OpenGL
在接收我們的輸入),如我們調用glColor3f
,則OpenGL
接收到這個輸入後修改自己的當前這個狀態。OpenGL
可以進入停止狀態,不在接收輸入。在程序退出之前,OpenGL
總會先停止工作的。
2. OpenGL 上下文 ( context )
- 在應用程序調用任何
OpenGL
指令之前,需要首先安排創建一個OpenGL
的上下文,這個上下文是一個龐大的狀態機,保存了OpenGL
中的各種狀態,這也是OpenGL
指令執行的基礎。- 不管在哪個語音中,
OpenGL
的函數,都是類似C語言
一樣的面向過程的函數,本質上都是對OpenGL
上下文這個狀態機中的某一個狀態或者對象的操作,當然,需要先把這個對象設置爲當前對象。通過對OpenGL
指令的封裝,是可以將OpenGL
的相關調用分裝成一個面向對象的圖形API
。- 由於
OpenGL
是一個巨大的狀態機,切換上下文會產生較大的開銷。但是不同的繪製模塊,可能需要使用完全獨立的狀態管理,因此,可以在應用程序中,分別創建多個不同的上下文,在不同線程中使用不同的上下文,上下文之間共享紋理、緩衝區資源等。這種方案比反覆切換上下文或者大量修改宣傳專題,更加合理高效。
3. 渲染(Rendering)
渲染:將圖形/圖像數據轉換爲
2D
空間圖像操作叫做渲染(Rendering)
4. 頂點數組(VertexArray)& 頂點緩存區(VertexBuffer)
- 圖畫一般是先話好圖像的骨架,再填充顏色,對應
OpenGL
也一樣。頂點數據就是要畫的圖像的骨架。比如,要畫一個三角形,需要三個頂點,這個三個頂點就是頂點數據。OpenGL
的圖像是有圖元構成,在OpenGL ES
中有三種圖元:點、線、三角形。- 開發者可以選擇指定的函數指針,在調用繪製方法的時候,直接有內存傳入頂點數據,也就是說這部分數據之前是存在在內存中的,被稱爲頂點數組
- 性能更高的做法是,提前分配一塊顯存,將頂點數據預先傳入到顯存當中,這部分的顯存,稱爲頂點緩存區
- 頂點是在繪製一個圖形時,它的頂點位置數據,而這個數據可以直接存在在數組中,或者將其緩存到
GPU
內存中。- 頂點數組是內存中的一個數組,頂點緩衝區是
GPU
顯存中的一塊區域。
5. 管線
在
OpenGL
下渲染圖形,就會經歷一個一個的節點,而這樣的操作可以理解爲管線,可以類比爲流水線,每個任務類似流水線執行,任務之間有先後順序。之所以成爲管線,是因爲顯卡在處理數據的時候是按照一個固定的順序來的,而且是嚴格按照這個順序,就像水管,水從一端流向另一端,順序不能打破。
6. 固定管線 和 可編程管線
在早起
OpenGL
版本,封裝了很多中着色器程序塊,內置的一段代碼包含了光照、座標變換,裁剪等諸多功能的固定着色器來幫助開發者完成圖形的渲染,而開發者只需要傳入相應的參數,就能快速的完成圖形渲染。類似於封裝很多API
,只要調用,就可以實現功能,不需要關注底層原理,這被稱爲固定管線或者存儲着色器隨着
OpenGL
的使用場景的豐富,固定管線或者存在着色器無法完成每一個業務,這個將相關部分開放成可編程,稱爲可編程管線,使用GLSL語法
來編程驅使GPU
。
7. 着色器(shader)
將固定宣傳管線變成了可編程渲染管線
OpenGL
在實際調用繪製函數之前,需要指定一個由shader
編譯而成的着色器(代碼段),由GPU
執行,可以類比爲:函數和方法是一段代碼段,由CPU
來使用。着色器)也是代碼段,由GPU
執行。
常見的着色器主要有:
- 頂點着色器(VertexShader)
- 片段着色器(FragmentShader),又叫像素着色器(PixelShader),只是在
OpenGL
和Dx
中不同的叫法。- 曲面細分着色器(TessellationShader)
OpenGL
在處理shader
時,通過編譯,鏈接等步驟,生成了着色器程序(GLProgram
),着色器程序同時包含了頂點着色器和片段着色器的運算邏輯。在OpenGL
進行繪製時,先有頂點着色器對傳入的頂點數據進行運算,再通過圖元裝配,將頂點轉換爲圖元,然後進行光柵化,將圖元這種矢量圖形,轉換爲柵格化數據,最後,將柵格化數據傳入片段着色器進行運行,片段着色器會對柵格化數據中的每一個像素進行運算,並決定像素的顏色。
固定着色器:又叫存儲着色器,是有蘋果提供的API
代碼段,通過傳入參數進行調用自定義着色器:自己通過
GLSL
語法自定義編程的代碼段
8. 頂點着色器(VertexShader)
- 一般處理圖形每一個頂點變換,比如:旋轉、平移、投影等
- 頂點着色器,是
OpenGL
中計算頂點屬性的程序,頂點着色器是逐頂點運算的程序,即:每一個頂點數據都會執行一次頂點着色器,這個過程是並行的,在頂點着色器運算過程中,無法訪問其他頂點的數據。- 一般來說典型的需要計算的頂點屬性,主要包括:頂點座標變換、逐頂點光照運算等等。頂點座標由自身座標系轉換到歸一化座標系的運算,就是在這裏發生的。
9. 片元着色器(VertexShader)
- 一般用來處理圖形中每一個像素點顏色計算和填充
- 片元着色器是
OpenGL
用於計算像素顏色的程序,是逐像素運算的程序,圖形中的每一個像素都會執行一次片元着色器,這個過程是有GPU
並行運算的。
10. GLSL(OpenGL shading Language)
GLSL
是用來在OpenGL
中着色器編程的語音,即開發人員自定義短小的着色器的語言,他們在圖形卡的GPU
上執行,代替了固定的渲染關係的一部分,是渲染管線中不同層次具有可編譯性。比如:視圖轉換,投影轉換等
GLSL
的着色器代碼分爲兩個部分:頂點着色器和片元着色器。
11. 光柵化(VertexShader)
光柵化:是把物體的數學描述以及與物體相關的顏色信息轉換到屏幕上用於對應位置的像素以及填充像素的顏色,這個過程稱爲光柵化;是把頂點數據轉換爲片元的過程;是一個將模擬信號轉化爲離散信號的過程。
光柵化具有將圖轉化爲一個個柵格組成的圖像的作用。特點是每個元素對應幀緩存區中的一像素。
光柵化過程產生的是片元。
光柵化 其實是一種將幾何圖元編程二維相圖的過程,該過程包含了兩部分的工作:
- 第一部分:決定窗口座標中的哪些整形柵格區域被基本圖元佔用
- 第二部分:分配一個顏色值和深度值到各個區域,
12. 紋理
紋理可以理解爲圖片,這個圖片是指的tga文件。在
OpenGL
更習慣叫紋理。在移動端要把
png
解壓縮轉換爲位圖,紋理就是位圖。
13. 混合(Blending)
在測試階段之後,如果像素依然沒有被踢除,那麼像素的顏色將會和幀緩衝區中顏色附着上的顏色進行混合。比如:一個藍色的
layer
和一個紅色的
layer
兩個圖層進行重疊,中間疊加產生的顏色是混合計算出來的。混合的算法可以通過
OpenGL
的函數進行指定,但是openGL
提供的混合算法是有限的,如果,需要更加複雜的混合算法,一般可以通過像素着色器進行實現,性能比原生的混合算法差一點。
14. 變換矩陣
記錄圖形想發生平移、縮放、旋轉變換,就需要使用變換矩陣
比如:一個正方形想要平移,需要四個頂點同時乘以一個矩陣,這個矩陣裏存儲的是平移、縮放、旋轉變換的結果。
15. 投影矩陣
用於將
3D
座標轉換爲二維屏幕座標,實際線條也將在二維座標下進行繪製
16. 渲染上屏/交換緩衝區
- 渲染緩衝區一般映射的是系統的資源,比如窗口,如果將圖像直接渲染到創建對應的渲染緩衝區,則可以直接將圖像顯示到屏幕上
- 如果每個窗口只有一個緩衝區,那麼在繪製過程中屏幕進行了刷新,窗口可以顯示不出完整的圖像
- 爲了解決這個問題,常規的
OpenGL
程序至少會有兩個緩衝區,顯示在屏幕上的稱爲屏幕緩衝區,沒有顯示在屏幕上的的稱爲離屏緩衝區,在一個緩衝區渲染完成後,通過將兩個緩衝區交換,實現圖像在屏幕上顯示。- 由於顯示器的刷新一般是逐步進行的,因此爲了防止交換緩衝區的時候,屏幕上下區域的圖像分屬於兩個不同的幀,因此交換一般會等待顯示親刷新完成的信號,在顯示器兩次刷新的間隔中進行交換,這個信號稱爲垂直同步信號,這個技術稱爲垂直同步。
- 使用雙緩衝區和垂直同步技術之後,由於總是要等待緩衝區交換之後在進行下一幀的渲染,使得幀率無法完全達到硬件允許的最高水平,爲了解決這個問題,引入了三緩衝區技術,在等待垂直同步時,來回交替渲染兩個離屏的緩衝區,而垂直同步發生時,屏幕緩衝區和最近渲染完成的離屏緩衝區交換,實現充分利用硬件性能的目的。
17. 投影方式
正投影(平行投影):圖片繪製不管遠近,都是
1 :1
進行繪製,顯示2D
效果。透視投影:遠小近大的原則繪製,顯示
3D
效果如下圖:
camera
並不是相機,是觀察者視角。
*
18. 視口
視口的大小是可以設置的,如圖:
19. 座標系
- 可以分爲:物體座標系、慣性座標系、世界座標系
- 座標系的轉換如下:
- 這麼多的座標系,是不是記不住,不會用,莫慌!最終都會來到規範座標系,可以一開始就給予規範座標系。
- 座標轉換計算