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

C++ 为什么在OpenGL上创建着色器后需要分离和删除它们?,c++,opengl,C++,Opengl,下面是一个例子,它说链接程序后必须将着色器从程序中分离,然后必须删除它们 < P>并行地编译C++,直觉上,我想象“链接”是实际创建程序的动作(如在生成可执行文件时),即分离意味着在某种程度上删除一个指向着色器对象的指针(我想它类似于 .o>代码>)。(这还不是很清楚-此时程序不是一个已编译的可执行程序吗?它如何仍然保存指向某个对象的指针?)-删除就像从文件夹中删除那些.o 但是这些都是猜测,那么到底发生了什么呢?来自OpenGL文档: 如果要删除的着色器对象附加到程序对象,则会将其标记为删除,

下面是一个例子,它说链接程序后必须将着色器从程序中分离,然后必须删除它们

< P>并行地编译C++,直觉上,我想象“链接”是实际创建程序的动作(如在生成可执行文件时),即分离意味着在某种程度上删除一个指向着色器对象的指针(我想它类似于<代码> .o>代码>)。(这还不是很清楚-此时程序不是一个已编译的可执行程序吗?它如何仍然保存指向某个对象的指针?)-删除就像从文件夹中删除那些
.o

但是这些都是猜测,那么到底发生了什么呢?

来自OpenGL文档:

如果要删除的着色器对象附加到程序对象,则会将其标记为删除,但对于任何渲染上下文,在不再附加到任何程序对象之前,不会删除该着色器对象(即,在删除之前,必须将其从其附加的位置分离)


因此,这更像是减少引用计数器,而不是实际的删除。

如果您了解多个程序可以共享同一个着色器,这可能会有所帮助。如果仅仅是将其从程序中分离的行为就导致其被删除,那么OpenGL 4.1中的单独着色器对象之类的事情就会实现得更快

您还应该知道,链接真正指的是或多或少的验证。当着色器链接在一起以创建程序时,所有的输入/输出变量都是连接的,并且都被分配了标识符。当程序运行时,它用着色器填充图形管道的每个阶段。因此,实际上,程序的所有oes封装了多个着色器阶段

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


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

我认为这更像是使用:你有一个“对象”的实例(例如,一个共享指针),然后你把它传递给创建它的实例的OpenGL程序,现在你有两个实例共享一个对象。当你删除你的实例时,OpenGL的实例仍然指向该对象。