iOS --- OpenGLES之着色器(shader)的编译、链接及使用

来源:互联网 发布:淘宝女装店铺推广文案 编辑:程序博客网 时间:2024/05/22 01:48

在上一篇博客 iOS — OpenGLES之着色器(shader)语法介绍 中,简要介绍了OpenGLES的着色器shader的基本语法,以及Vertex Shader和Fragment Shader的差异。本文中,将简要介绍着色器(shader)的编译、链接及使用。

Vertex Shader和Fragment Shader

Vertex Shader如下:

// variable pass intoattribute vec4 Position;    // position of vertexattribute vec4 SourceColor; // color of vertex// variable pass out into fragment shader// varying means that calculate the color of every pixel between two vertex linearly(smoothly) according to the 2 vertex's color varying vec4 DestinationColor;void main(void) {    DestinationColor = SourceColor;    // gl_Position is built-in pass-out variable. Must config for in vertex shader    gl_Position = Position;}

Fragment Shader如下:

varying lowp vec4 DestinationColor;void main(void) {    // must set gl_FragColor for fragment shader    gl_FragColor = DestinationColor;}

关于Shader的具体含义,请参考上一篇博客 iOS — OpenGLES之着色器(shader)语法介绍 。

编译shader

着色器脚本的编译过程比较固定,主要是以下步骤:

  1. 获取shader文件
  2. 创建shader对象
  3. 获取shader的源码
  4. 编译shader脚本
  5. 查询编译结果

封装函数如下:

+ (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType {    // 1 查找shader文件    NSString* shaderPath = [[NSBundle mainBundle] pathForResource:shaderName ofType:@"glsl"];    NSError* error;    NSString* shaderString = [NSString stringWithContentsOfFile:shaderPath encoding:NSUTF8StringEncoding error:&error];    if (!shaderString) {        NSLog(@"Error loading shader: %@", error.localizedDescription);        exit(1);    }    // 2 创建一个代表shader的OpenGL对象, 指定vertex或fragment shader    GLuint shaderHandle = glCreateShader(shaderType);    // 3 获取shader的source    const char* shaderStringUTF8 = [shaderString UTF8String];    int shaderStringLength = [shaderString length];    glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength);    // 4 编译shader    glCompileShader(shaderHandle);    // 5 查询shader对象的信息    GLint compileSuccess;    glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);    if (compileSuccess == GL_FALSE) {        GLchar messages[256];        glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);        NSString *messageString = [NSString stringWithUTF8String:messages];        NSLog(@"%@", messageString);        exit(1);    }    return shaderHandle;}

对于Vertex Shader和Fragment Shader都要编译:

GLuint vertexShader = [ShaderOperations compileShader:shaderVertex withType:GL_VERTEX_SHADER];GLuint fragmentShader = [ShaderOperations compileShader:shaderFragment withType:GL_FRAGMENT_SHADER];

该函数接收的第二个参数用于指定Vertex或Fragment:

#define GL_FRAGMENT_SHADER                               0x8B30#define GL_VERTEX_SHADER                                 0x8B31

连接Vertex Shader和Fragment Shader

连接Vertex Shader和Fragment Shader成一个完整的OpenGL Shader Program。

GLuint _glProgram = glCreateProgram();glAttachShader(_glProgram, vertexShader);glAttachShader(_glProgram, fragmentShader);glLinkProgram(_glProgram);// 检查link状态GLint linkSuccess;glGetProgramiv(_glProgram, GL_LINK_STATUS, &linkSuccess);if (linkSuccess == GL_FALSE) {    GLchar messages[256];    glGetProgramInfoLog(_glProgram, sizeof(messages), 0, &messages[0]);    NSString *messageString = [NSString stringWithUTF8String:messages];    NSLog(@"%@", messageString);    exit(1);}

使用Shader

GLuint _positionSlot;   // 用于绑定shader中的Position参数GLuint _colorSlot;      // 用于绑定shader中的SourceColor参数glUseProgram(_glProgram); // 让OpenGL执行glProgram_positionSlot = glGetAttribLocation(_glProgram, "Position");_colorSlot = glGetAttribLocation(_glProgram, "SourceColor");

这样,通过 _positionSlot 和_colorSlot 就可以向Shader中传递所需参数,分别对应Position和SourceColor。如给_positionSlot传递数据,即顶点数组数据:

GLfloat vertices[] = {    0.0f,  0.5f, 0.0f,    -0.5f, -0.5f, 0.0f,    0.5f,  -0.5f, 0.0f };// 给_positionSlot传递vertices数据glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices );glEnableVertexAttribArray(_positionSlot); //使用时要enable

Demo地址

本文的一系列demo都可在github中找到,DemoOpenGL,如有不准确的地方,欢迎指正。

参考资料

以上部分,简要介绍了着色器(Shader)的基本使用情况。主要参考资料:
OpenGL Tutorial for iOS: OpenGL ES 2.0
iOS — OpenGLES之着色器(shader)语法介绍
OpenGL ES渲染管线与着色器

0 0