EGL(Embedded Graphics Library)
- OpenGL ES 命令需要
渲染上下?
和繪制表面
才能完成圖形圖像的繪制 - 渲染上下?: 存儲(chǔ)相關(guān)OpenGL ES狀態(tài)社裆,是一個(gè)狀態(tài)機(jī)
- 繪制表面:?于繪制圖元的表面,需要指定渲染的緩沖區(qū),例如顏?緩沖區(qū)碰纬、深度緩沖區(qū)和模板緩沖區(qū)
- OpenGL ES API 并沒(méi)有提供如何創(chuàng)建渲染上下文或者上下文如何連接到原生窗口系 統(tǒng). EGL 是Khronos 渲染API(如OpenGL ES) 和原?窗?系統(tǒng)之間的接?.
唯?支持 OpenGL ES 卻不支持EGL的平臺(tái)是iOS. Apple 提供?己的EGL API的iOS實(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 ES 和OpenVG之間同步错沽,或者在OpenGL和本地窗口的繪圖命令之間
- 管理”渲染資源“,比如紋理映射(Rendering map)
GLSL語(yǔ)言
- xcode中不支持GLSL語(yǔ)言對(duì)頂點(diǎn)/片元著色器的編譯和連接肺孤,因此需要在項(xiàng)目中創(chuàng)建兩個(gè)空文件罗晕,分別命名為
shader.vsh
和shaderv.fsh
- 使用
vsh、fsh
后綴的原因是方便區(qū)分著色器赠堵,其本質(zhì)就是一個(gè)字符串 - 是否可以直接使用NSString小渊?并不建議這樣做,因?yàn)榇a結(jié)構(gòu)不清晰茫叭,不易讀
- 這兩個(gè)文件中是否可以加中文注釋酬屉?不建議加中文注釋,會(huì)報(bào)奇怪的錯(cuò)誤揍愁,由于在xcode中書(shū)寫(xiě)GLSL呐萨,完全是純手寫(xiě),沒(méi)有任何提示莽囤,排查問(wèn)題不好排查
- 使用
下面是一些類型及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分量無(wú)符號(hào)整型向量 |
bvec2,bvec3,bvec4 | 2分量贺氓、3分量、4分量bool型向量 |
矩陣數(shù)據(jù)類型
最常用的是mat3床蜘、mat4
類型(mat列×行) | 描述 |
---|---|
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)變量就需要它來(lái)修飾
- attribute:數(shù)據(jù)只能從客戶端中傳遞到頂點(diǎn)著色器虏冻,且只能在頂點(diǎn)著色器中使用
- 修飾的數(shù)據(jù):頂點(diǎn)、紋理弹囚、顏色厨相、法線等
- API通常以
glVertex...
開(kāi)頭,例如glVertexAttribPointer
- 其中的紋理坐標(biāo)鸥鹉,需要頂點(diǎn)著色器間接傳遞到片元著色器蛮穿,需要在頂點(diǎn)與片元著色器中定義一個(gè)一模一樣的紋理坐標(biāo),通過(guò)這個(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...
開(kāi)頭 - 片元著色器中最終顏色,即拿到紋理對(duì)應(yīng)坐標(biāo)下的紋素肺樟。紋素是紋理對(duì)應(yīng)像素點(diǎn)的顏色值檐春,需要通過(guò)內(nèi)建函數(shù)
texture2D(紋理,紋理坐標(biāo))
計(jì)算么伯,將最終返回的顏色值賦值給內(nèi)建變量gl_FragColor
//需要定義精度疟暖,否則可能會(huì)報(bào)錯(cuò)
precsion highp float;
//紋理坐標(biāo) 必須與頂點(diǎn)著色器中一模一樣,通過(guò)這個(gè)參數(shù)獲取傳遞過(guò)來(lái)的值
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> | 只是普通的本地變量硬爆,外部不見(jiàn)欣舵,外部不可訪問(wèn) |
const | ?個(gè)編譯常量,或者說(shuō)是?個(gè)對(duì)函數(shù)來(lái)說(shuō)為只讀的參數(shù) |
in/varying | 從以前階段傳遞過(guò)來(lái)的變量 |
in/varying centroid | ?個(gè)從以前的階段傳遞過(guò)來(lái)的變量摆屯,使?質(zhì)?插值 |
out/attribute | 傳遞到下?個(gè)處理階段或者在?個(gè)函數(shù)中指定?個(gè)返回值 |
out/attribute centroid | 傳遞到下?個(gè)處理階段邻遏,質(zhì)心插值 |
uniform | ?個(gè)從客戶端代碼傳遞過(guò)來(lái)的變量,在頂點(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
錯(cuò)誤代碼 | 描述 |
---|---|
GL_NO_ERROR | 從上?次調(diào)?glGetError 以來(lái)沒(méi)有生成任何錯(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
- 指定shader的source --
glShaderSource
- 編譯shader --
glCompileShader
以下是創(chuàng)建與編譯一個(gè)著色器的相關(guān)API
自定義程序
自定義程序一般有以下步驟:
- 創(chuàng)建一個(gè)程序?qū)ο?--
glCreateProgram
- 著色器與程序連接/附著 --
glAttachShader
- 鏈接程序 --
glLinkProgram
- 使用程序 --
glUseProgram
以下是創(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>