着色器子程序示例

来源:互联网 发布:python数组转字符串 编辑:程序博客网 时间:2024/06/04 20:04

在早期的GLSL里面,要实现函数分支选择,一般是使用if-else分支选择,虽然简单但也显得有些粗暴。
从GL 4.0开始,内核支持着色器子程序(subroutine)功能,这个功能有点类似函数指针,需要先顶一一个函数类型,然后实现N个这个类型的函数对象,最后使用Uniform的方式让用户指定运行时调用的函数。

#version 430 core  out vec4 fColor;  subroutine vec4 userColor();subroutine (userColor) vec4 Red(){    return vec4(1.0, 0.0, 0.0, 1.0);}subroutine (userColor) vec4 Green(){    return vec4(0.0, 1.0, 0.0, 1.0);}subroutine (userColor) vec4 Blue(){    return vec4(0.0, 0.0, 1.0, 1.0);}subroutine uniform userColor myColor;void main()  {      fColor = myColor();  }

这是一个简单的shader示例,第三行定义了一个函数指针类型,紧接着的是三个实现,最后是一个uniform变量,由程序指定具体值。

    GLint myColorLoc = glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "myColor");    if (myColorLoc < 0)    {        exit(EXIT_FAILURE);    }    GLuint RedIndex;    GLuint GreenIndex;    GLuint BlueIndex;    RedIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Red");    GreenIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Green");    BlueIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Blue");    if (RedIndex == GL_INVALID_INDEX ||         GreenIndex == GL_INVALID_INDEX ||         BlueIndex == GL_INVALID_INDEX)    {        exit(EXIT_FAILURE);    }    GLsizei n;    glGetProgramStageiv(program, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &n);    GLuint *indices = new GLuint[n];    indices[myColorLoc] = BlueIndex;    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);    delete [] indices;

首先使用glGetSubroutineUniformLocation函数获取子程序的Uniform的位置,之后使用glGetSubroutineIndex函数来获取子程序的索引号,两个都拿到之后,先查询一下现在激活的子程序的Uniform的个数,因为glUniformSubroutinesuiv函数的第二个传入参数就是它。glUniformSubroutinesuiv的第三个传入参数是一个GLuint的数组,数组长度由前一个参数n指定,第i个子程序Uniform的子程序对应于indices[i]的值。

subroutine

修改indices[myColorLoc]为不同的子程序索引,就能调用相应的函数。

0 0
原创粉丝点击