Multitextureing+Mask

Hi every body,

I intend to use multitextureing to build an Image + opaque mask. I'd like to have transparent bubbles like a circular spot which has alpha of 0 in its center and gradually increasing alpha to 1.By putting the bubble in a part of image, the mask fades and that part of image becomes visible.

What I have in mind is:

Image comes first (as first texture), then an opaque mask defined by GL_QUADS(as second texture), finally spot is added. There is no bother with multitextureing, but how I make it possible for bubble to fade the mask but not the image and image become visable. What blending functions should I use?
Any idea to help?

Thanks,

My first impression is that you want something particle like, like a bubble image billboarded, alpha modulated by a radial gradient of sorts and blended with the background.

A shader rendition of this would be pretty straightforward. If instead you are looking at fixed function processing, I think the texture environment combiner (glTexEnvf) is what you want to look at. Though I have to admit my fixed function skills are a bit rusty.

Thanks Hlz,
Well, I have tried several ways and parameter changes in (glTexEnvf) without success. Do you have any idea how to use (glTexEnvf)? besides what blending function should I use?

Here is a very old wrapper I made up years ago. The relevant section of the spec is in the comments. Not even sure if it still works but I hope it’s of some use to you. I would urge you to consider using shaders instead, as practically all hardware is capable of it these days.


// ------------------------------------------------------------------------------------------------
// EnvCombine
// - See the 2.1 spec, § 3.8.13, p. 184
// ------------------------------------------------------------------------------------------------
struct EnvCombine4
{
    GLenum SrcFactor; 
    GLenum DestFactor;
    bool UsePrimary;

    EnvCombine4(GLenum srcFactor, GLenum destFactor, bool usePrimary)
        : SrcFactor(srcFactor)
        , DestFactor(destFactor)
        , UsePrimary(usePrimary)
    {}

    void Apply(int texUnit)
    {        
        glActiveTexture(GL_TEXTURE0 + texUnit);
        if (texUnit == 0)
        {
            // No previous unit, so blend with framebuffer
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            glBlendFunc(SrcFactor, DestFactor);
        }
        else
        {
            // Combine  BLEND : A * B + (1 - A) * C
            // Combine4 ADD   : A * B + C * D
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);

            // Arg0
            GLenum srcColor = UsePrimary ? GL_PRIMARY_COLOR_EXT : GL_TEXTURE;
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, srcColor);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

            // Arg1
            switch (SrcFactor)
            {
            case GL_ZERO: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
                break;
            case GL_ONE: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_SRC_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
                break;
            case GL_ONE_MINUS_SRC_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_SRC_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA);
                break;
            case GL_ONE_MINUS_SRC_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_ALPHA);
                break;
            case GL_DST_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
                break;
            case GL_ONE_MINUS_DST_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_DST_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA);
                break;
            case GL_ONE_MINUS_DST_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_ALPHA);
                break;
            }

            // Arg2
            glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
            glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);

            // Arg3
            switch (DestFactor)
            {
            case GL_ZERO: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
                break;
            case GL_ONE: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_SRC_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
                break;
            case GL_ONE_MINUS_SRC_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_SRC_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_ALPHA);
                break;
            case GL_ONE_MINUS_SRC_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, srcColor);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_ALPHA);
                break;
            case GL_DST_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
                break;
            case GL_ONE_MINUS_DST_COLOR: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
                break;
            case GL_DST_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_ALPHA);
                break;
            case GL_ONE_MINUS_DST_ALPHA: 
                glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT);
                glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_ALPHA);
                break;
            }
        }
    }
};