سؤال

I am working on an OpenGL ES 2 project on iOS to learn OpenGL ES 2. Online I found an Objective-C implementation for linking and compiling the shaders, and I used this implementation as a template for my own. Unfortunately, I mis-typed the line for uploading my texture data as glUniform1f instead of glUniform1i. Looked like this ...

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

My project has multiple objects with their own textures. This typo resulted in only the texture for the last drawn object being shown on all the objects. I suspected something was wrong with my texture IDs or similar, and so logged out the texture IDs and such at each draw call, and could not find anything wrong that way.

This was a really hard bug for me to find, and I would like to understand what was going on with this bug. My question is what is it about glUniform1f vs glUniform1i that would cause this behavior? I am a little surprised that the shaders didn't just fail to link and compile, or that any textures were drawn at all.

هل كانت مفيدة؟

المحلول

Uniforms are just (per-program) OpenGL state. The way you set the uniform values is completely independent of linking the shaders to a program object - the GL knows nothing about that at shader link time, the program just has a bunch of active uniforms and you can set them to anything you like at any time.

Uniforms always have a type. And you have to use the correct glUniform*() function matching the type of your uniform variable, otherwise the GL error GL_INVALID_OPERATION is generated (and the operation has no further effect). FOr sampler uniforms, you need to set the index of the texture unit as integer, hence glUniform1i() is the correct function, while glUniform1f() - which is for floats - will not work. As you did not set the uniform, the previous value of that uniform will be used - and it will be 0 if you never set it.

So what happened is that you sampled from the texure bound to texture unit GL_TEXTURE0, and not the one you wanted. You might use that texture unit when you create your textures, which would explain will there is still the "last" textture bound.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top