iOSios developers音视频从入门到放弃

OpenGL ES _ 着色器_程序

2016-08-12  本文已影响0人  酷走天涯

OpenGL ES _ 入门_01
OpenGL ES _ 入门_02
OpenGL ES _ 入门_03
OpenGL ES _ 入门_04
OpenGL ES _ 入门_05
OpenGL ES _ 入门练习_01
OpenGL ES _ 入门练习_02
OpenGL ES _ 入门练习_03
OpenGL ES _ 入门练习_04
OpenGL ES _ 入门练习_05
OpenGL ES _ 入门练习_06
OpenGL ES _ 着色器 _ 介绍
OpenGL ES _ 着色器 _ 程序
OpenGL ES _ 着色器 _ 语法
OpenGL ES_着色器_纹理图像
OpenGL ES_着色器_预处理
OpenGL ES_着色器_顶点着色器详解
OpenGL ES_着色器_片断着色器详解
OpenGL ES_着色器_实战01
OpenGL ES_着色器_实战02
OpenGL ES_着色器_实战03

学习是一件开心的额事情
演示图

你不知道这个东西,请不要看了,请看我的其他文章先了解一下O!

学习目标

掌握着色器程序的执行过程


简单的例子

<code>

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;
}  

</code>
稍微解释一下:代码的作用是模拟重力加速度,对一个点的位置进行变换.


OpenGL /GLSL 程序接口

先上图

着色器创建流程

C语言,大家应该很熟悉吧! C 语言的编译过程步骤:
1.编译器检查错误
2.将他转换成目标代码(.o文件)
3.将一组目标文件进行链接,最后成为一个可执行文件

在OpenGL 程序中使用GLSL 着色器也是一个相似的过程,要在应用程序中使用顶点或者片段着色器需要按照顺序执行下面的步骤:
1.创建着色器对象
2.把着色器代码编译成源代码
3.验证是否着色器是否编译成功
为了把多个着色器对象链接起来,我们需要创建着色器程序
4.创建一个着色器程序
5.把着色器对象链接到这个着色器程序中
6.链接着色器
7.验证着色器链接阶段已经成功完成.
8.使用着色器进行顶点或者片段处理.


函数讲解 (用到的主要是C语法)


IOS 代码上一份方便大家理解

<code>
- (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;
    }

</code>

代码下载地址

点我下载

参考

OpenGL 编程指南>

上一篇 下一篇

猜你喜欢

热点阅读