glGetActiveUniformName的意外行为

Unexpected behavior of glGetActiveUniformName

本文关键字:意外 glGetActiveUniformName      更新时间:2023-10-16

glGetActiveUniformName是一个函数,可用于根据文档查询GLSL制服的名称长度。这可以通过将uniformName设置为NULL(0)并提供GLsizei指针作为length的out变量来实现。执行此操作时,会期望在length参数中返回统一名称的长度,但如上所述调用函数后,此变量保持不变。给出了一个错误,即GL_INVALID_VALUE,根据文档,它可能意味着三件事之一:

GL_INVALID_VALUE is generated if uniformIndex is greater than or equal to the value of GL_ACTIVE_UNIFORMS.
GL_INVALID_VALUE is generated if bufSize is negative.
GL_INVALID_VALUE is generated if program is not the name of a program object for which glLinkProgram has been issued.

在我的情况下,uniformIndex为0,GL_ACTIVE_UNIFORMS报告为5bufSize故意设置为0,因此不能为负数。在使用的程序上使用GL_LINK_STATUS调用glGetProgram将返回GL_TRUE(1)。这排除了导致此错误的所有3个已知原因。根据glGetError,在调用glGetActiveUniformName之前没有以前的错误,并且使用有效的bufSizeuniformName调用它都成功且没有错误,并按预期写入uniformName中的缓冲区;正确书写制服的名字。

除了没有报告制服名称的长度和错误之外,还有其他令人不安的迹象;如果bufSize设置为大于零的正值,并且uniformName为NULL(0),则函数仍会写入uniformName,这可能会导致严重的内存损坏。这种行为也不符合规范,规范规定如果uniformName为NULL(0),则不应向其写入任何内容。

把上面的所有信息放在一起,我想我可以放心地得出结论,我的代码中没有错误,但我自己的代码之外有一个错误,这就是我在这里发帖的原因。如上所述使用时,是否有人可以验证此函数的行为?

我认为这很可能是一个驱动程序问题,这意味着只有运行nVidia驱动程序/硬件的人才会看到这个问题,但现在排除任何用户组还为时过早。

附言:上述情况发生在一台运行最新驱动程序(专门为验证上述语句而更新)并安装了nVidia GeForce 660 GTX的机器上。该机器是一台运行64位Windows 7 Professional SP1的Dell XPS 8500。该程序是使用Visual Studio 2012 Professional生成的,已完全更新。这篇文章也发布到了英伟达开发者论坛和DevMaster上,发布在这里是为了更好地曝光,并希望更快地解决这个问题。

更新1:有问题的代码在另一台使用不同GPU(nVidia GeForce 9600M GT)的机器上进行了测试,再次使用了最新的驱动程序,并获得了相同的结果。此计算机正在运行64位Windows 7 Ultimate SP1。二进制文件也是用VS2012构建的。

这里的文档似乎是错误的。OpenGL规范在这里非常清楚:length表示实际写入缓冲区的字符数。此外,规范不要求对uniformName参数进行任何NULL检查。

或者,换句话说,您不能使用glGetActiveUniformName来获取制服名称的长度。您必须使用glGetActiveUniform来完成此操作。

我已经更正了维基上的文档。