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 切换可编程管线相关推荐
- 从固定管线到可编程管线:十段代码入门OpenGL
文章目录 1. 最简单的OpenGL应用程序 2. 视点系统和投影矩阵 3. 深度缓冲区和深度测试 4. 模型的旋转和平移 5. VBO和顶点混合数组 6. 纹理映射和纹理坐标 7. 光照和法向量计算 ...
- Windows进程与线程学习笔记(八)—— 线程切换与TSS/FS
Windows进程与线程学习笔记(八)-- 线程切换与TSS/FS 要点回顾 线程切换与TSS 内核堆栈 调用API进0环 实验:分析SwapContext 线程切换与FS 段描述符结构 分析Swap ...
- 【OS学习笔记】二十九 保护模式八:任务切换对应的汇编代码之用户程序代码
本汇编代码对应以下两篇文章对应的用户程序汇编代码: [OS学习笔记]二十六 保护模式八:任务门-任务切换 [OS学习笔记]二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中 ...
- 【OS学习笔记】二十八 保护模式八:任务切换对应的汇编代码之内核代码
本汇编代码对应以下两篇文章对应的内核汇编代码: OS学习笔记]二十六 保护模式八:任务门-任务切换 [OS学习笔记]二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套 ...
- OpenGL(可编程管线):Bezier曲面
Bezier曲面 Bezier线 de Casteljau算法 Bezier曲面 bezier曲面编程思想 实例 代码 运行结果 Bezier线 贝塞尔曲线由一组参数方程定义,方程组中使用控制点指定特 ...
- 基于Qt的OpenGL可编程管线学习(9)- X射线
X射线也就是轮廓线,效果如下图所示 原理:物体表面的法线与人眼睛缩成的角度为90度时,刚好能看到物体的轮廓 Fragment shader代码如下: uniform sampler2D U_MainT ...
- 基于Qt的OpenGL可编程管线学习(14)- 正片叠底、逆正片叠底
1.正片叠底 shader // 正片叠底 uniform sampler2D U_MainTexture; uniform sampler2D U_SubTexture;varying vec2 M ...
- OpenGL(可编程管线):椭圆的绘制和贴图
和绘制圆一样的思路,八分法绘制椭圆,借助上面的参数方程,以原点为(0,0)为例,上代码: 椭圆的绘制 构建椭圆类 代码解释 运行结果 情况一:长轴在x轴 情况二:长轴在y轴 情况三:长轴等于短轴(圆) ...
- Python开发【第八篇】:网络编程 Socket
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
最新文章
- OCP-052 053部分答案解析
- memcached java 多线程_springboot使用memcache缓存
- java中的session对象,Java对象中Response与session对象的方法是什么?
- 设计模式 分类和原则
- linux下安装nvm进行node的版本的快速切换
- Kubernetes集群安全概述
- 借助云开发轻松实现后台数据批量导出丨实战
- ant压缩和解压缩工具类
- 爬虫python代码网易云_python-网易云简单爬虫
- 电泳涂装行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- linux glance删除命令,OpenStack Glance v2 API任意文件删除漏洞(CVE-2012-5482)
- Atitit Atitit 零食erp数据管理---世界著名零食系列数据.docx世界著名零食
- 阿里云keepalived的虚拟ip怎么让外网访问_Nginx之Keepalived高可用工具
- 面试被问到平衡二叉树如何平衡?
- 【20140205】曼昆著《经济学原理》读书笔记
- vue 用echarts写的进度条组件
- 火车头采集html文档没内容,火车头采集器:编辑任务中常见问题
- 修改Win10右键菜单
- 前端处理blob文件流
- Linux之安装Nginx(安装包方式)