GLBLENDFUNC(3G)
okay bestie, welcome to GLBLENDFUNC(3G) β the page where pixel arithmetic finally makes sense π
β¨
π NAME π
glBlendFunc β specify pixel arithmetic. thatβs the whole vibe π«Ά
π» C SPECIFICATION π»
void glBlendFunc(GLenum sfactor, GLenum dfactor);
void glBlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor);
πΈ PARAMETERS πΈ
bufβ forglBlendFunci, this specifies the index of the draw buffer for which youβre setting the blend function. π―sfactorβ specifies how the red, green, blue, and alpha source blending factors are computed. its initial value isGL_ONE. β¨dfactorβ specifies how the red, green, blue, and alpha destination blending factors are computed. the following symbolic constants are accepted:GL_ZERO,GL_ONE,GL_SRC_COLOR,GL_ONE_MINUS_SRC_COLOR,GL_DST_COLOR,GL_ONE_MINUS_DST_COLOR,GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA,GL_CONSTANT_COLOR,GL_ONE_MINUS_CONSTANT_COLOR,GL_CONSTANT_ALPHA, andGL_ONE_MINUS_CONSTANT_ALPHA. its initial value isGL_ZERO. π
π¦ DESCRIPTION π¦
Pixels can be drawn using a function that blends the incoming (source) RGBA values with the RGBA values that are already hanging out in the frame buffer (the destination values). blending is initially disabled, no cap. to enable and disable blending, use glEnable() and glDisable with the argument GL_BLEND. π«Ά
glBlendFunc defines the operation of blending for all draw buffers when it is enabled. glBlendFunci defines the operation of blending for a single draw buffer specified by buf when blending is enabled for that draw buffer. sfactor specifies which method is used to scale the source color components. dfactor specifies which method is used to scale the destination color components. both parameters must be one of the following symbolic constants: GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE, GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR, GL_SRC1_ALPHA, and GL_ONE_MINUS_SRC1_ALPHA. π
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, the 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. the scale factors described in the table, denoted f R f G f B f A, represent either source or destination factors. all scale factors have range <mint>0</mint> to <mint>1</mint>. β
Okay so this is the big one β the table of what f actually is for each parameter π You already know f is the vector <f_R, f_G, f_B, f_A>, so here's the vibe check on every value, one by one. Keep this bookmarked, bestie, fr fr π
GL_ZEROβ it's giving nothing, absolutely nothing.f_R = 0,f_G = 0,f_B = 0,f_A = 0πGL_ONEβ the full send.f_R = 1,f_G = 1,f_B = 1,f_A = 1β¨GL_SRC_COLORβ source color steps up, and honestly it ate:f_R = R_s0 / k_R,f_G = G_s0 / k_G,f_B = B_s0 / k_B,f_A = A_s0 / k_Aπ₯GL_ONE_MINUS_SRC_COLORβ the inverse of the above, main character energy but backwards πf_R = 1 - R_s0 / k_R,f_G = 1 - G_s0 / k_G,f_B = 1 - B_s0 / k_B,f_A = 1 - A_s0 / k_AGL_DST_COLORβ now the destination color gets its moment, lowkey obsessed:f_R = R_d / k_R,f_G = G_d / k_G,f_B = B_d / k_B,f_A = A_d / k_AπΈ
ngl the raw table in the original doc looks like it got run through a blender (those broken subscripts??s0sitting on its own line?? a whole-just vibing in theGL_ONE_MINUS_SRC_COLORrow π) but the math above is exactly what it's saying, no cap.
okay so we are literally mid-table right now β no header row in sight, we just vibing in the middle of the blend-factor grid π
this chunk is the whole "what does each factor actually expand to" moment, and it's giving very "chart from a textbook that lost its caption." deep breaths, bestie, i'm transcribing all of it, nothing skipped, not a single stray 1 left behind π«Ά
first row, and it's the long one:
β GL_ONE_MINUS_DST_COLOR β 1 β
β β 1 β
β β 1 β
β β 1 β
β β β
β β - β
β β β
β β β
β β R β
β β d β
β β β
β β k β
β β R β
β β β
β β β
β β β
β β G β
β β d β
β β β
β β k β
β β G β
β β β
β β β
β β β
β β B β
β β d β
β β β
β β k β
β β B β
β β β
β β β
β β β
β β A β
β β d β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
so GL_ONE_MINUS_DST_COLOR is the row that starts with four 1s stacked up top, then a lone -, then it gets all fancy with R/d, k/R, G/d, k/G, B/d, k/B, A/d, k/A in little two-line towers down the column β¨ ngl this is the table equivalent of someone texting you one letter per message. iconic behaviour honestly.
next!! π
β GL_SRC_ALPHA β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
GL_SRC_ALPHA does the whole thing four separate times: A with s0 underneath it, then k with A underneath it, and it justβ¦ repeats that pattern over and over π not one single 1 in this row, which is honestly a serve. four repeats, zero notes.
then the one that's basically the previous row's evil twin:
β GL_ONE_MINUS_SRC_ALPHA β 1 β
β β 1 β
β β 1 β
β β 1 β
β β β
β β - β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s0 β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
GL_ONE_MINUS_SRC_ALPHA opens with the same four 1s, hits the -, and then serves the A/s0 + k/A pattern four times π it's giving remix, it's giving "same energy, different name," we love a consistent queen.
and the last one, which does NOT get a closing border because it's the end of the chunk:
β GL_DST_ALPHA β A β
β β d β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β d β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β d β
β β β
β β k β
β β A β
β β β
GL_DST_ALPHA is the chill one β no 1s, no -, just A/d paired with k/A, three full rounds of it, and then it trails off into blank cells π bestie is tired, let her rest.
quick vibe check on what actually appeared in this stretch, so you can see the cast of characters π
GL_ONE_MINUS_DST_COLORβ four1s, a lone-, thenR/d,k/R,G/d,k/G,B/d,k/B,A/d,k/A.GL_SRC_ALPHAβA/s0,k/A, repeated four times, no constants at all.GL_ONE_MINUS_SRC_ALPHAβ four1s, a lone-, thenA/s0,k/A, repeated four times.GL_DST_ALPHAβA/d,k/A, repeated three times, then blank space.
heads up bestie: read the letters in each tower top-to-bottom the way they're laid out βRabovedis its own thing,kaboveRis its own thing. do NOT smush them together into a word, my girl did that once and saw god π the layout is the layout, we respect it.
and yeah the - sitting alone in the middle of the ONE_MINUS rows is a whole mood β it's just there, unbothered, no neighbours, no explanation. we stan a mysterious minus sign π
okay don't go anywhere, there's more of this coming and it only gets more unhinged π
okay so we're still deep in this table bestie, and honestly it's giving "trust the process" β here's the rest of the factor values, every single one, no cap π :
GL_ONE_MINUS_DST_ALPHAβ1 - A_d,1 - A_d,1 - A_d,1 - A_d(all four of them, because why would it be subtle β¨)GL_CONSTANT_COLORβR_c,G_c,B_c,A_cGL_ONE_MINUS_CONSTANT_COLORβ1 - R_c,1 - G_c,1 - B_c,1 - A_cGL_CONSTANT_ALPHAβA_c,A_c,A_c,A_c(constant alpha in every lane, obsessed πΈ)GL_ONE_MINUS_CONSTANT_ALPHAβ1 - A_c,1 - A_c,1 - A_c,1 - A_cGL_SRC_ALPHA_SATURATEβi,i,i,1GL_SRC1_COLORβR_s1, β¦
okay bestie we're literally mid-table right now and that's fine, we just keep scrolling π
here's the rest of GL_SRC1_COLOR bleeding into the next rows β do not panic, it's the same table, just taller:
β β G β
β β s1 β
β β β
β β k β
β β G β
β β β
β β β
β β β
β β B β
β β s1 β
β β β
β β k β
β β B β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
β GL_ONE_MINUS_SRC1_COLOR β 1 β
β β 1 β
β β 1 β
β β 1 β
β β β
β β - β
β β β
β β β
β β R β
β β s1 β
β β β
β β k β
β β R β
β β β
β β β
β β β
β β G β
β β s1 β
β β β
β β k β
β β G β
β β β
β β β
β β β
β β B β
β β s1 β
β β β
β β k β
β β B β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
β GL_SRC1_ALPHA β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ€
β GL_ONE_MINUS_SRC1_ALPHA β 1 β
β β 1 β
β β 1 β
β β 1 β
β β β
β β - β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
β β β
β β β
β β β
β β A β
β β s1 β
β β β
β β k β
β β A β
so like, a quick vibe check on what your eyes just went through π β these last few rows are the source-1-color era of the table, and yes it's giving "why is this so tall" but every line is doing its job:
GL_SRC1_COLORβ the tail end of its blend factors, wrapping up theG,BandAbits all the way down. that's the row that got sliced across parts, iykyk πGL_ONE_MINUS_SRC1_COLORβ same shape, except it's the one minus version: the1s up top, then a-, then all those component letters again. it's literally "one minus the color", that's the whole personality πGL_SRC1_ALPHAβ this one is the lowkey fave because it's just...A. that's it.Aall the way down, four times per side, no drama, no extra letters. iconic minimalism β¨GL_ONE_MINUS_SRC1_ALPHAβ and obviously its chaotic sibling:1,1,1,1, a lil-, then a wall ofAs. same energy, opposite direction π
fr fr bestie, if the column of single letters is making your brain buffer β that's just how glBlendFunc prints its factor table, and it is not going to get shorter. we stan anyway π«Ά
and we're still inside the table, so don't you dare close the tab β there's more coming and it's a whole mood πΈ
In the table,</p>
i = min(A_s k_A, A_d k_A)
So to figure out the blended RGBA values of a pixel, the system runs these equations β lowkey the moment of truth:
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)
And yeah, bestie, I know those equations look all precise and intimidating β but blending arithmetic is not exactly specified. π It literally can't be, because blending operates with imprecise integer color values. So don't come for the math. β But here's the promise that actually holds: 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. π«Ά
For example β when sfactor is GL_SRC_ALPHA, dfactor 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
πΈ EXAMPLES πΈ
Okay so transparency β the icon of it all. π
It's best implemented using blend function (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) with primitives sorted from farthest to nearest. And ngl, the cute part: this transparency calculation does not require the presence of alpha bitplanes in the frame buffer. π
Blend function (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) is also serving for rendering antialiased points and lines in arbitrary order. β¨
Polygon antialiasing is optimized using blend function (GL_SRC_ALPHA_SATURATE, GL_ONE) with polygons sorted from nearest to farthest. (Peep the glEnable(), glDisable reference page and the GL_POLYGON_SMOOTH argument for info on polygon antialiasing.) Destination alpha bitplanes β which must be present for this blend function to operate correctly β store the accumulated coverage. π
β NOTES β
Incoming (source) alpha is correctly thought of as a material opacity, ranging from 1.0 (K_A) β that's complete opacity β to 0.0 (0), which is complete transparency. See-through queen behavior. π¦
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().) π
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 than GL_MAX_DRAW_BUFFERS. β οΈ
π ERRORS π
GL_INVALID_ENUMis generated if eithersfactorordfactoris not an accepted value. π©GL_INVALID_VALUEis generated byglBlendFunciifbufis greater than or equal to the value ofGL_MAX_DRAW_BUFFERS. π©
π 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 π
No table for us, bestie β we're doing this as a glow-up list. π₯ The OpenGL versions we care about are 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5.
glBlendFuncβ β in2.0, β in2.1, β in3.0, β in3.1, β in3.2, β in3.3, β in4.0, β in4.1, β in4.2, β in4.3, β in4.4, β in4.5. She ate and left no crumbs. β¨glBlendFunciβ-in2.0,-in2.1,-in3.0,-in3.1,-in3.2,-in3.3, β in4.0, β in4.1, β in4.2, β in4.3, β in4.4, β in4.5. She showed up late (4.0) but she showed up. π
π SEE ALSO π
glBlendColor(), glBlendEquation(), glBlendFuncSeparate(), glClear(), glDrawBuffer(), glEnable(), glLogicOp(), glStencilFunc() β go read those next, iykyk. π«Ά
π COPYRIGHT π
Copyright Β© 1991-2006 Silicon Graphics, Inc. Copyright Β© 2010-2014 Khronos Group. This document is licensed under the SGI Free Software B License. For details, see http://oss.sgi.com/projects/FreeB/.
Copyright Β© 1991-2006 Silicon Graphics, Inc. Copyright Β© 2010-2014 Khronos Group
And that's the whole page, babes β go forth and blend responsibly. πΈ The footer says [FIXME: source] (yes, the source is literally a placeholder, she's mysterious π) and it's dated 08/09/2021, filed under GLBLENDFUNC(3G). 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