NO.14 - OpenGL ES GLSL語言以及自定義著色器常用API

OpenGL ES GLSL語言

EGL(Embedded Graphics Library)
  • OpenGL ES 命令需要渲染上下?繪制表面才能完成圖形圖像的繪制
  • 渲染上下?: 存儲(chǔ)相關(guān)OpenGL ES狀態(tài)唬复,是一個(gè)狀態(tài)機(jī)
  • 繪制表面:?于繪制圖元的表面,需要指定渲染的緩存區(qū),例如顏?緩忠怖、深度和模板
  • OpenGL ES API 并沒有提供如何創(chuàng)建渲染上下文或者上下文如何連接到原生窗口系 統(tǒng). EGLKhronos 渲染API(如OpenGL ES) 和原?窗?系統(tǒng)之間的接?. 唯?支持 OpenGL ES 卻不支持EGL的平臺(tái)是iOS. Apple 提供?己的EGL APIiOS實(shí)現(xiàn),稱為EAGL
  • 因?yàn)槊總€(gè)窗?系統(tǒng)都有不同的定義,所以EGL提供基本的不透明類型—EGLDisplay, 這 個(gè)類型封裝了所有系統(tǒng)相關(guān)性,用于和原生窗?系統(tǒng)接?

主要功能

  • 和本地窗口系統(tǒng)(native windowing system)通訊
  • 查詢可用的配置
  • 創(chuàng)建OpenGL ES 可用的繪圖表面drawing surface
  • 同步不同類別的API之間的渲染,比如在OpenGL ESOpenVG之間同步灰伟,或者在OpenGL和本地窗口的繪圖命令之間
  • 管理渲染資源案腺,比如紋理映射(Rendering map
GLSL語言

xcode中不支持GLSL語言對(duì)頂點(diǎn)/片元著色器的編譯和連接效扫,因此需要在項(xiàng)目中創(chuàng)建兩個(gè)空文件看幼,分別命名為shader.vshshaderv.fsh

  • 使用vsh展懈、fsh后綴的原因是方便區(qū)分著色器销睁,其本質(zhì)就是一個(gè)字符串
  • 是否可以直接使用NSString?并不建議這樣做存崖,因?yàn)榇a結(jié)構(gòu)不清晰冻记,不易讀
  • 這兩個(gè)文件中是否可以加中文注釋?不建議加中文注釋来惧,會(huì)報(bào)奇怪的錯(cuò)誤冗栗,由于在xcode中書寫GLSL,完全是純手寫供搀,沒有任何提示隅居,排查問題不好排查
類型及API的總結(jié)

向量數(shù)據(jù)類型
常用的vec2、vec3葛虐、vec4胎源,默認(rèn)是浮點(diǎn)類型

vec2,vec3,vec4
2分量、3分量挡闰、4分量浮點(diǎn)向量
ivec2,ivec3,ivec4
2分量乒融、3分量掰盘、4分量整型向量
uvec2,uvec3,uvec4
2分量、3分量赞季、4分量無符號(hào)整型向量
bvec2,bvec3,bvec4
2分量愧捕、3分量、4分量bool型向量

矩陣數(shù)據(jù)類型

mat2,mat2x2
兩?兩列
mat3,mat3x3
三行三列
mat4,mat4x4
四行四列
mat2x3
三行兩列
mat2x4
四行兩列
mat3x2
兩行三列
mat3x4
四行三列
mat4x2
兩行四列
mat4x3
三行四列

變量存儲(chǔ)限定符
常用varying申钩、attribute次绘、uniform

  • varying 修飾符:當(dāng)需要將頂點(diǎn)著色器的數(shù)據(jù)傳遞到片元著色器時(shí),兩個(gè)著色器中一模一樣的紋理坐標(biāo)變量就需要它來修飾
  • attribute:數(shù)據(jù)只能從客戶端中傳遞到頂點(diǎn)著色器撒遣,且只能在頂點(diǎn)著色器中使用
    • 修飾的數(shù)據(jù):頂點(diǎn)邮偎、紋理、顏色义黎、法線等
    • API通常以glVertex...開頭禾进,例如glVertexAttribPointer
    • 其中的紋理坐標(biāo),需要頂點(diǎn)著色器間接傳遞到片元著色器廉涕,需要在頂點(diǎn)與片元著色器中定義一個(gè)一模一樣的紋理坐標(biāo)泻云,通過這個(gè)變量將紋理坐標(biāo)數(shù)據(jù)間接傳遞到片元著色器,varying lowp vec2 varyTextCoord;
    • 頂點(diǎn)著色器計(jì)算之后的頂點(diǎn)結(jié)果需要賦值給GLSL的內(nèi)建變量gl_Position
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;

void main()
{
    varyTextCoord = textCoordinate;
    gl_Position = position;
}
  • uniform:從app代碼傳遞到vertex狐蜕、fragment中所用的變量
    • vertex宠纯,fragment中一般將uniform當(dāng)成常量
    • uniform可以傳的數(shù)據(jù):視圖矩陣、投影矩陣层释、投影視圖矩陣
    • API通常以glUniform...開頭
    • 片元著色器中最終顏色婆瓜,即拿到紋理對(duì)應(yīng)坐標(biāo)下的紋素。紋素是紋理對(duì)應(yīng)像素點(diǎn)的顏色值贡羔,需要通過內(nèi)建函數(shù)texture2D(紋理廉白,紋理坐標(biāo))計(jì)算,將最終返回的顏色值賦值給內(nèi)建變量gl_FragColor
//需要定義精度治力,否則可能會(huì)報(bào)錯(cuò)
precsion highp float;
//紋理坐標(biāo) 必須與頂點(diǎn)著色器中一模一樣,通過這個(gè)參數(shù)獲取傳遞過來的值
varying lowp vec2 varyTextCoord;
//紋理 
uniform sampler2D colorMap;   

void main(){
    //1蒙秒、拿到紋理對(duì)應(yīng)坐標(biāo)下的紋素。紋素是紋理對(duì)應(yīng)像素點(diǎn)的顏色值
    lowp vec4 temp = texture2D(colorMap, varyTextCoord);
    
    //2宵统、非常重要且必須的內(nèi)建變量:gl_FragColor
    gl_FragColor = temp晕讲;
} 

<none> 只是普通的本地變量,外部不見马澈,外部不可訪問
const ?個(gè)編譯常量瓢省,或者說是?個(gè)對(duì)函數(shù)來說為只讀的參數(shù)
in/varying 從以前階段傳遞過來的變量
in/varying centroid ?個(gè)從以前的階段傳遞過來的變量,使?質(zhì)?插值
out/attribute 傳遞到下?個(gè)處理階段或者在?個(gè)函數(shù)中指定?個(gè)返回值
out/attribute centroid 傳遞到下?個(gè)處理階段痊班,質(zhì)心插值
uniform ?個(gè)從客戶端代碼傳遞過來的變量勤婚,在頂點(diǎn)之間不做改變

OpenGL ES 錯(cuò)誤處理

如果不正確使用OpenGL ES 命令,應(yīng)用程序就會(huì)產(chǎn)生一個(gè)錯(cuò)誤編碼涤伐,且會(huì)被記錄馒胆,可以用glGetError查詢缨称,一旦查詢到錯(cuò)誤代碼,當(dāng)前的錯(cuò)誤代碼就會(huì)復(fù)位為GL_NO_ERROR

GL_NO_ERROR 從上?次調(diào)?glGetError 以來沒有生成任何錯(cuò)誤
GL_INVALID_ENUM GLenum 參數(shù)超出范圍,忽略生成錯(cuò)誤命令
GL_INVALID_VALUE 數(shù)值型 參數(shù)超出范圍,忽略生成錯(cuò)誤命令
GL_INVALID_OPERATION 特定命令在當(dāng)前OpenGL ES 狀態(tài)?法執(zhí)?
GL_OUT_OF_MEMORY 內(nèi)存不足時(shí)執(zhí)?該命令,如果遇到這個(gè)錯(cuò)誤,除?當(dāng)前錯(cuò)誤代碼,否則OpenGL ES 管線的 狀態(tài)被認(rèn)為未定義

OpenGL ES 自定義著色器常用API

自定義著色器

自定義著色器一般有以下步驟:

  • 創(chuàng)建頂點(diǎn)著色器/片元著色器 --glCreateShader
  • 指定shadersource --glShaderSource
  • 編譯shader --glCompileShader

創(chuàng)建與編譯一個(gè)著色器的相關(guān)API


創(chuàng)建與編譯一個(gè)著色器的相關(guān)API

自定義程序

自定義程序一般有以下步驟:

  • 創(chuàng)建一個(gè)程序?qū)ο?--glCreateProgram
  • 著色器與程序連接/附著 --glAttachShader
  • 鏈接程序 --glLinkProgram
  • 使用程序 --glUseProgram

創(chuàng)建與鏈接程序的相關(guān)API


創(chuàng)建與鏈接程序的相關(guān)API
著色器與程序的 編譯 & 鏈接
  • 需要?jiǎng)?chuàng)建2個(gè)基本對(duì)象才能使用著色器進(jìn)行傳染:著色器對(duì)象和程序?qū)ο?/li>
  • 獲取鏈接后著色器對(duì)象一般的編譯&鏈接分為6步:
  • 創(chuàng)建一個(gè)頂點(diǎn)著色器對(duì)象和一個(gè)片元著色器對(duì)象
  • 將源代碼鏈接到每個(gè)著色器對(duì)象
  • 編譯著色器對(duì)象
  • 創(chuàng)建一個(gè)程序?qū)ο?/li>
  • 將編譯后的著色器對(duì)象連接到程序?qū)ο?/li>
  • 鏈接程序?qū)ο?/li>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祝迂,一起剝皮案震驚了整個(gè)濱河市睦尽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌型雳,老刑警劉巖当凡,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異纠俭,居然都是意外死亡沿量,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門冤荆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朴则,“玉大人,你說我怎么就攤上這事匙赞》鹨矗” “怎么了妖碉?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵涌庭,是天一觀的道長。 經(jīng)常有香客問我欧宜,道長坐榆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任冗茸,我火速辦了婚禮席镀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夏漱。我一直安慰自己豪诲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布挂绰。 她就那樣靜靜地躺著屎篱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葵蒂。 梳的紋絲不亂的頭發(fā)上交播,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音践付,去河邊找鬼秦士。 笑死,一個(gè)胖子當(dāng)著我的面吹牛永高,可吹牛的內(nèi)容都是我干的隧土。 我是一名探鬼主播提针,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼曹傀!你這毒婦竟也來了关贵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤卖毁,失蹤者是張志新(化名)和其女友劉穎揖曾,沒想到半個(gè)月后亥啦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翔脱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了届吁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片错妖。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疚沐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亮蛔,到底是詐尸還是另有隱情痴施,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布辣吃,位于F島的核電站,受9級(jí)特大地震影響芬探,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偷仿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一哩簿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炎疆,春花似錦卡骂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亿遂,卻和暖如春浓若,著一層夾襖步出監(jiān)牢的瞬間渺杉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來泰國打工挪钓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留是越,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓碌上,卻偏偏與公主長得像倚评,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子馏予,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361