This is hopefully a simple question: I have an OpenGL texture and would like to be able to change its opacity, how do I do that? The texture already has an alpha channel and blending works fine, but I want to be able to decrease the opacity of the whole texture, to fade it into the background. I have fiddled with glBlendFunc
, but with no luck – it seems that I would need something like GL_SRC_ALPHA_MINUS_CONSTANT
, which is not available. I am working on iPhone, with OpenGL ES.
8 Answers
I have no idea about OpenGL ES, but in standard OpenGL you would set the opacity by declaring a colour for the texture before you use it:
// R, G, B, A
glColor4f(1.0, 1.0, 1.0, 0.5);
The example would give you 50% alpha without affecting the colour of your texture. By adjusting the other values you can shift the texture colour too.

- 678
- 4
- 9
-
With what kind of setting for glBlendFunc? – zoul Nov 03 '08 at 15:12
-
2Well this is dependent on application but I would typically use: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); – Dan Nov 03 '08 at 15:40
-
3This works because the default texture environment is set to GL_MODULATE – noop Jul 12 '11 at 15:34
Use a texture combiner. Set the texture stage to do a GL_MODULATE
operation between a texture and constant color. Then change the constant color from your code (glTexEnv
, GL_TEXTURE_ENV_COLOR
).
This should come as "free" in terms of performance. On most (if not all) graphics chips combiner operations take the same number of GPU cycles (usually 1), so just using a texture versus doing a modulate operation (or any other operation) is exactly the same cost.

- 5,965
- 27
- 28
Basically you have two options: use glTexEnv for your texture with GL_MODULATE and specify the color using glColor4* and use a non-opaque level for the alpha channel. Note that glTexEnv should be issued only once, when you first load your texture. This scenario will not work if you specify colors in your vertex-attributes though. Those will namely override any glColor4* color you may set. In that case, you may want to resort to either of 2 options: use texture combiners (advanced topic, not nice to use in fixed-pipeline), or "manually" change the vertex color attribute of each individual vertex (can be undesirable for larger meshes).

- 1,509
- 2
- 17
- 22
If you are using modern OpenGL..
You can do this in the fragment shader :
void main()
{
color = vec4(1.0f, 1.0f, 1.0f, OPACITY) * texture(u_Texture, TexCoord);
}
This allows you to apply a opacity value to a texture without disrupting the blending.

- 315
- 3
- 14
Thank You all for the ideas. I’ve played both with glColor4f and glTexEnv and at last forced myself to read the glTexEnv manpage carefully. The manpage says that in the GL_MODULATE texturing mode, the resulting color is computed by multiplying the incoming fragment by the texturing color (C=Cf×Ct), same goes for the alpha. I tried glColor4f(1, 1, 1, opacity) and that did not work, but passing the desired opacity into all four arguments of the call did the trick. (Still not sure why though.)

- 102,279
- 44
- 260
- 354
-
3And this made you decide to flag your own "answer" as the accepted answer? – zmippie Jan 26 '11 at 08:48
-
-
You are setting something wrong with the textures. What Dan answered works and makes sense, your 'solution' is a hack. – cjcela Mar 17 '11 at 13:11
-
2This is normal, if you alphablend your resulting color into background or alphablend with GL_ONE parameter for source alpha, instead of GL_SRC_ALPHA. In that case, you wouldn't need to change all the color components. – noop Jul 12 '11 at 15:36
Most likely you are using cg to get your image into a texture. When you use cg, the alpha is premultiplied, thus why you have to use the alpha for rgba of the color4f func.
The most straightforward way is to change the texture's alpha value on the fly. Since you tell OpenGL about the texture at some point, you will have the bitmap in memory. So just rebind the texture to the same texture id. In case you don't have it in memory, (due to space constraints, since you are on ES), you can retrieve the texture to a buffer again, using glGetTexImage(). That's the clean solution.
Saving/retrieving operations are a bit costly, though, so you might want another solution. Thinking about it, you might be able to work with geometry behind your the geometry displaying your texture or simply work on the material/colour of the geometry that holds the texture. You will probably want to have some additive blending of the back-geometry. Using a glBlendFunc of
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA),
you might be able to "easily" and - more important, cheaply - achieve the desired effect.

- 2,381
- 14
- 16
-
One textur is typically used for multiple objects, changing it would change transparency for all the objects. Also, on many systems texture uploads are much slower than a simple copy operation because of internal format conversions. – noop Jul 12 '11 at 15:33
I suspect that you had a black background, and thus by decreasing the amount of every color, you were effectively fading the color to black.