Что делает glUseProgram (0)?

Документы OpenGL для glUseProgram утверждают, что вызов его с аргументом нуля приведет к тому, что результаты выполнения шейдера будут undefined.

Однако после небольшого поиска я увидел пару примеров людей, использующих glUseProgram для удаления текущей шейдерной программы.

Является ли это поведение надежным? Если нет, то что именно делает glUseProgram(0)?

Ответы

Ответ 1

glUseProgram означает, что данный программный объект является текущей программой, которая будет использоваться для вещей, которые используют программы (glUniform, команды рендеринга и т.д.). 0 во многом напоминает NULL для объектов OpenGL. Он представляет not an object (для большинства объектов). Поэтому glUseProgram означает, что никакая программа не является текущей, поэтому программа не будет использоваться для программ, которые используют программы.

Если вы пытаетесь вызвать функции glUniform, когда никакая программа не указана, они будут сбой с ошибкой. Если вы попытаетесь выполнить рендеринг, когда никакая программа не будет текущей, произойдет одна из двух.

  • В OpenGL 3.1+, основном профиле, вы получите ошибку GL_INVALID_OPERATION, так как основной OpenGL должен выполнить рендеринг с помощью программы.
  • В профилях совместимости или версии 3.0 или менее вы получите рендеринг с фиксированной функцией.

Ответ 2

В отличие от многих ответов здесь и в других местах, glUseProgram (0) небезопасен. Вы можете использовать его для установки состояния рендеринга на недопустимый программный объект, но если он все еще связан с этим при рендеринге, поведение undefined.

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

Из doc:

"Если программа равна нулю, то текущее состояние рендеринга относится к недействительный программный объект и результаты выполнения шейдера undefined"

Поэтому результаты полностью специфичны для ОС, драйверов и видеокарты. Во многих случаях он возвращается в режим фиксированной функции. Тем не менее, он может так же легко сохранить последний шейдер, отобразить мусор или вызвать segfault (я видел, как это произошло).

Ответ 3

Он сообщает OpenGL использовать конвейер с фиксированной функцией.

Ответ 4

После использования glUseProgram(myShader) весь последующий рендеринг будет выполнен с использованием идентификатора шейдера myShader.

Если вы вызываете это каждый раз, когда у вас есть изменение материала в modern openGL 3.1+, использование glUseProgram(0) мало используется.

Однако, если вы планируете интегрировать рендеринг фиксированной функции там, например glVertex3f(..), то glUseProgram(0) будет следить за тем, чтобы последний используемый шейдер больше неактивен, и он будет использовать конвейер фиксированной функции, например glColor3f(...)