快速了解圖形API
OpenGL(Open Graphics Library)
????OpenGL是?個跨編程語?言温学、跨平臺的編程圖形程序接?口泌绣,它將計算機的資源抽象稱為?個OpenGL的對象蟆盹,對這些資源的操作抽象為?個的OpenGL指令阐滩。
OpenGL ES (OpenGL for Embedded Systems)
????OpenGL ES是 OpenGL三維圖形 API 的?子集坪稽,針對?手機忧饭、 PDA和游戲主機等嵌?入式設備?而設計扛伍,去除了了許多不不必要和性能較低的API接?口。
DirectX?
????DirectX?是由很多API組成的词裤,DirectX并不不是?個單純的圖形API. 最重要的是DirectX是屬于 Windows上?個多媒體處理理API刺洒。并不支持Windows以外的平臺,所以不是跨平臺框架吼砂, 按照性 質分類逆航,可以分為四?大部分,顯示部分渔肩、聲?音部分因俐、輸?入部分和?網絡部分。?
Metal?
????Apple為游戲開發(fā)者推出了了新的平臺技術Metal周偎,該技術能夠為 3D 圖像提?高 10 倍的渲染性能抹剩。Metal是Apple為了了解決3D渲染?而推出的框架。
OpenGL名詞解析?
1. OpenGL 狀態(tài)機
??狀態(tài)機描述了一個對象在其生命周期內所經歷的各種狀態(tài)蓉坎,狀態(tài)間的轉變澳眷,發(fā)生轉變的動因,條件及轉變中所執(zhí)行的活動蛉艾∏唬或者說,狀態(tài)機是一種行為伺通,說明對象在其生命周期中相應事件所經歷的狀態(tài)序列以及對那些狀態(tài)事件的響應箍土,所以狀態(tài)機具有以下的特點:
??有記憶功能,可以記住當前的狀態(tài)罐监。
??可以接收輸入吴藻,根據輸入的內容和自己原先的狀態(tài)修改自己當前狀態(tài),并且可以有對應的輸出弓柱。
??當進入特殊狀態(tài)(停機狀態(tài))的時候沟堡,便不再接收輸入侧但,停止工作。
2. OpenGL?上下?(context)
????????在應用程序調用任何 OpenGL 指令之前航罗,需要安排創(chuàng)建一個 OpenGL 的上下文瞄勾,這個上下文是一個非常龐大的狀態(tài)機,保存了 OpenGL 的各種狀態(tài)于颖,這也是 OpenGL 指令執(zhí)行的基礎坪仇。
??OpenGL 的函數不管在哪個語言中,都是類C語言一樣的面向過程的函數复亏,本質上都是對 OpenGL 上下文這個龐大的狀態(tài)機中的某個狀態(tài)或者對象進行操作趾娃,當然你得首先把這個對象設置為當前對象。因此缔御,通過對 OpenGL 指令的封裝抬闷,是可以將 OpenGL 的相關調用封裝成為一個面向對象的圖形 API 的。
??由于 OpenGL 上下文是一個巨大的狀態(tài)機耕突,切換上下文往往會產生較大的開銷笤成,但是不同的繪制模塊可能需要使用完全獨立的狀態(tài)管理,因此眷茁,可以在應用程序中分別創(chuàng)建多個不同的上下文炕泳,在不同線程中使用不同的上下文,上下文之間共享紋理蔼卡、緩沖區(qū)等資源喊崖。這樣的方案會比反復切換上下文或者大量修改渲染狀態(tài)更加合理高效。
3. 渲染(Rendering)
????將數學和圖形數據轉換成3D空間圖像的操作叫做渲染雇逞。? ??
4. 頂點數組(VertexArray)和頂點緩沖區(qū)(VertexBuffer)
? ? 畫圖時荤懂,一般是先畫好圖像的骨架,然后再往骨架里填充顏色塘砸,這對于OpenGL也是一樣的节仿。頂點數據就是要畫的圖像的骨架,和現實中不同的是掉蔬,OpenGL中的圖像都是由圖元組成的廊宪。在OpenGL ES中,有3種類型的圖元:點女轿、線箭启、三角形。
????????那么這些頂點數據存儲在哪兒呢蛉迹?開發(fā)者可以選擇設定函數指針傅寡,在調用繪制方法的時候,直接由內存?zhèn)魅腠旤c數據,也就是說這部分數據之前是存儲在內存當中的荐操,稱為頂點數組芜抒。而性能更高的做法是,提前分配一塊顯存托启,將頂點數據預先傳入到顯存當中宅倒。這部分顯存,稱之為頂點緩沖區(qū)屯耸。
????????頂點指的是我們繪制一個圖形時拐迁,它的頂點位置數據。而這個數據可以直接存儲在數組中或者將其緩存到GPU內存中
5. 管線
? ? 在OpenGL 下渲染圖形,就會經歷一個一個節(jié)點疗绣,而這樣的操作可以理解為管線唠亚。大家可以想象成流水線,每個任務類似流水線般執(zhí)行持痰。任務之間有先后順序。 管線是一個抽象的概念祟蚀,之所以稱之為管線是因為顯卡在處理數據的時候是按照一個固定的順序來的工窍,而且嚴格按照這個順序。這個順序就是渲染流程前酿,而管線指的是這個過程患雏。
6. 固定管線/存儲著色器
? ? ?在早期的OpenGL 版本,它封裝了很多種著色器程序塊內置的一些包含了光照罢维、坐標變換淹仑、裁剪等等諸多功能的固定shader程序來完成,來幫助開發(fā)者來完成圖形的渲染肺孵。 而開發(fā)者只需要傳入相應的參數匀借,就能快速完成圖形的渲染.。類似于iOS開發(fā)會封裝很多API平窘,而我們只需要調用就可以實現功能吓肋,不需要關注底層實現原理。
????在固定管線下瑰艘,使用固定存儲著色器是鬼,固定存儲著?器由GLTools的C++類GLShaderManager管理,它們能夠滿?進?基本渲染的基本要求紫新。
????但是由于OpenGL 的使用場景非常豐富均蜜,固定管線或存儲著色器無法完成每一個業(yè)務,這時將相關部分開放成可編程芒率。
7.?著色器程序Shader
? ? ?OpenGL在實際調用繪制函數之前囤耳,還需要指定一個由shader編譯成的著色器程序。Shader 就是一個代碼段,在固定渲染管線架構下紫皇,Shader 是已經被封裝好了的慰安,開發(fā)者直接調用即可。在可編程架構下聪铺,需要開發(fā)者自己編寫Shader程序化焕。常見的著色器主要有頂點著色器(VertexShader)、片段(元)著色器(FragmentShader)/ 像素著色器(PixelShader)铃剔、幾何著色器撒桨、曲面細分著色器等〖担可惜的是凤类,直到OpenGL ES 3.0,依然只支持了頂點著色器和片段著色器這兩個最基礎的著色器普气。
????OpenGL在處理shader時谜疤,和其他編譯器一樣,需要通過編譯现诀、鏈接等步驟夷磕,生成著色器程序(glProgram),著色器程序同時包含了頂點著色器和片段著色器的運算邏輯仔沿。在OpenGL進行繪制的時候坐桩,首先由頂點著色器對傳入的頂點數據進行運算。再通過圖元裝配封锉,將頂點轉換為圖元绵跷。然后進行光柵化,將圖元這種矢量圖形成福,轉換為柵格化數據碾局。最后,將柵格化數據傳入片段著色器中進行運算闷叉。片段著色器會對柵格化數據中的每一個像素進行運算擦俐,并決定像素的顏色。
頂點著?器(VertexShader):
? ??頂點著?器是OpenGL中?于計算頂點屬性的程序握侧。
?????般來說典型的需要計算的頂點屬性主要包括頂點坐標變換蚯瞧、逐頂點光照運算等等。頂點坐標由?身坐標系轉換到歸一化坐標系的運算品擎,就是在這里發(fā)?的埋合。
????頂點著?器是逐頂點運算的程序,也就是說每個頂點數據都會執(zhí)?一次頂點著?器萄传。當然這是并行的甚颂,并且頂點著?器運算過程中?法訪問其他頂點的數據蜜猾。
片元著色器(FragmentShader):? ??
? ??一般用來處理圖形中每個像素點顏色的計算和填充。
????片段著色器是OpenGL中用于計算片段(像素)顏色的程序振诬。片段著色器是逐像素運算的程序蹭睡,也就是說每個像素都會執(zhí)行一次片段著色器,這個過程也是并行的赶么。
8. GLSL (OpenGL Shading Language)
? ? ?OpenGL著色語言(OpenGL Shading Language)是用來在OpenGL中著色編程的語言肩豁,也即開發(fā)人員寫的短小的自定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執(zhí)行的辫呻,代替了固定的渲染管線的一部分清钥,使渲染管線中不同層次具有可編程性。比如:視圖轉換放闺、投影轉換等祟昭。GLSL(GL Shading Language)的著色器代碼分成2個部分:Vertex Shader(頂點著色器)和 Fragment(片斷著色器),有時還會有Geometry Shader(幾何著色器)怖侦。
9. 光柵化(Rasterization)
????光柵化就是把頂點數據轉換為片元的過程篡悟。具有將圖轉化為?個個柵格組成的圖象 的作?,特點是每個元素對應幀緩沖區(qū)中的?像素匾寝。
????光柵化其實是?種將?何圖元變?yōu)槎S圖像的過程恰力。該過程包含了兩部分的?作。第?部分工作:決定窗?坐標中的哪些整型柵格區(qū)域被基本圖元占?旗吁;第?部分?作:分配一個顏?值和?個深度值到各個區(qū)域。
????把物體的數學描述以及與物體相關的顏色信息轉換為屏幕上用于對應位置的像素及?于填充像素的顏?停局,這個過程稱為光柵化很钓。這是?個將模擬信號轉化為離散信號的過程。
10. 紋理(Texture)
????紋理可以理解為圖?董栽。 在渲染圖形時需要在頂點圍成的區(qū)域中填充圖?码倦,使得場景更加逼真。?這?使?的圖?锭碳,就是常說的紋理袁稽。只是在OpenGL,我們更加習慣叫紋理擒抛,?不是圖?推汽。
11. 混合(Blending)
????在測試階段之后,如果像素依然沒有被剔除歧沪,那么像素的顏?將會和幀緩沖區(qū)中顏?附著上的顏色進?混合歹撒,混合的算法可以通過OpenGL的函數進行指定。但是OpenGL提供的混合算法有限诊胞。如果需要更加復雜的混合算法暖夭,一般可以通過片段著?器進?實現,當然性能會?原?的混合算法差?些。
12. 矩陣
? ??變換矩陣(Transformation):例如圖形想發(fā)?平移迈着、縮放竭望、旋轉等變換,就需要使用變換矩陣裕菠。
? ??投影矩陣(Projection):?于將3D坐標轉換為?維屏幕坐標咬清,實際線條也將在二維坐標下進行繪制。
13. 渲染上屏/交換緩沖區(qū)(SwapBuffer)
????渲染緩沖區(qū)?般映射的是系統(tǒng)的資源?如窗?糕韧。如果將圖像直接渲染到窗口對應的渲染緩沖區(qū)枫振,則可以將圖像顯示到屏幕上。
????值得注意的是萤彩,如果每個窗?只有?個緩沖區(qū)粪滤,那么在繪制過程中屏幕進?了刷新,窗?可能顯示出不完整的圖像雀扶。
????為了解決這個問題杖小,常規(guī)的OpenGL程序?少都會有兩個緩沖區(qū)。顯示在屏幕上的稱為屏幕緩沖區(qū)愚墓,沒有顯示的稱為離屏緩沖區(qū)予权。在一個緩沖區(qū)渲染完成之后,通過將屏幕緩沖區(qū)和離屏緩沖區(qū)交換浪册,實現圖像在屏幕上顯示扫腺。
????由于顯示器的刷新?般是逐?進?的,為了防?交換緩沖區(qū)的時候屏幕上下區(qū)域的圖像分屬于兩個不同的幀村象,交換一般會等待顯示器刷新完成的信號笆环,在顯示器器兩次刷新的間隔中進?交換,這個信號就被稱為垂直同步信號厚者,這個技術被稱為垂直同步躁劣。
????使用了雙緩沖區(qū)和垂直同步技術之后,由于總是要等待緩沖區(qū)交換之后再進?下?幀的渲染库菲,使得幀率無法完全達到硬件允許的最??平账忘。為了解決這個問題,引?了三緩沖區(qū)技術熙宇。在等待垂直同步時鳖擒,來回交替渲染兩個離屏的緩沖區(qū),?垂直同步發(fā)?生時烫止,屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換败去,實現充分利利?硬件性能的?的。