简体   繁体   English

Qt和OpenGL:纹理透明度

[英]Qt & OpenGL : texture transparency

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. 绿色纹理在正确的位置具有适当的透明度,但是当我在前面移动粉色纹理时,它将在应该透明的位置显示背景色。

在此处输入图片说明

This is the snippet code of the paintGL method that renders the textures. 这是渲染纹理的paintGL方法的代码片段。

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. svg类的toImage方法从svg文件生成一个新的QImage对象,因此新纹理值应随每一帧更新。

Where am I doing wrong? 我在哪里做错了? Thanks! 谢谢!

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. 即使部分纹理是(部分或全部)透明的,OpenGL仍会写入深度缓冲区,因此,粉红光的四边形似乎会遮挡绿光。 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. 您也可以只编写片段着色器以discard透明的片段。 But this results in artifacts if you have semi-transparent fragments, which you have, because of texture filtering and mipmaps. 但是,如果您具有半透明的片段(由于纹理过滤和mipmap),则会产生伪像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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