glGetActiveUniformName的意外行为
Unexpected behavior of glGetActiveUniformName
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之前没有以前的错误,并且使用有效的bufSize和uniformName调用它都成功且没有错误,并按预期写入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
来完成此操作。
我已经更正了维基上的文档。
- 在C++中对T*类型执行std::move的意外行为
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 处理除以零会导致<csignal>意外行为
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 使用vscode调试时,GDB意外退出
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 尝试将字符串/字符转换为整数会产生意外结果
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- C++标头错误 C2238 意外标记";"
- C++中意外的多头值
- vector.size() 在比较中意外工作
- 使用 malloc() 时出现意外大小
- 多线程程序中出现意外的内存泄漏
- 为什么static_cast基础类型的枚举类int8_t获得意外值?
- 字符串比较中的意外输出
- 我的代码中的意外价值以及我如何修复它
- C++ 编译错误:意外的类型名称"字符串":预期的表达式