OpenGL fragment shader alpha issues

opengl

#1

I’m working on an OpenGL shader, which I want to have transparency. However I can’t get the alpha channel to have any effect.

My super simple example fragment shader:

void main()
{
    gl_FragColor = vec4 (0.0, 0.5, 0.5, 0.0);
}

I would expect this to be completely transparent and show the underlying colour (in my case black). I get the full colour being shown. I’ve managed to get the effect I want by manually blending colours in the shader, but I want to have the shader operating on top of a GUI so I need proper alpha blending.

I’m using the OpenGLApp as a base; below is the simplified render method:

void MainComponent::render()
{
    OpenGLHelpers::clear (Colours::black);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    if (shader == nullptr)
        return;

    auto desktopScale = openGLContext.getRenderingScale();

    std::unique_ptr<LowLevelGraphicsContext> glContext (createOpenGLGraphicsContext (openGLContext,
        roundToInt (desktopScale * getWidth()),
        roundToInt (desktopScale * getHeight())));

    auto mouseRel = getMouseXYRelative().toFloat() * desktopScale;

    shader->onShaderActivated = [&glContext, &mouseRel](OpenGLShaderProgram& p)
    {
        auto bounds = glContext->getClipBounds().toFloat();
        p.setUniform("u_mouse", mouseRel.x, mouseRel.y);
    };

    shader->fillRect(*glContext, glContext->getClipBounds());
}

#2

Cracked it!

I just had to move the gl function calls to right before the call to shader->fillRect:

void MainComponent::render()
{
    OpenGLHelpers::clear (Colours::black);
    
    if (shader == nullptr)
        return;

    auto desktopScale = openGLContext.getRenderingScale();

    std::unique_ptr<LowLevelGraphicsContext> glContext (createOpenGLGraphicsContext (openGLContext,
        roundToInt (desktopScale * getWidth()),
        roundToInt (desktopScale * getHeight())));

    auto mouseRel = getMouseXYRelative().toFloat() * desktopScale;

    shader->onShaderActivated = [&glContext, &mouseRel](OpenGLShaderProgram& p)
    {
        auto bounds = glContext->getClipBounds().toFloat();
        p.setUniform("u_mouse", mouseRel.x, mouseRel.y);
    };

    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    shader->fillRect(*glContext, glContext->getClipBounds());
}

My assumption is that they won’t have any effect until after the context is created.