iOS --- OpenGLES之着色器(shader)的编译、链接及使用
2016-01-03 18:38
435 查看
在上一篇博客 iOS — OpenGLES之着色器(shader)语法介绍 中,简要介绍了OpenGLES的着色器shader的基本语法,以及Vertex Shader和Fragment Shader的差异。本文中,将简要介绍着色器(shader)的编译、链接及使用。
Fragment Shader如下:
关于Shader的具体含义,请参考上一篇博客 iOS — OpenGLES之着色器(shader)语法介绍 。
获取shader文件
创建shader对象
获取shader的源码
编译shader脚本
查询编译结果
封装函数如下:
对于Vertex Shader和Fragment Shader都要编译:
该函数接收的第二个参数用于指定Vertex或Fragment:
这样,通过 _positionSlot 和_colorSlot 就可以向Shader中传递所需参数,分别对应Position和SourceColor。如给_positionSlot传递数据,即顶点数组数据:
OpenGL Tutorial for iOS: OpenGL ES 2.0
iOS — OpenGLES之着色器(shader)语法介绍
OpenGL ES渲染管线与着色器
Vertex Shader和Fragment Shader
Vertex Shader如下:// variable pass into attribute vec4 Position; // position of vertex attribute 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
着色器脚本的编译过程比较固定,主要是以下步骤:获取shader文件
创建shader对象
获取shader的源码
编译shader脚本
查询编译结果
封装函数如下:
+ (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渲染管线与着色器
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- THREE.JS入门教程(2)着色器-上
- THREE.JS入门教程(3)着色器-下
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- prettify 代码高亮着色器google出品
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- 举例详解iOS开发过程中的沙盒机制与文件