OpenGL ES 3.0入门之顶点着色器和程序介绍

96
半城coding
2018.08.16 15:35 字数 1457

原文地址: https://lm1024.xyz/archives/108

着色器

本文主要介绍顶点着色器和片段着色器在脚本执行过程是怎样被执行的。一般着色器包括两种(顶点着色器和片段着色器)每一个着色器从在程序运行的过程中都会经历 创建 -->加载 --> 编译 --> 创建着色程序--->将编译好的着色器连接到着色程序上---> 链接程序对象 --> 使用 的过程

image

统一变量和属性

统一变量——是存储应用程序通过OpenGL ES 3.0 API 传递给着色器的只读常数值的变量
1、命名统一变量块
概念:统一变量的值由统一变量缓冲区支持,会分配一个统一变量块索引
示例:


image

2、默认统一变量块
概念:在命名统一变量块之外的统一变量
示例:


image

3、 获取和设置统一变量
查询程序中活动统一变量的列表流程:

  • 使用glGetProgramiv获取统一变量的数量
  • 使用glGetProgramiv获取着色程序中最大统一变量名称的字符数
  • 使用glGetActiveUniform获取统一变量的细节
  • 使用glGetUniformLocation获取统一变量的位置
  • 加载统一变量的值,方法太多 后面会统一整理到一个API 附录中
GLint maxUniformLen;
GLint numUniforms;
char * uniformName;
GLint indenx;

glGetProgramiv (progObj, GL_ACTIVE_UNIFORMS, &numUniforms);
glGetProgramiv (progObj, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLen);

uniformName = malloc ( sizeof(char) * maxUniformLen);

for (index = 0; index < numUniforms; index++)
{
    GLint size;
    GLenum type;
    GLint locationl

    glGetActiveUniform (progObj, index, maxUniformLen, NULL, &size, &type, uniformName);

    location = glGetUniformLocation (progObj, uniformName);

    switch (type)
    {
        case GL_FLOAT:
            break;
        case GL_FLOAT_VEC2:
            break;
        default:
            break;
     }
}

4、统一对象缓冲区
定义:
使用缓冲区对象存储统一变量数据,从而在程序中的着色器之间甚至程序之间共享统一变量,这种缓冲区对象称作统一缓冲区对象
作用:
可以更新打的统一变量时降低API开销,增加统一变量的可用存储
统一变量在内存中的形式:

  • 类型为bool、int、uint和float成员保存在内存的特定偏移,分别记作为单个bool、int、unit和float的类型分量
  • 类型为bool、int、uint和float成员的向量保存在始于特定便宜的连续内存位置中,第一个分类在最低偏移处
  • C列R行的列优先矩阵被当成C浮点列向量的一个数据对待,每个向量包含R个分量
  • R行C列的行优先矩阵被当成R浮点向量的一个数组,每个向量包含C个分量
  • 标量、向量和矩阵的数组按照元素的顺序存储与内存中,成员0放在最低偏移处,数组中没对元素之间的偏移量是一个常数称作为数据跨距,可以在链接的程序中用glGetActiveUniformsiv查询

5、 std140布局

  • 标量变量 : 基线堆积是标量的大小,例如sizeof(GLint)
  • 2分量向量 : 基线对齐是基础分类类型大小的两倍
  • 3分量或者4分量向量 : 基线对齐是基础分量类型大小的4倍
  • 标量或者向量数组 : 基线对齐和数组跨距设置为匹配单元素数数组的基线对齐,整个数组被填充为vec4大小的倍数
  • C列R行的列优先矩阵 : 根据规整4,存储为一个右C个具有R个分类的向量组成的数组
  • M个C列R行的列有限矩阵组成的数组 : 根据规则4,存储为由M * C 个具有R个分量的向量组成的数组
  • C列R行的行优先矩阵 : 根据规则4,存储为一个由R个向量组成的数组,其中每个乡里有C个分量
  • M个C列R行的行优先矩阵 : 根据规则4,存储为由M*R个具有C个分量的向量组成的数组
  • 单个结构 : 根据前面的规则计算偏移和大小。结构的大小将填充为vec4大小的倍数
  • S个结构组成的数组 : 基线对齐根据数组元素的基线计算对齐,数组的元素根据『单个结构』规则计算

着色器编译器

当我们执行『shader创建编译过程』后可以调用glReleaseShaderCompiler释放掉着色器所占用的系统资源

程序二进制码

思考: 我们在执行了『shader创建编译过程后』能不能将我们编译好的着色程序保存程文件?
答案: 答案是可以的,程序二进制码是完全变一盒链接的程序的二进制表现形式。它们很有用,可以保存到文件系统供以后使用,conger避免在线编译的代价。也可以直接使用编译好的程序二进制码,这样没有必要在实现中分发这着色器源代码

流程:

  • 执行『shader编译链接』后使用 glGetProgramBinary检索程序二进制码
  • 使用glprogramBinary将其保存到文件系统,或者将程序二进制码读回OpenGL ES 实现

写在最后

都是概念真的不知道写点什么,把作者的总结贴上来吧

在本章节中,我们介绍了创建、编译和链接着色器到程序的方法。着色对象和程序对象组成了OpenGL ES 3.0中的基本对象。我们讨论了如何查找程序对象的信息以及加载统一变量的方法。此外,还学习了着色器源代码和程序二进制码的差别以及各自的使用方法。

Objective-c 学习
Web note ad 1