GLBLENDFUNCSEPARATE(3G)
Okay bestie, this is the glBlendFuncSeparate page from the 3G manual β and the header is serving [FIXME: manual] realness, we love that for us. π
π NAME π
glBlendFuncSeparate β specify pixel arithmetic for RGB and alpha components separately. Yes, separately. Groundbreaking, iconic, we stan. β¨
β¨ C SPECIFICATION β¨
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha);
void glBlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB,
GLenum srcAlpha, GLenum dstAlpha);
π PARAMETERS π
bufβ ForglBlendFuncSeparatei, this specifies the index of the draw buffer for which to set the blend functions. That's the one you're targeting, bestie. π―srcRGBβ Specifies how the red, green, and blue blending factors are computed. The initial value isGL_ONE. πdstRGBβ Specifies how the red, green, and blue destination blending factors are computed. The initial value isGL_ZERO. π«ΆsrcAlphaβ Specifies how the alpha source blending factor is computed. The initial value isGL_ONE. β¨dstAlphaβ Specifies how the alpha destination blending factor is computed. The initial value isGL_ZERO. πΈ
π¦ DESCRIPTION π¦
Okay so pixels can be drawn using a function that blends the incoming (source) RGBA values with the RGBA values that are already in the frame buffer (the destination values). Blending is initially disabled. Use glEnable() and glDisable with argument GL_BLEND to enable and disable blending. That's the vibe check. π₯
glBlendFuncSeparate defines the operation of blending for all draw buffers when it is enabled. glBlendFuncSeparatei defines the operation of blending for a single draw buffer specified by buf when enabled for that draw buffer. srcRGB specifies which method is used to scale the source RGB-color components. dstRGB specifies which method is used to scale the destination RGB-color components. Likewise, srcAlpha specifies which method is used to scale the source alpha color component, and dstAlpha specifies which method is used to scale the destination alpha component. The possible methods are described in the following table. Each method defines four scale factors, one each for red, green, blue, and alpha. π
In the table and in subsequent equations, first source, second source and destination color components are referred to as R s0 G s0 B s0 A s0, R s1 G s1 B s1 A s1, and R d G d B d A d, respectively. The color specified by glBlendColor() is referred to as R c G c B c A c. They are understood to have integer values between 0 and k R k G k B k A, where
k c = 2 m c - 1
and m R m G m B m A is the number of red, green, blue, and alpha bitplanes. π§
Source and destination scale factors are referred to as s R s G s B s A and d R d G d B d A. All scale factors have range 0 to 1. β
Okay so here's the big glow-up table β every parameter, and exactly what it does to the RGB factor and the Alpha factor. I'm not gonna lie to you bestie, this is the part everyone screenshots π
GL_ZEROβ RGB factor is0,0,0. Alpha factor is0. Literally the void. Nothing survives. π³οΈGL_ONEβ RGB factor is1,1,1. Alpha factor is1. Everything survives, full main character energy πGL_SRC_COLORβ RGB factor isR_s0/k_R,G_s0/k_G,B_s0/k_B. Alpha factor isA_s0/k_A. So the source colour is literally the multiplier, no cap πGL_ONE_MINUS_SRC_COLORβ RGB factor is1 - R_s0/k_R,1 - G_s0/k_G,1 - B_s0/k_B. Alpha factor is1 - A_s0/k_A. One minus the source colour β the inverse girlies are thriving β¨GL_DST_COLORβ RGB factor isR_d/k_R,G_d/k_G,B_d/k_B. Alpha factor isA_d/k_A. Now it's the destination's turn to be the multiplier, slay π¦
Pssst β in case your brain just glitched:R_s0,G_s0,B_s0andA_s0are the source colour/alpha,R_d,G_d,B_dandA_dare the destination ones. Thekdenominators are those normalising constants. Same letters, same meanings, all the way down the table, iykyk π«Ά
okay bestie we're picking up exactly where we left off β mid-table, mid-subscript, no shame π the row above is wrapping up its little k-over-B situation, and then we get three whole factor rows to look at. no heading, we're just sliding back in like it's nothing π
β β β β
β β k β β
β β B β β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ€
β GL_ONE_MINUS_DST_COLOR β 1 β 1 β
β β 1 β - β
β β 1 β β
β β β A β
β β - β d β
β β β β
β β β k β
β β R β A β
β β d β β
β β β β
β β k β β
β β R β β
β β β β
β β β β
β β β β
β β G β β
β β d β β
β β β β
β β k β β
β β G β β
β β β β
β β β β
β β β β
β β B β β
β β d β β
β β β β
β β k β β
β β B β β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ€
β GL_SRC_ALPHA β A β A β
β β s0 β s0 β
β β β β
β β k β k β
β β A β A β
β β β β
β β β β
β β β β
β β A β β
β β s0 β β
β β β β
β β k β β
β β A β β
β β β β
β β β β
β β β β
β β A β β
β β s0 β β
β β β β
β β k β β
β β A β β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ€
β GL_ONE_MINUS_SRC_ALPHA β 1 β 1 β
β β 1 β - β
β β 1 β β
β β β A β
β β - β s0 β
β β β β
β β k β k β
β β A β A β
β β β β
β β β β
β β β β
β β A β β
β β s0 β β
β β β β
β β k β β
β β A β β
β β β β
β β β β
β β β β
β β A β β
β β s0 β β
β β β β
β β k β β
β β A β β
okay so real talk about what you're even looking at π«Ά β this whole chunk is pure text-art. the terminal took every subscript and banished it to its own line, so a letter with a smaller letter underneath is just that letter with its subscript, doing her best. the little k piles stacked under the letters? same situation. she's typesetting math, we're just witnessing β¨
the three factor names that show up here are GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, and GL_ONE_MINUS_SRC_ALPHA β and each one gets two big ol' cells of stacked symbols sitting next to her in the row.
vibe check on the cells themselves:
GL_ONE_MINUS_DST_COLORβ her first cell opens with1,1,1, then a-, then theR/d,k/R,G/d,k/G,B/d,k/Bstacks. her second cell is way chiller:1,-, and anA/dwith ak/Aunderneath.GL_SRC_ALPHAβ starts withAovers0, thenkoverA, and then that sameA/s0+k/Apattern repeats down the cell. the second cell mirrors theA/s0+k/Asituation at the top and then goes quiet.GL_ONE_MINUS_SRC_ALPHAβ same opening move as the first row (1,1,1,-), but her second cell is doing1,-,A/s0,k/A, and then theA/s0+k/Astacks keep rolling down like a little chorus π
β οΈ do not try to retype this by hand, bestie. the spacing is load-bearing, the subscripts will absolutely humble you, and one missing space turns the whole thing into modern art π
and yeah β the β bars are the column walls and the βββββΌββββ€ lines are the row dividers, so if your eyes are glazing over, just follow the walls. the factor name lives in the first cell, and everything after it is her stacked-up symbol situation, one column at a time π
she is still not done though β this table has more where that came from, so hydrate and keep scrolling πΈ
okay bestie, table time continues π
quick reminder of the layout: left column = the sfactor/dfactor parameter, middle column = the source blend factor, right column = the destination blend factor. The little subscripts matter: d is for destination, c is for constant. Here's the next chunk, row by row π
GL_DST_ALPHAβ source factor:(A_d, A_d, A_d, A_d); destination factor:(A_d, A_d, A_d, A_d). Both sides just copy the destination alpha into every component, lowkey obsessed with how symmetric that is β¨GL_ONE_MINUS_DST_ALPHAβ source factor:(1, 1, 1, 1) - (A_d, A_d, A_d, A_d); destination factor:(1, 1, 1, 1) - (A_d, A_d, A_d, A_d). It's giving "invert the dst alpha," the1minus each component is literally doing the whole job π¦GL_CONSTANT_COLORβ source factor:(R_c, G_c, B_c, A_c); destination factor:(R_c, G_c, B_c, A_c). The constant color, same on both sides, main character energy fr fr πΈGL_ONE_MINUS_CONSTANT_COLORβ source factor:(1, 1, 1, 1) - (R_c, G_c, B_c, A_c); destination factor:(1, 1, 1, 1) - (R_c, G_c, B_c, A_c). Same constant color but flipped, one minus on every component, no cap πGL_CONSTANT_ALPHAβ source factor:(A_c, A_c, A_c, A_c); destination factor:(A_c, A_c, A_c, A_c). Constant alpha spread across all four components on both sides, slay π
okay so we're literally still in the thick of the table, bestie β no escape yet π. and the formatter has fully betrayed us: every cell got stacked vertically instead of sitting pretty in a row, so I'mma read each one top-to-bottom for you. think of it like reading a text from your friend who sends one word per message. you get it. β¨
so, continuing where we left off, the factor table keeps going like this:
GL_ONE_MINUS_CONSTANT_ALPHAβ left cell, stacked top-to-bottom:1 1 1 - A c A c A c A cΒ· right cell:1 - A cGL_SRC_ALPHA_SATURATEβ left cell:i i iΒ· right cell:1GL_SRC1_COLORβ left cell:R s1 k R G s1 k G B s1 k BΒ· right cell:A s1 k AGL_ONE_MINUS_SRC1_COLORβ left cell:1 1 1 1 - R s1 k R G s1 k G B s1 k BΒ· right cell:1 - A s1 k AGL_SRC1_ALPHAβ left cell:A s1 k AΒ· right cell:A s1 k A
π«Ά a tiny heads-up so nobody panics: those s1 bits are the dual-source subscript vibe, and the A, c, i, R, G, B letters are exactly the letters the table uses β I'm not renaming a single one, because that would be a crime and also wrong. characters are sacred here, periodt. π
and yeah, GL_SRC1_ALPHA row is where this part of the page cuts off, so the table is still not done with us β it just keeps going in the next bit. stay with me, we're so close to the end of the grid π
πΈ
β¦and the grid lands on its very last row, bestie π β here's everything that's still in those boxes:
GL_ONE_MINUS_SRC1_ALPHAβ your girl is not gonna pretend the cells didn't get stacked vertically in transit π so here's every token from that row, straight up, no edits:1,1,1,-,A_s1,k_A
And then the table hands you its little helper variable:
i = min(A_s, 1 - A_d)
So to figure out the actual blended RGBA values of a pixel, the system busts out these bad boys β the equation block is giving main character energy fr π :
R_d = min(k_R, R_s s_R + R_d d_R)
G_d = min(k_G, G_s s_G + G_d d_G)
B_d = min(k_B, B_s s_B + B_d d_B)
A_d = min(k_A, A_s s_A + A_d d_A)
Okay lowkey important caveat incoming π«Ά β despite how precise those equations look, blending arithmetic is not exactly specified, because blending operates with imprecise integer color values. But here's the guarantee you can take to the group chat: a blend factor that should be equal to 1 is guaranteed not to modify its multiplicand, and a blend factor equal to 0 reduces its multiplicand to 0. Iconic behaviour, no cap β¨
For example, when srcRGB is GL_SRC_ALPHA, dstRGB is GL_ONE_MINUS_SRC_ALPHA, and A_s is equal to k_A, the equations reduce to a simple replacement:
R_d = R_s
G_d = G_s
B_d = B_s
A_d = A_s
πΈ NOTES πΈ
- Incoming (source) alpha is correctly thought of as a material opacity β ranging from
1.0(k_A), which represents complete opacity, to0.0(0), which represents complete transparency. Obsessed with a clean scale honestly π - When more than one color buffer is enabled for drawing, the GL performs blending separately for each enabled buffer, using the contents of that buffer for destination color. (See
glDrawBuffer().) Yes bestie, it's per-buffer, don't come for me π - When dual source blending is enabled (i.e., one of the blend factors requiring the second color input is used), the maximum number of enabled draw buffers is given by
GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, which may be lower thanGL_MAX_DRAW_BUFFERS. So likeβ¦ check it before you flex π₯
π ERRORS π
GL_INVALID_ENUMis generated if either srcRGB or dstRGB is not an accepted value. Not an accepted value? Not the vibe. Periodt.GL_INVALID_VALUEis generated byglBlendFuncSeparateiif buf is greater than or equal to the value ofGL_MAX_DRAW_BUFFERS. Sir, that buffer does not exist π
π ASSOCIATED GETS π
glGet()with argumentGL_BLEND_SRC_RGBglGet()with argumentGL_BLEND_SRC_ALPHAglGet()with argumentGL_BLEND_DST_RGBglGet()with argumentGL_BLEND_DST_ALPHAglIsEnabled()with argumentGL_BLEND
π VERSION SUPPORT π
The original grid down here is all about which OpenGL Version does what β columns run 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, and the rows are labelled Function / Feature Name. Here's the tea, de-gridded π«Ά
glBlendFuncSeparateββin every single one:2.0,2.1,3.0,3.1,3.2,3.3,4.0,4.1,4.2,4.3,4.4,4.5. She's been here since day one, an absolute legend πglBlendFuncSeparateiβ-for2.0,2.1,3.0,3.1,3.2,3.3(naur, she slept through those π), thenβfor4.0,4.1,4.2,4.3,4.4,4.5. Late to the party but she ATE π
π«Ά SEE ALSO π«Ά
glBlendColor(), glBlendFunc(), glBlendEquation(), glClear(), glDrawBuffer(), glEnable(), glLogicOp(), glStencilFunc()
the whole friend group, go say hi π
Β©οΈ COPYRIGHT Β©οΈ
Copyright Β© 1991-2006 Silicon Graphics, Inc. Copyright Β© 2010-2018 Khronos Group. This document is licensed under the SGI Free Software B License. For details, see http://oss.sgi.com/projects/FreeB/.
Β©οΈ COPYRIGHT Β©οΈ (the second one, yes there are two π )
Copyright Β© 1991-2006 Silicon Graphics, Inc.
Copyright Β© 2010-2014 Khronos Group
And that's the whole page, bestie!! π¦ You made it to the very end, I'm so proud π This lil' beauty comes from [FIXME: source], stamped 08/09/2021, and answers to the name GLBLENDFUNCSEPARATE(3G). Screenshot it, memorise it, live it. Mwah πβ¨
π¦ where this page comes from
- centos-stream 9: gl-manpages 1.1-24.20190306.el9 Β· MIT and Open Publication
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms