Search code examples
qtqt6qtopengl

How to create QOffscreenSurface with alpha?


Found an example of offscreen rendering in QT (there is a working code in Update 1).

But was unable to make it support alpha, see the code below:

    QSurfaceFormat surfaceFormat;
    surfaceFormat.setColorSpace(QSurfaceFormat::ColorSpace::sRGBColorSpace);
    surfaceFormat.setRenderableType(QSurfaceFormat::RenderableType::OpenGL);
    surfaceFormat.setMajorVersion(4);
    surfaceFormat.setMinorVersion(3);
    surfaceFormat.setAlphaBufferSize(8);

    if (surfaceFormat.hasAlpha())
    {
        qInfo() << "The surface has alpha.";
    }
    else
    {
        qInfo() << "The surface does not have alpha.";
    }

it always prints "The surface has alpha." but my offscreen rendering works without alpha or saying more exactly I am getting a strange effect, the transparent pixels becomes white while the background is black:

enter image description here

compare it with the original image without transparency:

enter image description here

the difference is vec4(fragColor, 0.5) and vec4(fragColor, 1.0) in the fragment shader:

program.addShaderFromSourceCode(QOpenGLShader::Fragment,
                               "#version 330\r\n"
                               "in vec3 fragColor;\n"
                               "out vec4 color;\n"
                               "void main() {\n"
                               "    color = vec4(fragColor, 1.0);\n"
                               "}\n"
                               );

Is there some other option I can set?

My environment: Windows 10, MSVC 2019, QT 6.2.

EDIT1:

Did some further experimentation and added the following before rendering the triangle:

        glDisable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBlendEquation(GL_FUNC_ADD);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

and got white background:

enter image description here

with glClearColor(0, 0, 0, 0.5) I got gray:

enter image description here


Solution

  • Your image viewer displays your image on a white background so you see white or gray. With glClearColor(0, 0, 0, 1) you will see a transparent triangle on a black background:

        glDisable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBlendEquation(GL_FUNC_ADD);
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

    but resulting triangle will be partially transparent, so white image viewer background will be partially visible under the triangle.