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 切换可编程管线相关推荐

  1. 从固定管线到可编程管线:十段代码入门OpenGL

    文章目录 1. 最简单的OpenGL应用程序 2. 视点系统和投影矩阵 3. 深度缓冲区和深度测试 4. 模型的旋转和平移 5. VBO和顶点混合数组 6. 纹理映射和纹理坐标 7. 光照和法向量计算 ...

  2. Windows进程与线程学习笔记(八)—— 线程切换与TSS/FS

    Windows进程与线程学习笔记(八)-- 线程切换与TSS/FS 要点回顾 线程切换与TSS 内核堆栈 调用API进0环 实验:分析SwapContext 线程切换与FS 段描述符结构 分析Swap ...

  3. 【OS学习笔记】二十九 保护模式八:任务切换对应的汇编代码之用户程序代码

    本汇编代码对应以下两篇文章对应的用户程序汇编代码: [OS学习笔记]二十六 保护模式八:任务门-任务切换 [OS学习笔记]二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中 ...

  4. 【OS学习笔记】二十八 保护模式八:任务切换对应的汇编代码之内核代码

    本汇编代码对应以下两篇文章对应的内核汇编代码: OS学习笔记]二十六 保护模式八:任务门-任务切换 [OS学习笔记]二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套 ...

  5. OpenGL(可编程管线):Bezier曲面

    Bezier曲面 Bezier线 de Casteljau算法 Bezier曲面 bezier曲面编程思想 实例 代码 运行结果 Bezier线 贝塞尔曲线由一组参数方程定义,方程组中使用控制点指定特 ...

  6. 基于Qt的OpenGL可编程管线学习(9)- X射线

    X射线也就是轮廓线,效果如下图所示 原理:物体表面的法线与人眼睛缩成的角度为90度时,刚好能看到物体的轮廓 Fragment shader代码如下: uniform sampler2D U_MainT ...

  7. 基于Qt的OpenGL可编程管线学习(14)- 正片叠底、逆正片叠底

    1.正片叠底 shader // 正片叠底 uniform sampler2D U_MainTexture; uniform sampler2D U_SubTexture;varying vec2 M ...

  8. OpenGL(可编程管线):椭圆的绘制和贴图

    和绘制圆一样的思路,八分法绘制椭圆,借助上面的参数方程,以原点为(0,0)为例,上代码: 椭圆的绘制 构建椭圆类 代码解释 运行结果 情况一:长轴在x轴 情况二:长轴在y轴 情况三:长轴等于短轴(圆) ...

  9. Python开发【第八篇】:网络编程 Socket

    Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

最新文章

  1. OCP-052 053部分答案解析
  2. memcached java 多线程_springboot使用memcache缓存
  3. java中的session对象,Java对象中Response与session对象的方法是什么?
  4. 设计模式 分类和原则
  5. linux下安装nvm进行node的版本的快速切换
  6. Kubernetes集群安全概述
  7. 借助云开发轻松实现后台数据批量导出丨实战
  8. ant压缩和解压缩工具类
  9. 爬虫python代码网易云_python-网易云简单爬虫
  10. 电泳涂装行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  11. linux glance删除命令,OpenStack Glance v2 API任意文件删除漏洞(CVE-2012-5482)
  12. Atitit Atitit 零食erp数据管理---世界著名零食系列数据.docx世界著名零食
  13. 阿里云keepalived的虚拟ip怎么让外网访问_Nginx之Keepalived高可用工具
  14. 面试被问到平衡二叉树如何平衡?
  15. 【20140205】曼昆著《经济学原理》读书笔记
  16. vue 用echarts写的进度条组件
  17. 火车头采集html文档没内容,火车头采集器:编辑任务中常见问题
  18. 修改Win10右键菜单
  19. 前端处理blob文件流
  20. Linux之安装Nginx(安装包方式)

热门文章

  1. 初三物理光学知识点总结_初中物理光学知识点总结
  2. RabbitMQ—发布消息确认和消费消息确认
  3. leetcode-滑动窗口/双指针/哈希表
  4. 转:干货 :手把手教你Tableau高级数据分析功能(附数据集)
  5. 显示某个区域2,蒙板
  6. 医疗基本知识之医嘱篇(三)医嘱中药物、药品、处方的处理
  7. Perf的安装与简单使用
  8. 哪些行业需要用到高防服务器
  9. JP-Word简谱编辑 V4.35官方正式版
  10. 校办研修之计算机培训简报,我校举办“智慧课堂教学模式与实践专题研修班”...