着色器子程序示例

原创 2015年11月21日 18:51:50

在早期的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]为不同的子程序索引,就能调用相应的函数。

版权声明:本文为博主原创文章,未经博主允许不得转载。

GLSL-使用Subroutines选择着色器功能

http://blog.csdn.net/xiajun07061225/article/details/7664336     在GLSL中,subroutine是这样一种机制:它根据某个变...

OpenGl中使用着色器的基本步骤及GLSL渲染简单示例

OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行是在G...
  • dcrmg
  • dcrmg
  • 2016年12月14日 23:34
  • 4559

OpenGL(二十四) VAO、VBO和着色器使用示例

1. 新建一个工程,新建一个头文件Shader.h,内容如下: #ifndef _SHADER_H_ #define _SHADER_H_ #include #include #incl...
  • dcrmg
  • dcrmg
  • 2016年12月06日 23:33
  • 639

DirectX11 顶点着色器示例

顶点着色器示例 下面是一个顶点着色器的示例,它的代码非常简单:cbuffer cbPerObject { float4x4 gWVP; };void VS(float3 iPosL : PO...

OpenGL 着色器语言+源码

  • 2017年11月07日 11:51
  • 48B
  • 下载

Android OpenGLES2.0(七)——着色器语言GLSL

在前面的博客中,我们都使用到了片元着色器和顶点着色器,相信我们对着色器语言有了一点了解。前面我们所使用的着色器,代码非常简单,能做的事情非常有限,而在后面的博客中我们将会用到的着色器的越来越复杂,所以...
  • junzia
  • junzia
  • 2016年10月16日 16:07
  • 3846

Unity着色器和屏幕特效开发秘笈

  • 2016年09月10日 21:21
  • 3.5MB
  • 下载

第二节 WebGL中着色器语言(GLSL ES)的简介

本篇的内容讲述了有关着色器的一些基础知识,以及着色器的创建和编译。
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:着色器子程序示例
举报原因:
原因补充:

(最多只允许输入30个字)