Quick OpenGL newbie question. I have this line in my fragment shader:
uniform sampler2D mytexture;
I grepped into the sample code I'm using and I couldn't find any reference to mytexture
; only found calls which activate a texture unit and bind a texture to it that was previously copied to the GPU.
My question is, how does the fragment shader know that the only texture I'm using has to be referred via mytexture
?
I would have thought a
glBindTextureToUniform(texture_id, "mytexture");
or similar had to be called.
The mapping is between the texture unit and the uniform but not the texture, as concept3d mentions. The reason for this discrepancy is multi-texturing.
Texturing units is the machinery in OpenGL to facilitate multi-texturing. When you want multiple textures to be looked-up in your shaders, you bind each to a different texture unit (actually you bind it to a target within the unit) and have different uniforms for each to refer them to in a shader. Each texturing unit has multiple targets like 1D, 2D, 3D, etc.
The texture looked-up in the shader, through the uniform, refers to the unit. Its type (e.g. sampler2D
) decides the target in the unit that is used. Here is how the mapping is
uniform sampler2D mytexture; | | | | | +--->GL_TEXTURE0 / UNIT 0 GL_TEXTURE1 / UNIT 1 GL_TEXTURE2 / UNIT 2 | +--------------------+ +--------------------+ +--------------------+ | | +------------+ | | +------------+ | | +------------+ | | | | TEXTURE_1D | | | | TEXTURE_1D | | | | TEXTURE_1D | | | | +------------+ | | +------------+ | | +------------+ | | | +------------+ | | +------------+ | | +------------+ | +---------------->| TEXTURE_2D | | | | TEXTURE_2D | | | | TEXTURE_2D | | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | … | | TEXTURE_3D | | | | TEXTURE_3D | | | | TEXTURE_3D | | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | |TEX_1D_ARRAY| | | |TEX_1D_ARRAY| | | |TEX_1D_ARRAY| | | +------------+ | | +------------+ | | +------------+ | | . | | . | | . | | . | | . | | . | | . | | . | | . | +--------------------+ +--------------------+ +--------------------+
It's to these targets (the inner boxes) to which you upload the texture data from an image or a table, etc. The active unit, if not set explicitly, is by default GL_TEXTURE0
.
how does the fragment shader know that the only texture I'm using has to be referred via mytexture in the fragment shader?
It's better to set the uniform with the unit ID. If you did not and it still works, then you are depending on the forgiving behaviour of your graphics driver. It may not work on all devices or even a future version of the driver. We will have to look up the spec. to know if this is allowed.