You have to set the texture swizzling parameters, to treat OpenGL to read the green and blue color channel from the red color channel, when the texture is looked up - see glTexParameteri
:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED );
See OpenGL 4.6 API Compatibility Profile Specification; 16.1 Texture Environments and Texture Functions; page 595:
They are derived by computing the
base color Cb and Ab from the filtered texture values Rt, Gt, Bt, At, Lt, and It as shown in table 16.1, ...
Texture Base Texture base color Internal Format Cb Ab
...
RED (Rt, 0, 0) 1
RG (Rt, Gt, 0) 1
RGB (Rt, Gt, Bt) 1
RGBA (Rt, Gt, Bt) At
Table 16.1: Correspondence of filtered texture components to texture base components.
...followed by swizzling the components of Cb, controlled by the values of the texture parameters TEXTURE_SWIZZLE_R
, TEXTURE_SWIZZLE_G
, TEXTURE_SWIZZLE_B
, and TEXTURE_SWIZZLE_A
. If the value of TEXTURE_SWIZZLE_R
is denoted by swizzler, swizzling computes the first component of Cs according to
if (swizzler == RED)
Cs[0] = Cb[0];
else if (swizzler == GREEN)
Cs[0] = Cb[1];
else if (swizzler == BLUE)
Cs[0] = Cb[2];
else if (swizzler == ALPHA)
Cs[0] = Ab;
else if (swizzler == ZERO)
Cs[0] = 0;
else if (swizzler == ONE)
Cs[0] = 1; // float or int depending on texture component type
If you would use a shader program, it would be possible to do something similar in the fragment shader, by Swizzling:
in vec3 uv;
out vec4 frag_color;
uniform sampler2D u_texture;
void main()
{
frag_color = texture(u_texture, uv).rrra;
}