《OpenGL编程指南(原书第9版)》——2.7 独立的着色器对象

2.7 独立的着色器对象

高级技巧
在OpenGL 4.1版本之前(不考虑扩展功能),在应用程序中,同一时间只能绑定一个着色器程序。如果你的程序需要使用多个片元着色器来处理来自同一个顶点着色器的几何体变换数据,那么这样会变得很不方便。此时只能将同一个顶点着色器复制多份,并且多次绑定到不同的着色器程序,从而造成了资源的浪费和代码的重复。
独立的着色器对象可以将不同程序的着色阶段(例如顶点着色)合并到同一个程序管线中。
第一步,我们需要创建用于着色器管线的着色器程序。我们可以调用glProgramParameteri()函数并且设置参数为GL_PROGRAM_SEPARABLE,然后再链接着色器程序。这样该程序就被标识为在程序管线中使用。如果想要简化这个过程,还可以直接使用新增的glCreateShaderProgramv()来封装着色器编译过程,并且将程序标识为可共享(如上文所述),然后链接到最终的对象。
将着色器程序集合合并之后,就需要用这个新的着色器管线结构来合并多个程序中的着色阶段。对于OpenGL中的大部分对象来说,都有一个生成-绑定-删除的过程,以及对应可用的函数。着色器管线的创建可以调用glCreateProgramPipelines(),即创建一个未使用的程序管线标识符,然后将它传入glBindProgramPipeline(),使得该程序可以自由编辑(例如,添加或者替换着色阶段)和使用。与其他生成的对象相似,程序管线可以通过glDeleteProgramPipelines()来删除。
当绑定了一个程序管线之后,可以调用glUseProgramStages()将之前标记为独立的程序对象关联到管线上,它通过位域的方式来描述该管线处理几何体和着色片元时,给定程序所处的着色阶段。而之前的glUseProgram()只能直接调用一个程序并且替换当前绑定的程序管线。
为了确保管线可以使用,着色器阶段之间的接口—in和out变量—也必须是匹配的。非独立的着色器对象在程序链接时就可以检查这些接口的匹配情况,与之相比,使用独立程序对象的着色器管线只能在绘制–调用过程中进行检查。如果接口没有正确匹配,那么所有的可变变量(out变量)都未定义。
内置的gl_PerVertex块必须重新声明,以便显式地指定固定管线接口中的哪些部分可以使用。如果管线用到了多个程序,那么这一步是必需的。
例如:

这样我们就建立了着色器的输出接口,它将用于后继的管线阶段当中。这里必须使用gl_PerVertex自己的内置成员。如果不同的着色器程序都用到了同一个内置的块接口,那么所有的着色器都必须使用相同的方式重新声明这个内置的块。
因为独立的着色器对象可以有各自独立的程序uniform集合,所以我们可以使用两种方法来设置uniform变量的值。第一种方法是通过glActiveShaderProgram()来选择一个活动的着色器程序,然后调用glUniform()和glUniformMatrix()来设置某个着色器程序的uniform变量的值。另一种推荐的方法是调用glProgramUniform()和glProgramUniformMatrix()函数,它们有一个显式的program对象参数,这样可以独立地设置某个程序的uniform变量的值。
void glProgramUniform{1234}{fdi ui}(GLuint program, GLint location, TYPE value);
void glProgramUniform{1234}{fdi ui}v(GLuint program, GLint location, GLsizei count, const TYPE* values);
void glProgramUniformMatrix{234}{fd}v(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLf?loat* values);
void glProgramUniformMatrix{2x3,2x4,3x2,3x4,4x2,4x3}{fd}v( GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLf?loat* values);
glProgramUniform()和glProgramUniformMatrix()函数的使用与glUniform()和glUniformMatrix()的使用是一样的,唯一的区别是使用一个program参数来设置准备更新uniform变量的着色器程序。这些函数的主要优点是,program可以不是当前绑定的程序(即最后一个使用glUseProgram()指定的着色器程序)。

时间: 2024-09-17 03:52:08

《OpenGL编程指南(原书第9版)》——2.7 独立的着色器对象的相关文章

《OpenGL编程指南》一2.7 独立的着色器对象

2.7 独立的着色器对象 高级技巧在OpenGL 4.1版本之前(不考虑扩展功能),在应用程序中,同一时间只能绑定一个着色器程序.如果你的程序需要使用多个片元着色器来处理来自同一个顶点着色器的几何体变换数据,那么这样会变得很不方便.此时只能将同一个顶点着色器复制多份,并且多次绑定到不同的着色器程序,从而造成了资源的浪费和代码的重复.独立的着色器对象可以将不同程序的着色阶段(例如顶点着色)合并到同一个程序管线中.第一步,我们需要创建用于着色器管线的着色器程序.我们可以调用glProgramPara

《面向对象的思考过程(原书第4版)》一1.2 对象及遗留系统

本节书摘来自华章出版社<面向对象的思考过程(原书第4版)>一书中的第1章,第1.2节,[美] 马特·魏斯费尔德(Matt Weisfeld) 著 1.2 对象及遗留系统 在面向对象成为主流之前,开发人员面临的问题一直就是如何将新的面向对象技术与现有的系统集成起来.面向对象与结构化(或命令式)编程之间拥有明显的界限,而结构化编程当时则是主流的开发范式.而我始终反对面向对象和结构化编程是不兼容的这一观点,因为我认为面向对象与结构化编程绝不是互斥的.它们是互补的,因为对象可以与结构化代码很好地集成.

《面向对象的思考过程(原书第4版)》一3.6 对象操作

本节书摘来自华章出版社<面向对象的思考过程(原书第4版)>一书中的第3章,第3.6节,[美] 马特·魏斯费尔德(Matt Weisfeld) 著黄博文 译更多章节内容可以访问"华章计算机"公众号查看. 3.6 对象操作 当处理复杂的数据结构和对象时,编程中的很多最基本的操作会变得越来越复杂.例如,当你想复制或比较原始数据类型时,过程非常简单.然而,复制和比较对象则并不简单.<Effective C++>第34页中,Scott Meyers专门花了整个小节来讲述复

《Java语言导学(原书第6版)》一一2.1 对象

2.1 对象对象是理解面向对象技术的关键概念.生活中有很多对象的例子,如狗.桌子.电视机.自行车等.生活中的对象都有两个共同的属性:状态和行为.狗有名字.颜色.品种等状态,以及犬吠.抓东西.摇尾巴等行为.自行车有当前档位.当前脚踏频率.当前速度等状态和换档.变换踏板频率.刹车等行为.根据面向对象编程的思路来确定生活中对象的状态和行为是很好的方法.前面已经介绍了生活中的几个对象.对每个对象,都有两个问题:"它处于什么状态"和"它会发生什么行为".仔细观察并写下这些状态

《Java语言导学(原书第6版)》一2.1 对象

2.1 对象 对象是理解面向对象技术的关键概念.生活中有很多对象的例子,如狗.桌子.电视机.自行车等.生活中的对象都有两个共同的属性:状态和行为.狗有名字.颜色.品种等状态,以及犬吠.抓东西.摇尾巴等行为.自行车有当前档位.当前脚踏频率.当前速度等状态和换档.变换踏板频率.刹车等行为.根据面向对象编程的思路来确定生活中对象的状态和行为是很好的方法.前面已经介绍了生活中的几个对象.对每个对象,都有两个问题:"它处于什么状态"和"它会发生什么行为".仔细观察并写下这些状

《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.4 对象输入/输出流与序列化

2.4 对象输入/输出流与序列化 当你需要存储相同类型的数据时,使用固定长度的记录格式是一个不错的选择.但是,在面向对象程序中创建的对象很少全部都具有相同的类型.例如,你可能有一个称为staff的数组,它名义上是一个Employee记录数组,但是实际上却包含诸如Manager这样的子类实例. 我们当然可以自己设计出一种数据格式来存储这种多态集合,但是幸运的是,我们并不需要这么做.Java语言支持一种称为对象序列化(object serialization)的非常通用的机制,它可以将任何对象写出到

《信息可视化:交互设计(原书第2版)》——2.10节显著对象

2.10 显著对象对象间不同关系的显示有助于消费者的决策判断.消费者的心目中通常有一辆理想的汽车.虽然当前可能没有这辆车,但还是可以用同样的方式将这辆理想汽车(图2-7)描述出来.为了避免混淆,应该使用一个特别的图标以示区分.这样,所有可选汽车和理想汽车之间的关系就可以得到视觉呈现.可选汽车图标和理想汽车图标之间的距离代表了它们和理想汽车之间的差异.同样的,一辆汽车可以成为"备选项"并得到某种形式的标注(图2-8),从而减低存储该信息的需求.

《信息可视化:交互设计(原书第2版)》——2.6节交互式对象选择

2.6 交互式对象选择在研究价格总图前,消费者可能会偶然地在一组汽车图片(图2-3)中看到一辆特别有吸引力的汽车,然后就会很自然地查询这辆车的价格以及更多的细节(detail)信息.虽然价格可以直接标注在图片下方,但是在可能多于10个的属性中只标出价格不一定是合理的.一种解决办法是,用价格条形图上方的图标来表示该车在条形图中的位置.为了用同样的方式标示出所有汽车,可以在条形图上方创建一个如图2-4 所示的"对象向量"(object vector).对象向量同样可以立即显示出每个价格段中

《OpenGL编程指南(原书第9版)》——导读

前言 OpenGL图形系统是图形硬件的一种软件接口(GL表示Graphics Library,即图形库).它使得用户可以创建交互式的程序以产生运动的三维对象的颜色图像.通过OpenGL,我们可以使用计算机图形学技术产生逼真的图像,或者通过一些虚构的方式产生虚拟的图像.这本指南将告诉你如何使用OpenGL图形系统进行编程,得到你所期望的视觉效果. 本书的主要内容 本书中包含以下章节: 第1章对OpenGL可以完成的工作进行了概览.它还提供了一个简单的OpenGL程序并解释了一些本质性的编程细节,它