How do I make textures transparent in OpenGL?

15,613

So the other answer which was here but was deleted mentioned this - Generally, for alpha blending to work correctly you need to sort the objects from far to near in the coordinate system of the camera.
This is why your polygons are blended with the background. You can confirm that this is indeed the problem by disabling the depth test. Without depth test all the fragments are displayed and you'll be able to see the alpha blending.

More on this in this page.

Share:
15,613
Nick Bolton
Author by

Nick Bolton

Hello, I'm the CEO of Symless, the company behind Synergy, software that lets you share one mouse and keyboard between multiple computers.

Updated on June 04, 2022

Comments

  • Nick Bolton
    Nick Bolton almost 2 years

    I've tried to research this on Google but there doesn't appear to me to be any coherent simple answers. Is this because it's not simple, or because I'm not using the correct keywords?

    Nevertheless, this is the progress I've made so far.

    1. Created 8 vertices to form 2 squares.
    2. Created a texture with a 200 bit alpha value (so, about 80% transparent).
    3. Assigned the same texture to each square, which shows correctly.
    4. Noticed that when I use a texture with 255 alpha, it appears brighter.

    The init is something like the following:

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    
    glEnable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGenTextures(1, textureIds);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    
    int i, j;
    GLubyte pixel;
    for (i = 0; i < TEXTURE_HEIGHT; i++)
    {
        for (j = 0; j < TEXTURE_WIDTH; j++)
        {
            pixel = ((((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255);
            texture[i][j][0] = pixel;
            texture[i][j][1] = pixel;
            texture[i][j][2] = pixel;
            texture[i][j][3] = 200;
        }
    }
    
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
    glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGBA,
        TEXTURE_WIDTH, TEXTURE_HEIGHT,
        0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
    

    This is somewhat similar to the code snippet from page 417 in the book, OpenGL Programming Guide, and creates a check pattern.

    And then, the display function contains...

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    
    // Use model view so that rotation value is literal, not added.
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    
    // ... translation, etc ...
    
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, +1.0, 0.0); // top left
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); // bottom left
    glTexCoord2f(1.0, 1.0); glVertex3f(+1.0, -1.0, 0.0); // bottom right
    glTexCoord2f(1.0, 0.0); glVertex3f(+1.0, +1.0, 0.0); // top right
    glEnd();
    
        // not neccecary to repeat, just good practice
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, +1.0, -1.0); // top left
    glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -1.0, -1.0); // bottom left
    glTexCoord2f(1.0, 1.0); glVertex3f(+1.5, -1.0, -1.0); // bottom right
    glTexCoord2f(1.0, 0.0); glVertex3f(+1.5, +1.0, -1.0); // top right
    glEnd();
    
    glFlush();
    glDisable(GL_TEXTURE_2D);
    
    glPopMatrix();
    
    SwapBuffers();
    

    So, this renders a 2nd square in the background; I can see this but it looks like they're being blended with the background (I assume this because they are darker with 200 bit alpha than 255 bit) instead of the texture behind...

    Transparent textures not working

    As you can see, no transparency... How can I fix this?