2012-02-02 130 views
47

我的代码以某种方式接近GLSL着色器管理,它创建每个着色器和相关程序并删除每个着色器和程序。最近,我读http://www.opengl.org/wiki/GLSL_Object它就在那里说:正确的方法来删除GLSL着色器?

Shader对象,由于被附加到程序对象,将 继续即使你删除Shader对象存在。当系统不再附加到任何程序 对象(当用户要求删除它时),系统只会删除 。

如果我在连接到程序后在着色器对象上调用glDeleteShader(),我只需要跟踪程序吗?假设这总是正确的,是否安全?

回答

56

是的 - 事实上,它是非常渴望尽快分离和删除着色器对象。这样,驱动程序可以释放它用来存放着色器源代码和未链接目标代码的所有内存,这些代码可能相当实用。测量我已经做了指示不删除着色器对象通过5到10倍

+1

即使已经给出了相同的建议,实际记忆参数和测量结果为+1。 – 2012-02-02 18:14:01

+14

虽然根据[文档](http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml)所述,您所说的是正确的(“在链接操作之后,应用程序可以自由修改所连接的着色器对象,编译附加着色器对象,分离着色器对象,删除着色器对象以及附加其他着色器对象。“),我遇到了一些不喜欢它的不喜欢它的不喜欢它,尤其是在移动平台上。因为与此有关的问题让我感到沮丧了好几天,所以我建议你不要在之后分离着色器一个链接(删除很好) – 2013-07-28 03:55:13

+4

问题是,只要删除着色器而不分离它,可能不会释放内存 - 它可能只是递减一个引用计数,直到你分离着色器才会变为0。着色器仍然附着,用户可能再次调用链接来重新链接程序,所以驱动程序需要保持足够的信息来做到这一点。所以你需要权衡内存使用与潜在的问题,破坏驱动程序... – 2013-08-28 17:33:32

6

是的。然后您可以安全地删除着色器。事实上,这是首选的方式,因为你的维护较少。您无需跟踪要删除的内容,也不会忘记这么做。而且,它仍然有效。

“删除”着色器,与所有 OpenGL的对象,只是设置一个标志,上面写着不需要它了。 OpenGL会在它自己需要它的时候保持它的状态,并且会在随后的任何时候执行实际的删除操作(最有可能,但不一定是在程序被删除后)。

+1

事实上,你甚至可以在链接后分离着色器(它们实际上只包含完全进入程序的代码),所以它们会立即被删除。 – 2012-02-02 15:00:00

13

通常,着色器对象管理的工作方式很简单。着色器对象实际上并不是做的,所以根本没有必要跟踪它们。着色器对象应该存在足够长的时间才能成功链接程序对象。在此之后,着色器应该从程序中分离出来并删除。

上面假设您不想使用着色器对象与其他程序链接,当然。这当然是可能的。在这种情况下,应该在链接所有程序后删除着色器对象。

3

增加了每个着色器增量内存使用简单:后glLinkProgram()呼叫glDeleteShader()每个着色器,这标志着他们删除,不再需要程序的时候调用glDeleteProgram() - 这个调用不仅会删除程序,而且会将所有着色器分离并删除它们(如果没有被其他程序使用)。因此通常你不必打电话glDetachShader()。 阅读glDeleteProgram()的文档。