OpenGL blending equations

Is there a website that lists all the equations used for the different OpenGL blending modes, for instance

glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR);
glBlendFunc(GL_ONE, GL_DST_COLOR);

Anybody know of a site?

src factor (apply to src_color - incoming color):
GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, and GL_SRC_ALPHA_SATURATE

dest factor (apply to existing framebuffer color):
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, and GL_ONE_MINUS_DST_ALPHA

Blending equation:
result_color = src_factor(incoming_color) + dst_factor(framebuffer_color).

Meaning of factors:
GL_ZERO(col) = 0 * col = 0
GL_ONE(col) = 1 * col = col
GL_DST_COLOR(col) = framebuffer_color * col
GL_ONE_MINUS_DST_COLOR(col) = (1 - framebuffer_color) * col
GL_SRC_ALPHA(col) = col.a * col
GL_ONE_MINUS_SRC_ALPHA(col) = (1 - col.a) * col
GL_DST_ALPHA(col) = framebuffer_color.a * col
GL_ONE_MINUS_DST_ALPHA(col) = ( 1 - framebuffer_color.a) * col
GL_SRC_ALPHA_SATURATE(col) = (f, f, f, 1)*col; f=min(col.a, 1-framebuffer_color.a)

examples:
glBlendFunc(GL_ONE, GL_ONE)
1 * src_col + 1 * framebuffer_color = src_col + framebuffer_color => color add

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
src_col.a * src_col + (1 - src_col.a) * framebuffer_color => decal

glBlendFunc(GL_DST_COLOR, GL_ZERO)
framebuffer_color * src_col + 0 * framebuffer_color = framebuffer_color * src_col => modulate colors

yooyo

Uh…you’re at the site. :slight_smile: All of the relevent information is listed on pages 178 and 179 (pages 191 and 192 of the pdf) of the OpenGL 1.5 spec.

Also keep in mind there is a glBendFunc and a glBlendEquation function that do different things …

Thanks for all that information, but I’m having a little problem. I’m trying to implemented glBlendFunc(GL_DST_COLOR, GL_ZERO), and this is what I do for a single pixel

for each R, G, B value

srcR/=255.0;
dstR/=255.0;
newR = srcRdstR + 0srcR;
newR*=255.0;
if(newR > 255) newR = 0;

But doing this doesn’t get me even close to the result of what OpenGL displays. This for some reason, simply makes whatever was in the destination image become darker, but doesn’t blend the two correctly. Is this the correct way for GL_DST_COLOR, GL_ZERO ?

I guess :
if(newR > 255) newR = 0;
should read :
if(newR > 255) newR = 255;

Oh, type in my post. I meant to put if(val > 255) val = 255.

Anyway, still have this problem. Anybody?

With glBlendFunc(GL_DST_COLOR, GL_ZERO) you actually multiply incoming image and framebuffer. As colors are taken in the range [0,1], it must darken the image (only white leave it as is).

You can do some experiments with Photoshop or Gimp, use 2 layers, the top one in ‘multiply’ mode.

If you don’t see such effect in OpenGL, it is a bug, because I do see that !

Well I’ve come up with the following code below, and it only seems to work for the following situations:

glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR);
glBlendFunc(GL_ONE, GL_ONE);

All other situations do not produce the correct result.

Any help with the code below is much appreciated.

 
for(int i=0; i < 3; i++)
{

                c0 = dst[i]/255.0;
                c1 = src[i]/255.0;

                if(blend0 == GL_ZERO)
                        newc0 = 0*c0;
                else if(blend0 == GL_ONE)
                        newc0 = 1*c0;
                else if(blend0 == GL_SRC_COLOR)
                        newc0 = c0*c0;
                else if(blend0 == GL_DST_COLOR)
                        newc0 = c1*c1;
                else if(blend0 == GL_ONE_MINUS_SRC_COLOR)
                        newc0 = (1-c0);
                else if(blend0 == GL_ONE_MINUS_DST_COLOR)
                        newc0 = (1-c1);
                        
                if(blend1 == GL_ZERO)
                        newc1 = 0*c1;
                else if(blend1 == GL_ONE)
                        newc1 = 1*c1;
                else if(blend1 == GL_SRC_COLOR)
                        newc1 = c0*c0;
                else if(blend1 == GL_DST_COLOR)
                        newc1 = c1*c1;
                else if(blend0 == GL_ONE_MINUS_SRC_COLOR)
                        newc1 = (1-c0);
                else if(blend0 == GL_ONE_MINUS_DST_COLOR)
                        newc1 = (1-c1);


                val = (newc0+newc1)*255;
                if(val > 255) val=255;
                if(val < 0) val=0;

                dst[i] = (char)val;
}
 

Try it this way:

c0 = src[i]/255.0;
c1 = dst[i]/255.0;

Originally posted by oconnellseanm:
Well I’ve come up with the following code below <…>
Here you go. I’ve marked the places where I made corrections.

 
for(int i=0; i < 3; i++)
{

                c0 = src[i]/255.0;  //<-
                c1 = dst[i]/255.0;  //<-

                if(blend0 == GL_ZERO)
                        newc0 = 0*c0;
                else if(blend0 == GL_ONE)
                        newc0 = 1*c0;
                else if(blend0 == GL_SRC_COLOR)
                        newc0 = c0*c0;
                else if(blend0 == GL_DST_COLOR)
                        newc0 = c0*c1; //<-
                else if(blend0 == GL_ONE_MINUS_SRC_COLOR)
                        newc0 = c0*(1-c0); //<-
                else if(blend0 == GL_ONE_MINUS_DST_COLOR)
                        newc0 = c0*(1-c1); //<-
                        
                if(blend1 == GL_ZERO)
                        newc1 = 0*c1;
                else if(blend1 == GL_ONE)
                        newc1 = 1*c1;
                else if(blend1 == GL_SRC_COLOR)
                        newc1 = c0*c1;  //<-
                else if(blend1 == GL_DST_COLOR)
                        newc1 = c1*c1;
                else if(blend0 == GL_ONE_MINUS_SRC_COLOR)
                        newc1 = (1-c0)*c1; //<-
                else if(blend0 == GL_ONE_MINUS_DST_COLOR)
                        newc1 = (1-c1)*c1; //<-


                val = (newc0+newc1)*255;
                if(val > 255) val=255;
                if(val < 0) val=0;

                dst[i] = (char)val;
}

You’ve yet to address the efficiency of your code, I take it? :slight_smile: