OpenGL-ES (OpenGL for Embedded Systems)
作為OpenGL的子集肿轨,OpenGL-ES專為移動(dòng)端的圖像顯示而生端盆,其針對(duì)于手機(jī)等嵌入式設(shè)備所進(jìn)行了定制與優(yōu)化闪唆,使移動(dòng)端的設(shè)備圖像加載更高效,3D圖像的渲染更快速,質(zhì)量更高
渲染模塊
同桌面端設(shè)備一樣饱苟,移動(dòng)端OpenGL-ES的渲染也是由CPU
和GPU
協(xié)同完成的,CPU
負(fù)責(zé)調(diào)動(dòng)OpenGL模塊编矾,并將頂點(diǎn)數(shù)據(jù)
由內(nèi)存中取出并傳入GPU
中熟史,GPU
負(fù)責(zé)將頂點(diǎn)數(shù)據(jù)進(jìn)行處理,并執(zhí)行渲染
操作窄俏。
渲染流程
頂點(diǎn)著色器
- 通過(guò)`attribute通道`負(fù)責(zé)接收`CPU`傳遞來(lái)的頂點(diǎn)信息(在iOS中蹂匹,為了穩(wěn)定性,默認(rèn)將attribute通道關(guān)閉)
- 通過(guò)`uniform通道`統(tǒng)一變量凹蜈,并進(jìn)行后續(xù)處理
- 通過(guò)`采集器`來(lái)對(duì)`紋理`進(jìn)行處理
- 通過(guò)GLSL內(nèi)建變量限寞,將頂點(diǎn)數(shù)據(jù)處理成需要的形式(`gl_Position`),并使用
- 通過(guò)特定語(yǔ)法仰坦,修改點(diǎn)的大小
- 通過(guò)矩陣變換履植,獲取真正坐標(biāo)
- 計(jì)算光照信息
- 生成紋理坐標(biāo)并傳遞給片元著色器
圖元裝配
計(jì)算頂點(diǎn)信息,將`頂點(diǎn)數(shù)據(jù)`計(jì)算為多個(gè)`圖元`
光柵化
將`圖元`轉(zhuǎn)換為`片段`悄晃,為后續(xù)`片元著色器`的工作做準(zhǔn)備
片元著色器
- 通過(guò)uniform通道統(tǒng)一變量玫霎,以便于后續(xù)處理
- 接收頂點(diǎn)著色器傳遞來(lái)的`紋理坐標(biāo)`,計(jì)算紋理坐標(biāo)的填充顏色妈橄,并對(duì)紋理坐標(biāo)的像素點(diǎn)進(jìn)行顏色填充
逐片段操作
? 逐片段操作是由OpenGL-ES內(nèi)部所完成的庶近,其最終將圖像數(shù)據(jù)放到幀緩沖區(qū),顯示于屏幕上
EGL(Embedded Graphics Library)
EGL
針對(duì)于移動(dòng)端眷蚓,OpenGL-ES需要設(shè)定新的命令來(lái)鏈接窗口拦盹,因此需要一個(gè)新的庫(kù)來(lái)執(zhí)行這個(gè)操作,這個(gè)庫(kù)就是EGL
, EGL
是OpenGL-ES 和原?窗?系統(tǒng)之間的接口
EAGL
? 出于Apple一貫精益求精的精神溪椎,apple當(dāng)然不滿足EGL的效率普舆,因此apple自己研發(fā)了一個(gè)庫(kù)用于替代EGL
,這個(gè)庫(kù)就是EAGL
GLSL(OpenGL著色器語(yǔ)言)
著色器
著色器是使用一種叫GLSL的類C語(yǔ)言寫成的校读。GLSL是為圖形計(jì)算量身定制的沼侣,它包含一些針對(duì)向量和矩陣操作的有用特性。
著色器的開頭總是要聲明版本歉秫,接著是輸入和輸出變量蛾洛、uniform和main函數(shù)。每個(gè)著色器的入口點(diǎn)都是main函數(shù)雁芙,在這個(gè)函數(shù)中我們處理所有的輸入變量轧膘,并將結(jié)果輸出到輸出變量中。
向量
GLSL中的向量
是一個(gè)可以包含有1兔甘、2谎碍、3或者4個(gè)分量的容器,分量的類型可以是前面默認(rèn)基礎(chǔ)類型的任意一個(gè)洞焙。它們可以是下面的形式(n
代表分量的數(shù)量):
類型 | 含義 |
---|---|
vec n
|
包含n 個(gè)float 分量的默認(rèn)向量 |
bvec n
|
包含n 個(gè)bool 分量的向量 |
ivec n
|
包含n 個(gè)int 分量的向量 |
uvec n
|
包含n 個(gè)unsigned int 分量的向量 |
dvec n
|
包含n 個(gè)double 分量的向量 |
向量重組
一個(gè)向量的分量可以通過(guò)vec.x這種方式獲取蟆淀,這里x是指這個(gè)向量的第一個(gè)分量拯啦。你可以分別使用.x、.y熔任、.z和.w來(lái)獲取它們的第1褒链、2、3疑苔、4個(gè)分量甫匹。GLSL也允許你對(duì)顏色使用rgba,或是對(duì)紋理坐標(biāo)使用stpq訪問(wèn)相同的分量惦费。
vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
輸入輸出 in
out
著色器是各自獨(dú)立的小程序, 它們都是一個(gè)整體的一部分,每個(gè)著色器都有特定的輸入和輸出兵迅,這樣使它們可以進(jìn)行數(shù)據(jù)交流及傳遞。GLSL定義了in和out關(guān)鍵字專門來(lái)實(shí)現(xiàn)這個(gè)目的趁餐。每個(gè)著色器使用這兩個(gè)關(guān)鍵字設(shè)定輸入和輸出,只要一個(gè)輸出變量與下一個(gè)著色器階段的輸入匹配篮绰,它就會(huì)傳遞下去后雷。
如果我們需要從一個(gè)著色器向另一個(gè)著色器發(fā)送數(shù)據(jù),我們必須在發(fā)送方著色器中聲明一個(gè)輸出吠各,在接收方著色器中聲明一個(gè)類似的輸入臀突。當(dāng)類型和名字都一樣的時(shí)候,OpenGL就會(huì)把兩個(gè)變量鏈接到一起贾漏,它們之間就能發(fā)送數(shù)據(jù)了(這是在鏈接程序?qū)ο髸r(shí)完成的)候学。
varying
uniform
attribute
varying
變量是 vertex shader
和 fragment shader
之間做數(shù)據(jù)傳遞用的。一般 vertex shader
修改 varying
變量的值纵散,然后 fragment shader
使用該 varying
變量的值梳码。因此 varying
變量在 vertex shader
和 fragment shader
二者之間的聲明必須是一致的。
uniform
變量是外部程序傳遞給 vertex shader
fragment shader
的變量伍掀。
attribute
變量是只能在 vertex shader
中使用的變量掰茶。