2012-02-02 2 views
47

Мой код приближается к управлению шейдерами GLSL в том смысле, что он создает каждый шейдер и связанную с ним программу и удаляет каждый шейдер и программу. Я недавно прочитал http://www.opengl.org/wiki/GLSL_Object и там говорится, что:Правильный способ удаления шейдеров GLSL?

Объект шейдер, благодаря привязываясь к программному объекту, будет продолжать существовать, даже если вы удалите объект затенения. Будет удалено только системой, если она больше не привязана к какой-либо программе объект (и когда пользователь попросил его удалить, конечно).

Могу ли я получить это правильно, если я позвоню glDeleteShader() на объекте шейдера после установления связи с программой, нужно только следить за программу? Можно ли предположить, что это всегда верно?

ответ

56

Да - на самом деле очень желательно отсоединить и удалить ваши шейдерные объекты как можно скорее. Таким образом, драйвер может освободить всю память, которую он использует, для хранения копии источника шейдера и несвязанного объектного кода, что может быть весьма существенным. Измерения, которые я сделал, показывают, что НЕ удаление объектов шейдерных увеличивает добавочную использование памяти на шейдер по 5-10 раз

+1

Даже если его, конечно, та же самая рекомендация уже дана, +1 для аргумента практической памяти и измерений. –

+14

Несмотря на то, что вы говорите правильно в соответствии с [документацией] (http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml) («После операции с ссылкой приложения могут изменять прикрепленные шейдеры объекты, компилировать прикрепленные шейдерные объекты, отделять объекты шейдеров, удалять объекты шейдеров и присоединять дополнительные шейдерные объекты.»), Я столкнулся с некоторыми недобросовестными драйверами, которым это не нравится, когда вы отсоединяете шейдеры, особенно на мобильных платформах. Поскольку проблема, связанная с этим, оставила меня расстроенным в течение нескольких дней, я бы рекомендовал вам НЕ отделять шейдеры после ссылка (удаление в порядке). –

+4

Проблема в том, что просто удаление шейдера без отсоединения может не освободить память - это может просто уменьшить счетчик ссылок, который не будет идти до 0, пока вы не отсоедините шейдер. шейдер все еще подключен, пользователь может снова позвонить по ссылке, чтобы повторно подключиться к программе, поэтому драйверу нужно обходиться достаточно информации, чтобы сделать это. Поэтому вам нужно обменяться использованием памяти с потенциальными проблемами на сломанных драйверах ... –

6

Да. Тогда вы можете безопасно удалить шейдер. На самом деле это предпочтительный способ, потому что у вас меньше обслуживания. Вам не нужно отслеживать, что нужно удалить, и вы не можете забыть это сделать. И он все равно будет работать.

«Удаление» шейдер, как и с всех OpenGL объектов, просто устанавливает флаг, который говорит вы не нужно больше. OpenGL будет поддерживать его до тех пор, пока он сам понадобится, и будет выполнять фактическое удаление в любое время позже (скорее всего, но не обязательно, после удаления программы).

+1

Фактически вы можете даже отсоединить шейдеры после связывания (они на самом деле содержат только код, который затем полностью входит в программу), поэтому они сразу же удаляются. –

13

В общем, способ управления объектами шейдеров прост. Объекты Shader действительно не do ничего, поэтому нет никакого смысла их отслеживать. Объекты Shader должны существовать достаточно долго, чтобы успешно связать программный объект. По истечении этого времени шейдеры должны быть отделены от программы и удалены.

Вышеупомянутое предполагает, что вы не пытаетесь использовать объект шейдера для связи с другой программой, конечно. Это, безусловно, возможно. В этом случае вы должны удалить свои шейдерные объекты после того, как вы связали все свои программы.

3

Вкратце: после glLinkProgram() вызова glDeleteShader() для каждого шейдера, это не помечает их на удаление и когда программа больше не нужна вызов glDeleteProgram() - этот вызов не только удаляет программу, но также отделяет все прикрепленные к ней шейдеры и удаляет их (если не используется какой-либо другой программой).

Так что обычно вам не нужно когда-либо звонить glDetachShader(). Прочитайте документы для glDeleteProgram().

Смежные вопросы