演示图

你不知道这个东西,请不要看了,请看我的其他文章先了解一下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 _ 着色器_程序相关推荐

  1. OpenGL ES _ 着色器_片断着色器详解

    OpenGL ES _ 入门_01 OpenGL ES _ 入门_02 OpenGL ES _ 入门_03 OpenGL ES _ 入门_04 OpenGL ES _ 入门_05 OpenGL ES ...

  2. OpenGL ES像素着色器

    OpenGL ES像素着色器 原文   http://www.tairan.com/archives/7509 目 录 准备开始 像素着色器 vs 顶点/片段着色器 像素着色器101:渐变 像素着色器 ...

  3. OpenGL ES像素着色器教程

    OpenGL ES像素着色器教程 时间 2014-08-27 09:54:51   泰然 原文   http://www.tairan.com/archives/7509 主题  OpenGL ES ...

  4. 【OpenGL ES】着色器Shader与程序Program

    在OpenGL ES 3程序中,Shader和Program是两个重要的概念,至少需要创建一个顶点Shader对象.一个片段Shader对象和一个Program对象,才能用着色器进行渲染,理解Shad ...

  5. Opengl ES之着色器

    前言 在前面我们介绍了 OpenglEs之EGL环境搭建 ,在后面的例子中,我们将无可避免地需要使用到着色器.而着色器才是Opengl的灵魂所在,有了着色器才有了Opengl天马行空的世界. 图形渲染 ...

  6. 【我的OpenGL学习进阶之旅】着色器和程序(上)------着色器

    着色器和程序 一.前言 二.着色器和程序 2.1 创建和编译一个着色器 2.1.1 创建着色器 2.1.2 删除着色器 2.1.3 提供着色器源代码 2.1.4 编译色器 2.1.4 查询有关着色器对 ...

  7. OpenGL ES (三)着色器和程序

    OpenGL ES学习系列文章: 上一篇:OpenGL ES (二)EGL介绍和使用 下一篇:OpenGL ES (二)EGL介绍和使用 着色器和程序 前言 1.创建Shader 2.加载Shader ...

  8. Learn OpenGL(七)——OpenGL中使用着色器的基本步骤及GLSL渲染简单示例

    OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...

  9. 【《WebGL编程指南》读书笔记——着色器和程序对象的准备】

    本文为<WebGL编程指南>第九章下半部分读书笔记 总目录链接:https://blog.csdn.net/floating_heart/article/details/124001572 ...

最新文章

  1. Google 多任务学习框架 MMoE
  2. icem密度盒怎么设置_seo中关键词密度的问题
  3. [Python从零到壹] 十一.数据分析之Numpy、Pandas、Matplotlib和Sklearn入门知识万字详解(1)
  4. 【转】2.4SharePoint服务器端对象模型 之 访问网站和列表数据(Part 4)
  5. toj 4613 Number of Battlefields
  6. 宏程序自动生成软件_【软件】宏程序自动生成器V3.0下载
  7. NSNotFound
  8. 2015与2016年终总结
  9. 真实感水体渲染技术总结
  10. 计算机求和便捷应用,4种常用求和方法 | Excel自动求和全攻略!
  11. 1.2. Linear and Quadratic Discriminant Analysis(线性判别和二次判别分析)(一)
  12. 能和机器划拳,猜中你的表情,百度开了一家超好玩的“AI体验店”
  13. 怎么教你如何查看电脑的蓝牙版本【解决方案】
  14. Studio 3T的使用
  15. 游戏元素属性的设计原则
  16. 时间序列平稳性的统计检验
  17. 打印Excel工作表时忽略打印区域
  18. 官方免费的正版Xshell,人人都可以马上拥有
  19. php去掉字符串带逗号前面的字符,php 怎么去掉字符串最后一个逗号
  20. 三农数据(1996-2020)十六:农产品进出口、农村居民纯收入、消费支出及结构

热门文章

  1. 在plsql里面怎么去掉空行_PLSQL基本操作手册.doc
  2. linux vfs 根节点名称,Linux:文件,目录项,索引节点,超级块,VFS,具体文件系统...
  3. Java用户修改密码
  4. 刀片服务器显示连接线,通过浏览器对刀片服务器进行管理
  5. js调用python接口_JavaScript如何调用Python后端服务
  6. oracle数据库9i安装,Oracle 9i数据库服务器的安装和辅助软件安装教程
  7. 没有bug队——加贝——Python 练习实例 17,18
  8. 计算机组成原理AB什么运算,计算机组成原理运算器实验.doc
  9. loadRunner安装及使用步骤
  10. 【Android】Android Studio中新创建的app目录结构