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