删除GLSL着色器的正确方法?

rio*_*oki 49 opengl glsl

我的代码以这种方式接近GLSL着色器管理,它创建每个着色器和相关程序并删除每个着色器和程序.我最近阅读了http://www.opengl.org/wiki/GLSL_Object,并指出:

由于附加到程序对象,着色器对象即使删除着色器对象也将继续存在.只有在系统不再附加到任何程序对象时(当用户要求删除它时),它才会被系统删除.

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

Chr*_*odd 59

是的 - 事实上,非常希望尽快分离和删除着色器对象.这样,驱动程序可以释放它用来保存着色器源和未链接目标代码副本的所有内存,这可能非常重要.我所做的测量表明,不删除着色器对象会使每个着色器的增量内存使用量增加5-10倍

  • 虽然根据[文档](http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml)所说的是正确的("在链接操作之后,应用程序可以自由修改附加的着色器对象,编译附加的着色器对象,分离着色器对象,删除着色器对象,并附加其他着色器对象."),我遇到了一些在分离着色器时不喜欢它的不良行为,特别是在移动平台上.由于与此相关的问题让我感到沮丧几天,我建议你不要在链接后分离着色器(删除很好). (14认同)
  • 问题是只是删除着色器而不分离它可能不会释放内存 - 它可能只是递减一个引用计数,在你分离着色器之前它不会变为0.只要着色器仍然连接,用户可能会再次调用链接以重新链接程序,因此驱动程序需要保留足够的信息来执行此操作.因此,您需要在内存使用方面与破坏的驱动程序上的潜在问题进 (4认同)

Nic*_*las 13

通常,着色器对象管理的工作方式很简单.着色器对象实际上没有做任何事情,因此跟踪它们毫无意义.着色器对象应该存在足够长的时间才能成功链接程序对象.在此之后,着色器应与程序分离并删除.

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


Dam*_*mon 6

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

所有 OpenGL对象一样,"删除"着色器只会设置一个标记,表示不再需要它.只要它本身需要,OpenGL就会保留它,并且会在以后的任何时候进行实际的删除(最有可能,但不一定,在程序被删除后).


小智 5

简而言之:在glLinkProgram()调用glDeleteShader()每个着色器之后,这会将它们标记为删除,并且当不再需要该程序时调用glDeleteProgram()- 此调用不仅会删除程序,还会分离所有附加到它的着色器并删除它们(如果没有被任何其他程序使用) )。

所以通常你不必调用glDetachShader(). 阅读glDeleteProgram().