I’m having some trouble understanding how texture binding really works. Of course it is simple when you’re dealing with just one texture, but when more textures come into play, the official documentation isn’t really clear on how the state changes.

First of all, how are the texture bindings represented in the state? I imagine it’s something similar to this, in pseudo-code:

I suppose that other targets are not updated? What about shader usage, are these two uniform variables referring to different texture targets in the same unit, or should I bind only one texture target to a given texture unit at a time?

What about shader usage, are these two uniform variables referring to different texture targets in the same unit, or should I bind only one texture target to a given texture unit at a time?

This is why I suggested that you forget that you can bind multiple textures to the same texture unit. But if you insist on knowing how this works:

Samplers in GLSL are typed. Each sampler type maps to a specific texture target. So for a given sampler uniform, the value assigned to the uniform tells which texture unit to pull data from, and the type of the sampler tells which target it gets data from.

However, OpenGL explicitly forbids you from assigning two uniforms of different sampler types to the same texture unit. I mean, you can do it, but if you try to render with that program, you either get GL_INVALID_OPERATION or undefined behavior (I’ve forgotten which).

This is why you should forget that this is possible; you can’t use it to do anything useful. So just pretend that every bind call to a texture unit also unbinds every other target from that texture unit.

That makes much more sense now, thanks. I was asking if it is possible because my GL wrapper optimizes away unnecessary command calls (as sending a command to the GPU is way more expensive than a simple if check), and I need to know what sort of state do I need to store client-side. My final wrapper isn’t going to permit this invalid behavior of assigning different targets to a single texture unit in the end anyways.

It seems pretty clearly described in “Textures (state per texture unit)”, Table 23.17 in GL4.6.

I don’t quite understand is how glBindTexture affects the state… I suppose that other targets are not updated?

Correct. You can easily verify this by introspecting the GL_TEXTURE_BINDING_* state described in that table.

What about shader usage, are these two uniform variables referring to different texture targets in the same unit, or should I bind only one texture target to a given texture unit at a time?

As Alfonse alluded, sampler uniforms can’t refer to the same unit if they have different types. So while you can bind (and TexImage etc) 2D and 3D to unit zero simultaneously, if you try to sample from them, it is an INVALID__OPERATION at draw time. See glValidateProgram and the relevant condition in the specification: “Any two active samplers in the set of active program objects are of different types, but refer to the same texture image unit.”

In the ancient pre-shader world, the glEnable state of the texture targets determined which target is actually sampled on each unit.