Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » OpenGL alpha channel woes!

This thread is locked; no one can reply to it. rss feed Print
OpenGL alpha channel woes!
Richard Phipps
Member #1,632
November 2001
avatar

Ok, can someone explain something to me?

I have an image with an alpha channel attached to it.

If I set OpenGL to just work on the alpha channel with glColorMask( false, false, false, true ), I can then subtract from the alpha channel with a GL_ZERO, GL_ONE_MINUS_SRC_ALPHA blending mode and some drawing operations.

However every combination I've tried to get it to add to the alpha channel (in some kind of additive blending mode) doesn't do anything. Even using a pure GL_ONE, GL_ONE doesn't touch the alpha channel..

Am I missing something here?

Rich.

Wilson Saunders
Member #5,872
May 2005
avatar

This could be a Z-buffering issue.

You should post a screen shot so we could better diagnose the problem.

I remember when I first was experimenting with the alpha channel textures.
I would draw a polygon with an alpha layered texture on top of it. The polygon would blot out some (not all) of the objects behind it. It turns the z buffer (the thing that determines if a pixel should be set to the value of a polygon or not set because it is behind another object) considered my Alpha channel polygon a solid object and refused to draw what was behind it.

The solution is to render your entire scene without your alpha textures first, then render your alpha textures in sorted order from furthest to closest. That way the z buffer has no opportunity to clobber a new polygon with blank alpha data.

Hope this helps

________________________________________________
Play my games at http://monkeydev.com

Richard Phipps
Member #1,632
November 2001
avatar

Hmm.. Thanks for that. I'm using Openlayer so am not using the Z buffer directly. Maybe that is the problem?

Dustin Dettmer
Member #3,935
October 2003
avatar

We need more information. Is the alpha channel in the texture? Are you trying to apply transparency to a normally translucent texture? What API are you using to do it? OpenLayer or OpenGL or both? What parts in Ogl and which are in Ol?

Post some code while you're at it.

Richard Phipps
Member #1,632
November 2001
avatar

Ok.

I have a texture with an alpha layer which I blit to the screen in OpenLayer. I then blit another smaller texture with an alpha channel to it in a SUBTRACTIVE blend mode. Then I copy the resulting RGBA image back into the original texture from the screen:

1 if (mouse_b != 0)
2 {
3 // Draw image.
4 Blenders::Set( ALPHA_BLENDER );
5
6 gfxImages[0]->Blit(0, 0, 1.0);
7
8 // Only work on the Alpha.
9 Canvas::SetPixelWriteMode( ALPHA_ONLY );
10
11 if (mouse_b == 1) Blenders::Set( SUBTRACTIVE_BLENDER );
12 if (mouse_b == 2) Blenders::Set( ADDITIVE_BLENDER );
13
14 // Draw mouse.
15 gfxImages[2]->Blit(mouse_x, mouse_y, 1.0);
16 
17 Blenders::Set( ALPHA_BLENDER );
18
19 // Copy new image.
20 gfxImages[0]->CopyFromScreen(0, 0);
21
22 // Back to working on the full RGBA.
23 Canvas::SetPixelWriteMode( COLOR_AND_ALPHA );
24 }

Using the left mouse button I can draw holes in the texture, but with the right mouse button nothing happens as the ADDITIVE_BLENDER doesn't seem to work in this situation.

Any ideas?

Dustin Dettmer
Member #3,935
October 2003
avatar

Wow, OL is weird...

Richard Phipps
Member #1,632
November 2001
avatar

Why do you say that?

I've tried using OpenGL commands here and gotten the same result. :-/

Dustin Dettmer
Member #3,935
October 2003
avatar

if (mouse_b == 2) Blenders::Set( ADDITIVE_BLENDER );

I'm used to

if (mouse_b == 2) glBlendFunc(GL_SRC_ALPHA, GL_ONE);

Which i've only recently gotten a complete grasp over.

razor
Member #2,256
April 2002
avatar

In my experience the screen doesn't like to always store an alpha channel, even if you explicitly tell it to enable it... especially in windows. From what I read that's what you are trying to do, so it might be a bit complicated.

EDIT: Heh... "there is no alpha channel" :D

Whoooo Oregon State University

Richard Phipps
Member #1,632
November 2001
avatar

Razor: I thought of that as well, but it works with the subtractive blender. With that the alpha values in parts of the image are reduced or removed altogether. So that does seem to suggest to me that the screen is storing the alpha channel.

Ciro Duran
Member #3,011
December 2002
avatar

I have not used OpenLayer ever, but I do have used OpenGL extensively. You should check the Red Book, Chapter 7 about Blending if you want to know more about blending and transparency. Basically the blending operation takes the source color (the one coming from the pixel you are going to draw, say, Cs), and the destination color (the pixel that is already drawn in the framebuffer, let's call it Cd), multiplies each one by the factors you specify in glBlendFunc(), and adds them for the final color (Cf), which overwrites Cd in the framebuffer.

The OpenGL context has by default the (GL_ONE, GL_ZERO) blend function, which overwrites the pixels in the framebuffer. You should switch to the (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blend function, which works pretty well for your usual transparency effect. The blending function (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA) in your post basically overwrites the source color (you multiply by zero the source color).

Make sure, being with the OpenLayer API or with OpenGL directly, to turn on the blending operation (glEnable(GL_BLEND).

I saw that OpenLayer is mainly 2D, so you should not be turning on the depth buffer test, in order to discard the Z-buffer issue W.S. points out.

Remember too that by drawing with the blending operation on will force you to draw your stuff ordered: solid things first and the transparent things.

I hope this helps you a bit.

Cheers,

Ciro.

EDIT: Clarifying the blending op.

---
El Ciro

In the beginning, God said "light_source { <0, 0, 0> color White }" and light was created.

Krzysztof Kluczek
Member #4,191
January 2004
avatar

Quote:

The OpenGL context has by default the (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blend function, which works pretty well for your usual transparency effect.

OpenGL specification says that it is (ONE, ZERO) by default. :)

Ciro Duran
Member #3,011
December 2002
avatar

Oops. My bad, it's edited :-). Thanks.

---
El Ciro

In the beginning, God said "light_source { <0, 0, 0> color White }" and light was created.

Richard Phipps
Member #1,632
November 2001
avatar

EDIT:

I've got it to work with the additive blend! It seems I was not drawing the image to the screen with the right blending. Now it works great!

Thanks for all the help!! :D

Go to: