简体   繁体   中英

Alpha blending textures and primitives

I have two textures and a triangle primitive(the colors for its vertices is defined by glColor4f ).

Texture A looks like this:

纹理A

Texture B looks like this:

纹理B

Triangle Primitive P looks like this:

原始P

When I render texture A, and then texture BI get expected result ie The middle of the rectangle is transparent.

渲染A然后渲染B

However if I render the primitive P followed by texture A, and then texture B, I get wrong colors. P is not pure red and the texture colors all turn black.

P-> A-> B

How do I fix this so that proper transparency and colors are maintained.

Texture Parameters:

    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER));
    GLfloat debugColor[] = {1.0f, 0.0f, 1.0f, 1.0f};
    GL_CALL(glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, debugColor));

Blending function:

GL_CALL(glEnable(GL_BLEND));
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

Rendering of P, A and B:

        if(true)
        {
            // Render Primitive P

            GL_CALL(glBegin(GL_TRIANGLES));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(-0.5f, -0.5f));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(0.0f, 0.5f));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(0.5f, -0.5f));

            glEnd();
        }
        if(true)
        {
            // Render Texture A

            GL_CALL(glBindTexture(GL_TEXTURE_2D, textureId));
            GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0,
                                 GL_RGBA, GL_UNSIGNED_BYTE, image));

            real32 screenPercentage = 0.25f;

            GL_CALL(glBegin(GL_TRIANGLES));

            // Lower triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 0.0f));
            GL_CALL(glVertex2f(screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            //  Upper triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            GL_CALL(glTexCoord2f(0.0f, 1.0f));
            GL_CALL(glVertex2f(-screenPercentage, -screenPercentage));

            glEnd();
        }

        if(true)
        {
            // Render Texture B

            GL_CALL(glBindTexture(GL_TEXTURE_2D, textureId));
            GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, window[0].offscreenBuffer.width, window[0].offscreenBuffer.height, 0,
                                 GL_RGBA, GL_UNSIGNED_BYTE, window[0].offscreenBuffer.data));

            real32 screenPercentage = 1.0f;

            GL_CALL(glBegin(GL_TRIANGLES));

            // Lower triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 0.0f));
            GL_CALL(glVertex2f(screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            // Upper triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            GL_CALL(glTexCoord2f(0.0f, 1.0f));
            GL_CALL(glVertex2f(-screenPercentage, -screenPercentage));

            glEnd();
        }

EDIT: After trying @Rabbid76 's solution:

        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        if(true)
        {
        // Render triangle with all vertices having color 1.0f, 0.0f, 0.0f, 1.0f 
        }
        if(true)
        {
        // Render texture A with color set to 1.0f, 1.0f, 1.0f, 1.0f and the appropriate texture u,v coordinates
        }

        if(true)
        {
            // Render texture B with color set to 1.0f, 1.0f, 1.0f, 1.0f and the appropriate texture u,v coordinates
        }

I get the following result:

在此处输入图片说明

The colors are still not right even tho the alpha of all the three entities is 1.0f and that of the hollow region is 0.0f

If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode ( GL_TEXTURE_ENV_MODE ) is GL_MODULATE . See glTexEnv .

This causes that the color of the texels of the texture is "mixed" by the last color which you have set by glColor4f .
When you render the texture, then the red color of the triangle is still set, this causes that the textures are tint red. The green and blue color channels get completely lost and since the textures have no red color channel, everything what is left is a black color.

To solve you issue, you have to set a white color, before you render the textures:

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

And disable GL_TEXTURE_2D before you render the triangle, but enable it before you render the textures.
Note there is always a texture bound, there is nothing like "no texture", the default texture object 0 is a valid object too. This causes that the texture lookup gives a completely black color and this is mixed by the red color, which is set by glColor4f :

glDisable( GL_TEXTURE_2D );
if( true )
{
    // Render Primitive P
    .....
}

glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glEnable( GL_TEXTURE_2D );
if ( true )
{
    // Render Texture A
    .....
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM