一.OpenGL簡(jiǎn)介
OpenGL(英語(yǔ):Open Graphics Library暖眼,譯名:開放圖形庫(kù)或者“開放式圖形庫(kù)”)是用于渲染2D卫枝、3D矢量圖形的跨語(yǔ)言、跨平臺(tái)的應(yīng)用程序編程接口(API)。它將計(jì)算機(jī)的資源抽象稱為?個(gè)個(gè)OpenGL的對(duì)象矗烛,對(duì)這些資源的操作抽象為?個(gè)個(gè)的OpenGL指令,開發(fā)者可以在mac程序中使用OpenGl來(lái)實(shí)現(xiàn)圖形渲染箩溃。圖形API的目的就是實(shí)現(xiàn)圖形的底層渲染瞭吃,比如游戲場(chǎng)景/游戲人物的渲染,音視頻解碼后數(shù)據(jù)的渲染涣旨,地圖上的渲染歪架,動(dòng)畫繪制等。在iOS開發(fā)中霹陡,開發(fā)者唯一能夠GPU的就是圖形API和蚪。(GPU---圖形處理器(英語(yǔ):Graphics Processing Unit,縮寫:GPU)烹棉,又稱顯示核心攒霹、視覺處理器、顯示芯片浆洗,是一種專門在個(gè)人電腦催束、工作站、游戲機(jī)和一些移動(dòng)設(shè)備(如平板電腦伏社、智能手機(jī)等)上做圖像和圖形相關(guān)運(yùn)算工作的微處理器抠刺。)
二.OpenGL專業(yè)名詞解析
? ? 1.OpenGL?上下?( context )
? ??????OpenGL Context,中文解釋就是OpenGL的上下文摘昌,因?yàn)镺penGL沒有窗口的支持速妖,我們?cè)谑褂肙penGl的時(shí)候,一般是在main函數(shù)創(chuàng)建窗口:?
????????//GLUT窗口大小聪黎、窗口標(biāo)題
????????glutInitWindowSize(800, 600);
????????glutCreateWindow("Triangle");
? ? ????然后我們?cè)趧?chuàng)建的窗口里面繪制罕容,個(gè)人理解上下文的意思就是指的是OpenGL的作用范圍,當(dāng)然OpenGL的Context不只是這個(gè)窗口,這個(gè)窗口我們可以理解為OpenGL的default framebuffer杀赢,所以Context還包含關(guān)于這個(gè)framebuffer的一些參數(shù)設(shè)置信息烘跺,具體內(nèi)容可以查看OpenGL的Context的結(jié)構(gòu)體,Context記錄了OpenGL渲染需要的所有信息脂崔,它是一個(gè)大的結(jié)構(gòu)體滤淳,它里面記錄了當(dāng)前繪制使用的顏色、是否有光照計(jì)算以及開啟的光源等非常多我們使用OpenGL函數(shù)調(diào)用設(shè)置的狀態(tài)和狀態(tài)屬性等等砌左,你可以把它理解為是一個(gè)巨大的狀態(tài)機(jī)脖咐,它里面保存OpenGl的指令,在圖形渲染的時(shí)候汇歹,可以理解為這個(gè)狀態(tài)機(jī)開始工作了屁擅,對(duì)某個(gè)屬性或者開關(guān)發(fā)出指令。它的特點(diǎn)就是:有記憶功能产弹,接收輸入派歌,根據(jù)輸入的指令,修改當(dāng)前的狀態(tài)痰哨,并且可以輸出內(nèi)容胶果,當(dāng)停機(jī)的時(shí)候不再接收指令。
2.渲染
? ? ? ? 渲染就是把數(shù)據(jù)顯示到屏幕上斤斧,在OpenGl中早抠,渲染指的是將圖形/圖像數(shù)據(jù)轉(zhuǎn)換為2D空間圖像操作叫渲染
3.頂點(diǎn)數(shù)組/頂點(diǎn)緩沖區(qū)
? ? ? ? 在OpenGL中,基本圖元有三種:點(diǎn)撬讽,線蕊连,三角形,復(fù)雜的圖形由這三種圖元組成游昼,我們?cè)诋孅c(diǎn)/線/三角形的時(shí)候是不是應(yīng)該先知道每個(gè)頂點(diǎn)的坐標(biāo)甘苍,而這些坐標(biāo)放在數(shù)組里,就叫頂點(diǎn)數(shù)組酱床。頂點(diǎn)數(shù)組存在內(nèi)存當(dāng)中羊赵,但是為了提高性能趟佃,提前分配一塊顯存扇谣,將頂點(diǎn)數(shù)組預(yù)先存入到顯存當(dāng)中,這部分的顯存就叫頂點(diǎn)緩沖區(qū)闲昭。
4.著色器(shader)
????????為什么要使用著色器罐寨?我們知道,OpenGL一般使用經(jīng)典的固定渲染管線來(lái)渲染對(duì)象序矩,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)算,并決定像素的顏?(頂點(diǎn)著色器和片段/片元著色器會(huì)在下面講解)
5.管線
? ? ? ? OpenGL在渲染圖形/圖像的時(shí)候是按照特定的順序來(lái)執(zhí)行的强品,不能修改打破膘侮,管線的意思個(gè)人理解是(舉例,不對(duì)的地方請(qǐng)大神指點(diǎn)
):讀取頂點(diǎn)數(shù)據(jù)—>頂點(diǎn)著色器—>組裝圖元—>光柵化圖元—>片元著色器—>寫入幀緩沖區(qū)—>顯示到屏幕上,類似這樣的流水線的榛,當(dāng)圖像/圖形顯示到屏幕上琼了,這一條管線完成工作。下面是分步講解:
? ?????(1)讀取頂點(diǎn)數(shù)據(jù)指的是將待繪制的圖形的頂點(diǎn)數(shù)據(jù)傳遞給渲染管線中夫晌。
? ? ????(2)頂點(diǎn)著色器最終生成每個(gè)定點(diǎn)的最終位置雕薪,執(zhí)行頂點(diǎn)的各種變換,它會(huì)針對(duì)每個(gè)頂點(diǎn)執(zhí)行一次晓淀,確定了最終位置后所袁,OpenGL就可以把這些頂點(diǎn)集合按照給定的參數(shù)類型組裝成點(diǎn),線或者三角形凶掰。
? ? ? (3)組裝圖元階段包括兩部分:圖元的組裝和圖元處理燥爷,圖元組裝指的是頂點(diǎn)數(shù)據(jù)根據(jù)設(shè)置的繪制方式參數(shù)結(jié)合成完整的圖元蜈亩,例如點(diǎn)繪制方式中每個(gè)圖元就只包含一個(gè)點(diǎn),線段繪制方式中每個(gè)圖源包含兩個(gè)點(diǎn)前翎;圖元處理主要是剪裁以使得圖元位于視景體內(nèi)部的部分傳遞到下一個(gè)步驟稚配,視景體外部的部分進(jìn)行剪裁。視景體的概念與投影有關(guān)港华。
? ? ? (4)光柵化圖元主要指的是將一個(gè)圖元離散化成可顯示的二維單元片段药有,這些小單元稱為片元。一個(gè)片元對(duì)應(yīng)了屏幕上的一個(gè)或多個(gè)像素苹丸,片元包括了位置愤惰,顏色,紋理坐標(biāo)等信息赘理,這些值是由圖元的頂點(diǎn)信息進(jìn)行插值計(jì)算得到的宦言。
? ? ? (5)片元著色器為每個(gè)片元生成最終的顏色,針對(duì)每個(gè)片元都會(huì)執(zhí)行一次商模。一旦每個(gè)片元的顏色確定了奠旺,OpenGL就會(huì)把它們寫入到幀緩沖區(qū)中。
6.頂點(diǎn)著色器
????????????般?來(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ò)程中?法訪問其他頂點(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ā)?的践盼。
7.片元著色器(片段著色器)
? ???????般?來(lái)處理圖形中每個(gè)像素點(diǎn)顏?計(jì)算和填充?段著?器是OpenGL中?于計(jì)算?段(像素)顏?的程序。?段著?器是逐像素運(yùn)算的程序宾巍,也就是說(shuō)每個(gè)像素都會(huì)執(zhí)??次?段著?器咕幻,當(dāng)然也是并?的
8.光柵化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ò)程
9.紋理
? ??????紋理可以理解為圖?.??家在渲染圖形時(shí)需要在其編碼填充圖?,為了使得場(chǎng)景更加逼真.?這?使?的圖?,就是常說(shuō)的紋理.但是在OpenGL,我們更加習(xí)慣叫紋理,?不是圖?
10.混合(Blending)
? ??????在測(cè)試階段之后崎苗,如果像素依然沒有被剔除,那么像素的顏?將會(huì)和幀緩沖區(qū)中顏?附著上的顏?進(jìn)?混合舀寓,混合的算法可以通過(guò)OpenGL的函數(shù)進(jìn)?指定胆数。但是OpenGL提供的混合算法是有限的,如果需要更加復(fù)雜的混合算法互墓,?般可以通過(guò)像素著?器進(jìn)?實(shí)現(xiàn)必尼,當(dāng)然性能會(huì)?原?的混合算法差?些,個(gè)人理解有點(diǎn)像iOS給RGB中紅篡撵,綠判莉,藍(lán)設(shè)置不同的值得到不同的顏色,只是這里是操作片元著色器育谬,來(lái)達(dá)到不同的顯示券盅。
11.變換矩陣(Transformation)/投影矩陣Projection?
? ? ? ? 在iOS核心動(dòng)畫中我們也會(huì)和矩陣打交到,變換矩陣顧名思義就是對(duì)圖像/圖形的放大/縮小/平移/選裝等座處理膛檀。
????????投影矩陣就是?于將3D坐標(biāo)轉(zhuǎn)換為?維屏幕坐標(biāo),實(shí)際線條也將在?維坐標(biāo)下進(jìn)?繪制 ? ?
12.渲染上屏/交換緩沖區(qū)(SwapBuffer)? ? ?
? ????渲染緩沖區(qū)?般映射的是系統(tǒng)的資源?如窗?锰镀。如果將圖像直接渲染到窗?對(duì)應(yīng)的渲染緩沖區(qū),則可以將圖像顯示到屏幕上咖刃。
??????但是泳炉,值得注意的是,如果每個(gè)窗?只有?個(gè)緩沖區(qū)嚎杨,那么在繪制過(guò)程中屏幕進(jìn)?了刷新花鹅,窗?可能顯示出不完整的圖像
??????為了解決這個(gè)問題,常規(guī)的OpenGL程序?少都會(huì)有兩個(gè)緩沖區(qū)枫浙。顯示在屏幕上的稱為屏幕緩沖區(qū)翠胰,沒有顯示的稱為離屏緩沖區(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è)問題,引?了三緩沖區(qū)技術(shù)涩嚣,在等待垂直同步時(shí)崇众,來(lái)回交替渲染兩個(gè)離屏的緩沖區(qū)掂僵,?垂直同步發(fā)?時(shí),屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換顷歌,實(shí)現(xiàn)充分利?硬件性能的?的
13.坐標(biāo)系
? ? ? OpenGl常見的坐標(biāo)系有:
????????1. Object or model coordinates(物體或模型坐標(biāo)系)每一個(gè)實(shí)物都有自己的坐標(biāo)系锰蓬,在高中數(shù)學(xué)中,以自身建立的坐標(biāo)系眯漩,自身坐標(biāo)系由世界坐標(biāo)系平移而來(lái)
????????2. World coordinates(世界坐標(biāo)系)個(gè)人理解為地球相對(duì)自己建立的坐標(biāo)系芹扭,地球上所有生物都處于這個(gè)坐標(biāo)系當(dāng)中
????????3. Eye (or Camera) coordinates(眼(或相機(jī))坐標(biāo)系)
? ? ? ? 4. Normalized device coordinates(標(biāo)準(zhǔn)化的設(shè)備坐標(biāo)系)
? ? ? ? 5. Window (or screen) coordinates(.窗口(或屏幕)坐標(biāo)系)個(gè)人理解為iOS下
? ? ? ? 6.Clip coordinates(裁剪坐標(biāo)系)主要作用是當(dāng)圖形/圖像超出時(shí)夕土,按照這個(gè)坐標(biāo)系裁剪纬朝,裁剪好之后轉(zhuǎn)換到screen坐標(biāo)系
14.正投影/透視投影
? ? ????正投影:類似于照鏡子预皇,1:1形成圖形大小签财,這里不做重點(diǎn)講解
? ? ? ? 透視投影:在OpenGL中未蝌,如果想對(duì)模型進(jìn)行操作寄锐,就要對(duì)這個(gè)模型的狀態(tài)(當(dāng)前的矩陣)乘上這個(gè)操作對(duì)應(yīng)的一個(gè)矩陣.如果乘以變換矩陣(平移, 縮放, 旋轉(zhuǎn)), 那相乘之后, 模型的位置被變換;如果乘以投影矩陣(將3D物體投影到2D平面), 相乘后, 模型的投影方式被設(shè)置;如果乘以紋理矩陣(), 模型的紋理方式被設(shè)置.而用來(lái)指定乘以什么類型的矩陣, 就是glMatriMode(GLenummode);glMatrixMode有3種模式: GL_PROJECTION 投影, GL_MODELVIEW 模型視圖, GL_TEXTURE 紋理.所以掩幢,在操作投影矩陣以前缤骨,需要調(diào)用函數(shù):glMatrixMode(GL_PROJECTION); //將當(dāng)前矩陣指定為投影矩陣然后把矩陣設(shè)為單位矩陣
最后附上一篇搭建OpenGl的文章:http://www.reibang.com/p/43ae1587f45b