在调试我的系统时,我发现我使用的所有着色器都从未编译过。所有 GLSL 程序都愉快地链接在一起,并且工作得非常顺利。
我已在整个代码库中搜索了对 glCompileShader
的调用,但没有找到。
我的问题是:这是我正在使用的实现的特定行为吗?链接程序时是否隐式执行着色器编译?是可选的吗?如果是这种情况,除了检索错误日志之外,显式执行此操作还有什么优点?
我在文档中找不到像我这样的案例,如果我遗漏了某些内容,您能指出吗?
我的供应商是 NVIDIA(驱动程序 337.88)
编辑:另外,我不使用glCreateShaderProgram()
,而只是使用glCreateProgram()
创建着色器程序。
最佳答案
这大部分在评论中得到了解决(感谢@Andon、@derhass 和其他人),但由于这是一个有趣的问题,让我在答案中总结一下,并添加更多数据。
不考虑预编译着色器,您需要在使用 glLinkProgram()
链接程序之前通过调用 glCompileShader()
来编译着色器。根据我收集的数据,跳过 glCompileShader()
调用可以正常工作:
- Windows 8.1 下的 NVIDIA GeForce GT 740M。
- Linux 下的 NVIDIA(来自 @derhass)。
- Windows 8 下的 NVIDIA GeForce GT 620M(来自 @cifz)
它失败了:
- Windows 8.1 下的 Intel HD 4600。
- Mac OS 10.9.2 下的 Intel Iris。
- iOS 7.1 下的 iPad Air。
- 两台不同的 Android 平板电脑。
因此,这种行为显然与 NVIDIA 无关。规范指出,在链接之前编译着色器是必要的。从 3.3 规范来看:
Linking will also fail if one or more of the shader objects, attached to program are not compiled successfully.
4.4 规范不太明确,将可能的错误条件转换为以下开头的列表:
Linking can fail ...
通常can表明行为是可选的,但我不确定这是否是这里的意图。在我看来,规范只是重新格式化了,预期的行为并没有改变。所以恕我直言,这是一个错误。这不是一个非常严重的问题,因为所有合法使用仍然有效,但我不认为 NVIDIA 所做的事情严格遵循规范。
无论如何,在 glLinkProgram()
之前调用 glCompileShader()
对于代码跨平台工作是必要的。
关于opengl - glCompileShader 是可选的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24171290/