GPUImage源码解读之GLProgram

GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。其实是作者对OpenGL ES program的面向对象封装

初始化 - (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderString:(NSString *)fShaderString; - (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderFilename:(NSString *)fShaderFilename; - (id)initWithVertexShaderFilename:(NSString *)vShaderFilename fragmentShaderFilename:(NSString *)fShaderFilename; program program = glCreateProgram(); shader c语言编译流程:预编译、编译、汇编、链接 glsl的编译过程类似c语言,主要有glCompileShader、glAttachShader、glLinkProgram三步 创建shader

分别根据两个Shader String来创建两个Shader。但是要注意区别的是,两个Shader的type对应的GLEnum是不一样的。
创建并且compile shader的过程包括几步:

创建OpenGL ES Shader:VertexShader的type是GL_VERTEX_SHADER;而FragmentShader是GL_FRAGMENT_SHADER。

shader = glCreateShader(type);

加载Source String:

source = (GLchar *)[shaderString UTF8String]; glShaderSource(*shader, 1, &source, NULL);

编译Shader:

glCompileShader(*shader);

检查Shader的状态;如果创建失败,则获取log:

glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { GLint logLength; glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetShaderInfoLog(*shader, logLength, &logLength, log); if (shader == &vertShader) { self.vertexShaderLog = [NSString stringWithFormat:@"%s", log]; } else { self.fragmentShaderLog = [NSString stringWithFormat:@"%s", log]; } free(log); } }

将生成的两个Shader Attach到Program上:

glAttachShader(program, vertShader); glAttachShader(program, fragShader);

link program并且检查program的状态,如果link失败,则获取log;如果link成功,则表示GLProgram的初始化完毕:

glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) return NO; if (vertShader) { glDeleteShader(vertShader); vertShader = 0; } if (fragShader) { glDeleteShader(fragShader); fragShader = 0; } self.initialized = YES;

use

glUseProgram(program); Attribute的管理 简介

attribute变量是只能在vertex shader中使用的变量。它不能在fragment shader中声明attribute变量,也不能被fragment shader中使用)

在application中,一般用函数glBindAttribLocation()来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer()为每个attribute变量赋值。

在GPUImage中,作者通过一个attributes数组来管理attribute变量。

- (void)addAttribute:(NSString *)attributeName { if (![attributes containsObject:attributeName]) { [attributes addObject:attributeName]; glBindAttribLocation(program, (GLuint)[attributes indexOfObject:attributeName], [attributeName UTF8String]); } } // END:addattribute // START:indexmethods - (GLuint)attributeIndex:(NSString *)attributeName { return (GLuint)[attributes indexOfObject:attributeName]; }

如上述函数所示,每当加入一个attribute时,会先判断在数组中有没有这个变量,如果没有的话,就加到数组中,并且绑定到shader中。变量获取的位置也就是在数组中的位置

uniform的管理 简介

uniform变量 外部程序传递给shader的变量.
函数glUniform**()函数赋值的.shader 中是只读变量,不能被 shader 修改.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyfww.html