我正在iOS上开发一个OpenGL ES 2项目来学习OpenGL ES 2.在线我发现了一个用于链接和编译着色器的Objective-C实现,我将这个实现用作我自己的模板。不幸的是,我错误地输入了将纹理数据上传为glUniform1f而不是glUniform1i的行。看起来像这样......
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, self.texture);
glUniform1f(_texUniform, 1); // this line should be glUniform1i
我的项目有多个具有自己纹理的对象。这个错字导致只有最后绘制的对象的纹理显示在所有对象上。我怀疑我的纹理ID或类似物有问题,所以在每次绘制调用时都记录了纹理ID等,并且找不到任何错误。
这是一个非常难以找到的错误,我想了解这个错误发生了什么。我的问题是glUniform1f vs glUniform1i会导致这种行为吗?我有点惊讶的是着色器没有链接和编译,或者根本没有绘制任何纹理。
答案 0 :(得分:4)
Uniformas只是(每程序)OpenGL状态。设置统一值的方式完全独立于将着色器链接到程序对象 - 在着色器链接时GL不知道任何内容,程序只有一堆活动的制服,你可以将它们设置为你喜欢的任何东西时间。
制服总有一种类型。并且您必须使用与统一变量类型匹配的正确glUniform*()
函数,否则将生成GL错误GL_INVALID_OPERATION
(并且操作没有进一步的效果)。对于采样器制服,您需要将纹理单元的索引设置为整数,因此glUniform1i()
是正确的函数,而glUniform1f()
- 用于浮动 - 将不起作用。由于您没有设置制服,因此将使用该制服的先前值 - 如果您从未设置它,它将为0。
所以发生的事情是你从绑定到纹理单元GL_TEXTURE0
的纹理中采样,而不是你想要的那个。您可以在创建纹理时使用该纹理单元,这可以解释是否仍然存在“最后”文本绑定。