圖形API簡(jiǎn)介
OpenGL?(Open Graphics Library)是一個(gè)跨編程語(yǔ)?市咆、跨平臺(tái)的編程圖形程序接口缓淹,它將計(jì)算機(jī)的資源抽象稱為?個(gè)OpenGL的對(duì)象每币,對(duì)這些資源的操作抽象為?個(gè)的OpenGL指令
OpenGL ES?(OpenGL for Embedded Systems)是?OpenGL?三維圖形?API?的子集力麸,針對(duì)手機(jī)拐辽、?PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì),去除了了許多不必要和性能較低的API接口佛吓。
DirectX?是由很多API組成的宵晚,DirectX并不是一個(gè)單純的圖形API.?最重要的是DirectX是屬于?Windows上一個(gè)多媒體處理理框架.并不支持Windows以外的平臺(tái),所以不是跨平臺(tái)框架.?按照性 質(zhì)分類,可以分為四大部分维雇,顯示部分坝疼、聲音部分、輸入部分和?絡(luò)部分.
Metal :?Metal: Apple為游戲開發(fā)者推出了新的平臺(tái)技術(shù)?Metal谆沃,該技術(shù)能夠?yàn)?3D?圖 像提高?10?倍的渲染性能.Metal?是Apple為了解決3D渲染而推出的框架
OpenGL?專業(yè)名詞解析
?1.OpenGL?上下? ( context )
??在應(yīng)?程序調(diào)?任何OpenGL的指令之前,需要安排?先創(chuàng)建?個(gè)OpenGL的上下?仪芒。這個(gè)上下?是?個(gè)?常龐?的狀態(tài)機(jī)唁影,保存了OpenGL中的各種狀態(tài),這也是OpenGL指令執(zhí)?的基礎(chǔ)掂名。
? ?OpenGL的函數(shù)不管在哪個(gè)語(yǔ)?中据沈,都是類似C語(yǔ)??樣的?向過(guò)程的函數(shù),本質(zhì)上都是對(duì)OpenGL上下?這個(gè)龐?的狀態(tài)機(jī)中的某個(gè)狀態(tài)或者對(duì)象進(jìn)?操作饺蔑,當(dāng)然你得?先把這個(gè)對(duì)象設(shè)置為當(dāng)前對(duì)象锌介。因此,通過(guò)對(duì)OpenGL指令的封裝,是可以將OpenGL的相關(guān)調(diào)用封裝成為一個(gè)面向?qū)ο蟮膱D形API孔祸。
? ?由于OpenGL上下?是?個(gè)巨?的狀態(tài)機(jī)隆敢,切換上下?往往會(huì)產(chǎn)?較?的開銷,但是不同的繪制模塊崔慧,可能需要使?完全獨(dú)?的狀態(tài)管理拂蝎。因此,可以在應(yīng)?程序中分別創(chuàng)建多個(gè)不同的上下?惶室,在不同線程中使?不同的上下?温自,上下?之間共享紋理、緩沖區(qū)等資源皇钞。這樣的?案悼泌,會(huì)?反復(fù)切換上下?,或者?量修改渲染狀態(tài)夹界,更加合理?效的.
2.OpenGL?狀態(tài)機(jī)
? 狀態(tài)機(jī)是理論上的?種機(jī)器.這個(gè)?常難以理解.所以我們把這個(gè)狀態(tài)機(jī)這么理解.狀態(tài)機(jī)描述了?對(duì)象在其?命周期內(nèi)所經(jīng)歷的各種狀態(tài)馆里,狀態(tài)間的轉(zhuǎn)變,發(fā)?轉(zhuǎn)變的動(dòng)因掉盅,條件及轉(zhuǎn)變中所執(zhí)?的活動(dòng)也拜。或者說(shuō)趾痘,狀態(tài)機(jī)是?種?為慢哈,說(shuō)明對(duì)象在其?命周期中響應(yīng)事件所經(jīng)歷的狀態(tài)序列以及對(duì)那些狀態(tài)事件的響應(yīng)。因此具有以下特點(diǎn):
1. 有記憶功能永票,能記住其當(dāng)前的狀態(tài)
2. 可以接收輸?卵贱,根據(jù)輸?的內(nèi)容和??的原先狀態(tài),修改??當(dāng)前狀態(tài)侣集,并且可以有對(duì)應(yīng)輸出
3.? 當(dāng)進(jìn)?特殊狀態(tài)(停機(jī)狀態(tài))的時(shí)候键俱,變不再接收輸?,停??作世分;
3. 渲染
將圖形/圖像數(shù)據(jù)轉(zhuǎn)換成3D空間圖像操作叫做渲染(Rendering)编振。
4. 頂點(diǎn)數(shù)組( VertexArray )?和 頂點(diǎn)緩沖區(qū)(?VertexBuffer )
??畫圖?般是先畫好圖像的?架,然后再往?架??填充顏?臭埋,這對(duì)于OpenGL也是?樣的踪央。頂點(diǎn)數(shù)據(jù)就是要畫的圖像的?架,和現(xiàn)實(shí)中不同的是瓢阴,OpenGL中的圖像都是由圖元組成畅蹂。在OpenGLES中,有3種類型的圖元:點(diǎn)荣恐、線液斜、三?形累贤。那這些頂點(diǎn)數(shù)據(jù)最終是存儲(chǔ)在哪?的呢?開發(fā)者可以選擇設(shè)定函數(shù)指針少漆,在調(diào)?繪制?法的時(shí)候臼膏,直接由內(nèi)存?zhèn)?頂點(diǎn)數(shù)據(jù),也就是說(shuō)這部分?jǐn)?shù)據(jù)之前是存儲(chǔ)在內(nèi)存當(dāng)中的检疫,被稱為頂點(diǎn)數(shù)組讶请。?性能更?的做法是,提前分配?塊顯存屎媳,將頂點(diǎn)數(shù)據(jù)預(yù)先傳?到顯存當(dāng)中夺溢。這部分的顯存,就被稱為頂點(diǎn)緩沖區(qū)烛谊。頂點(diǎn)緩存區(qū)在顯卡顯存中风响。
??頂點(diǎn)指的是我們?cè)诶L制?個(gè)圖形時(shí),它的頂點(diǎn)位置數(shù)據(jù).?這個(gè)數(shù)據(jù)可以直接存儲(chǔ)在數(shù)組中或者將其緩存到GPU內(nèi)存中.
5. 管線
??在OpenGL下渲染圖形,就會(huì)有經(jīng)歷?個(gè)?個(gè)節(jié)點(diǎn).?這樣的操作可以理解管線。?家可以想象成流?線丹禀,每個(gè)任務(wù)類似流?線般執(zhí)?状勤,任務(wù)之間有先后順序, 管線是?個(gè)抽象的概念双泪,之所以稱之為管線是因?yàn)轱@卡在處理數(shù)據(jù)的時(shí)候是按照?個(gè)固定的順序來(lái)的持搜,?且嚴(yán)格按照這個(gè)順序。就像?從?根管?的?端流到另?端焙矛,這個(gè)順序是不能打破的葫盼。
6. 固定管線/存儲(chǔ)著色器
??在早期的OpenGL版本,它封裝了很多種著?器程序塊內(nèi)置的?段包含了光照、坐標(biāo)變換村斟、裁剪等等諸多功能的固定Shader程序來(lái)完成,來(lái)幫助開發(fā)者來(lái)完成圖形的渲染. ?開發(fā)者只需要傳?相應(yīng)的參數(shù),就能快速完成圖形的渲染. 類似于iOS開發(fā)會(huì)封裝很多API,?我們只需要調(diào)?,就可以實(shí)現(xiàn)功能.不需要關(guān)注底層實(shí)現(xiàn)原理贫导。
??但是由于OpenGL的使?場(chǎng)景?常豐富,固定管線或存儲(chǔ)著?器?法完成每?個(gè)業(yè)務(wù).這時(shí)將相關(guān)部分開放成可編程。
7. 著?器程序(Shader)
??就全?的將固定渲染管線架構(gòu)變?yōu)榱丝删幊啼秩竟芫€蟆盹。因此孩灯,OpenGL在實(shí)際調(diào)?繪制函數(shù)之前,還需要指定?個(gè)由Shader編譯成的著?器程序逾滥。常?的著?器主要有頂點(diǎn)著?器(VertexShader)峰档,?段著?器(FragmentShader)/像素著?器(PixelShader),?何著?器(GeometryShader)寨昙,曲?細(xì)分著?器(TessellationShader)面哥。?段著?器和像素著?器只是在OpenGL和DX中的不同叫法?已∫愦可惜的是,直到OpenGLES 3.0归榕,依然只?持了頂點(diǎn)著?器和?段著?器這兩個(gè)最基礎(chǔ)的著?器尸红。
??OpenGL在處理shader時(shí),和其他編譯器?樣。通過(guò)編譯外里、鏈接等步驟怎爵,?成了著?器程序(glProgram),著?器程序同時(shí)包含了頂點(diǎn)著?器和?段著?器的運(yùn)算邏輯盅蝗。在OpenGL進(jìn)?繪制的時(shí)候鳖链,?先由頂點(diǎn)著?器對(duì)傳?的頂點(diǎn)數(shù)據(jù)進(jìn)?運(yùn)算。再通過(guò)圖元裝配墩莫,將頂點(diǎn)轉(zhuǎn)換為圖元芙委。然后進(jìn)?光柵化,將圖元這種?量圖形狂秦,轉(zhuǎn)換為柵格化數(shù)據(jù)灌侣。最后,將柵格化數(shù)據(jù)傳??段著?器中進(jìn)?運(yùn)算裂问。?段著?器會(huì)對(duì)柵格化數(shù)據(jù)中的每?個(gè)像素進(jìn)?運(yùn)算侧啼,并決定像素的顏?。
9. 頂點(diǎn)著?器(VertexShader)
???般?來(lái)處理圖形每個(gè)頂點(diǎn)變換(旋轉(zhuǎn)/平移/投影等)
??頂點(diǎn)著?器是OpenGL中?于計(jì)算頂點(diǎn)屬性的程序堪簿。頂點(diǎn)著?器是逐頂點(diǎn)運(yùn)算的程序痊乾,也就是說(shuō)每個(gè)頂點(diǎn)數(shù)據(jù)都會(huì)執(zhí)??次頂點(diǎn)著?器,當(dāng)然這是并?的椭更,并且頂點(diǎn)著?器運(yùn)算過(guò)程中?法訪問(wèn)其他頂點(diǎn)的數(shù)據(jù)哪审。
???般來(lái)說(shuō)典型的需要計(jì)算的頂點(diǎn)屬性主要包括頂點(diǎn)坐標(biāo)變換、逐頂點(diǎn)光照運(yùn)算等等甜孤。頂點(diǎn)坐標(biāo)由?身坐標(biāo)系轉(zhuǎn)換到歸?化坐標(biāo)系的運(yùn)算协饲,就是在這?發(fā)?的。
10. ?元/片段/像素著?器程序(FragmentShader)
???般?來(lái)處理圖形中每個(gè)像素點(diǎn)顏?計(jì)算和填充缴川。
???段著?器是OpenGL中?于計(jì)算?段(像素)顏?的程序茉稠。?段著?器是逐像素運(yùn)算的程序,也就是說(shuō)每個(gè)像素都會(huì)執(zhí)??次?段著?器把夸,當(dāng)然也是并?的而线。
11.?GLSL(OpenGL Shading Language)
??OpenGL著?語(yǔ)?(OpenGL Shading Language)是?來(lái)在OpenGL中著?編程的語(yǔ)?,也即開發(fā)?員寫的短?的?定義程序恋日,他們是在圖形卡的GPU(Graphic Processor Unit圖形處理單元)上執(zhí)?的膀篮,代替了固定的渲染管線的?部分,使渲染管線中不同層次具有可編程性岂膳。?如:視圖轉(zhuǎn)換誓竿、投影轉(zhuǎn)換等。GLSL(GL Shading Language)的著?器代碼分成2個(gè)部分:Vertex Shader(頂點(diǎn)著?器)和Fragment(?斷著?器)谈截。
12. 光柵化(Rasterization)
??是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程筷屡,具有將圖轉(zhuǎn)化為?個(gè)個(gè)柵格組成的圖象的作?涧偷,特點(diǎn)是每個(gè)元素對(duì)應(yīng)幀緩沖區(qū)中的?像素。
??光柵化就是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程毙死,?元中的每?個(gè)元素對(duì)應(yīng)于幀緩沖區(qū)中的?個(gè)像素燎潮。
??光柵化其實(shí)是?種將?何圖元變?yōu)?維圖像的過(guò)程。該過(guò)程包含了兩部分的?作扼倘。第?部分?作:決定窗?坐標(biāo)中的哪些整型柵格區(qū)域被基本圖元占?确封;第?部分?作:分配?個(gè)顏?值和?個(gè)深度值到各個(gè)區(qū)域。光柵化過(guò)程產(chǎn)?的是?元再菊。
??把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏?信息轉(zhuǎn)換為屏幕上?于對(duì)應(yīng)位置的像素及?于填充像素的顏?爪喘,這個(gè)過(guò)程稱為光柵化,這是?個(gè)將模擬信號(hào)轉(zhuǎn)化為離散信號(hào)的過(guò)程袄简。
13.紋理
??紋理可以理解為圖?腥放,?家在渲染圖形時(shí)需要在其編碼填充圖?,為了使得場(chǎng)景更加逼真绿语。?這?使?的圖?秃症,就是常說(shuō)的紋理,但是在OpenGL吕粹,我們更加習(xí)慣叫紋理,?不是圖?种柑。
15. 混合(Blending)
??在測(cè)試階段之后,如果像素依然沒(méi)有被剔除匹耕,那么像素的顏?將會(huì)和幀緩沖區(qū)中顏?附著上的顏?進(jìn)?混合聚请,混合的算法可以通過(guò)OpenGL的函數(shù)進(jìn)?指定。但是OpenGL提供的混合算法是有限的稳其,如果需要更加復(fù)雜的混合算法驶赏,?般可以通過(guò)像素著?器進(jìn)?實(shí)現(xiàn),當(dāng)然性能會(huì)?原?的混合算法差?些既鞠。
16.變換矩陣(Transformation)
??例如圖形想發(fā)?平移,縮放,旋轉(zhuǎn)變換.就需要使?變換矩陣煤傍。
17. 投影矩陣(Projection)
???于將3D坐標(biāo)轉(zhuǎn)換為?維屏幕坐標(biāo),實(shí)際線條也將在?維坐標(biāo)下進(jìn)?繪制。
18. 視口嘱蛋、窗口
??視口是與設(shè)備相關(guān)的一個(gè)矩形區(qū)域蚯姆,坐標(biāo)單位是與設(shè)備相關(guān)的“像素”,大多數(shù)情況下洒敏,視口與客戶區(qū)相同龄恋。窗口的坐標(biāo)是邏輯坐標(biāo),與設(shè)備無(wú)關(guān)凶伙,可能是像素郭毕、毫米或者英寸。窗口坐標(biāo)的原點(diǎn)與視口坐標(biāo)的原點(diǎn)始終對(duì)應(yīng)于同一點(diǎn)函荣。對(duì)于同一個(gè)圖形显押,用窗口坐標(biāo)系統(tǒng)表達(dá)的該區(qū)域的長(zhǎng)和寬與視口的坐標(biāo)系統(tǒng)表達(dá)的長(zhǎng)和寬是不同的链韭。二者就定義了這兩個(gè)坐標(biāo)系統(tǒng)的比例關(guān)系。程序作圖時(shí)煮落,使用的坐標(biāo)總是是窗口坐標(biāo)。而實(shí)際的顯示或輸出設(shè)備卻各有自己的坐標(biāo)踊谋。視口是設(shè)備自己的坐標(biāo)蝉仇,窗口是邏輯坐標(biāo)
19. 渲染上屏/交換緩沖區(qū)(SwapBuffer)
??渲染緩沖區(qū)?般映射的是系統(tǒng)的資源?如窗?。如果將圖像直接渲染到窗?對(duì)應(yīng)的渲染緩沖區(qū)殖蚕,則可以將圖像顯示到屏幕上轿衔。
??但是,值得注意的是睦疫,如果每個(gè)窗?只有?個(gè)緩沖區(qū)害驹,那么在繪制過(guò)程中屏幕進(jìn)?了刷新,窗?可能顯示出不完整的圖像
??為了解決這個(gè)問(wèn)題蛤育,常規(guī)的OpenGL程序?少都會(huì)有兩個(gè)緩沖區(qū)宛官。顯示在屏幕上的稱為屏幕緩沖區(qū),沒(méi)有顯示的稱為離屏緩沖區(qū)瓦糕。在?個(gè)緩沖區(qū)渲染完成之后底洗,通過(guò)將屏幕緩沖區(qū)和離屏緩沖區(qū)交換,實(shí)現(xiàn)圖像在屏幕上的顯示咕娄。
??由于顯示器的刷新?般是逐?進(jìn)?的亥揖,因此為了防?交換緩沖區(qū)的時(shí)候屏幕上下區(qū)域的圖像分屬于兩個(gè)不同的幀,因此交換?般會(huì)等待顯示器刷新完成的信號(hào)圣勒,在顯示器兩次刷新的間隔中進(jìn)?交換费变,這個(gè)信號(hào)就被稱為垂直同步信號(hào),這個(gè)技術(shù)被稱為垂直同步
??使?了雙緩沖區(qū)和垂直同步技術(shù)之后圣贸,由于總是要等待緩沖區(qū)交換之后再進(jìn)?下?幀的渲染挚歧,使得幀率?法完全達(dá)到硬件允許的最??平。為了解決這個(gè)問(wèn)題旁趟,引?了三緩沖區(qū)技術(shù)昼激,在等待垂直同步時(shí),來(lái)回交替渲染兩個(gè)離屏的緩沖區(qū)锡搜,?垂直同步發(fā)?時(shí)橙困,屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換,實(shí)現(xiàn)充分利?硬件性能的?的