3

glGetActiveUniformName 是一个函数,可用于根据文档查询 GLSL 统一的名称长度。这可以通过将uniformName设置为 NULL (0) 并将GLsizei指针作为 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 报告为 5。bufSize故意设置为 0,因此不能为负数。在使用的程序上使用 GL_LINK_STATUS 调用 glGetProgram 会返回 GL_TRUE (1)。这排除了此错误的所有 3 个已知原因。根据 glGetError 在调用 glGetActiveUniformName 之前没有先前的错误,并使用有效的bufSizeuniformName调用它都成功且没有错误,并按预期写入uniformName中的缓冲区;正确书写制服的名称。

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

将上面的所有信息放在一起,我想我可以有把握地得出结论,我的代码中没有错误,而是在我自己的代码之外的某个地方出现了错误,这就是我在这里发布的原因。如上所述使用时,是否有人可以验证此功能的行为?

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

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

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

4

1 回答 1

2

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

或者,换一种说法,您不能使用glGetActiveUniformName来获取制服名称的长度。你必须这样做glGetActiveUniform

我已经更正了 wiki 上的文档

于 2013-02-19T23:34:14.270 回答