關(guān)于OPenGL仑荐,對(duì)于初學(xué)者來(lái)說(shuō),沒(méi)有一套完整的教程纵东,摸索很久都是一頭霧水粘招。因?yàn)樾鹿ぷ魇亲鱿鄼C(jī)維護(hù),OpenGL是主角偎球,所以打算寫(xiě)一系列入門(mén)級(jí)的教程洒扎,盡量是站在初學(xué)者的角度,大牛請(qǐng)出門(mén)右拐衰絮。
1袍冷、什么是OpenGL?
全稱是:Open Graphics Library
簡(jiǎn)單說(shuō)就是圖形庫(kù)
2猫牡、OpenGL ES
(OpenGL for Embedded Systems) 是 OpenGL 三維圖形 API 的子集胡诗,針對(duì)手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)淌友。
OpenGL ES相對(duì)于OpenGL來(lái)說(shuō)煌恢,減少了許多不是必須的方法和數(shù)據(jù)類型,去掉了不必須的功能亩进,對(duì)代價(jià)大的功能做了限制症虑,比OpenGL更為輕量缩歪。在OpenGL ES的世界里归薛,沒(méi)有四邊形、多邊形匪蝙,無(wú)論多復(fù)雜的圖形都是由點(diǎn)主籍、線和三角形組成的
3、介紹一下頂點(diǎn)著色器和片元著色器
先知道有這個(gè)東西就行逛球,第二篇文章我們將結(jié)合demo使用千元。
3.1 著色器語(yǔ)言
僅適合GPU編程,對(duì)于頂點(diǎn)著色器和片元著色器的開(kāi)發(fā)都需要用到著色器語(yǔ)言進(jìn)行開(kāi)發(fā)颤绕。
著色語(yǔ)言中有許多內(nèi)建的原生數(shù)據(jù)類型以及構(gòu)建數(shù)據(jù)類型幸海,如:浮點(diǎn)型(float)祟身、布爾型(bool)、整型(int)物独、矩陣型(matrix)以及向量型(vec2袜硫、vec3等)等〉猜ǎ總體來(lái)說(shuō)婉陷,這些數(shù)據(jù)類型可以分為標(biāo)量、向量官研、矩陣秽澳、采樣器、結(jié)構(gòu)體以及數(shù)組等戏羽。 著色器支持下面數(shù)據(jù)類型
float bool int 基本數(shù)據(jù)類型
vec2 包含了2個(gè)浮點(diǎn)數(shù)的向量
vec3 包含了3個(gè)浮點(diǎn)數(shù)的向量
vec4 包含了4個(gè)浮點(diǎn)數(shù)的向量
ivec2 包含了2個(gè)整數(shù)的向量
ivec3 包含了3個(gè)整數(shù)的向量
ivec4 包含了4個(gè)整數(shù)的向量
bvec2 包含了2個(gè)布爾數(shù)的向量
bvec3 包含了3個(gè)布爾數(shù)的向量
bvec4 包含了4個(gè)布爾數(shù)的向量
mat2 2*2維矩陣
mat3 3*3維矩陣
mat4 4*4維矩陣
sampler1D 1D紋理采樣器
sampler2D 2D紋理采樣器
sampler3D 3D紋理采樣器
3.2 頂點(diǎn)著色器 (Vertex Shader)
頂點(diǎn)著色器(Vertex Shader)是在GPU上運(yùn)行的小程序担神。從名稱可以看出,可通過(guò)處理它們來(lái)處理頂點(diǎn)始花。此程序使用OpenGL ES SL語(yǔ)言來(lái)編寫(xiě)杏瞻。它是一個(gè)描述頂點(diǎn)或像素特性的簡(jiǎn)單程序。下面是頂點(diǎn)著色器示例代碼
uniform mat4 uMVPMatrix; //應(yīng)用程序傳入頂點(diǎn)著色器的總變換矩陣
attribute vec4 aPosition; // 應(yīng)用程序傳入頂點(diǎn)著色器的頂點(diǎn)位置
attribute vec2 aTextureCoord; // 應(yīng)用程序傳入頂點(diǎn)著色器的頂點(diǎn)紋理坐標(biāo)
attribute vec4 aColor // 應(yīng)用程序傳入頂點(diǎn)著色器的頂點(diǎn)顏色變量
varying vec4 vColor // 用于傳遞給片元著色器的頂點(diǎn)顏色數(shù)據(jù)
varying vec2 vTextureCoord; // 用于傳遞給片元著色器的頂點(diǎn)紋理數(shù)據(jù)
void main()
{
gl_Position = uMVPMatrix * aPosition; // 根據(jù)總變換矩陣計(jì)算此次繪制此頂點(diǎn)位置
vColor = aColor; // 將頂點(diǎn)顏色數(shù)據(jù)傳入片元著色器
vTextureCoord = aTextureCoord; // 將接收的紋理坐標(biāo)傳遞給片元著色器
}
(1)attribute變量(屬性變量)只能用于頂點(diǎn)著色器中衙荐,不能用于片元著色器捞挥。 一般用該變量來(lái)表示一些頂點(diǎn)數(shù)據(jù),如:頂點(diǎn)坐標(biāo)忧吟、紋理坐標(biāo)砌函、顏色等。
(2)uniforms變量(一致變量)用來(lái)將數(shù)據(jù)值從應(yīng)用程其序傳遞到頂點(diǎn)著色器或者片元著色器溜族。 該變量有點(diǎn)類似C語(yǔ)言中的常量(const)讹俊,即該變量的值不能被shader程序修改。一般用該變量表示變換矩陣煌抒、光照參數(shù)仍劈、紋理采樣器等。
(3)varying變量(易變變量)是從頂點(diǎn)著色器傳遞到片元著色器的數(shù)據(jù)變量寡壮。頂點(diǎn)著色器可以使用易變變量來(lái)傳遞需要插值的顏色贩疙、法向量、紋理坐標(biāo)等任意值况既。 在頂點(diǎn)與片元shader程序間傳遞數(shù)據(jù)是很容易的这溅,一般在頂點(diǎn)shader中修改varying變量值,然后片元shader中使用該值棒仍,當(dāng)然悲靴,該變量在頂點(diǎn)及片元這兩段shader程序中聲明必須是一致的 。例如:上面代碼中應(yīng)用程序中由頂點(diǎn)著色器傳入片元著色器中的vColor變量莫其。
(4)gl_Position 為內(nèi)建變量癞尚,表示變換后點(diǎn)的空間位置耸三。 頂點(diǎn)著色器從應(yīng)用程序中獲得原始的頂點(diǎn)位置數(shù)據(jù),這些原始的頂點(diǎn)數(shù)據(jù)在頂點(diǎn)著色器中經(jīng)過(guò)平移浇揩、旋轉(zhuǎn)吕晌、縮放等數(shù)學(xué)變換后,生成新的頂點(diǎn)位置临燃。新的頂點(diǎn)位置通過(guò)在頂點(diǎn)著色器中寫(xiě)入gl_Position傳遞到渲染管線的后繼階段繼續(xù)處理睛驳。
3.3 片元著色器 (Fragment Shader)
片元著色器計(jì)算每個(gè)像素的顏色和其它屬性。它通過(guò)應(yīng)用光照值膜廊、凹凸貼圖乏沸,陰影,鏡面高光爪瓜,半透明等處理來(lái)計(jì)算像素的顏色并輸出蹬跃。它也可改變像素的深度(z-buffering)或在多個(gè)渲染目標(biāo)被激活的狀態(tài)下輸出多種顏色。一個(gè)片元著色器不能產(chǎn)生復(fù)雜的效果铆铆,因?yàn)樗辉谝粋€(gè)像素上進(jìn)行操作蝶缀,而不知道場(chǎng)景的幾何形狀。下面是片元著色器簡(jiǎn)單實(shí)例代碼薄货。
precision mediump float; // 設(shè)置工作精度
varying vec4 vColor; // 接收從頂點(diǎn)著色器過(guò)來(lái)的頂點(diǎn)顏色數(shù)據(jù)
varying vec2 vTextureCoord; // 接收從頂點(diǎn)著色器過(guò)來(lái)的紋理坐標(biāo)
uniform sampler2D sTexture; // 紋理采樣器翁都,代表一幅紋理
void main()
{
gl_FragColor = texture2D(sTexture, vTextureCoord) * vColor;// 進(jìn)行紋理采樣
}
此片元著色器的主要功能為根據(jù)接收的記錄片元紋理坐標(biāo)的易變變量中的紋理坐標(biāo),調(diào)用texture2D內(nèi)建函數(shù)從采樣器中進(jìn)行紋理采樣谅猾,得到此片元的顏色值柄慰。最后,將采樣到的顏色值傳給gl_FragColor內(nèi)建變量税娜,完成片元的著色
varying 指的是從頂點(diǎn)著色器傳遞到片元著色器的數(shù)據(jù)變量
gl_FragColor 為內(nèi)置變量坐搔,用來(lái)保存片元著色器計(jì)算完成的片元顏色值,此顏色值將送入渲染管線的后繼階段進(jìn)行處理敬矩。
3.4 編譯和鏈接
著色器需要編譯概行,然后鏈接到OpenGL程序中,一個(gè)OpenGL程序就是一個(gè)頂點(diǎn)著色器和一個(gè)片元著色器鏈接在一起變成單個(gè)對(duì)象弧岳。
著色器經(jīng)過(guò)編譯后鏈接成一個(gè)program凳忙,對(duì)于CPU來(lái)說(shuō),兩個(gè)著色器是一體的缩筛,輸入有Attribute消略、Unifroms和采樣器(紋理/Textures)堡称,輸出就是Framebuff瞎抛,但這里我們關(guān)注一下gl_Position(位置)和gl_fragColor(顏色),因?yàn)檫@兩個(gè)是兩個(gè)著色器的主要輸出(在什么位置顯示什么顏色)却紧。
Attribute:頂點(diǎn)屬性桐臊,也就是存儲(chǔ)頂點(diǎn)的坐標(biāo)信息(對(duì)于著色器只讀)
Unifroms:常量胎撤,一般存放矩陣變換或者光照之類(對(duì)于著色器只讀)
Varying:頂點(diǎn)著色器和片元著色器間的通信接口變量,在頂點(diǎn)著色器中寫(xiě)入值(如顏色断凶、紋理坐標(biāo)等)在片元著色器中讀出(對(duì)于片元著色器只讀)
gl_Position伤提、gl_PointSize、gl_FrontFacing认烁、gl_FragColor肿男、gl_FragCoord、gl_FrontFacing和gl_PointCoord:這些都是著色器內(nèi)置的特殊變量却嗡,編譯器已經(jīng)定義好的舶沛,用到的時(shí)候再詳細(xì)說(shuō)明
4、坐標(biāo)系
OpenGL的坐標(biāo)系比較特殊窗价,屏幕中間為原點(diǎn)如庭,橫x軸(左-1右1),豎y軸(上1下-1)撼港,垂直屏幕為z軸坪它。
5、 OpenGL ES2.0 繪制過(guò)程
- 讀取頂點(diǎn)數(shù)據(jù)
- 執(zhí)行頂點(diǎn)著色器
- 組裝圖元
- 光柵化圖元
- 執(zhí)行片元著色器
- 寫(xiě)入幀緩沖區(qū)
- 顯示到屏幕
OpenGL 作為本地庫(kù)字節(jié)運(yùn)行在硬件上帝牡,在java層定義的圖像數(shù)據(jù)需要被OpenGL存取往毡,需要把內(nèi)存從java堆復(fù)制到本地堆
頂點(diǎn)著色器是針對(duì)每個(gè)頂點(diǎn)都會(huì)執(zhí)行的程序,是確定每個(gè)頂點(diǎn)的位置靶溜。同理卖擅,片元著色器是針對(duì)每個(gè)片元都會(huì)執(zhí)行的程序,確定每個(gè)片元的顏色墨技。
著色器需要編譯惩阶,然后鏈接到OpenGL程序中,一個(gè)OpenGL程序就是一個(gè)頂點(diǎn)著色器和一個(gè)片元著色器鏈接在一起變成單個(gè)對(duì)象扣汪。
第一節(jié)沒(méi)看懂沒(méi)關(guān)系断楷,對(duì)這些概念有個(gè)印象就好,第二節(jié)從demo開(kāi)始正式學(xué)習(xí)Andrid OpenGL崭别,敬請(qǐng)期待
導(dǎo)讀:
《OpenGL從入門(mén)到放棄02 》GLSurfaceView和Renderer
感謝:
整個(gè)系列文章的學(xué)習(xí)資源來(lái)自# 湖廣午王
在洪洋的 玩安卓 網(wǎng)站上面搜索到的系列文章
一些概念的東西是直接copy冬筒,然后對(duì)于一些難理解的點(diǎn)加以注釋和補(bǔ)充。