OpenGL has no way of knowing what objects you're going to draw in
the future.
All it knows about is the current object being drawn, and the results
of everything already drawn, stored in the frame buffer.
Therefore, the blending operation uses the current object and the
pixels in the framebuffer, and then stores the result into the same
pixel locations in the framebuffer (hence the term destination).
+ | = |
Once the blended pixels have been stored in the framebuffer, they're treated just like any other pixels - OpenGL doesn't remember that they were transparent.
This means that, if you want to draw a transparent object in front of
an opaque object, you should draw the opaque object first.
Otherwise, if the opaque object is draw second, OpenGL will determine
(using depth buffering) that it's behind the transparent object,
and not draw the hidden parts at all, rather than doing the transparency
blending.
Draw sphere, then cube | Draw cube, then sphere |
---|---|
Example code: drawOrder0.c
Therefore, you should draw all your opaque objects first, followed by the transparent object(s).
But, this isn't enough, if you have several transparent objects in your scene, and one might appear in front of another.
Example code: drawOrder1.c
In this case, you need to make sure to always draw the objects in back-to-front order - i.e., draw the farthest object first, then the next nearer object, ..., and the nearest object last.
This order depends on the camera's position, as well as the objects' positions.
A generalized solution is beyond the scope of this lecture, but if you need to implement one, you will want to design your program to keep all of its objects in a generic list, so that it can draw them in any order. Then, take a look at the qsort() function.