c++ - Qt 和 OpenGL : texture transparency

标签 c++ qt opengl textures transparency

我有两个以相同方式渲染的纹理。绿色纹理在正确的位置具有正确的透明度,但是当我将粉色纹理移到前面时,它在应该透明的地方显示了背景颜色。

enter image description here

这是渲染纹理的 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();
}

svg 类的 toImage 方法从 svg 文件生成一个新的 QImage 对象,因此新的纹理值应该随每一帧更新。

我哪里做错了?谢谢!

最佳答案

这可能是因为您启用了深度测试。即使部分纹理(部分或完全)透明,OpenGL 仍会写入深度缓冲区,因此粉红色光的四边形看起来会遮挡绿光。它以相反的方式工作,因为粉红色的光首先被绘制,所以绿色的光在那个时候还没有被写入深度缓冲区。

通常的解决方案是以从后到前的顺序渲染透明纹理。

如果片段是透明的,您也可以只将片段着色器写入 discard 片段。但是如果你有半透明的片段,这会导致伪影,因为纹理过滤和 mipmaps。

关于c++ - Qt 和 OpenGL : texture transparency,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53195913/

相关文章:

c++ - 处理 HTTP POST 请求/响应

qt - Qt应用程序的多平台崩溃报告系统

qt - 在 QDialog 中,调整窗口大小以包含 QTableView 的所有列

cocoa - NSTextField 优于 NSOpenGLView

c++ - 在 C++ 中传递对指针的引用

c++ - static_assert signed shift right 具有二进制补码行为是否合法?

c++ - Symbian C++ - S60 应用程序通过 TRK 和 Carbide 启动,但之后或下载时不启动

qt - Qdebug 显示十六进制值

c++ - Qt 中的 OpenGL 不绘制红色方 block

OpenGL Alpha 混合问题,忽略混合(可能)?