1.OpenGL 上下文(context)
- 在應(yīng)用程序調(diào)用任何OpenGL的指令之前,需要安排?先創(chuàng)建一個 OpenGL 的上下文。這個上下?是一個?常龐大的狀態(tài)機,保存了了OpenGL中的各種狀態(tài),這也是OpenGL指令執(zhí)行的基礎(chǔ)
- OpenGL的函數(shù)不管在哪個語言中,都是類似C語言一樣的面向過程的函數(shù),本質(zhì)上都是對OpenGL上下文這個龐大的狀態(tài)機中的某個狀態(tài)或者對象進行操作,當(dāng)然你得首先把這個對象設(shè)置為當(dāng)前對象。因此,通過 OpenGL 指令的封裝,是可以將OpenGL的相關(guān)調(diào)?用封裝成為一個面向?qū)ο蟮膱D形API的
- 由于OpenGL上下文是一個巨大的狀態(tài)機,切換上下文往往會產(chǎn)?較?大的開銷,但是不同的繪制模塊,可能需要使?完全獨立的狀態(tài)管理。因此,可以在應(yīng)用程序中分別創(chuàng)建多個不同的上下文,在不同線程中使用不同的上下文,上下文之間共享紋理、緩沖區(qū)等資源。這樣的方案,會比反復(fù)切換上下文,或者大量修改渲染狀態(tài),更加合理高效的.
2.OpenGL 狀態(tài)機
- 狀態(tài)機是理論上的?種機?.這個非常難以理解.所以我們把這個狀態(tài)機這么理解.狀態(tài)機描述了了一個對象在其生命周期內(nèi)所經(jīng)歷的各種狀態(tài),狀態(tài)間的轉(zhuǎn)變,發(fā)生轉(zhuǎn)變的動因,條件及轉(zhuǎn)變中所執(zhí)行的活動。或者說,狀態(tài)機是一種行為,說明對象在其?命周期中響應(yīng)事件所經(jīng)歷的狀態(tài)序列以及對那些狀態(tài)事件的響應(yīng)。因此具有以下特點:
- 有記憶功能,能記住其當(dāng)前的狀態(tài)
- 可以接收輸入,根據(jù)輸入的內(nèi)容和?己的原先狀態(tài),修改?己當(dāng)前狀態(tài),并且可以有對應(yīng)輸出
- 當(dāng)進?入特殊狀態(tài)(停機狀態(tài))的時候,變不不再接收輸?入,停??作;
我個人有把狀態(tài)機這個概念理解為一個單例對象,保存一些當(dāng)前 OpenGL 在運行的屬性和狀態(tài)
- 類推到OpenGL 中,可以這么理解:
- OpenGL可以記錄?己的狀態(tài)(如當(dāng)前所使用的顏色、是否開啟了混合功能等)
- OpenGL可以接收輸入(當(dāng)調(diào)?OpenGL函數(shù)的時候,實際上可以看成OpenGL在接收我們的輸入),如我們調(diào)用glColor3f,則OpenGL接收到這個輸入后會修改自己的“當(dāng)前顏色”這個狀態(tài);
- OpenGL可以進?停?狀態(tài),不再接收輸?入。在程序退出前,OpenGL總會先停?工作的;
3.渲染
將圖形/圖像數(shù)據(jù)轉(zhuǎn)換成3D空間圖像操作叫做渲染(Rendering)。
4.頂點數(shù)組(VertexArray)頂點緩沖區(qū)(VertexBuffer)
- 畫圖一般是先畫好圖像的骨架,然后再往骨架?面填充顏色,這對于 OpenGL 也是一樣的。頂點數(shù)據(jù)就是要畫的圖像的骨架,和現(xiàn)實中不同的是,OpenGL 中的圖像都是由圖元組成。在OpenGLES中,有3種類型的圖 元:點、線、三?角形。那這些頂點數(shù)據(jù)最終是存儲在哪?的呢?開發(fā)者可以選擇設(shè)定函數(shù)指針,在調(diào)?繪制方法的時候,直接由內(nèi)存?zhèn)魅腠旤c數(shù)據(jù),也就是說這部分?jǐn)?shù)據(jù)之前是存儲在內(nèi)存當(dāng)中的,被稱為頂點數(shù)組。?性能更?的做法是,提前分配一塊顯存,將頂點數(shù)據(jù)預(yù)先傳入到
顯存當(dāng)中。這部分的顯存,就被稱為頂點緩沖區(qū)。 - 頂點指的是我們在繪制一個圖形時,它的頂點位置數(shù)據(jù).而這個數(shù)據(jù)可以直接存儲在數(shù)組中或者將其緩存到
GPU內(nèi)存中。
5.管線
在 OpenGL 下渲染圖形,就會有經(jīng)歷一個一個節(jié)點.?這樣的操作可以理解管線.?家可以想象成流水線.每個任務(wù)類似流水線般執(zhí)行.任務(wù)之間有先后順序. 管線是?個抽象的概念,之所以稱之為管線是因為顯卡在處理數(shù)據(jù)的時候是按照一個固定的順序來的,而且嚴(yán)格按照這個順序。就像水從一根管子的一端流到另一端,這個順序是不能打破的。
6.固定管線/存儲著色器?
- 在早期的 OpenGL 版本,它封裝了很多種著色器程序塊內(nèi)置的一段包含了光照、坐標(biāo)變換、裁剪等諸多功能的固定shader程序來完成,來幫助開發(fā)者來完成圖形的渲染。而開發(fā)者只需要傳入相應(yīng)的參數(shù),就能快速完成圖形的渲染。類似于iOS開發(fā)會封裝很多API,?我們只需要調(diào)用,就可以實現(xiàn)功能。不需要關(guān)注底層實現(xiàn)原理。
- 但是由于 OpenGL 的使用場景?常豐富,固定管線或存儲著色器無法完成每?個業(yè)務(wù)。這時將相關(guān)部分開放成可編程。
7.著??程序 (Shader)
- 就全?的將固定渲染管線架構(gòu)變?yōu)榱丝删幊啼秩竟芫€。因此,OpenGL 在實際調(diào)用繪制函數(shù)之前,還需要指定?個由shader編譯成的著色器程序。常見的著??主要有頂點著??(VertexShader),片段著?? (FragmentShader)/像素著??(PixelShader),?何著?? (GeometryShader),曲?細分著??(TessellationShader)。?段著??和像素著??只是在OpenGL和DX中的不同叫法?而已。可惜的是,直到 OpenGLES 3.0,依然只支持了頂點著色器和?段著??這兩個最基礎(chǔ)的著??。
- OpenGL 在處理shader時,和其他編譯器一樣。通過編譯、鏈接等步驟,?成了了著??程序(glProgram),著??程序同時包含了頂點著??和?段著??的運算邏輯。在OpenGL進?繪制的時候,首先由頂點著??對傳?的頂點數(shù)據(jù)進?運算。再通過圖元裝配,將頂點轉(zhuǎn)換為圖元。然后進?光柵化,將圖元這種?量圖形,轉(zhuǎn)換為柵格化數(shù)據(jù)。最后,將柵格化數(shù)據(jù)傳?片段著??中進行運算。片段著色?會對柵格化數(shù)據(jù)中的每一個像素進行運算,并決定像素的顏?。
8.頂點著色器 (VertexShader)
- 一般用來處理圖形每個頂點變換(旋轉(zhuǎn)/平移/投影等)
- 頂點著??是OpenGL中用于計算頂點屬性的程序。頂點著??是逐頂點運算的程序,也就是說每個頂點數(shù)據(jù)都會執(zhí)?一次頂點著色?,當(dāng)然這是并行的,并且頂點著??運算過程中無法訪問其他頂點的數(shù)據(jù).
- 一般來說典型的需要計算的頂點屬性主要包括頂點坐標(biāo)變換、逐頂點光照運算等等。頂點坐標(biāo)由自身坐標(biāo)系轉(zhuǎn)換到歸一化坐標(biāo)系的運算,就是在這里發(fā)?生的。
9.?片元著?色器?程序 (FragmentShader)
- 一般用來處理圖形中每個像素點顏色計算和填充。
- 片段著??是OpenGL中?于計算?段(像素)顏色的程序。?段著?器是逐像素運算的程序,也就是說每個像素都會執(zhí)行?次片段著色?,當(dāng)然也是并行的。
10.GLSL(OpenGL Shading Language)
- OpenGL著?色語?言(OpenGL Shading Language)是?來在OpenGL中著色編程的語言,也即開發(fā)人員寫的短小的?定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理理單元)上執(zhí)行的,代替了固定的渲染管線的?部分,使渲染管線中不同層次具有可編程性。比如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等。GLSL(GL Shading Language)的著色器代碼分成2個部分: Vertex Shader(頂點著??)和Fragment(片斷著??)
11.光柵化(Rasterization)
- 是把頂點數(shù)轉(zhuǎn)換為片元的過程,具有將圖轉(zhuǎn)化為?個柵格組成的圖象的作?,特點是每個元素對應(yīng)幀緩沖區(qū)中的?像素。
- 光柵化就是把頂點數(shù)據(jù)轉(zhuǎn)換為片元的過程。?元中的每?個元素對應(yīng)于幀緩沖區(qū)中的一個像素。
- 光柵化其實是一種將幾何圖元變?yōu)槎S圖像的過程。該過程包含了兩部分的工作。第一部分工作:決定窗口坐標(biāo)中的哪些整型柵格區(qū)域被基本圖元占用;第二部分工作:分配一個顏色值和?個深度值到各個區(qū)域。光柵化 過程產(chǎn)生的是片元。
- 把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上?于對應(yīng)位置的像素及用于填充像素的顏色,這個過程稱為光柵化,這是一個將模擬信號轉(zhuǎn)化為離散信號的過程。
12.紋理
紋理可以理解為圖片。大家在渲染圖形時需要在其編碼填充圖片,為了使得場景更加逼真。?這里使?的圖?,就是常說的紋理。但是在OpenGL,我們更加習(xí)慣叫紋理,而不是圖片。
13.混合(Blending)
在測試階段之后,如果像素依然沒有被剔除,那么像素的顏色將會和幀緩沖區(qū)中顏?色附著上的顏?進行混合,混合的算法可以通過 OpenGL 的函數(shù)進?指定。但是 OpenGL 提供的混合算法是有限的,如果需要更加復(fù)雜的混合算法,一般可以通過像素著??進?實現(xiàn),當(dāng)然性能會比原生的混合算法差一些。
14.變換矩陣(Transformation)
例如圖形想發(fā)生平移,縮放,旋轉(zhuǎn)變換,就需要使?用變換矩陣。
15.投影矩陣(Projection)
?用于將3D坐標(biāo)轉(zhuǎn)換為二維屏幕坐標(biāo),實際線條也將在二維坐標(biāo)下進行繪制。
16.渲染上屏/交換緩沖區(qū)(SwapBuffer)
- 渲染緩沖區(qū)一般映射的是系統(tǒng)的資源比如窗口。如果將圖像直接渲染到窗口對應(yīng)的渲染緩沖區(qū),則可以將圖像顯示到屏幕上。
- 但是,值得注意的是,如果每個窗口只有一個緩沖區(qū),那么在繪制過程中屏幕進行了了刷新,窗?可能顯示出不完整的圖像。
- 為了解決這個問題,常規(guī)的OpenGL程序至少都會有兩個緩沖區(qū)。顯示在屏幕上的稱為屏幕緩沖區(qū),沒有顯示的稱為離屏緩沖區(qū)。在一個緩沖區(qū)渲染完成之后,通過將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實現(xiàn)圖像在屏幕上的顯示。
- 由于顯示器的刷新一般是逐?進行的,因此為了防?交換緩沖區(qū)的時候屏幕上下區(qū)域的圖像分屬于兩個不同的幀,因此交換一般會等待顯示器?刷新完成的信號,在顯示?兩次刷新的間隔中進行交換,這個信號就被稱為垂直同步信號,這個技術(shù)被稱為垂直同步。
- 使?用了雙緩沖區(qū)和垂直同步技術(shù)之后,由于總是要等待緩沖區(qū)交換之后再進行下一幀的渲染,使得幀率無法完全達到硬件允許的最?水平。為了解決這個問題,引?了三緩沖區(qū)技術(shù),在等待垂直同步時,來回交替渲染兩個離屏的緩沖區(qū),而垂直同步發(fā)生時,屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換,實現(xiàn)充分利用硬件性能的目的。