1
votes

I have two textures rendered in the same way. The green texture has the right transparency in the right places, but when I move the pink texture in front, it shows the background color where it should be transparent.

enter image description here

This is the snippet code of the paintGL method that renders the textures.

void OpenGLWidget::paintGL()
{
    // ...

    for (int i = 0; i < lights.size(); i++)
    {
        glUseProgram(lights[i].program);

        setUniform3fv(program, "lightPosition", 1, &lights[i].position[0]);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, lights[i].texture);

        lights[i].svg.setColor(toColor(lights[i].diffuse));
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lights[i].svg.width(), lights[i].svg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, lights[i].svg.toImage().constBits());
        glGenerateMipmap(GL_TEXTURE_2D);

        glBindVertexArray(lights[i].vertexArray);
        glDrawElements(GL_TRIANGLES, lights[i].indices.size(), GL_UNSIGNED_BYTE, nullptr);
    }

    update();
}

The toImage method of the svg class generates a new QImage object from the svg file, so the new texture value should be updated with each frame.

Where am I doing wrong? Thanks!

1
Aside: there's no need to call glTexImage2D and glGenerateMipmap each time you render. Only upload textures and generate mipmaps when they actually change. - Thomas

1 Answers

2
votes

This probably happens because you have depth testing enabled. Even though parts of the texture are (partly or fully) transparent, OpenGL still writes to the depth buffer, so the pink light's quad appears to obscure the green light. It works the other way round, because the pink light is drawn first, so the green light hasn't been written to the depth buffer at that point.

The usual solution to this is to render transparent textures in back to front order.

You could also just write your fragment shader to discard fragments if they are transparent. But this results in artifacts if you have semi-transparent fragments, which you have, because of texture filtering and mipmaps.