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 β€” For glBlendFuncSeparatei, 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 is GL_ONE. πŸ’–
  • dstRGB β€” Specifies how the red, green, and blue destination blending factors are computed. The initial value is GL_ZERO. 🫢
  • srcAlpha β€” Specifies how the alpha source blending factor is computed. The initial value is GL_ONE. ✨
  • dstAlpha β€” Specifies how the alpha destination blending factor is computed. The initial value is GL_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 is 0, 0, 0. Alpha factor is 0. Literally the void. Nothing survives. πŸ•³οΈ
  • GL_ONE β€” RGB factor is 1, 1, 1. Alpha factor is 1. Everything survives, full main character energy πŸ‘‘
  • GL_SRC_COLOR β€” RGB factor is R_s0/k_R, G_s0/k_G, B_s0/k_B. Alpha factor is A_s0/k_A. So the source colour is literally the multiplier, no cap πŸ’–
  • GL_ONE_MINUS_SRC_COLOR β€” RGB factor is 1 - R_s0/k_R, 1 - G_s0/k_G, 1 - B_s0/k_B. Alpha factor is 1 - A_s0/k_A. One minus the source colour β€” the inverse girlies are thriving ✨
  • GL_DST_COLOR β€” RGB factor is R_d/k_R, G_d/k_G, B_d/k_B. Alpha factor is A_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_s0 and A_s0 are the source colour/alpha, R_d, G_d, B_d and A_d are the destination ones. The k denominators 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 with 1, 1, 1, then a -, then the R/d, k/R, G/d, k/G, B/d, k/B stacks. her second cell is way chiller: 1, -, and an A/d with a k/A underneath.
  • GL_SRC_ALPHA β€” starts with A over s0, then k over A, and then that same A/s0 + k/A pattern repeats down the cell. the second cell mirrors the A/s0 + k/A situation 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 doing 1, -, A/s0, k/A, and then the A/s0 + k/A stacks 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," the 1 minus 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 c
  • GL_SRC_ALPHA_SATURATE β€” left cell: i i i Β· right cell: 1
  • GL_SRC1_COLOR β€” left cell: R s1 k R G s1 k G B s1 k B Β· right cell: A s1 k A
  • GL_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 A
  • GL_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, to 0.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 than GL_MAX_DRAW_BUFFERS. So like… check it before you flex πŸ”₯

πŸ’€ ERRORS πŸ’€

  • GL_INVALID_ENUM is generated if either srcRGB or dstRGB is not an accepted value. Not an accepted value? Not the vibe. Periodt.
  • GL_INVALID_VALUE is generated by glBlendFuncSeparatei if buf is greater than or equal to the value of GL_MAX_DRAW_BUFFERS. Sir, that buffer does not exist 😭

πŸ” ASSOCIATED GETS πŸ”

  • glGet() with argument GL_BLEND_SRC_RGB
  • glGet() with argument GL_BLEND_SRC_ALPHA
  • glGet() with argument GL_BLEND_DST_RGB
  • glGet() with argument GL_BLEND_DST_ALPHA
  • glIsEnabled() with argument GL_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 β€” - for 2.0, 2.1, 3.0, 3.1, 3.2, 3.3 (naur, she slept through those πŸ’€), then βœ” for 4.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 Β© 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 Β© 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