OpenGL(八)使用 subroutine 切换可编程管线
Subroutine 功能是在OpenGL 4.0 版本号里才添加的。因此对于各种Android手机。这个功能基本跪了。假设你发现你的程序报错:ARB_shader_subroutine。那就说明当前显卡不支持。只是大体思路能够了解一下。由于思路相似的功能有其它的实现方式。
原理
在shader中声明一个函数变量,然后定义它的指针,并将其作为一个uniform变量公开出去。最后定义非常多复写函数就可以。
实现
由于版本号限制。使用 subroutine 要注意在shader中添加版本号的编译宏:
#version 400 core
在shader中编写:
subroutine vec4 SurfaceColor();
subroutine uniform SurfaceColor U_SurfaceColor; subroutine (SurfaceColor) vec4 Ambient()
{
//...
} subroutine (SurfaceColor) vec4 Diffuse()
{
//...
} subroutine (SurfaceColor) vec4 Specular()
{
//...
} void main()
{
gl_FragColor = U_SurfaceColor();
}
在shader中,每个函数中的代码段代表一种处理函数。
还有一方面在GL指令中,绑定这个函数指针,并为其指定实现函数的索引值,就可以实现效果的控制。
surfaceColorLocation = glGetSubroutineUniformLocation(program,GL_FRAGMENT_SHADER,"U_SurfaceColor"); GLuint ambientLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Ambient");
GLuint diffuseLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Diffuse");
GLuint specularLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Specular"); //draw
glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&ambientLightIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
总结
本文介绍了OpenGL中的 subroutine 机制,通过它能够切换shader的内容。在Unity3d中使用Shader.maximumLOD技术能够达到相似的效果,相关内容能够參考官方文档
关注我的微信公众号,获取很多其它优质内容
OpenGL(八)使用 subroutine 切换可编程管线的更多相关文章
- GPU的历史:从固定管线到可编程管线再到通用计算平台
开始的时候GPU不能编程,也叫固定管线的,就是把数据按照固定的通路走完. 和CPU同样作为计算处理器,顺理成章就出来了可编程的GPU,但是那时候想在GPU上编程可不是容易的事,你只能使用GPU汇编来写 ...
- QT_OPENGL-------- 4.可编程管线绘制三角形
一.环境:qt下qmake编译首先在qt .pro文件中添加glew和glfw的链接 LIBS+= -L/usr/lib64 -lGLEW LIBS +=-L/usr/local/lib -lglfw ...
- MFC+OpenGL可编程管线
[github链接] 网上的代码大都是固定管线渲染的,今天下午整理了下,把setPixelFormat.初始化glew.创建GL 4,2 context等操作封装到一个MFC类OpenGLWidget ...
- Android学习指南之三十八:Android手势操作编程[转]
手势操作在我们使用智能设备的过程中奉献了不一样的体验.Android开发中必然会进行手势操作方面的编程.那么它的原理是怎样的呢?我们如何进行手势操作编程呢? 手势操作原理 首先,在Android系统中 ...
- 图解Python 【第八篇】:网络编程-进程、线程和协程
本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...
- Python开发【第八篇】:网络编程 Socket
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- 读书笔记_Effective_C++_条款四十八:了解模板元编程
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...
- python【第八篇】socket网络编程
内容大纲 1.socke基础 两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建 立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API ...
- JavaScript八张思维导图—编程风格
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
随机推荐
- nginx基于tcp负载均衡
官方参考文档:http://nginx.org/en/docs/stream/ngx_stream_core_module.html 只有nginx1.9以上的版本才支持tcp负载均衡 配置必须出现在 ...
- react native native module
React Native Native Modules,官方地址:https://facebook.github.io/react-native/docs/native-modules-android ...
- ceph 安装记录
ceph 安装 http://docs.ceph.com/docs/master/start/quick-ceph-deploy/ 1. 系统要求 centos 7 systemctl disable ...
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- ReentrantLock和ReentrantReadWriteLock对比
本文系作者原创,转载请注明:https://www.cnblogs.com/yanfei1819/p/10314533.html ReentrantLock 一.简介 ReentrantLock重入锁 ...
- 洛谷P4587 [FJOI2016]神秘数(主席树)
题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...
- 洛谷——P2381 圆圆舞蹈
P2381 圆圆舞蹈 题目描述 熊大妈的乃修在时针的带领下,围成了一个圆圈舞蹈,由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时针 ...
- DBCS 从256开始
ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是一套基于拉丁字母的字符编码,共收录了 128 个字符,用一个字 ...
- sql 常见错误
notFound = 1403L; .dupKey = -1L; openCloseErr = -2117L; cursorNotOpenErr = -1002L; .nullCursor = -14 ...
- BZOJ 4443 [Scoi2015]小凸玩矩阵(二分答案+二分图匹配)
[题目链接]http://www.lydsy.com/JudgeOnline/problem.php?id=4443 [题目大意] 从矩阵中选出N个数,其中任意两个数字不能在同一行或同一列 求选出来的 ...