mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-29 14:42:26 +00:00
GRAPHICS: Fix dest alpha formula in blendPixelPtr
The original alpha computation formula had a problem: If something was drawn on top of a pixel that was already fully opaque, there would be an overflow in the computed alpha, and the destination alpha would be truncated to 0 (fully transparent). In commit 264ba4a9 this formula was replaced with another one, which did not have overflows but also was not correct. This commits introduces a new formula, where the rounding errors have been turned in another direction; drawing a fully opaque pixel on top of a transparent one would result in a pixel which is almost, but not fully, opaque. However, this is no problem in practice, since drawing fully opaque pixels can be achieved with much less code as a special case, so add that (also improves rendering speed).
This commit is contained in:
parent
51d7405a7b
commit
4b81b1299d
@ -620,7 +620,10 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
|
||||
template<typename PixelType>
|
||||
inline void VectorRendererSpec<PixelType>::
|
||||
blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
|
||||
if (sizeof(PixelType) == 4) {
|
||||
if (alpha == 0xff) {
|
||||
// fully opaque pixel, don't blend
|
||||
*ptr = color | _alphaMask;
|
||||
} else if (sizeof(PixelType) == 4) {
|
||||
const byte sR = (color & _redMask) >> _format.rShift;
|
||||
const byte sG = (color & _greenMask) >> _format.gShift;
|
||||
const byte sB = (color & _blueMask) >> _format.bShift;
|
||||
@ -628,15 +631,17 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
|
||||
byte dR = (*ptr & _redMask) >> _format.rShift;
|
||||
byte dG = (*ptr & _greenMask) >> _format.gShift;
|
||||
byte dB = (*ptr & _blueMask) >> _format.bShift;
|
||||
byte dA = (*ptr & _alphaMask) >> _format.aShift;
|
||||
|
||||
dR += ((sR - dR) * alpha) >> 8;
|
||||
dG += ((sG - dG) * alpha) >> 8;
|
||||
dB += ((sB - dB) * alpha) >> 8;
|
||||
dA += ((0xff - dA) * alpha) >> 8;
|
||||
|
||||
*ptr = ((dR << _format.rShift) & _redMask)
|
||||
| ((dG << _format.gShift) & _greenMask)
|
||||
| ((dB << _format.bShift) & _blueMask)
|
||||
| (*ptr & _alphaMask);
|
||||
| ((dA << _format.aShift) & _alphaMask);
|
||||
} else if (sizeof(PixelType) == 2) {
|
||||
int idst = *ptr;
|
||||
int isrc = color;
|
||||
@ -651,7 +656,9 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
|
||||
(_blueMask & ((idst & _blueMask) +
|
||||
((int)(((int)(isrc & _blueMask) -
|
||||
(int)(idst & _blueMask)) * alpha) >> 8))) |
|
||||
(idst & _alphaMask));
|
||||
(_alphaMask & ((idst & _alphaMask) +
|
||||
((int)(((int)(_alphaMask) -
|
||||
(int)(idst & _alphaMask)) * alpha) >> 8))));
|
||||
} else {
|
||||
error("Unsupported BPP format: %u", (uint)sizeof(PixelType));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user