[Scummvm-devel] Alpha blending (0.13.0)
Marcus Comstedt
marcus at mc.pp.se
Sun Feb 1 15:25:25 CET 2009
Hi guys.
I've fixed the function VectorRendererSpec::blendPixelPtr() on
the release branch to handle the alpha channel correctly, in
order to fix the regression that the menus were looking crap
on the DC. :-)
To address the concerns that it was bad maintainability to have
double functions, I made one single function that works with both
pixel formats that have an alpha channel, and those that do not.
And by switching the hardware blending model to pre-multiplied alpha¹,
the code is actually identical to the old one, but with an extra
bitwise or, which will be optimized away by constant folding by
any decent optimizer for pixel formats without alpha (expression
is '... | (kAlphaMask & x)' where kAlphaMask is constant zero for
such pixel formats).
I've tested the code on the Dreamcast and on Linux with the SDL
backend, but it would be good to test it on the PSP as well,
since it has a different alpha format from both these. Joost?
I did not change applyScreenShading(), as it did not seem to be used,
but a similar fix is possible for kShadingDim at least. For
kShadingLuminance, simply preserving the old alpha should be enough,
but of course only the overlay would be affected, not any game
graphics.
¹) Pre-multiplied alpha means that the values of the red, green, and
blue components in the pixel are already scaled to be in the range
[0.0, alpha] instead of [0.0, 1.0], so a semi-transparent white
pixel is 0x80808080, not 0x80ffffff. For a 1-bit alpha format
like the 1555 format used on PSP, the only difference is that
a transparent pixel should always be 0x0000, not some random RGB
value with the alpha set to 0.
If/when someone makes a GL backend, the correct blending function
to use is:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Marcus
More information about the Scummvm-devel
mailing list