着色器子程序示例

原创 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是这样一种机制:它根据某个变...
  • pizi0475
  • pizi0475
  • 2012年09月01日 19:36
  • 1779

【OpenGL】GLSL中的函数和子程序(subroutines)

这篇文章里讲一下在GLSL如何使用函数和子程序(subroutines)。 在GLSL中使用函数 GLSL支持函数,它们的语法结构和C很相似。但是调用约定会有所不同。下面,我们以一个普通的...
  • candycat1992
  • candycat1992
  • 2013年05月25日 09:55
  • 10127

用着色器编写第一个程序

我们用着色编写画一个三角形    #include //#include #include #include #include #include #include #include #include...
  • zhouyelihua
  • zhouyelihua
  • 2014年10月14日 11:00
  • 1261

着色器编程实验指导

  • 2017年12月11日 20:06
  • 123KB
  • 下载

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

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

[UnityShader2]顶点片段着色器实例(三)

参考链接: 1.漫反射
  • lyh916
  • lyh916
  • 2015年06月11日 11:28
  • 1479

OpenGL着色器的使用总结

1.把着色器写到文本文件中,以便在程序中读取调用shader.vert;shader.fragment 2.用读文件的方式把两个着色器中的代码读到字符串中 3.新建shader对象,判断创建是否成...
  • hudfang
  • hudfang
  • 2015年10月16日 19:07
  • 1519

ABAQUS学习记录1——用户子程序综述

一级标题ABAQUS提供了相当丰富的单元类型,材料属性等数据库可供用户选择,但是工程问题是千变万化的,为了满足用户的特殊工程要求,ABAQUS为用户提供了强大而又灵活的用户子程序接口(USER SUB...
  • sinat_33528967
  • sinat_33528967
  • 2016年07月23日 11:49
  • 3550

子程序(过程、函数、方法)

一般程序设计语言包含两种基本的抽象:过程抽象和数据抽象。过程抽象有时也称控制抽象。   子程序在1950年以前就发明了,作为一种抽象那时候并未被完全接受。相反,最初它被看做是一种节省代码的...
  • bytxl
  • bytxl
  • 2015年09月08日 09:12
  • 1303

OpenGL着色器介绍

本文主要介绍如何使用OpenGL实现着色器程序,首先会简单介绍着色器在OpenGL渲染管线中是什么个位置,接着是介绍可以通过GLSL语言实现的两类着色器:顶点着色器和片段着色器,最后使用OpenGL实...
  • caoshangpa
  • caoshangpa
  • 2016年12月04日 17:56
  • 2126
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:着色器子程序示例
举报原因:
原因补充:

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