PDA

View Full Version : Transparency problem


Sohta
2003.12.01, 01:22 PM
Okay, I have a display list that I wish to display as a opaque object or as a transparent object depending on the situation.

Now if the polygons in the display list are texture mapped, it's easy, I'd just set the material's alpha value to either 1.0 or 0.5 depending on the situation.

The tricky problem here is that my display lists contain calls to glColor4v() (I'm currently using GL_COLOR_MATERIAL). So the alpha channel gets changed during the execution of the display list.

Also, when I draw the object in the "Opaque mode", I may have translucent parts. So I need to use glColor4f (and not glColor3f ). The idea is to create a "ghost mode".

My question to you is : what's the most effecient way to do blending without using the alpha channel?

current options:

- 1
draw the display list in an offscreen buffer,
call glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_SCALE, 0.5);
And then copy (and blend) the pixels to the current color buffer.

(wich is probably a bad idea, since it could get heavy if the object is seen from a short distance. i.e. lots of pixels to multiply by the color matrix, transfer and blend)

- 2
Use plain colored textures with an alpha channel for non-textured polygons. (feels a bit wasty)

- 3
Give up transparency in the base objects and use the alpha channel only for the ghost-mode. (a bit of a shame)

any suggestions?

thanks

Sohta
2003.12.01, 01:36 PM
Lol, Ive just noticed that I asked for ways to do it without the alpha channel, but all of my suggestions involve the alpha channel in a way or another... well, hopefully you get the idea anyways.

Fenris
2003.12.01, 01:39 PM
I'd suggest that you in your display list draw:
ï First all non-translucent polygons
ï Then every translucent poly

In the display list, don't call glColor4f until you hit the translucent polys. (This assumes that you only use glColor4f for alpha) This means that the opaque polys will be drawn using whatever the state machine is set to when you call the list. Like so:


Pseudo-code
DrawOpaque
{
glColor4f (1,1,1,1);
CallList
{
DrawOpaquePolys(); <-- These will be drawn with a=1
glColor4f (1,1,1,0.5);
DrawTranslucentPolys(); <-- a = 0.5
}
}

DrawGhost
{
glColor4f (1,1,1,0.75); <-- To differ ghost-opaque from ghost-translucent
CallList
{
DrawOpaquePolys(); <-- These will be drawn with a=0.75
glColor4f (1,1,1,0.5);
DrawTranslucentPolys(); <-- a = 0.5
}
}


HTH,

arekkusu
2003.12.01, 01:45 PM
There might be a texture COMBINE mode using the CONSTANT color of the texture environment as a global alpha color to modulate against that will do what you want, but it probably depends exactly what you're doing with textures and colors.

Don't forget, if you use COMBINE mode you can specify separate sources for RGB and ALPHA combining. (No destination alpha, unfortunately for me...)

Sohta
2003.12.01, 01:49 PM
(oups, arekkusu was a bit fast here, replying to Fenris's post)

It's a good idea, but, as you said, I have to use glColor only for the alpha channel. The problem is that it's not the case.

On top of that, i just checked my doc, and glColor3f resets the alpha channel to 1.0 (wich means that option #3 is out).

The essence of my problem really comes from the calls to glColor in the display list, wich are used for the color of the polygon (sorry, I failed to mention that).

Thanks anyways.

arekkusu
2003.12.01, 01:54 PM
What if you reverse it and put glTexEnv calls in the display list to modify the CONSTANT color's alpha. Then you can use glColor to set the alpha before calling the display list.

You want a COMBINE mode that multiplies the incoming fragment alpha (current color) with the constant alpha, and fragment color (current color) with the texture, if you care about tinting etc.

Sohta
2003.12.01, 02:00 PM
Your first option was better. Since I call glColor in the display list (to change the current color, not just the alpha). The alpha value set by the glColor call before the list is called will the overloaded to 1.0 during the list.

However... your first option might just work. The only question that remains (memory fading). The texEnv parameters are still in effect if the binded texture is 0 right?

Fenris
2003.12.01, 02:05 PM
Ah, I see.

Of course, there's still the possibility to keep two display lists around - one for opaque and one for ghost meshes...

Sohta
2003.12.01, 02:06 PM
Actually, I could use texEnv calls to manage the RGB color in the list too. But i'm pretty sure that glColor4f will be more efficient.

Thanks for the help!

Sohta
2003.12.01, 02:56 PM
I've got my answer, it's actually pretty simple, thanks to GL_ARB_imaging

I just have to call :
glBlendColor(0.0,0.0,0.0,0.7);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);

before drawing the ghost version.

thanks to all who helped

arekkusu
2003.12.01, 04:18 PM
Good. Anyway, no, the texture environment, including the constant color, is per texture unit.

Edit:
If you go with glBlendColor you better make sure that the imaging subset is available on your target machines. It's not implemented on some Radeons. The texture environment is probably a better choice compatibility-wise.