The vertex shader only accepts the texture coordinates as a vertex attribute and forwards the coordinates to the fragment shader. By default, it will also guarantee that the fragment will receive the properly interpolated coordinate based on its position in a triangle:
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoordIn;
out vec2 texCoordOut;
void main()
{
gl_Position = vec4(position, 1.0f);
texCoordOut = texCoordIn;
}
The fragment shader then accepts the texCoord
output variable as an input variable. You can then add a texture to the fragment shader by declaring a uniform sampler2D
. To sample a fragment of the texture we use a built-in function texture
which has two parameters. First is the texture we want to sample from and the second is the coordinate of this texture:
in vec2 texCoordOut;
out vec4 color;
uniform sampler2D image;
void main()
{
color = texture(image, texCoordOut);
}
Note that image
isn't the direct texture id here. It's the id of the texture unit that will be sampled. In turn, textures aren't bound to programs directly; they are bound to texture units. This is achieved by first making the texture unit active with glActiveTexture
, and then calling glBindTexture
will affect this particular texture unit. However, since the default texture unit is texture unit 0
, programs using one texture can be made simpler omitting this call.