OpenGL 文档glUseProgram
声称使用零参数调用它会导致着色器执行的结果为undefined
.
然而,经过一番搜索后,我看到了一些人们glUseProgram
用来卸载当前着色器程序的例子。
这种行为可靠吗?如果不是,那么具体是glUseProgram(0)
做什么的?
OpenGL 文档glUseProgram
声称使用零参数调用它会导致着色器执行的结果为undefined
.
然而,经过一番搜索后,我看到了一些人们glUseProgram
用来卸载当前着色器程序的例子。
这种行为可靠吗?如果不是,那么具体是glUseProgram(0)
做什么的?
glUseProgram
表示给定的程序对象是将用于使用程序(glUniform
、渲染命令等)的当前程序。0 很像NULL
OpenGL 对象。它不代表一个对象(对于大多数对象)。因此,glUseProgram(0)
意味着没有程序是当前的,因此没有程序将用于使用程序的事物。
glUniform
如果您在没有当前程序的情况下尝试调用这些函数,它们将失败并出现错误。如果您尝试在没有当前程序时进行渲染,则会发生以下两种情况之一。在 OpenGL 3.1+ 核心配置文件中,您将获得未定义的行为,因为核心 OpenGL必须使用程序进行渲染。在兼容性配置文件或版本 3.0 或更低版本中,您将获得固定功能渲染。
与这里和其他地方的许多答案相反,glUseProgram(0)
不会恢复到固定功能模式。以这种方式使用它是不安全的。您可以使用它将渲染状态设置为无效的程序对象,但如果在渲染发生时它仍然绑定到 this,则行为是undefined。
从文档:
“如果程序为零,则当前渲染状态指的是无效的程序对象,着色器执行的结果是
undefined
”
因此,结果完全特定于操作系统、驱动程序和显卡。在许多情况下,它似乎恢复到固定功能模式,但这不是规范中定义的,不应依赖。它可以很容易地保留最后一个着色器、渲染垃圾或导致段错误(我已经看到这种情况发生)。
它告诉 OpenGL 使用固定功能管道。
一旦您使用glUseProgram(myShader)
所有后续渲染,将使用着色器 ID 完成myShader
。
如果您每次在 a 中进行重大更改时都调用它modern openGL 3.1+
,那么 . 几乎没有用处glUseProgram(0)
。
但是,如果您打算在其中集成一些固定功能渲染,例如glVertex3f(..)
,那么glUseProgram(0)
将确保最后使用的着色器不再处于活动状态,并且它将使用固定功能管道,例如glColor3f(...)