2014-05-15 51 views
2

我正在开发iOS上的OpenGL ES 2项目来学习OpenGL ES 2.在线我发现了一个用于链接和编译着色器的Objective-C实现,并且我使用这个实现作为我自己的模板。不幸的是,我错误地键入上传我的纹理数据为glUniform1f而不是glUniform1i。看起来像这样...glUniform1f vs glUniform1i混淆

glActiveTexture(GL_TEXTURE1);     
glBindTexture(GL_TEXTURE_2D, self.texture); 
glUniform1f(_texUniform, 1);  // this line should be glUniform1i 

我的项目有自己的纹理多个对象。这个错字导致所有对象上只显示最后绘制的对象的纹理。我怀疑我的纹理ID或类似的东西有问题,因此在每次绘制调用时注销了纹理ID等,并且找不到任何错误。

这是一个很难找到的错误,我想了解这个错误是怎么回事。我的问题是glUniform1f vs glUniform1i会导致这种行为?我有点惊讶,着色器不仅没有链接和编译,也没有绘制任何纹理。

回答

4

Uniformas只是(每个程序)OpenGL状态。您设置统一值的方式完全独立于将着色器链接到程序对象 - GL在着色器链接时对此一无所知,该程序只有一堆活动制服,您可以将它们设置为任何您喜欢的任何内容时间。

制服总是有一个类型。并且必须使用与您的统一变量类型匹配的正确的glUniform*()函数,否则会生成GL错误GL_INVALID_OPERATION(并且操作不再有效果)。对于采样器制服,您需要将纹理单元的索引设置为整数,因此glUniform1i()是正确的函数,而glUniform1f() - 这是浮点数 - 将不起作用。因为你没有设置制服,所以这套制服的以前的价值将被使用 - 如果你从未设置,它将会是0。

所以发生了什么是你从纹理单元GL_TEXTURE0,而不是你想要的纹理采样。你可以在创建纹理时使用该纹理单元,这将解释是否仍然存在“最后”的纹理边界。

+0

谢谢 - 现在有道理。 – dloranz