Separate Framebuffer blend settings are ignored.

I have a question about the glDisablei and glBlendFunci function.

I want to draw/store additional fragment information in an FBO. If I change/disable the global blend setting via glDisable or glBlendFunc the attached code works as expected.

If I use glDisablei or glBlendFunci the global blend function (for FB 0) is still used and the FBO data is unusable. I’m using alpha blending in other places so it is necessary to switch between blend functions for each frame.

// generate Textures

    glGenTextures(3, deferredTextureName);

    glActiveTexture(GL_TEXTURE7);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    // GLenum internalColorFormat = GL_RGBA16F;
    glTexStorage2D(GL_TEXTURE_2D, 1, internalColorFormat , _screenResolution.x, _screenResolution.y);

    glActiveTexture(GL_TEXTURE8);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    // GLenum internalDepthFormat = GL_DEPTH_COMPONENT24;
    glTexStorage2D(GL_TEXTURE_2D, 1, internalDepthFormat , _screenResolution.x, _screenResolution.y);

    glActiveTexture(GL_TEXTURE9);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[2]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexStorage2D(GL_TEXTURE_2D, 1, internalColorFormat , _screenResolution.x, _screenResolution.y);


    // setup FB

    glGenFramebuffers(1, &deferredFBOName);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,deferredFBOName);

    // doesn't work
    // glDisablei(GL_BLEND, deferredFBOName);
    // glBlendFunci(deferredFBOName,GL_ONE,GL_ZERO);
        
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, deferredTextureName[0], 0);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, deferredTextureName[1], 0);    
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, deferredTextureName[2], 0);    

    GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE) ...


// write

    glActiveTexture(GL_TEXTURE7);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[0]);  
   
    glActiveTexture(GL_TEXTURE8);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[1]);  

    glActiveTexture(GL_TEXTURE9);
    glBindTexture(GL_TEXTURE_2D, deferredTextureName[2]);  

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,deferredFBOName);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
    glDrawBuffers(2, drawBuffers);

glBlendFunci and glDisablei are global states.

glBlendFunc and glDisable say “use this blend function for ALL color attachments for all drawBuffers in the future”.
glBlendFunci and glDisablei say “use this blend function for color attachment X for all drawBuffers in the future”.

The indexed functions are used if you have a drawBuffer with several color render targets. For example if you use an “frame buffer object” and render to 2 images at the same time. And want to use different blend functions for each image.

Thank you. Your answer solved my problem.