OpenGL ES相關(guān)API及GLSL語(yǔ)言使用

EGL(Embedded Graphics Library)

一、概念說明
  • OpenGL ES 命令需要渲染上下文和繪制表面才能完成圖形圖像的繪制。
  • 渲染上下文: 存儲(chǔ)相關(guān)OpenGL ES狀態(tài)。
  • 繪制表面: 是?于繪制圖元的表面,它指定渲染所需要的緩存區(qū)類型,例如顏?緩存區(qū)、深度緩存區(qū)和模板緩存區(qū)。
  • OpenGL ES API并沒有提供如何創(chuàng)建渲染上下?或者上下文如何連接到原?窗?系統(tǒng)。 EGLKhronos渲染API(如OpenGL ES) 和原生窗?系統(tǒng)之間的接?。 唯?支持OpenGL ES 卻不?持EGL的平臺(tái)是iOS。
二、EGL的主要功能
  • 和本地窗?系統(tǒng)(native windowing system)通訊;
  • 查詢可?的配置;
  • 創(chuàng)建OpenGL ES可用的“繪圖表面”(drawing surface);
  • 同步不同類別的API之間的渲染,?如在OpenGL ESOpenVG之間同步,或者在OpenGL和本地窗?的繪圖命令之間;
  • 管理“渲染資源”,比如紋理映射(rendering map)。

GLSL語(yǔ)法

一、簡(jiǎn)介

  • GLSLOpenGL Shading Language) 全稱OpenGL著色語(yǔ)言,是用來在 OpenGL中著色編程的語(yǔ)言,也即開發(fā)人員寫的短小的自定義程序,他們是在圖形卡的GPU上執(zhí)行的,代替了固定的渲染管線的一部分,使渲染管線中不同層次具有可編程性。
  • GLSL 其使用C 語(yǔ)言作為基礎(chǔ)高階著色語(yǔ)言,避免了使用匯編語(yǔ)言或硬件規(guī)格語(yǔ)言的復(fù)雜性。

二、變量命名

GLSL的變量命名方式與C語(yǔ)言類似,可使用字母,數(shù)字以及下劃線,不能以數(shù)字開頭。還需要注意的是,變量名不能以gl_作為前綴,這個(gè)是GLSL保留的前綴,用于GLSL 的內(nèi)部變量。

三、數(shù)據(jù)類型說明

  • 向量數(shù)據(jù)類型
類型 說明
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ǔ)限定符
限定符 說明
< 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)之間不做改變
  • GLenum glGetError(void):如果不正確使用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 以來沒有?成任何錯(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)為未定義

四、vsh和fsh的示例說明

① 什么是vshfsh?
  • Xcode中不支持GLSL語(yǔ)言對(duì)頂點(diǎn)、片元著色器的編譯和連接,因此需要在項(xiàng)目中創(chuàng)建兩個(gè)空文件,分別命名為shader.vshshaderv.fsh
  • shader.vshshaderv.fsh中的vshfsh只是區(qū)分“頂點(diǎn)著色器”和“片元著色器”類;(可以隨意更改,僅為一個(gè)字符串)
② 頂點(diǎn)坐標(biāo)(vsh)
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;

void main() {
    varyTextCoord = textCoordinate;
    gl_Position = position;
}

  • 數(shù)據(jù)修飾類型常用uniform、attribute、varying三種;
  • uniformOCSwift代碼傳遞到vertex、fragment(常量,一般不修改);可以傳遞視圖矩陣、投影矩陣、投影視圖矩陣,
  • attribute:數(shù)據(jù)只能從客戶端中傳遞到頂點(diǎn)著色器,且只能在頂點(diǎn)著色器中使用;常用來修飾頂點(diǎn)、紋理坐標(biāo)、顏色、法線等數(shù)據(jù);
  • varying:當(dāng)需要將頂點(diǎn)著色器的數(shù)據(jù)傳遞到片元著色器時(shí),兩個(gè)著色器中一樣的紋理坐標(biāo)變量就需要它來修飾。
③ 紋理渲染(fsh
// 需要定義精度,防止報(bào)錯(cuò)
precsion highp float;
// 紋理坐標(biāo):必須與頂點(diǎn)著色器中一樣,通過這個(gè)參數(shù)獲取傳遞過來的值
varying lowp vec2 varyTextCoord;
// 紋理
uniform sampler2D colorMap;   

void main(){
    // 拿到紋理對(duì)應(yīng)坐標(biāo)下的紋素,紋素是紋理對(duì)應(yīng)像素點(diǎn)的顏色值
    lowp vec4 temp = texture2D(colorMap, varyTextCoord);

    // 內(nèi)建變量:gl_FragColor
    gl_FragColor = temp;
} 

  • 片元著色器中最終顏色,即拿到紋理對(duì)應(yīng)坐標(biāo)下的紋素。紋素是紋理對(duì)應(yīng)像素點(diǎn)的顏色值,需要通過內(nèi)建函數(shù)texture2D(紋理,紋理坐標(biāo))計(jì)算,將最終返回的顏色值賦值給內(nèi)建變量gl_FragColor。

五、著?器與程序

① 主要步驟

需要?jiǎng)?chuàng)建2個(gè)基本對(duì)象才能?著色器進(jìn)行渲染: 著?器對(duì)象和程序?qū)ο?;獲取鏈接后著?器對(duì)象的一般過程包括6個(gè)步驟:

  • 創(chuàng)建?個(gè)頂點(diǎn)著?器對(duì)象和?個(gè)?段著?器對(duì)象;
  • 將源代碼鏈接到每個(gè)著?器對(duì)象;
  • 編譯著?器對(duì)象;
  • 創(chuàng)建?個(gè)程序?qū)ο螅?/li>
  • 將編譯后的著?器對(duì)象連接到程序?qū)ο螅?/li>
  • 鏈接程序?qū)ο蟆?/li>
② 創(chuàng)建與編譯一個(gè)著色器
  • 創(chuàng)建著色器
GLuint glCreateShader(GLenum type);
type — 創(chuàng)建著?器的類型,GL_VERTEX_SHADER 或者 GL_FRAGMENT_SHADER
返回值 — 是指向新著?器對(duì)象的句柄,可以調(diào)? glDeleteShader 刪除 

void glDeleteShader(GLuint shader);
shader — 要?jiǎng)h除的著?器對(duì)象句柄

void glShaderSource(GLuint shader , GLSizei count ,const GLChar * const *string, const GLint *length);
shader — 指向著?器對(duì)象的句柄
count — 著?器源字符串的數(shù)量,著?器可以由多個(gè)源字符串組成,但是每個(gè)著?器只有一個(gè)main函數(shù) string — 指向保存數(shù)量的 count 的著?器源字符串的數(shù)組指針
length — 指向保存每個(gè)著?器字符串大小且元素?cái)?shù)量為 count 的整數(shù)組指針

  • 編譯著色器
void glCompileShader(GLuint shader); 
shader — 需要編譯的著?器對(duì)象句柄

void glGetShaderiv(GLuint shader , GLenum pname , GLint *params );
shader — 需要編譯的著?器對(duì)象句柄
pname — 獲取的信息參數(shù),可以為 GL_COMPILE_STATUS/GL_DELETE_STATUS/ GL_INFO_LOG_LENGTH/GL_SHADER_SOURCE_LENGTH/ GL_SHADER_TYPE
params — 指向查詢結(jié)果的整數(shù)存儲(chǔ)位置的指針.

void glGetShaderInfolog(GLuint shader , GLSizei maxLength, GLSizei *length , GLChar *infoLog);
shader — 需要獲取信息?志的著?器對(duì)象句柄
maxLength — 保存信息?志的緩存區(qū)?小
length — 寫?的信息日志的?度(減去 null 終?符); 如果不需要知道長(zhǎng)度,這個(gè)參數(shù)可以為Null 
infoLog — 指向保存信息日志的字符緩存區(qū)的指針

③ 創(chuàng)建與鏈接程序
  • 創(chuàng)建
GLUint glCreateProgram( )
創(chuàng)建?個(gè)程序?qū)ο?返回值: 返回?個(gè)執(zhí)行新程序?qū)ο蟮木浔?
void glDeleteProgram( GLuint program ) 
program : 指向需要?jiǎng)h除的程序?qū)ο缶浔?
// 著?器與程序連接/附著
void glAttachShader( GLuint program , GLuint shader );
program : 指向程序?qū)ο蟮木浔?shader : 指向程序連接的著?器對(duì)象的句柄
// 斷開連接
void glDetachShader(GLuint program);
program : 指向程序?qū)ο蟮木渚浔?shader : 指向程序斷開連接的著?器對(duì)象句柄

  • 鏈接程序
glLinkProgram(GLuint program) 
program: 指向程序?qū)ο缶浔?鏈接程序之后, 需要檢查鏈接是否成功. 你可以使用 glGetProgramiv 檢查鏈接狀態(tài): 
void glGetProgramiv (GLuint program,GLenum pname, GLint *params);
program: 需要獲取信息的程序?qū)ο缶浔?
pname : 獲取信息的參數(shù),可以是:
        GL_ACTIVE_ATTRIBUTES 
        GL_ACTIVE_ATTRIBUTES_MAX_LENGTH 
        GL_ACTIVE_UNIFORM_BLOCK 
        GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH 
        GL_ACTIVE_UNIFROMS 
        GL_ACTIVE_UNIFORM_MAX_LENGTH 
        GL_ATTACHED_SHADERS 
        GL_DELETE_STATUS
        GL_INFO_LOG_LENGTH
        GL_LINK_STATUS 
        GL_PROGRAM_BINARY_RETRIEVABLE_HINT 
        GL_TRANSFORM_FEEDBACK_BUFFER_MODE 
        GL_TRANSFORM_FEEDBACK_VARYINGS 
        GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 
        GL_VALIDATE_STATUS
params : 指向查詢結(jié)果整數(shù)存儲(chǔ)位置的指針

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容