0%

OpenGL学习笔记(五)—— 着色器

GLSL

着色器是运行在 GPU 的小程序,用于渲染管线的特定阶段工作。着色器是使用 GLSL 语言编写的,其格式大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#version 版本号

in 数据类型 变量名;
in 数据类型 变量名;

out 数据类型 变量名;

uniform 数据类型 变量名;

void main()
{
// 处理过程
输出变量 = 处理结果;
}

其中:#version 用于指定使用的 OpenGL 对应的版本号;in 类型是用于输入的数据(也就是上一阶段的输出数据);out 类型是用于输出的数据(也就是下一阶段的输入数据);uniform 是全局数据类型,其作用是用于在 CPU 配置 GPU 的数据。

数据类型

GLSL 中包含默认基础数据类型:intfloatdoubleuintbool;以及两种容器类型: 向量(Vector)矩阵(Matrix)

向量

GLSL 中的向量是一个可以包含有 123 或者 4 个分量的容器;分量的类型是默认基础类型的任意一个;如下( n 代表分量的数量):

类型 含义
vecn 包含 nfloat 分量的默认向量
bvecn 包含 nbool 分量的向量
ivecn 包含 nint 分量的向量
uvecn 包含 nunsigned int 分量的向量
dvecn 包含 ndouble 分量的向量

Uniform

Uniform 是一种从 CPU 中的应用向 GPU 中的着色器发送数据的方式,且是全局唯一的。
使用方式:

  1. 获取 Uniform 变量在着色器程序中的位置(顶点着色器和片段着色器链接的着色器程序)。
  2. 通过 glUniform* 函数对其进行赋值。

创建着色器相关 API 简介。

glCreateShader

  1. 函数原型:GLuint glCreateShader(GLenum shaderType);
  2. 功能:创建一个空的着色器对象,并且返回一个引用的 ID;如果创建失败,则返回 0
  3. 参数说明:
    • shaderType:指定着色器类型
      • GL_COMPUTE_SHADER
      • GL_VERTEX_SHADER
      • GL_TESS_CONTROL_SHADER
      • GL_TESS_EVALUATION_SHADER
      • GL_GEOMETRY_SHADER
      • GL_FRAGMENT_SHADER

glShaderSource

  1. 函数原型:void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint *length);

  2. 功能:用于设置创建着色器的 GLSL 源码以供着色器编译使用。

  3. 参数说明:

    • shader:指定设置GLSL源码的着色器对象引用 ID。
    • count:指定GLSL源码字符串数组的元素个数(渲染的子元素)。
    • string:指定GLSL源码字符串数组指针。
    • length:指定GLSL源码字符串数组的长度。(设置为NULL则由系统计算。)
  4. 使用举例:

    1
    2
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

glCompileShader

  1. 函数原型:void glCompileShader(GLuint shader);
  2. 功能:依据添加的GLSL源码进行编译着色器。
  3. 参数说明:
    • shader:指定编译GLSL源码的着色器对象引用 ID。

glGetShaderiv

  1. 函数原型:void glGetShaderiv(GLuint shader, GLenum pname, GLint *params);

  2. 功能:查询着色器的相关编译信息。

  3. 参数说明:

    • shader:指定获取编译日志信息的着色器对象引用 ID。
    • pname:指定查询的日志信息类型。
      • GL_SHADER_TYPE
      • GL_DELETE_STATUS
      • GL_COMPILE_STATUS
      • GL_INFO_LOG_LENGTH
      • GL_SHADER_SOURCE_LENGTH
    • params:返回请求的对象参数,是否成功。
  4. 使用举例:

    1
    2
    GLint isSuccess;
    glGetShaderif(vertexShader, GL_COMPILE_STATUS, &isSuccess);

glGetShaderInfoLog

  1. 函数原型:void glGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog);

  2. 功能:获取着色器对象的相关信息。

  3. 参数说明:

    • shader:指定获取日志信息的着色器对象引用 ID。
    • maxLength:指定存储日志信息的缓冲最大长度。
    • length:返回日志信息的长度。
    • infoLog:指定用于接收日志信息的字符数组指针。
  4. 使用举例:

    1
    2
    GLchar infoLog[512];
    glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);

glCreateProgram

  1. 函数原型:GLuint glCreateProgram();
  2. 功能:创建一个着色器程序对象,并且返回一个引用的 ID;如果创建失败,则返回 0

glAttachShader

  1. 函数原型:void glAttachShader(GLuint program, GLuint shader);
  2. 功能:添加已编译的着色器对象着色器程序对象中。(可以添加任意数量的不同类型的着色器对象。)
  3. 参数说明:
    • program:指定目标着色器程序对象引用 ID。
    • shader:指定源着色器对象引用 ID。

glLinkProgram

  1. 函数原型:void glLinkProgram(GLuint program);
  2. 功能:链接所有已添加的着色器对象。(在链接时,每一个的输出都会对应于每一个着色器的输入,如果不符合时将会链接失败。)
  3. 参数说明:
    • program:指定需要链接的着色器程序对象引用 ID。

glGetProgramiv

  1. 函数原型:void glGetProgramiv(GLuint program, GLenum pname, GLint *param);

  2. 功能:查询着色器程序的相关链接信息。

  3. 参数说明:

    • program:指定获取链接日志信息的着色器程序对象引用 ID。
    • pname:指定查询的日志信息类型。(GL_LINK_STATUS 查询链接日志信息。)
    • params:返回请求的对象参数,是否成功
  4. 使用举例:

    1
    2
    GLint isSuccess;
    glGetProgramiv(program, GL_LINK_STATUS, &isSuccess);

glGetProgramInfoLog

  1. 函数原型:void glGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog);

  2. 功能:返回着色器程序对象的相关信息。

  3. 参数说明:

    • program:指定获取日志信息的着色器程序对象引用 ID。
    • maxLength:指定存储日志信息的缓冲最大长度。
    • length:返回日志信息的长度。
    • infoLog:指定用于接收日志信息的字符数组指针。
  4. 使用举例:

    1
    2
    GLchar infoLog[512];
    glGetProgramInfoLog(program, 512, NULL, infoLog);

glDeleteShader

  1. 函数原型:void glDeleteShader(GLuint shader)
  2. 功能:删除着色器对象。(建议:编译链接成功后的着色器进行删除操作,以清空缓存回收资源。)
  3. 参数说明:
    • shader:指定需要删除的着色器对象引用 ID。

Demo


参考资料

  1. learnopengl.com