GPUImage源碼解析 -- OpenGL ES基礎(chǔ)

GPUImage是一個開源的圖像處理工具谈山,它基于OpenGL ES實(shí)現(xiàn),Git地址為:https://github.com/BradLarson/GPUImage剖效。GPUImage最大的好處是它提供了一套非常好的圖像處理架構(gòu)寺董,并且提供了各種PhotoShop中常見的濾鏡的著色器。使用者只需要通過對這些濾鏡的組合猛遍,即可實(shí)現(xiàn)非常好的濾鏡效果。安卓版也有一個GPUImage:https://github.com/CyberAgent/android-gpuimage,但是這個版本遠(yuǎn)遠(yuǎn)沒有iOS版本的強(qiáng)大功能懊烤,支持的特性也相對少很多梯醒。最近項目中需要在Android上也實(shí)現(xiàn)一個濾鏡框架,那就順便詳細(xì)研究一下GPUImage的源碼腌紧,然后自己實(shí)現(xiàn)一個安卓版啦茸习。


OpenGL ES基礎(chǔ)

OpenGL ES是基于OpenGL簡化而來的用于嵌入式系統(tǒng)的圖像處理框架,基本上所有的嵌入式系統(tǒng)的圖像渲染最終都基于OpenGL ES壁肋。OpenGL ES提供了強(qiáng)大的圖形處理能力号胚,以及完善的上下文讓系統(tǒng)能將CPU中的數(shù)據(jù)傳輸?shù)紾PU中,并且進(jìn)行渲染浸遗。GPUImage也是基于OpenGL ES實(shí)現(xiàn)的猫胁。因此,了解一些OpenGL ES的基礎(chǔ)對于理解GPUImage的源碼也是非常有幫助的跛锌。

簡單的術(shù)語:

Vertex(頂點(diǎn)):在OpenGL中弃秆,所有的物體都是由頂點(diǎn)拼湊而成的,即使是一個圓或者一個球髓帽。每個球也是通過分解成非常小的三角形進(jìn)行渲染的菠赚。OpenGL中,渲染的最小元素包括三角形(GL_TRIANGLES)氢卡,線(GL_LINES)以及點(diǎn)(GL_POINTS)锈至。因此晨缴,他們都需要由頂點(diǎn)來定義他們在坐標(biāo)系中的位置译秦;

Fragment(片元):在OpenGL中,所有的顯示都是由片元來完成的击碗,OpenGL通過著色器為每一個片元設(shè)定顏色筑悴,然后GPU通過這些片元的顏色進(jìn)行渲染。Fragment可以說是OpenGL顯示的最小單元稍途。

Texture(紋理):紋理是一個包含元素信息的對象阁吝,OpenGL通過讀取紋理中的每個紋素(Texel)的顏色來給不同的片元進(jìn)行上色。

Shader(著色器):OpenGL中包含了兩種著色器械拍,頂點(diǎn)著色器(VertexShader)以及片元著色器(FragmentShader)突勇。著色器使用的是Shading Language進(jìn)行書寫,相當(dāng)于是另一門語言了坷虑,這里就不具體介紹了甲馋,有興趣的同學(xué)可以參考https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.3.30.pdf。

????VertexShader:主要作用是確定每個頂點(diǎn)在渲染坐標(biāo)系中的位置迄损,并且確定每個頂點(diǎn)的紋理位置坐標(biāo)定躏;

? ? FragmentShader:通過每個頂點(diǎn)的紋理坐標(biāo)和紋理,給每一個片元進(jìn)行上色。

坐標(biāo)系(Coordinate System):OpenGL之所以能夠很好地實(shí)現(xiàn)3D的效果痊远,就是因?yàn)橛幸粋€非常完善的坐標(biāo)系系統(tǒng)垮抗,這些坐標(biāo)系系統(tǒng)可以將一個點(diǎn)從自己的坐標(biāo)系映射到屏幕中的3D位置。坐標(biāo)系之間的變換通常通過矩陣進(jìn)行碧聪,包括Model-View-Projection矩陣冒版,簡稱MVP Matrix。

????Model Matrix是將一個點(diǎn)的位置從自己的坐標(biāo)系映射到周圍環(huán)境中(world coordinate)逞姿;

????View Matrix是將點(diǎn)的位置從世界坐標(biāo)系中壤玫,通過調(diào)整眼睛(或者說攝像頭)的位置,展示同一個物體不同方面的景象哼凯;

? ? Projection Matrix則是將點(diǎn)的位置最終轉(zhuǎn)化成在屏幕上顯示的位置欲间;

由于GPUImage中主要實(shí)現(xiàn)的是2D的圖片處理,并沒有涉及到太多的3D效果断部,因此基本沒有涉及到MVP矩陣變換猎贴。

幀緩存(FrameBuffer):我們在移動設(shè)備屏幕上看到的顯示其實(shí)都是一幀一幀的內(nèi)存。因此OpenGL使用了幀緩存的機(jī)制蝴光,現(xiàn)在緩存中完成渲染她渴,然后再將渲染好的幀呈現(xiàn)到屏幕上。其實(shí)在OpenGL中蔑祟,還有很多的Buffer趁耗,如RenderBuffer, DepthBuffer, Vertex Buffer, IndexBuffer等等,我們在使用到的時候再進(jìn)行具體介紹疆虚。

上下文(EGLContext):EGLContext是OpenGL用來渲染的一個上下文苛败,包含了很多的環(huán)境變量。在不同的系統(tǒng)中径簿,都有不同的實(shí)現(xiàn)罢屈,在iOS中,已經(jīng)封裝好的EAGLContext就非常容易使用了篇亭;而在Android中缠捌,如果需要自己控制每一個顯示的環(huán)節(jié)的話,則需要自己創(chuàng)建EGLContext译蒂。

Shader中的常用術(shù)語:

Attribute: 在Shader中曼月,有些屬性是針對每個頂點(diǎn)都不同的,比如它們的位置(position)柔昼,紋理坐標(biāo)(TextureCoordinate)哑芹,這些信息必須要在CPU中計算好,然后放入VertexBuffer或者VertexBufferObject中岳锁;GPU會在VB或者VBO中讀取到這些信息绩衷,才能計算出每個頂點(diǎn)顯示的位置蹦魔;

Uniform:不同于Attribute,uniform是對于所有的頂點(diǎn)或者片元都相同的一些參數(shù)咳燕,比如MVPMatrix勿决,Sampler以及一些其他的環(huán)境變量;

Sampler:采樣器招盲,OpenGL通過Sampler和TextureCoordinate來確定一個片元的顏色低缩。


OpenGL ES 渲染流程

1. Vertex Specification: 這個過程中,主要是計算出每個頂點(diǎn)在自己坐標(biāo)系中的位置曹货,并且將頂點(diǎn)的Attributes放置到VertexBuffer中咆繁,GPU會通過VertexBuffer中的信息讀取到每個頂點(diǎn)的Attribute并進(jìn)行處理;

2. Vertex Processing: 這個過程主要通過VertexShader以及MVP Matrix獲取到每個頂點(diǎn)的位置顶籽;

3. Primitive Assembly: 在頂點(diǎn)的信息確定完成了之后玩般,通過Primitive Assembly將這些頂點(diǎn)拼成最終需要顯示的圖形;

4. Rasterization:柵格化的過程是將圖形的立體位置轉(zhuǎn)換成在屏幕上顯示的位置的過程礼饱;

5. Fragment Processing:通過采樣器坏为,紋理坐標(biāo)給每個片元進(jìn)行著色;

6. Per-Fragment Operation:在每個片元的顏色確定了之后镊绪,還可以對每個片元進(jìn)行一些操作匀伏,比如Stencil Test,Depth Test等等蝴韭。

這邊主要是介紹了一些OpenGL ES的基礎(chǔ)够颠,以便更好的理解GPUImage的源代碼,現(xiàn)在一切就緒榄鉴,我們就可以開始擼代碼啦履磨!


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市牢硅,隨后出現(xiàn)的幾起案子蹬耘,更是在濱河造成了極大的恐慌,老刑警劉巖减余,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惩系,居然都是意外死亡位岔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門堡牡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抒抬,“玉大人,你說我怎么就攤上這事晤柄〔两#” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惠勒。 經(jīng)常有香客問我赚抡,道長,這世上最難降的妖魔是什么纠屋? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任涂臣,我火速辦了婚禮,結(jié)果婚禮上售担,老公的妹妹穿的比我還像新娘赁遗。我一直安慰自己,他們只是感情好族铆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布岩四。 她就那樣靜靜地躺著,像睡著了一般哥攘。 火紅的嫁衣襯著肌膚如雪炫乓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天献丑,我揣著相機(jī)與錄音末捣,去河邊找鬼。 笑死创橄,一個胖子當(dāng)著我的面吹牛箩做,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妥畏,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼邦邦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了醉蚁?” 一聲冷哼從身側(cè)響起燃辖,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎网棍,沒想到半個月后黔龟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滥玷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年氏身,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惑畴。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛋欣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出如贷,到底是詐尸還是另有隱情陷虎,我是刑警寧澤到踏,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站尚猿,受9級特大地震影響窝稿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谊路,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一讹躯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缠劝,春花似錦潮梯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脱羡,卻和暖如春萝究,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锉罐。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工帆竹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脓规。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓栽连,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侨舆。 傳聞我的和親對象是個殘疾皇子秒紧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容