一、簡(jiǎn)單了解圖形API?
????1阻问、OpenGL(Open Graphics Library)是一個(gè)跨平臺(tái)梧税、跨編程語(yǔ)言的編程圖形程序接口,它將計(jì)算機(jī)的資源抽象為一個(gè)個(gè)OpenGL對(duì)象称近,對(duì)這些資源的操作抽象為一個(gè)個(gè)OpenGL指令。
? ? 2哮塞、OpenGL ES(OpenGL for Embedded System)是OpenGL三維圖形API的子集刨秆,針對(duì)手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)忆畅,去除了許多不必要和性能較低的API接口衡未。
? ? 3、DirectX:是由很多API組成的,DirectX并不是一個(gè)單純的圖形API缓醋,最重要的是DirectX是屬于Windows上一個(gè)多媒體處理API如失,并不支持Windows以外的平臺(tái),所以不是跨平臺(tái)框架送粱,按照性質(zhì)分類(lèi)為四大部分:顯示部分褪贵,聲音部分,輸入部分以及網(wǎng)絡(luò)部分抗俄。
? ? 4脆丁、Metal:Apple為游戲開(kāi)發(fā)者推出的新平臺(tái)技術(shù),該技術(shù)能夠?yàn)?D圖像提高10倍的渲染性能动雹。Metal是Apple為了解決3D渲染而推出的框架槽卫。
二、OpenGL專(zhuān)有名詞解析
1胰蝠、OpenGL上下文(context)
????在應(yīng)用程序調(diào)用任何OpenGL指令之前歼培,需要安排首先創(chuàng)建一個(gè)OpenGL的上下文,這個(gè)上下文是一個(gè)非常龐大的狀態(tài)機(jī)茸塞,保存了OpenGL中的各種狀態(tài)躲庄,這也是OpenGL指令執(zhí)行的基礎(chǔ)
????OpenGL語(yǔ)言函數(shù)不管是在哪個(gè)語(yǔ)言中,都是類(lèi)似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)用封裝稱(chēng)為一個(gè)面向?qū)ο蟮膱D形API的。
????由于OpenGL上下文是一個(gè)巨大的狀態(tài)機(jī)荡短,切換上下文往會(huì)產(chǎn)生較大的開(kāi) 銷(xiāo)丐枉,但是不同的繪制模塊,可能需要使用完全獨(dú)立的狀態(tài)管理掘托。因此瘦锹,可 以在應(yīng)用程序中分別創(chuàng)建多個(gè)不不同的上下文,在不同線程中使用不不同的上 下文闪盔,上下文之間共享紋理弯院、緩沖區(qū)等資源。這樣的方案泪掀,會(huì)?反復(fù)切換 上下?听绳,或者?量修改渲染狀態(tài),更加合理?效的.
2异赫、OpenGL狀態(tài)機(jī)
????狀態(tài)機(jī)是理論上的一種機(jī)器椅挣,它描述了一個(gè)對(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)時(shí)間所經(jīng)歷的狀態(tài)序列以及對(duì)那些狀態(tài)事件的響應(yīng)适掰。
狀態(tài)機(jī)具有以下特點(diǎn):
????1、有記憶功能娩鹉,能夠記住當(dāng)前的狀態(tài)(比如OpenGL可以記住當(dāng)前所使用的顏色攻谁,是否開(kāi)啟了混合功能等)
? ? 2、可以接收輸入弯予,根據(jù)輸入的內(nèi)容和自己原先的狀態(tài)戚宦,修改自己當(dāng)前狀態(tài),并且可以有對(duì)應(yīng)的輸出(比如調(diào)用OpenGL函數(shù)的時(shí)候锈嫩,實(shí)際上就是在接收我們的輸入)
? ? 3受楼、當(dāng)進(jìn)入特殊狀態(tài)的時(shí)候(停機(jī)狀態(tài)),便不再接收輸入呼寸,停止工作艳汽。(OpenGL可以進(jìn)入停止?fàn)顟B(tài),不再接收輸入对雪,在程序退出前河狐,OpenGL總是會(huì)先停止工作)
3、渲染
????將圖像/圖形數(shù)據(jù)轉(zhuǎn)換成3D空間圖像操作叫做渲染
4瑟捣、頂點(diǎn)數(shù)組(VertexArray)和頂點(diǎn)緩沖區(qū)(VertexBuffer)
????畫(huà)圖一般都是先畫(huà)好圖像的骨架馋艺,然后再往骨架里面填充顏色,這對(duì)于OpenGL也是一樣的迈套,頂點(diǎn)數(shù)據(jù)就是要畫(huà)的圖像的骨架捐祠,和現(xiàn)實(shí)中不同的是,OpenGL的圖像都是由圖元組成桑李。在OpenGL ES中踱蛀,有3種類(lèi)型的圖元,點(diǎn)贵白,線率拒,三角形。那這些頂點(diǎn)數(shù)據(jù)是最終存儲(chǔ)在哪里呢禁荒?開(kāi)發(fā)者可以選擇指定函數(shù)指針俏橘,在調(diào)用繪制方法的時(shí)候,直接由內(nèi)存?zhèn)魅腠旤c(diǎn)數(shù)據(jù)圈浇,也就是說(shuō)這部分?jǐn)?shù)據(jù)之前是存儲(chǔ)在內(nèi)存之中的寥掐,被稱(chēng)為頂點(diǎn)數(shù)組.?而性能更高的做法是提前分配一塊顯存,將頂點(diǎn)數(shù)據(jù)預(yù)先傳入到顯存當(dāng)中磷蜀,這部分的顯存召耘,叫做頂點(diǎn)緩沖區(qū)。
????頂點(diǎn)指的是我們?cè)诶L制圖形的時(shí)候褐隆,它的頂點(diǎn)位置數(shù)據(jù)污它,而這個(gè)數(shù)據(jù)可以直接存儲(chǔ)在數(shù)組中或者將其緩存到CPU內(nèi)存中
5、管線
????在OpenGL下渲染圖形庶弃,就會(huì)有經(jīng)歷一個(gè)個(gè)節(jié)點(diǎn)衫贬,而這樣的操作可以理解成管線⌒ィ可以理解成流水線固惯,每個(gè)任務(wù)類(lèi)似流水線般執(zhí)行,任務(wù)之間有先后順序缴守,管線是一個(gè)抽象的概念葬毫,之所以被稱(chēng)為管線,是因?yàn)轱@卡在處理數(shù)據(jù)的時(shí)候屡穗,總是按照一個(gè)固定的順序來(lái)的贴捡,而且嚴(yán)格按照這個(gè)順序,這個(gè)順序不能被打破村砂。
6烂斋、固定管線和存儲(chǔ)著色器
????早期的OpenGL版本,它封裝了很多種著色器程序塊础废,內(nèi)置了一段包含光照汛骂、坐標(biāo)變換、裁剪等諸多功能的固定shader程序來(lái)完成色迂,來(lái)幫助來(lái)發(fā)著開(kāi)完成圖形的渲染香缺,而開(kāi)發(fā)者只需要傳入相應(yīng)的參數(shù),就能快速完成圖形的渲染歇僧,我們只需要會(huì)調(diào)用不需要知道底層的實(shí)現(xiàn)原理图张。
????但是由于OpenGL的使用場(chǎng)景非常豐富,固定管線或者存儲(chǔ)著色器無(wú)法完成每一個(gè)業(yè)務(wù)诈悍,這時(shí)將相關(guān)部分開(kāi)放成可編程
7祸轮、著色器程序shader
????著色器程序?qū)⒐潭ㄤ秩竟芫€架構(gòu)變成了可編程渲染管線。因此OpenGL在實(shí)際調(diào)用之前侥钳,還需要指定一個(gè)由著色器shader編譯而成的著色器程序适袜。常見(jiàn)的著色器主要有頂點(diǎn)著色器(VertexShader),片段著色器(FragmentShader舷夺,又叫片元著色器)/像素著色器(PixelShader)苦酱,幾何著色器(GeometryShader)售貌,曲面細(xì)分著色器(TessellationShader)。片段著色器和像素著色器只是在OpenGL和DX中的不同叫法而已疫萤∷炭纾可惜的是,直到OpenGL ES3.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ò)圖元進(jìn)行裝配则北,將頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為圖元。然后進(jìn)行進(jìn)行光柵化痕慢,將圖元這種矢量圖形尚揣,轉(zhuǎn)化為柵格化數(shù)據(jù),最后將柵格化數(shù)據(jù)傳入片元著色器中進(jìn)行運(yùn)算掖举,片元著色器會(huì)對(duì)柵格化數(shù)據(jù)中的每一個(gè)像素進(jìn)行運(yùn)算快骗,并決定像素的顏色。
8塔次、頂點(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ú)法訪問(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ā)生的。
9翠忠、片元著色器程序FragmentShader
一般用來(lái)處理圖形中每一個(gè)像素點(diǎn)顏色計(jì)算和填充
????片元著色器是OpenGL中用于計(jì)算片段(像素)顏色的程序鞠苟,片段著色器是逐像素運(yùn)算的程序,也就是說(shuō)每一個(gè)像素都會(huì)執(zhí)行一次片段著色器,當(dāng)然也是并行的当娱。
10吃既、GLSL(OpenGL shading language)
????OpenGL著色器語(yǔ)言是用來(lái)在OpenGL中著色編程的語(yǔ)言,也是開(kāi)發(fā)人員寫(xiě)的短小的自定義程序趾访。他們是在圖形卡的CPU(Graphics Processor圖形處理單元)上執(zhí)行的态秧,代替了固定的渲染管線的一部分,使渲染管線中不同層次居右可編程性扼鞋。比如視圖轉(zhuǎn)換、投影轉(zhuǎn)換等等愤诱,GLSL的著色器代碼分為兩個(gè)部分:VertexShader(頂點(diǎn)著色器)云头、FragmentShader(片段著色器)
11、光柵化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)槎S圖像的過(guò)程。該過(guò)程中包含了兩部分的工作对人。第一部分工作:決定窗口坐標(biāo)中的哪些整形柵格區(qū)域被基本圖元占用谣殊;第二部分工作:分配一個(gè)顏色值和深度值到各個(gè)領(lǐng)域。
????把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上用于對(duì)應(yīng)位置的像素用于填充像素的顏色牺弄,這個(gè)過(guò)程叫做光柵化姻几,這是一個(gè)將模擬信號(hào)轉(zhuǎn)化為離散信號(hào)的過(guò)程。
12势告、紋理
????紋理可以理解為圖片蛇捌。在渲染圖形的時(shí)候,需要在其編碼填充圖片咱台,為了使得場(chǎng)景更加逼真络拌,而這里使用的圖片,就是常說(shuō)的紋理回溺,在OpenGL中我們將它叫做紋理
13春贸、混合(Blending)
????在測(cè)試階段之后,如果像素依然沒(méi)有被剔除馅而,那么像素的顏色將會(huì)和幀緩沖區(qū)中顏色附著上的顏色進(jìn)行混合祥诽。混合的算法可以通過(guò)OpenGL函數(shù)進(jìn)行指定瓮恭,一般可以通過(guò)像素著色器進(jìn)行實(shí)現(xiàn)雄坪,當(dāng)然性?xún)r(jià)比會(huì)比原生的混合算法差一些。
14、變換矩陣(Transformmation)
????OpenGL圖像發(fā)生平移维哈,縮放绳姨,旋轉(zhuǎn)等變換需要使用變換需要使用變換矩陣。
15阔挠、投影矩陣(Projection)
????將3D坐標(biāo)轉(zhuǎn)換為二維屏幕坐標(biāo)飘庄。實(shí)際線條在將在二維坐標(biāo)系啊進(jìn)行繪制。
16购撼、渲染上屏和交換緩沖區(qū)(SwapBuffer)
????渲染緩沖區(qū)一般映射的是系統(tǒng)的資源跪削,比如窗口,如果將圖像直接渲染到窗口對(duì)應(yīng)的渲染緩沖區(qū)迂求,則可以將圖像顯示到屏幕上碾盐。
????但是值得注意的是,如果一個(gè)窗口只有一個(gè)緩沖區(qū)揩局,那么在繪制過(guò)程中屏幕進(jìn)行了刷新毫玖,窗口可能顯示不完整的圖像。
????為了解決這個(gè)問(wèn)題凌盯,常規(guī)的OpenGL至少有兩個(gè)緩沖區(qū)付枫,顯示在屏幕上的為屏幕緩沖區(qū),沒(méi)有顯示的為離屏緩沖區(qū)驰怎。在一個(gè)緩沖區(qū)渲染完成之后阐滩,通過(guò)將屏幕緩沖區(qū)和離屏緩沖區(qū)進(jìn)行交換,實(shí)現(xiàn)圖像在屏幕上的顯示砸西。
????由于顯示器的刷新一般是逐行進(jìn)行的叶眉,因此為了防止交換緩沖區(qū)的時(shí)候,屏幕上下區(qū)域的圖像分別屬于兩個(gè)不同的幀芹枷,因此交換一般會(huì)等待顯示器刷新完成的信號(hào)衅疙,在顯示器兩次刷新的間隔中進(jìn)行交換,這個(gè)信號(hào)被稱(chēng)為垂直同步信號(hào)鸳慈,這個(gè)技術(shù)被稱(chēng)為垂直同步饱溢。
????使用了雙緩沖和垂直同步技術(shù)之后,由于總是要等待緩沖區(qū)交換完成之后在進(jìn)行下一幀的渲染走芋,使得幀率無(wú)法完全達(dá)到硬件允許的最高水平绩郎,為了解決這個(gè)問(wèn)題,引入三緩沖區(qū)技術(shù)翁逞,在等待垂直同步的時(shí)候肋杖,來(lái)回交替兩個(gè)離屏的緩沖區(qū),而垂直同步發(fā)生時(shí)挖函,屏幕緩沖區(qū)和最近完成渲染的離屏緩沖區(qū)交換状植,實(shí)現(xiàn)充分利用硬件性能的目的。
[溪浣雙鯉的技術(shù)摸爬滾打之路](http://www.reibang.com/p/3fbecd65faae)