The
iPhone supports the following blending-related extensions in OpenGL ES
1.1:- GL_OES_blend_subtract (all iPhone models)
Allows you to specify a blending
operation other than addition, namely, subtraction.
- GL_OES_blend_equation_separate (iPhone 3GS and higher)
Allows you to specify two separate
blending operations: one for RGB, the other for alpha.
- GL_OES_blend_func_separate (iPhone 3GS and higher)
Allows you to
specify two separate pairs of blend factors: one pair for RGB, the
other for alpha.
With OpenGL ES 2.0, these extensions are part
of the core specification. Together they declare the following
functions:
void glBlendEquation(GLenum operation)
void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorAlpha, GLenum dfactorAlpha);
void glBlendEquationSeparate(GLenum operationRGB, GLenum operationAlpha);
For ES 1.1, remember to append
OES to the end of each function since that’s the
naming convention for extensions.
The parameters to
glBlendEquation and
glBlendEquationSeparate can be one of the
following:
- GL_FUNC_ADD
Adds the source operand to the source
operand; this is the default.
- GL_FUNC_SUBTRACT
Subtracts the destination operand from
the source operand.
- GL_FUNC_REVERSE_SUBTRACT
Subtracts the source operand from the
destination operand.
Again, remember to append
_OES for these constants when working with ES
1.1.
When all these extensions are supported, you
effectively have the ability to specify two unique equations: one for
alpha, the other for RGB. Each equation conforms to one of the following
templates:
FinalColor = SrcColor * sfactor + DestColor * dfactor
FinalColor = SrcColor * sfactor - DestColor * dfactor
FinalColor = DestColor * dfactor - SrcColor * sfactor
1. Why Is Blending Configuration Useful?
One use of
GL_FUNC_SUBTRACT is inverting a region of color on
the screen to highlight it. Simply draw a solid white rectangle and use
GL_ONE for both sfactordfactor. You could also use subtraction to perform a
comparison, or visual “diff,” between two images. and
The separate blending equations can be useful
too. For example, perhaps you’d like to leave the destination’s alpha
channel unperturbed because you’re storing information there for
something other than transparency. In such a case, you could say the
following:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
Another time to use separate blending
equations is when you need to draw your triangles in front-to-back order
rather than the usual back-to-front order. To pull this off, take
the following steps:
Set your clear color to (0, 0, 0,
1).
Make sure your source texture (or
per-vertex color) has premultiplied alpha.
Set your blend equation to the
following:
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
To see why this works, let’s go back to the
example of a half-opaque red triangle being rendered on top of a
half-opaque green triangle:
Clear to Black. Result: (0, 0, 0,
1).
Draw the half-opaque red triangle. Since
it’s premultiplied, its source color is (0.5, 0, 0, 0.5). Using the
previous blending equation, the result is (0.5, 0, 0, 0.5).
Draw the half-opaque green triangle; its
source color is (0, 0.5, 0, 0.5). The result after blending is (0.5,
0.25, 0, 0.25).
The resulting pixel is yellowish red, just as
you’d expect. Note that the framebuffer’s alpha value is always inverted
when you’re using this trick.