Texture Combiners: Difference between revisions
No edit summary |
|||
Line 1: | Line 1: | ||
Texture combiners became core in GL 1.3. You can combine by multiplying, replacing, adding, subtracting, DOT3 product.<br> | Texture combiners became core in GL 1.3. You can combine by multiplying, replacing, adding, subtracting, or doing a DOT3 product.<br> | ||
GL 1.4 added to the core a crossbar feature. This means that you sample GL_TEXTUREX from any other texture image unit (TIU).<br> | GL 1.4 added to the core a crossbar feature. This means that you sample GL_TEXTUREX from any other texture image unit (TIU).<br> | ||
For example, at TUI 4, you can sample GL_TEXTURE0 or GL_TEXTURE1 or GL_TEXTURE2 or GL_TEXTURE3.<br> | |||
The examples here also show the equivalent shader code in GLSL to encourage people to use shaders instead of the fixed pipeline.<br> | |||
<br> | <br> | ||
=== Example : multiply tex0 and tex1 === | === Example : multiply tex0 and tex1 === | ||
The keyword here is GL_MODULATE, which does the actual multiplication. | |||
glActiveTexture(GL_TEXTURE0); | glActiveTexture(GL_TEXTURE0); | ||
glBindTexture(GL_TEXTURE_2D, textureID0); | glBindTexture(GL_TEXTURE_2D, textureID0); | ||
Line 12: | Line 15: | ||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | ||
//Sample RGB, multiply by previous texunit result | //Sample RGB, multiply by previous texunit result | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); //Modulate RGB with RGB | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | ||
Line 18: | Line 21: | ||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | ||
//Sample ALPHA, multiply by previous texunit result | //Sample ALPHA, multiply by previous texunit result | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); //Modulate ALPHA with ALPHA | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | ||
Line 40: | Line 43: | ||
=== Example : Blend tex0 and tex1 based on a blending factor you supply === | === Example : Blend tex0 and tex1 based on a blending factor you supply === | ||
The keyword here is GL_INTERPOLATE. | |||
glActiveTexture(GL_TEXTURE0); | glActiveTexture(GL_TEXTURE0); | ||
glBindTexture(GL_TEXTURE_2D, textureID0); | glBindTexture(GL_TEXTURE_2D, textureID0); | ||
Line 47: | Line 51: | ||
glBindTexture(GL_TEXTURE_2D, textureID1); | glBindTexture(GL_TEXTURE_2D, textureID1); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | ||
//GL_CONSTANT refers to the call we make with glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor) | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); | ||
Line 55: | Line 60: | ||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); | ||
//------------------------ | //------------------------ | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | ||
Line 83: | Line 88: | ||
vec4 texel1 = texture2D(Texture1, TexCoord1); | vec4 texel1 = texture2D(Texture1, TexCoord1); | ||
gl_FragColor = mix(texel0, texel1, BlendFactor); | gl_FragColor = mix(texel0, texel1, BlendFactor); | ||
} | |||
=== Example : Blend tex0 and tex1 based on alpha of tex0 === | |||
The keyword here is GL_INTERPOLATE. | |||
glActiveTexture(GL_TEXTURE0); | |||
glBindTexture(GL_TEXTURE_2D, textureID0); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); | |||
//------------------------ | |||
glActiveTexture(GL_TEXTURE1); | |||
glBindTexture(GL_TEXTURE_2D, textureID1); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); | |||
//------------------------ | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA); | |||
The equivalent with GL 2.0 shaders | |||
//Fragment shader | |||
uniform sampler2D Texture0; | |||
uniform sampler2D Texture1; | |||
//------------------------ | |||
varying vec2 TexCoord0; | |||
varying vec2 TexCoord1; //Or just use TexCoord0 | |||
//------------------------ | |||
void main() | |||
{ | |||
vec4 texel0 = texture2D(Texture0, TexCoord0); | |||
vec4 texel1 = texture2D(Texture1, TexCoord1); | |||
gl_FragColor = mix(texel0, texel1, texel0.a); | |||
} | |||
=== Example : Blend tex1 and tex2 based on alpha of tex0 === | |||
The keyword here is GL_INTERPOLATE.<br> | |||
tex0's ALPHA is the mask. | |||
glActiveTexture(GL_TEXTURE0); | |||
glBindTexture(GL_TEXTURE_2D, textureID0); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); | |||
//------------------------ | |||
glActiveTexture(GL_TEXTURE1); | |||
glBindTexture(GL_TEXTURE_2D, textureID1); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DECAL); //Get RGB of this texture (tex1) | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); | |||
//------------------------ | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_DECAL); //Get ALPHA of previous TUI (tex0) | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); | |||
glActiveTexture(GL_TEXTURE2); | |||
glBindTexture(GL_TEXTURE_2D, textureID2); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); | |||
//------------------------ | |||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); | |||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA); | |||
With shaders, things are much more flexible. | |||
//Fragment shader | |||
uniform sampler2D Texture0; //Mask | |||
uniform sampler2D Texture1; | |||
uniform sampler2D Texture2; | |||
//------------------------ | |||
varying vec2 TexCoord0; | |||
//------------------------ | |||
void main() | |||
{ | |||
vec4 texel0 = texture2D(Texture0, TexCoord0); | |||
vec4 texel1 = texture2D(Texture1, TexCoord0); | |||
vec4 texel2 = texture2D(Texture2, TexCoord0); | |||
gl_FragColor = mix(texel1, texel2, texel0.a); | |||
} | |||
In this one, we place the mask at TIU 2 | |||
//Fragment shader | |||
uniform sampler2D Texture0; | |||
uniform sampler2D Texture1; | |||
uniform sampler2D Texture2; //Mask | |||
//------------------------ | |||
varying vec2 TexCoord0; | |||
//------------------------ | |||
void main() | |||
{ | |||
vec4 texel0 = texture2D(Texture0, TexCoord0); | |||
vec4 texel1 = texture2D(Texture1, TexCoord0); | |||
vec4 texel2 = texture2D(Texture2, TexCoord0); | |||
gl_FragColor = mix(texel0, texel1, texel2.a); | |||
} | } | ||
=== Example : Add tex0 and tex1 === | === Example : Add tex0 and tex1 === | ||
The keyword here is GL_ADD. | |||
glActiveTexture(GL_TEXTURE0); | glActiveTexture(GL_TEXTURE0); | ||
glBindTexture(GL_TEXTURE_2D, textureID0); | glBindTexture(GL_TEXTURE_2D, textureID0); | ||
Line 93: | Line 207: | ||
glBindTexture(GL_TEXTURE_2D, textureID1); | glBindTexture(GL_TEXTURE_2D, textureID1); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); //Add RGB with RGB | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); | ||
Line 99: | Line 213: | ||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); | ||
//------------------------ | //------------------------ | ||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); //Add ALPHA with ALPHA | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); | ||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); |
Revision as of 14:15, 11 July 2009
Texture combiners became core in GL 1.3. You can combine by multiplying, replacing, adding, subtracting, or doing a DOT3 product.
GL 1.4 added to the core a crossbar feature. This means that you sample GL_TEXTUREX from any other texture image unit (TIU).
For example, at TUI 4, you can sample GL_TEXTURE0 or GL_TEXTURE1 or GL_TEXTURE2 or GL_TEXTURE3.
The examples here also show the equivalent shader code in GLSL to encourage people to use shaders instead of the fixed pipeline.
Example : multiply tex0 and tex1
The keyword here is GL_MODULATE, which does the actual multiplication.
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID0); //Simply sample the texture glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //------------------------ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //Sample RGB, multiply by previous texunit result glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); //Modulate RGB with RGB glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); //Sample ALPHA, multiply by previous texunit result glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); //Modulate ALPHA with ALPHA glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
The equivalent with GL 2.0 shaders
//Fragment shader uniform sampler2D Texture0; uniform sampler2D Texture1; //------------------------ varying vec2 TexCoord0; varying vec2 TexCoord1; //Or just use TexCoord0 //------------------------ void main() { vec4 texel = texture2D(Texture0, TexCoord0); texel *= texture2D(Texture1, TexCoord1); gl_FragColor = texel; }
Example : Blend tex0 and tex1 based on a blending factor you supply
The keyword here is GL_INTERPOLATE.
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //------------------------ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); //GL_CONSTANT refers to the call we make with glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor) glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); //------------------------ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); //GL_CONSTANT refers to the call we make with glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor) glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA); //------------------------ float mycolor[4]; mycolor[0]=mycolor[1]=mycolor[2]=0.0; //RGB doesn't matter since we are not using it mycolor[3]=0.75; //Set the blend factor with this glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor);
The equivalent with GL 2.0 shaders
//Fragment shader uniform sampler2D Texture0; uniform sampler2D Texture1; uniform float BlendFactor; //------------------------ varying vec2 TexCoord0; varying vec2 TexCoord1; //Or just use TexCoord0 //------------------------ void main() { vec4 texel0 = texture2D(Texture0, TexCoord0); vec4 texel1 = texture2D(Texture1, TexCoord1); gl_FragColor = mix(texel0, texel1, BlendFactor); }
Example : Blend tex0 and tex1 based on alpha of tex0
The keyword here is GL_INTERPOLATE.
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //------------------------ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); //------------------------ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
The equivalent with GL 2.0 shaders
//Fragment shader uniform sampler2D Texture0; uniform sampler2D Texture1; //------------------------ varying vec2 TexCoord0; varying vec2 TexCoord1; //Or just use TexCoord0 //------------------------ void main() { vec4 texel0 = texture2D(Texture0, TexCoord0); vec4 texel1 = texture2D(Texture1, TexCoord1); gl_FragColor = mix(texel0, texel1, texel0.a); }
Example : Blend tex1 and tex2 based on alpha of tex0
The keyword here is GL_INTERPOLATE.
tex0's ALPHA is the mask.
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //------------------------ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DECAL); //Get RGB of this texture (tex1) glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); //------------------------ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_DECAL); //Get ALPHA of previous TUI (tex0) glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textureID2); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); //Interpolate RGB with RGB glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); //------------------------ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); //Interpolate ALPHA with ALPHA glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
With shaders, things are much more flexible.
//Fragment shader uniform sampler2D Texture0; //Mask uniform sampler2D Texture1; uniform sampler2D Texture2; //------------------------ varying vec2 TexCoord0; //------------------------ void main() { vec4 texel0 = texture2D(Texture0, TexCoord0); vec4 texel1 = texture2D(Texture1, TexCoord0); vec4 texel2 = texture2D(Texture2, TexCoord0); gl_FragColor = mix(texel1, texel2, texel0.a); }
In this one, we place the mask at TIU 2
//Fragment shader uniform sampler2D Texture0; uniform sampler2D Texture1; uniform sampler2D Texture2; //Mask //------------------------ varying vec2 TexCoord0; //------------------------ void main() { vec4 texel0 = texture2D(Texture0, TexCoord0); vec4 texel1 = texture2D(Texture1, TexCoord0); vec4 texel2 = texture2D(Texture2, TexCoord0); gl_FragColor = mix(texel0, texel1, texel2.a); }
Example : Add tex0 and tex1
The keyword here is GL_ADD.
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //------------------------ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); //Add RGB with RGB glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); //------------------------ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); //Add ALPHA with ALPHA glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
The equivalent with GL 2.0 shaders
//Fragment shader uniform sampler2D Texture0; uniform sampler2D Texture1; //------------------------ varying vec2 TexCoord0; //------------------------ void main() { vec4 texel0 = texture2D(Texture0, TexCoord0); vec4 texel1 = texture2D(Texture1, TexCoord0); gl_FragColor = clamp(texel0 + texel1, 0.0, 1.0); }