为什么在OpenGL上创建着色器后需要分离和删除着色器?

时间:2013-09-11 08:57:26

标签: c++ opengl

我正在关注this tutorial (link),它表示您必须在链接后将程序中的着色器分离,并且必须在此之后删除它们。

直截了当地编译C ++,我认为“链接”是实际创建程序(如在,制作可执行文件中)的行为, - 分离意味着以某种方式删除指针一个着色器对象(我想象它类似于.o,在程序中(它仍然不是很清楚 - 不是程序编译后的可执行文件)是什么?它如何仍然保存指针?) - 并且删除就像从文件夹中删除那些.o一样。

但这些都是猜测,那么实际发生了什么?

2 个答案:

答案 0 :(得分:9)

来自glDeleteShader上的OpenGL文档:

  

如果要删除的着色器对象附加到程序对象,它将被标记为删除,但它不会被删除,直到它不再附加到任何程序对象,对于任何渲染上下文(即,它必须在被删除之前与其所附的任何地方分开)

因此,它更像是递减参考计数器而不是实际删除。

答案 1 :(得分:3)

如果您了解多个程序可以共享同一个着色器,则可能会有所帮助。如果仅仅从程序中删除它会导致它被删除,那么OpenGL 4.1中的分离着色器对象就会更快地实现。

你还应该知道,真正引用的链接或多或少是验证。当着色器链接在一起以创建程序时,输入/输出变量全部连接并且使用的制服被分配标识符。程序运行时,它会使用着色器填充图形管道的每个阶段。所以实际上,程序所做的就是封装多个着色器阶段。

如果你研究ARB_separate_shader_objects扩展规范,它会更加清晰,它引入了程序管道对象的概念。您可以为每个阶段创建一个程序,而不是每个阶段都有一个带着色器的程序。整个GLSL程序方案总是有点迟钝,在大多数其他API中,每个阶段都有单独的着色器,并且没有这个程序链接无意义。

使用您的可执行程序类比。 GLSL着色器是实际的可执行文件,GLSL程序是有效的作业控制脚本。您的程序负责让每个着色器在各自的管道阶段运行,并作为传递变量(制服)的接口。