I tested everything. I ran through every line thrice to make sure it was right. I hooked up gdb. I looked at wikis, example implementations, the reference documentation. I googled. And yet I couldn’t seem to get alpha blended blitting to work.
I have two (or more) surfaces (SDL terminology, think “screen buffer”) and want to blit one onto the other, but with 50% opacity. There is nothing fancy about it – you just set a per-surface alpha value of 127 to the “top” surface and blit it onto the “bottom” one. Two lines of code, plus error handling. Easy. Trivial. Why the fucking hell doesn’t this work in my fucking program, for the fucking love of God?.
After about 2 hours of checking every function call, I switched into “monkey with a typewriter” mode. Randomly erasing and inserting stuff. Randomly changing things. Randomly eating bananas.
Nothing. Everything else worked just fine – I just could not get the friggin’ surfaces to blend onto each other, no matter what I tried.
So, I lit a cigarette and then it came to me… The ring buffer!
Yes, my to-be-blended surfaces came out of a ring buffer. Yes, there was the bug. It just returned the same surface over and over again – so I successfully blitted the same screens on top of each other. With 50% opacity. A graphical effect commonly known as “resource-wasting transparency-cancelling blending” (not a very catchy name, I know).
So, the morale of the story is: check your ring buffer implementations first.
Uh… or something like that, anyway.