1. 圖形api簡介
OpenGL(Open Graphics Library)是一個跨平臺惕它,跨編程語言的編程圖形程序接口。也就是一套編程圖形程序的標準废登,是用來調(diào)度GPU做事情的。
OpenGL ES (OpenGL for Embedded Systems)是OpenGl三維圖形API的子集郁惜,針對手機堡距、PDA和游戲主機等嵌入式設備而設計甲锡,去除了一些不必要的和性能低下的API接口。
DirectX 是由很多API組成的羽戒,他并不是一個單純的圖形API,最重要的是DirectX是屬于Windows上一個多媒體處理框架缤沦,并不支持Windows以外的平臺。所以不是跨平臺框架易稠,按照性質(zhì)分類缸废,可以分為四大部分,顯示部分驶社、聲音部分企量、輸入部分、網(wǎng)絡部分亡电。
Metal 是蘋果公司為游戲開發(fā)者推出的新的平臺技術(shù)届巩,該技術(shù)能為3D圖像提高10倍的渲染性能。是蘋果為解決3D渲染而推出的框架
2. 圖形API解決什么問題份乒?
簡單的說就是實現(xiàn)圖形的底層渲染恕汇,就是利用GPU來高效渲染圖形圖像。圖形API是IOS開發(fā)者唯一接近GPU的方式或辖。
3. OpenGL狀態(tài)機
狀態(tài)機是一臺可以保存狀態(tài)瘾英,并根據(jù)當前狀態(tài)進行相應輸出的機器。
核心要點
- 具有記憶功能
- 接收輸入颂暇,修改當前狀態(tài)缺谴,或根據(jù)當前狀態(tài)進行輸出
- 當進入特殊狀態(tài)(停機)時,不再接收輸入蟀架,停止工作瓣赂。
4. OpenGL上下文 (context)
上下文是可以理解為環(huán)境的意思,是context 翻譯過來的片拍。在應用程序調(diào)用任何OpenGL指令之前煌集,首先需要創(chuàng)建一個OpenGL的上下文。這個上下文是一個非常龐大的狀態(tài)機捌省,保存了OpenGL中的各種狀態(tài)苫纤,也是OpenGL指令的基礎。
OpenGL的函數(shù)不管在哪個語言中纲缓,都是類似C語言一樣的面向過程的函數(shù)卷拘。本質(zhì)上都是對OpenGl上下文這個龐大的狀態(tài)機中某個狀態(tài)或者對象進行操作,通過OpenGL指令的封裝祝高,可以將OpenGl的相關(guān)功能封裝成一個面向?qū)ο蟮膱D形API.
由于OpenGL上下文是一個巨大的狀態(tài)機栗弟,切換上下文往往會產(chǎn)生較大的開銷。但是不同的繪制模塊工闺,可能需要完全獨立的狀態(tài)管理乍赫。因此瓣蛀,可以在應用程序中分別創(chuàng)建多個不同的上下文,在不同的線程中使用不同的上下文雷厂,上下文共享紋理惋增、緩沖區(qū)等資源。這樣的方案改鲫,會比反復切換上下文诈皿,或者大量修改渲染狀態(tài),更加合理高效像棘。
核心要點
OpenGL指令執(zhí)行的基礎是一個非常龐大的狀態(tài)機稽亏。
OpenGl 上下文切換開銷比較大,雖然可能使用多個上下文讲弄,但上下文指尖共享紋理措左,緩沖區(qū)等資源.
OpenGL 的函數(shù)雖然是面向過程的,但可以把相關(guān)的調(diào)用封裝為面向過程的圖形API避除。
5. 渲染(Rendering)
將圖形/圖像數(shù)據(jù)轉(zhuǎn)換成2D空間圖像操作叫做渲染
6. 頂點數(shù)組(Vertext Array)和頂點緩沖區(qū)(Vertext Buffer)
我們知道畫圖一般是先畫好圖像的骨架怎披,或者說是輪廓,然后在往骨架中填充顏色瓶摆。對于OpenGL 也是一樣的凉逛,頂點數(shù)據(jù)就是要圖像的骨架。和現(xiàn)實生活中不同的是OpenGL的圖像都是由圖元組成群井,在OpenGL ES中状飞,有三種類型的圖元:點、線书斜、三角形诬辈。
在調(diào)用繪制方法的時候,直接由內(nèi)存?zhèn)魅腠旤c數(shù)據(jù)荐吉,也就是說這部分數(shù)據(jù)是存儲在內(nèi)存中的焙糟,被稱為頂點數(shù)組。而性能更高的做法是样屠,提前分配一塊顯存穿撮,將頂點數(shù)據(jù)預先傳入到顯存當中,這部分顯存痪欲,被稱為頂點緩存區(qū)悦穿。
7. 管線
在OpenGL下渲染圖形,會經(jīng)歷一個一個的節(jié)點业踢,這樣的操作可以理解為管線栗柒。管線是一個抽象的概念≈伲可以類比于工廠流水線傍衡,任務嚴格按照先后順序依次執(zhí)行深员。
8. 固定管線/存儲著色器
在早期的OpenGL版本中负蠕,封裝了多種著色器程序塊來幫助開發(fā)者快速完成圖形的渲染蛙埂,開發(fā)者只需要傳入相應的參數(shù),就能完成圖形的渲染遮糖,類似于ios開發(fā)會封裝很多API. 我們只需要調(diào)用绣的,就可以實現(xiàn)功能,不需要關(guān)心底層的實現(xiàn)原理欲账。
但是OpenGL的使用場景非常豐富屡江,固定管線或存儲著色器無法完成每一個業(yè)務,這時將相關(guān)部分開放成可編程赛不。
9. 著色器程序(Shader)
可編程的渲染管線惩嘉。
OpenGl在實際調(diào)用繪制函數(shù)之前,還需要指定一個由shader編譯成的著色器程序踢故。常見的著色器程序只要有頂點著色器文黎,片段著色器/像素著色器,幾何著色器殿较,曲面著色器耸峭,片段著色器和像素著色器只是在OpenGL和DX中的不同叫法而已,OpenGL ES 只支持頂點著色器和片段著色器這兩個最基礎的著色器淋纲。
OpenGL在處理shader時劳闹,和其他編譯器一樣,通過編譯洽瞬、鏈接等步驟本涕,生成了著色器程序,著色器程序同時包含頂點著色器和片段著色器的運算邏輯伙窃,在OpenGL進行繪制的時候菩颖,首先由頂點著色器對傳入的頂點數(shù)據(jù)進行運算,再通過圖元裝配对供,將頂點轉(zhuǎn)換為圖元位他。然后進行光柵化,將圖元這種矢量圖形产场,轉(zhuǎn)換為柵格化數(shù)據(jù)鹅髓。最后將柵格化數(shù)據(jù)傳入片段著色器中進行運算。片段著色器會對柵格化數(shù)據(jù)中的每一個像素進行運算京景,并決定像素的顏色窿冯。
核心要點
- 將固定管線架構(gòu)變?yōu)榭删幊痰匿秩竟芫€。
- OpenGL ES 只支持頂點著色器和片段著色器确徙。
- OpenGL 通過編譯醒串、鏈接等步驟执桌,將生成著色器程序。
- 繪制流程
9.1 頂點著色器(vertexShader)
OpenGL中用于計算頂點屬性的程序芜赌,一般用來處理圖形每個頂點變換(旋轉(zhuǎn)/平移/投影等)仰挣。頂點著色器是逐頂點運算的程序。也就是說每個頂點都會執(zhí)行一次頂點著色器缠沈。當然這是并行的膘壶,并且頂點著色器運算過程中無法訪問其他的頂點數(shù)據(jù)。
9.2 片段著色器(fragmentShader)
一般用來處理圖形中每個像素點顏色計算和填充洲愤。片段著色器是逐像素運算的程序颓芭,也就是每個像素都會執(zhí)行一次片段著色器。當然也是并行柬赐。(GPU有很多的運算單元)
10. GLSL(OpenGl Shading Language)
- OpenGL著色語言是用來在OpenGL中著色編程的語言亡问,也即開發(fā)人員寫的短小的自定義程序,他么實在圖形卡的GPU上執(zhí)行的肛宋,代替了固定的渲染管線的一部分州藕,使渲染管線中不同層次具有可編程性。GLSL著色器代碼分成2個部分:頂點著色器和片段著色器悼吱。
11. 光柵化Rasterization
是把頂點數(shù)據(jù)轉(zhuǎn)換為片元的過程慎框,具有將圖轉(zhuǎn)化為一個個柵格組成的圖像的作用,特點是每個元素對應幀緩沖區(qū)中的一像素后添。光柵化過程產(chǎn)生的是片元
光柵化其實就是一種將幾何圖元轉(zhuǎn)化為二位圖像的過程笨枯,包括兩個部分:
- 第一部分工作:決定窗口坐標中的哪些整型柵格區(qū)域被基本圖元占用
- 第二部分工作:分配一個顏色值和深度值到各個區(qū)域。
- 把物體的數(shù)學描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上用于對應位置的像素及用于填充像素的顏色遇西,這個過程稱為光柵化馅精,這是一個將模擬信號轉(zhuǎn)化為離散信號的過程
12. 紋理
紋理可以理解為圖片,在渲染圖形時需要在頂點圍成的區(qū)域中填充圖片粱檀,使得場景更加逼真洲敢,而這里使用的圖片,就是常說的紋理茄蚯,在OpenGL中压彭,習慣叫做紋理。
13. 混合(Blending)
在測試階段之后渗常,如果像素依然沒有被刪除壮不,那么像素的顏色將會和幀緩沖區(qū)中顏色附著上的顏色進行混合,混合的算法可以通過OpenGL的函數(shù)進行制定皱碘,但是OpenGl提供的混合算法是有限的询一,如果需要更加復雜的混合算法,一般可以通過片元著色器進行實現(xiàn),當然性能會比原生的混合算法差一些健蕊。
14. 矩陣
14.1 變換矩陣
例如圖形想要平移菱阵,縮放,旋轉(zhuǎn)等變換缩功,就需要使用變換矩陣
14.2 投影矩陣
用于將3D坐標轉(zhuǎn)換為二維屏幕坐標晴及,實際線條也將在二維坐標下進行繪制。
15. 渲染上屏/交換緩沖區(qū)
渲染緩沖區(qū)一般映射的系統(tǒng)資源是窗口掂之,如果將圖像直接渲染到窗口對應的渲染緩沖區(qū)抗俄,則可以將圖像顯示到屏幕上。
但是值得注意的是世舰,如果窗口只有一個緩沖區(qū),那么在繪制過程中槽卫,屏幕進行了刷新跟压,窗口可能顯示不完整的圖像。
為了解決這個問題歼培,常規(guī)的OpenGL程序至少有兩個緩沖區(qū)震蒋。顯示在屏幕上的稱為屏幕緩沖區(qū),沒有顯示在屏幕上的稱為離屏緩沖區(qū)躲庄,在一個緩沖區(qū)渲染完成之后查剖,通過將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實現(xiàn)圖像在屏幕上的刷新噪窘。
由于顯示器的刷新一般是逐行進行的笋庄,因此為了防止交換緩沖區(qū)的時候屏幕上下區(qū)域的圖像分屬于兩個不同的幀,因此交換一般會等待顯示器刷新完成的信號倔监。在顯示器的兩次刷新的間隔中進行交換直砂,這個信號被稱為垂直同步信號,這個技術(shù)被稱為垂直同步浩习【苍荩可以理解為加了一個鎖。防止圖像出現(xiàn)撕裂問題谱秽。
使用雙緩沖區(qū)和垂直同步技術(shù)之后洽蛀,由于總是要等待緩沖區(qū)交換之后,再進行下一幀的渲染疟赊,使得幀率無法完全達到硬件的允許的最高水平郊供。為了解決這個問題,引入三緩沖區(qū)技術(shù)听绳,在等待垂直同步信號時颂碘,來回交替渲染兩個離屏的緩沖區(qū),而垂直同步發(fā)生時,屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換头岔,實現(xiàn)充分的利用硬件性能的目的塔拳。
當顯示器刷新完成的信號到來時,如果cpu/gpu計算跟不上的峡竣,會導致屏幕重復顯示同一張圖像靠抑,這種現(xiàn)象就是常說的掉幀。理論上雙緩沖區(qū)跟三緩沖區(qū)都可能會發(fā)生屏幕掉幀(卡頓)的問題适掰。屏幕掉幀是為了解決圖像撕裂問題而引起的新的問題颂碧。