Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am attempting to understand how OpenGL (ES) blending works. I am finding it difficult to understand the documentation and how the results of glBlendFunc and glBlendEquation effect the final pixel that is written.

Do the source and destination out of glBlendFunc get added together with GL_FUNC_ADD by default?

This seems wrong because "basic" blending of GL_ONE, GL_ONE would output 2,2,2,2 then (Source giving 1,1,1,1 and dest giving 1,1,1,1).

I have written the following pseudo-code, what have I got wrong?

struct colour {
    float r, g, b, a;
};

colour blend_factor( GLenum factor, 
    colour source,
    colour destination,
    colour blend_colour ) {

    colour colour_factor;
    float i = min( source.a, 1 - destination.a );

    // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBlendFunc.xml
    switch( factor ) {
        case GL_ZERO: colour_factor = { 0, 0, 0, 0 }; break;
        case GL_ONE: colour_factor = { 1, 1, 1, 1 }; break;
        case GL_SRC_COLOR: colour_factor = source; break;
        case GL_ONE_MINUS_SRC_COLOR: colour_factor = { 1 - source.r, 1 - source.g, 1 - source.b, 1 - source.a }; break;
        // ...
    }

    return colour_factor;
}

colour blend( colour & source, 
    colour destination, 
    GLenum source_factor, // from glBlendFunc
    GLenum destination_factor, // from glBlendFunc
    colour blend_colour, // from glBlendColor
    GLenum blend_equation // from glBlendEquation
    ) {

    colour source_colour = blend_factor( source_factor, source, destination, blend_colour );
    colour destination_colour = blend_factor( destination_factor, source, destination, blend_colour );
    colour output;

    // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBlendEquation.xml
    switch( blend_equation ) {
        case GL_FUNC_ADD: output = add( mul( source, source_colour ), mul( destination, destination_colour ) );
        case GL_FUNC_SUBTRACT: output = sub( mul( source, source_colour ), mul( destination, destination_colour ) );
        case GL_FUNC_REVERSE_SUBTRACT: output = sub( mul( destination, destination_colour ), mul( source, source_colour ) );
    }

    return output;
}



void do_pixel() {

    colour final_colour;

    // Blending
    if( enable_blending ) {

        final_colour = blend( current_colour_output, framebuffer[ pixel ], ... );
    } else {

        final_colour = current_colour_output;
    }

}

Thanks!

share|improve this question
    
"Do the source and destination out of glBlendFunc get added together with GL_FUNC_ADD by default?" Are you really asking if the GL_FUNC_ADD function actually adds things? –  Nicol Bolas Jun 8 '12 at 22:33

1 Answer 1

up vote 6 down vote accepted
case GL_FUNC_ADD: output = add( source_colour, destination_colour )

This is where you've gone wrong. The source and destination factors are multiplied into the source and destination colors, then added together. The OpenGL Wiki article on blending goes into greater detail on this matter.

share|improve this answer
4  
Here's a handy visual to with that: i.stack.imgur.com/i2IAC.jpg –  knight666 Jun 9 '12 at 8:19
    
Ah, yes I see, edited it now. Thanks! –  yuumei Jun 9 '12 at 11:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.