c语言opengles程序,OpenGL ES _ 着色器_程序
演示圖
你不知道這個(gè)東西,請(qǐng)不要看了,請(qǐng)看我的其他文章先了解一下O!
學(xué)習(xí)目標(biāo)
掌握著色器程序的執(zhí)行過(guò)程
簡(jiǎn)單的例子
``
uniform float t; // 時(shí)間
uniform mat4 gl_ModelViewMatrix; // 模型視圖矩陣
attribute vec4 vel;
const vec4 g = vec4(0.0,-9.8,0.0) // 重力加速度
void main()
{
vec4 position = vel;
position += t*vel + t*t*g;
gl_Position = gl_ModelViewMatrix * position;
}
稍微解釋一下:代碼的作用是模擬重力加速度,對(duì)一個(gè)點(diǎn)的位置進(jìn)行變換.
OpenGL /GLSL 程序接口
先上圖
著色器創(chuàng)建流程
C語(yǔ)言,大家應(yīng)該很熟悉吧! C 語(yǔ)言的編譯過(guò)程步驟:
1.編譯器檢查錯(cuò)誤
2.將他轉(zhuǎn)換成目標(biāo)代碼(.o文件)
3.將一組目標(biāo)文件進(jìn)行鏈接,最后成為一個(gè)可執(zhí)行文件
在OpenGL 程序中使用GLSL 著色器也是一個(gè)相似的過(guò)程,要在應(yīng)用程序中使用頂點(diǎn)或者片段著色器需要按照**順序**執(zhí)行下面的步驟:
1.創(chuàng)建著色器對(duì)象
2.把著色器代碼編譯成源代碼
3.驗(yàn)證是否著色器是否編譯成功
為了把多個(gè)著色器對(duì)象鏈接起來(lái),我們需要?jiǎng)?chuàng)建著色器程序
4.創(chuàng)建一個(gè)著色器程序
5.把著色器對(duì)象鏈接到這個(gè)著色器程序中
6.鏈接著色器
7.驗(yàn)證著色器鏈接階段已經(jīng)成功完成.
8.使用著色器進(jìn)行頂點(diǎn)或者片段處理.
函數(shù)講解 (用到的主要是C語(yǔ)法)
GLUint glCreateShader(GLenum type);
作用:創(chuàng)建著色器對(duì)象
type 類型值兩個(gè): GL_VERTEX_SHADER(頂點(diǎn)做色器) 和 GL_VERTEX_SHADER(片段著色器) 返回一個(gè)非零的值,作為著色器的標(biāo)記
void glShaderSource(GLuint shader,GLsizei count,const GLchar**string,const Glint* length);
作用:創(chuàng)建著色器對(duì)象后,需要把著色器的源代碼和著色器對(duì)象關(guān)聯(lián)
參數(shù)1:shader 就是創(chuàng)建著色器成功返回的那個(gè)值
參數(shù)2:count 包含多個(gè)字符串,一般就1個(gè)字符串
參數(shù)3:字符串?dāng)?shù)組地址
參數(shù)4:,可以為NULL 代表字符串為NULL 結(jié)尾的,否則,length就代表具有就有count個(gè)元素,每個(gè)元素指定了string中對(duì)應(yīng)字符串的長(zhǎng)度,如果length數(shù)組中的某個(gè)元素對(duì)應(yīng)一個(gè)正整數(shù),就代表string數(shù)組中對(duì)應(yīng)字符串的長(zhǎng)度,如果是負(fù)整數(shù),對(duì)應(yīng)的字符串就是以NULL 結(jié)尾的.
void glCompileShader(GLuint shader)
作用:編譯著色器源代碼
參數(shù) : shader 著色器標(biāo)示
glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
作用: 查詢編譯結(jié)果
參數(shù)1:shader 著色器標(biāo)識(shí)
參數(shù)2:GL_COMPLE_STATUS
參數(shù)3:查詢結(jié)果返回
void glGetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei length ,char infoLog);
作用: 獲取編譯相關(guān)日志,調(diào)試情況下使用
參數(shù)1: shader 著色器對(duì)象標(biāo)識(shí)
參數(shù)2: bufsize 最大日志長(zhǎng)度
參數(shù)3: length 如果為NULL 不返回任何日志
參數(shù)4:infoLog 保存在緩沖區(qū)中
GLuint glCreateProgram()
作用:創(chuàng)建空的著色器程序
返回:非零,如果是0 則創(chuàng)建失敗
void AttachShader(GLuint program,GLuint shader);
作用: 把著色器和程序相關(guān)聯(lián)
參數(shù)1:program 著色器程序標(biāo)識(shí)
參數(shù)2:shader 著色器對(duì)象標(biāo)識(shí)
void glDetachShader(GLuint program,Gluint shader);
作用: 把著色器對(duì)象從著色器程序中分離出來(lái),以更改著色器的操作。
參數(shù)1:program 著色器程序標(biāo)識(shí)
參數(shù)2:shader 著色器對(duì)象標(biāo)識(shí)
void glLinkProgram()
作用:在著色器對(duì)象都連接到著色器程序之后,就要把這些對(duì)象連接成一個(gè)可執(zhí)行程序.
void glGetProgramInfoLog(GLuint program,GLsizei bufsize,GLsize length char infoLog)
作用:連接著色器程序也可能出現(xiàn)錯(cuò)誤,我們需要進(jìn)行查詢,獲取錯(cuò)誤日志信息
參數(shù)1: program 著色器程序標(biāo)識(shí)
參數(shù)2: bufsize 最大日志長(zhǎng)度
參數(shù)3: length 如果為NULL 不返回任何日志
參數(shù)4:infoLog 保存在緩沖區(qū)中
void glGetProgramiv (GLuint program, GLenum pname, GLint* params)
作用:查詢程序連接后的結(jié)果
參數(shù)1:program 著色器程序標(biāo)識(shí)
參數(shù)2: GL_LINK_STATUS
參數(shù)3:params 返回狀態(tài)
void glUserProgram(GLuint program)
作用: 程序連接成功后,就可以調(diào)用這個(gè)函數(shù),啟動(dòng)這個(gè)頂點(diǎn)或者片段著色器程序了,為了恢復(fù)使用固定功能的管線,可以向這個(gè)函數(shù)傳遞 0作為參數(shù).
void glDeleteShader(GLuint shader)
作用:刪除著色器對(duì)象,如果這個(gè)著色器對(duì)象被多個(gè)程序連接,一旦程序不再使用這個(gè)對(duì)象,那么它便會(huì)實(shí)際刪除
參數(shù): shader 著色器對(duì)象標(biāo)識(shí)
void glDeleteProgram(GLuint program)
作用: 刪除著色器程序 ,如果這個(gè)著色器未在任何渲染環(huán)境中使用,它將立即刪除。否則,會(huì)標(biāo)記為刪除,一旦它沒(méi)不被使用了,便立即被刪除
void GLboolean glIsShader(GLuint shader)
作用: 如果shader 是一個(gè)著色器對(duì)象名稱,則返回GL_TRUE, 否則返回GL_FALSE
void GLboolean glIsProgram(GLuint program)
作用: 如果program 是一個(gè)著色器程序,則返回GL_TRUE ,否則返回GL_FALSE
void glValidateProgram(GLuint program)
作用:用于驗(yàn)證一個(gè)著色器程序是否可以在當(dāng)前OpenGL 環(huán)境下使用,驗(yàn)證結(jié)果查詢,使用glGetProgramiv() 傳入?yún)?shù)GL_VALIDATE_STATUS 為參數(shù),查詢程序驗(yàn)證結(jié)果
IOS 代碼上一份方便大家理解
導(dǎo)入shader的步驟
第一步. 創(chuàng)建GLuint 類型的shader 標(biāo)示
第二步. 獲取shader 文件所在的路徑
第三步 獲取文件的內(nèi)容 并進(jìn)行NSUTF8StringEncoding 編碼
第四步. 根據(jù)類型創(chuàng)建shader 著色器對(duì)象
第五步. 關(guān)聯(lián)shader著色器源代碼
第六步. 編譯shader著色器對(duì)象源代碼
第七步. 檢查著色器源代碼編譯是否成功
第八步. 創(chuàng)建著色器程序
第九步. 將編譯好的著色器目標(biāo)文件鏈接到程序中去
第十步. 綁定著色器的屬性
第十一步. 將著色器和程序分開,并且釋放著色器
步驟就是多,最好封裝好,不重復(fù)敲代碼才是王道
``
- (BOOL)loadShaders
{
// 第一步.創(chuàng)建標(biāo)示
GLuint vertShader, fragShader;
// 第二步.獲取文件路徑
NSString *vertShaderPathname, *fragShaderPathname;
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"編譯失敗 vertex shader");
return NO;
}
// 創(chuàng)建 編譯 片斷著色器對(duì)象
fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
NSLog(@"Failed to compile fragment shader");
return NO;
}
// 第八步 創(chuàng)建一個(gè)著色器空程序
_program = glCreateProgram();
// 第九步 將頂點(diǎn)著色器鏈接到程序中
glAttachShader(_program, vertShader);
// 將片斷著色器鏈接到程序中
glAttachShader(_program, fragShader);
//第十步 綁定著色器的屬性
glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
if (![self linkProgram:_program]) {
NSLog(@"Failed to link program: %d", _program);
if (vertShader) {
glDeleteShader(vertShader);
vertShader = 0;
}
if (fragShader) {
glDeleteShader(fragShader);
fragShader = 0;
}
if (_program) {
glDeleteProgram(_program);
_program = 0;
}
return NO;
}
// Get uniform locations.
uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
// 第十三步 . 分離釋放頂點(diǎn)著色器對(duì)象 和片段著色器對(duì)象
if (vertShader) {
glDetachShader(_program, vertShader);
glDeleteShader(vertShader);
}
if (fragShader) {
glDetachShader(_program, fragShader);
glDeleteShader(fragShader);
}
return YES;
}
-(BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
//第三步 獲取文件的內(nèi)容 并進(jìn)行NSUTF8StringEncoding 編碼
const GLchar *source;
source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
NSLog(@"Failed to load vertex shader");
return NO;
}
//第四步 根據(jù)類型創(chuàng)建著色器對(duì)象
*shader = glCreateShader(type);
//第五步. 獲取著色器源代碼和著色器關(guān)聯(lián)
glShaderSource(*shader, 1, &source, NULL);
//第六步. 開始編譯著色器源代碼
glCompileShader(*shader);
#if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
NSLog(@"Shader compile log:\n%s", log);
free(log);
}
#endif
//第七步. 查看是著色器源代碼否編譯成功
GLint status;
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
glDeleteShader(*shader);
return NO;
}
return YES;
}
- (BOOL)linkProgram:(GLuint)prog
{
// 第十一 鏈接程序
glLinkProgram(prog);
#if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program link log:\n%s", log);
free(log);
}
#endif
// 第十二步 檢查著色器程序鏈接結(jié)果
GLint status;
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == 0) {
return NO;
}
代碼下載地址
點(diǎn)我下載
參考
OpenGL 編程指南>
總結(jié)
以上是生活随笔為你收集整理的c语言opengles程序,OpenGL ES _ 着色器_程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 进程 zabbix_Zabbix监控在w
- 下一篇: oracle fiscal year,V