一赵抢、簡介
1.OpenGL
OpenGl(Open Graphics Library)是一個跨編程語言、跨平臺的編程圖形程序接口声功,它將計算機的資源抽象稱為一個個OpenGL的對象烦却,對這些資源的操作抽象為一個個的OpenGL指令。
2.OpenGL ES
OpenGL ES(OpenGL for Embedded Systems)是OpenGL三維圖形API的子集先巴,針對手機其爵、PAD和游戲主機等嵌入式設(shè)備而設(shè)計冒冬,去除了許多不必要和性能較低的API接口。
3.DirectX
DirectX是由很多API組成的摩渺,DirectX并不是一個單純的圖形API简烤。最重要的是DirectX是屬于Windows
上一個多媒體處理API。并不支持Windows以外的平臺摇幻,所以不是跨平臺框架横侦。按照性質(zhì)分類,可以分為四大部分
- 顯示部分
- 聲音部分
- 輸入部分
- 網(wǎng)絡(luò)部分
4.Metal
Metal是Apple為游戲開發(fā)者推出的新的平臺技術(shù)囚企,該技術(shù)能哆為3D圖像提高10倍的渲染性能丈咐。它是Apple為了解決3D渲染而推出的框架瑞眼。
5.總結(jié)
OpenGL/OpenGL ES/Metal在任何項目中解決問題的本質(zhì)就是利用GPU芯片來高效渲染圖形圖像
圖形API是iOS開發(fā)者唯一接近GPU的方式
二龙宏、OpenGL專業(yè)名詞解析
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)或者對象進行操作锯蛀,當然你得首先把這個對象設(shè)置為當前對象灭衷。因此通過對OpenGL指令的封裝,是可以將OpenGL的相關(guān)調(diào)用封裝成為一個面向?qū)ο蟮膱D形API的旁涤。
- 由于OpenGL上下文是一個巨大的狀態(tài)機翔曲,切換上下文往往會產(chǎn)生較大的開銷,但是不同的繪制模塊劈愚,可能需要使用完全獨立的狀態(tài)管理瞳遍。因此,可以在應(yīng)用程序中分別創(chuàng)建多個不同的上下文菌羽,在不同的線程中使用不同的上下文掠械,上下文之間共享紋理、緩沖區(qū)等資源注祖。這樣的方案猾蒂,會比反復切換上下文描姚,或者大量修改渲染狀態(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)稚叹。因此具有以下特點:
- 有記憶功能,能記住其當前的狀態(tài)
- 可以接收輸入拿诸,根據(jù)輸入的內(nèi)容和自己的原先狀態(tài)扒袖,修改自己當前狀態(tài),并且可以有對應(yīng)輸出
- 當進入特殊狀態(tài)(停機狀態(tài))的時候亩码,便不再接收輸入季率,停止工作
- 類推到OpenGL中中來,可以這么理解:
- OpenGL可以記錄自己的狀態(tài)(如當前所使用的顏色描沟、是否開啟了混合功能等)
- OpenGL可以接收輸入(當調(diào)用OpenGL函數(shù)的時候飒泻,實際上可以看成OpenGL在接收我們的輸入),如我們調(diào)用
glColor3f
吏廉,則OpenGL接收到這個輸入后會修改自己的當前顏色
這個狀態(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ù),也就是說這部分數(shù)據(jù)之前是存儲在內(nèi)存當中的涛目,被稱為頂點數(shù)組
秸谢。而性能更高的做法是凛澎,提前分配一塊顯存,將頂點數(shù)據(jù)預先傳入到顯存當中估蹄,這部分的顯存塑煎,就被稱為頂點緩沖區(qū)
- 頂點指的就是我們在繪制一個圖形時,它的頂點位置數(shù)據(jù)臭蚁。而這個數(shù)據(jù)可以直接存儲在數(shù)組中或者將其緩存到GPU內(nèi)存中最铁。
5.管線
在OpenGL下渲染圖形,就會有經(jīng)歷一個一個節(jié)點垮兑,而這樣的操作可以理解為管線冷尉。大家可以想象成流水線,每個任務(wù)類似流水線般執(zhí)行系枪,任務(wù)之間有先后順序雀哨。管線是一個抽象的概念,之所以稱之為管線嗤无,是因為顯卡在處理數(shù)據(jù)的時候是按照一個固定的順序來的震束,而且嚴格按照這個順序。就像水從一根管子的一端流到另一端当犯,這個順序是不能打破的
6.固定管線/存儲著色器
- 在早起的OpenGL版本,它封裝了很多種著色器程序塊內(nèi)置的一段包含了光照割疾、坐標變換嚎卫、裁剪等等諸多功能的固定
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í)行一次頂點著色器,當然這是并行的洋丐,并且頂點著色器運算過程中無法訪問其他頂點的數(shù)據(jù)
- 一般來說典型的需要計算的頂點屬性主要包括頂點坐標變換呈昔、逐頂點光照運算等等。頂點坐標由自身坐標系轉(zhuǎn)換到歸一化坐標系的運算友绝,就是在這里發(fā)生的堤尾。
9.片元著色器程序FragmentShader
- 一般用來處理圖形中每個像素點顏色計算和填充
- 片段著色器是OpenGL中用于計算片段(像素)顏色的程序。片段著色器是逐像素運算的程序迁客,也就是說每個像素都會執(zhí)行一次片段著色器郭宝,當然也是并行的。
10.GLSL(OpenGL Shading Language)
OpenGL著色語言(OpenGL Shading Language)是用來在OpenGL中著色變成的語言哲泊,也即開發(fā)人員寫的短小的自定義程序剩蟀,他們是在圖形卡的GPU(Graphic Processor Unit圖形處理單元)上執(zhí)行的,代替了固定的渲染管線的一部分切威,使渲染管線中不同屋次具有可編程性育特。比如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等。GLLS的著色器代碼分成2個部分:
Vertex Shader
(頂點著色器)和Fragment
(片段著色器)
11.光柵化Rasterization
- 是把頂點數(shù)據(jù)轉(zhuǎn)換為片元的過程缰冤,具有將圖轉(zhuǎn)化為一個個柵格組成的圖像的作用犬缨,特點是每個元素對應(yīng)幀緩沖區(qū)中的一個像素
- 光柵化就是把頂點數(shù)據(jù)轉(zhuǎn)換為片元的過程,片元中的每一個元素對應(yīng)于幀緩沖區(qū)中的一個像素
- 光柵化其實是一種將幾個圖元變?yōu)槎S圖像的過程棉浸。該過程包含了兩部分的工作怀薛。第一部分工作:決定窗口坐標中哪些整形柵格區(qū)域被基本圖元占用;第二部分工作:分配一個顏色值和一個深度值到各個區(qū)域迷郑。光柵化過程產(chǎn)生的是片元
- 把物體的數(shù)學描述以及與物體相關(guān)的顏色信息轉(zhuǎn)換為屏幕上用于相對應(yīng)位置的像素及用于填充像素的顏色枝恋,這個過程稱為光柵化,這是一個將模擬信號轉(zhuǎn)化為離散信號的過程
12.紋理
紋理可以理解為圖片嗡害。大家在渲染圖形時需要在其編碼填充圖片焚碌,為了使得場景更加逼真,而這里使用的圖片霸妹。就是常說的紋理十电,但是在OpenGL,我們更加習慣叫紋理而不是圖片
13.混合(Blending)
在測試階段之后叹螟,如果像素依然沒有被剔除鹃骂,那么像素的顏色將會和幀緩沖區(qū)中顏色附著上的顏色進行混合,混合的算法可以通過OpenGL的函數(shù)進行指定罢绽。但是OpenGL提供的混合算法是有限的畏线,如果需要更加復雜的混合算法,一般可以通過像素著色器進行實現(xiàn)有缆,當然性能會比原生的混合算法差一些
14.變換矩陣(Transformation)
例如圖形想發(fā)生平移象踊、縮放、旋轉(zhuǎn)變換棚壁,就需要使用變換矩陣
15.投影矩陣Projection
用于將3D坐標轉(zhuǎn)換為二維屏幕坐標,實際線條也將在二維坐標下進行繪制
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)充分利用硬件性能的目的