Browse Source

Use premultiplied alpha for plDynamicTextMaps on GUI controls.

This fixes the irregular dark fringes around light text when not exactly pixel-aligned that are caused by independent interpolation of color and alpha. It also makes calculations simpler for things to come.
Christian Walther 13 years ago committed by Anne Marije v/d Meer
parent
commit
8c5286400a
  1. 9
      Sources/Plasma/CoreLib/hsColorRGBA.h
  2. 3
      Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIControlMod.cpp
  3. 3
      Sources/Plasma/NucleusLib/inc/hsGMatState.h
  4. 26
      Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.cpp
  5. 6
      Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h
  6. 63
      Sources/Plasma/PubUtilLib/plGImage/plFont.cpp
  7. 2
      Sources/Plasma/PubUtilLib/plGImage/plFont.h
  8. 22
      Sources/Plasma/PubUtilLib/plGImage/plMipmap.cpp
  9. 13
      Sources/Plasma/PubUtilLib/plGImage/plMipmap.h
  10. 18
      Sources/Plasma/PubUtilLib/plPipeline/DX/plDXPipeline.cpp

9
Sources/Plasma/CoreLib/hsColorRGBA.h

@ -103,6 +103,7 @@ struct hsColorRGBA {
hsColorRGBA& FromARGB32(uint32_t c); hsColorRGBA& FromARGB32(uint32_t c);
uint32_t ToARGB32() const; uint32_t ToARGB32() const;
uint32_t ToARGB32Premultiplied() const;
void Read(hsStream *stream); void Read(hsStream *stream);
void Write(hsStream *stream) const; void Write(hsStream *stream) const;
@ -141,6 +142,14 @@ inline uint32_t hsColorRGBA::ToARGB32() const
| (uint32_t(b * 255.99f) << 0); | (uint32_t(b * 255.99f) << 0);
} }
inline uint32_t hsColorRGBA::ToARGB32Premultiplied() const
{
return (uint32_t(a * 255.0f + 0.5f) << 24)
| (uint32_t(a * r * 255.0f + 0.5f) << 16)
| (uint32_t(a * g * 255.0f + 0.5f) << 8)
| (uint32_t(a * b * 255.0f + 0.5f) << 0);
}
inline hsColorRGBA operator+(const hsColorRGBA& s, const hsColorRGBA& t) inline hsColorRGBA operator+(const hsColorRGBA& s, const hsColorRGBA& t)
{ {
hsColorRGBA res; hsColorRGBA res;

3
Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIControlMod.cpp

@ -683,7 +683,7 @@ bool pfGUIControlMod::ISetUpDynTextMap( plPipeline *pipe )
extraH -= height; extraH -= height;
fDynTextMap->Reset(); fDynTextMap->Reset();
fDynTextMap->Create( width, height, HasFlag( kXparentBgnd ), extraW, extraH ); fDynTextMap->Create( width, height, HasFlag( kXparentBgnd ), extraW, extraH, true );
fDynTextMap->SetFont( GetColorScheme()->fFontFace, GetColorScheme()->fFontSize, GetColorScheme()->fFontFlags, fDynTextMap->SetFont( GetColorScheme()->fFontFace, GetColorScheme()->fFontSize, GetColorScheme()->fFontFlags,
HasFlag( kXparentBgnd ) ? false : true ); HasFlag( kXparentBgnd ) ? false : true );
@ -694,6 +694,7 @@ bool pfGUIControlMod::ISetUpDynTextMap( plPipeline *pipe )
// out with 1:1 mapping from textel to pixel // out with 1:1 mapping from textel to pixel
plLayer *layer = (plLayer *)fDynTextLayer; plLayer *layer = (plLayer *)fDynTextLayer;
layer->SetTransform( fDynTextMap->GetLayerTransform() ); layer->SetTransform( fDynTextMap->GetLayerTransform() );
layer->SetBlendFlags( layer->GetBlendFlags() | hsGMatState::kBlendAlphaPremultiplied );
// Let the derived classes do their things // Let the derived classes do their things
IPostSetUpDynTextMap(); IPostSetUpDynTextMap();

3
Sources/Plasma/NucleusLib/inc/hsGMatState.h

@ -85,7 +85,8 @@ enum hsGMatBlendFlags {
kBlendEnvBumpNext = 0x800000, kBlendEnvBumpNext = 0x800000,
kBlendSubtract = 0x1000000, kBlendSubtract = 0x1000000,
kBlendRevSubtract = 0x2000000, kBlendRevSubtract = 0x2000000,
kBlendAlphaTestHigh = 0x4000000 kBlendAlphaTestHigh = 0x4000000,
kBlendAlphaPremultiplied = 0x8000000
}; };
enum hsGMatClampFlags { enum hsGMatClampFlags {

26
Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.cpp

@ -76,7 +76,7 @@ plProfile_Extern(MemMipmaps);
//// Constructor & Destructor ///////////////////////////////////////////////// //// Constructor & Destructor /////////////////////////////////////////////////
plDynamicTextMap::plDynamicTextMap() plDynamicTextMap::plDynamicTextMap()
: fVisWidth(0), fVisHeight(0), fHasAlpha(false), fJustify(kLeftJustify), : fVisWidth(0), fVisHeight(0), fHasAlpha(false), fPremultipliedAlpha(false), fJustify(kLeftJustify),
fInitBuffer(nullptr), fFontSize(0), fFontFlags(0), fInitBuffer(nullptr), fFontSize(0), fFontFlags(0),
fFontAntiAliasRGB(false), fFontBlockRGB(false), fHasCreateBeenCalled(false) fFontAntiAliasRGB(false), fFontBlockRGB(false), fHasCreateBeenCalled(false)
{ {
@ -88,10 +88,10 @@ plDynamicTextMap::~plDynamicTextMap()
Reset(); Reset();
} }
plDynamicTextMap::plDynamicTextMap( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth, uint32_t extraHeight ) plDynamicTextMap::plDynamicTextMap( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth, uint32_t extraHeight, bool premultipliedAlpha )
: fInitBuffer(nullptr) : fInitBuffer(nullptr)
{ {
Create( width, height, hasAlpha, extraWidth, extraHeight ); Create( width, height, hasAlpha, extraWidth, extraHeight, premultipliedAlpha );
} }
//// SetNoCreate ////////////////////////////////////////////////////////////// //// SetNoCreate //////////////////////////////////////////////////////////////
@ -113,7 +113,7 @@ void plDynamicTextMap::SetNoCreate( uint32_t width, uint32_t height, bool has
//// Create /////////////////////////////////////////////////////////////////// //// Create ///////////////////////////////////////////////////////////////////
void plDynamicTextMap::Create( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth, uint32_t extraHeight ) void plDynamicTextMap::Create( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth, uint32_t extraHeight, bool premultipliedAlpha )
{ {
SetConfig( hasAlpha ? kARGB32Config : kRGB32Config ); SetConfig( hasAlpha ? kARGB32Config : kRGB32Config );
@ -121,6 +121,7 @@ void plDynamicTextMap::Create( uint32_t width, uint32_t height, bool hasAlpha
fVisWidth = (uint16_t)width; fVisWidth = (uint16_t)width;
fVisHeight = (uint16_t)height; fVisHeight = (uint16_t)height;
fHasAlpha = hasAlpha; fHasAlpha = hasAlpha;
fPremultipliedAlpha = premultipliedAlpha;
for( fWidth = 1; fWidth < width + extraWidth; fWidth <<= 1 ); for( fWidth = 1; fWidth < width + extraWidth; fWidth <<= 1 );
for( fHeight = 1; fHeight < height + extraHeight; fHeight <<= 1 ); for( fHeight = 1; fHeight < height + extraHeight; fHeight <<= 1 );
@ -385,7 +386,7 @@ void plDynamicTextMap::ClearToColor( hsColorRGBA &color )
if( !IIsValid() ) if( !IIsValid() )
return; return;
uint32_t i, hex = color.ToARGB32(); uint32_t i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
uint32_t *data = (uint32_t *)fImage; uint32_t *data = (uint32_t *)fImage;
// Buffer is of size fVisWidth x fVisHeight, so we need a bit of work to do this right // Buffer is of size fVisWidth x fVisHeight, so we need a bit of work to do this right
@ -500,6 +501,7 @@ void plDynamicTextMap::DrawString( uint16_t x, uint16_t y, const wchar_t *tex
fCurrFont->SetRenderClipRect( 0, 0, fVisWidth, fVisHeight ); fCurrFont->SetRenderClipRect( 0, 0, fVisWidth, fVisHeight );
fCurrFont->SetRenderColor( fFontColor.ToARGB32() ); fCurrFont->SetRenderColor( fFontColor.ToARGB32() );
fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB ); fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB );
fCurrFont->SetRenderFlag( plFont::kRenderAlphaPremultiplied, fPremultipliedAlpha );
fCurrFont->RenderString( this, x, y, text ); fCurrFont->RenderString( this, x, y, text );
} }
@ -520,6 +522,7 @@ void plDynamicTextMap::DrawClippedString( int16_t x, int16_t y, const wchar_t
fCurrFont->SetRenderClipping( x, y, width, height ); fCurrFont->SetRenderClipping( x, y, width, height );
fCurrFont->SetRenderColor( fFontColor.ToARGB32() ); fCurrFont->SetRenderColor( fFontColor.ToARGB32() );
fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB ); fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB );
fCurrFont->SetRenderFlag( plFont::kRenderAlphaPremultiplied, fPremultipliedAlpha );
fCurrFont->RenderString( this, x, y, text ); fCurrFont->RenderString( this, x, y, text );
} }
@ -539,6 +542,7 @@ void plDynamicTextMap::DrawClippedString( int16_t x, int16_t y, const wchar_t
SetJustify( fJustify ); SetJustify( fJustify );
fCurrFont->SetRenderClipping( clipX, clipY, width, height ); fCurrFont->SetRenderClipping( clipX, clipY, width, height );
fCurrFont->SetRenderColor( fFontColor.ToARGB32() ); fCurrFont->SetRenderColor( fFontColor.ToARGB32() );
fCurrFont->SetRenderFlag( plFont::kRenderAlphaPremultiplied, fPremultipliedAlpha );
fCurrFont->RenderString( this, x, y, text ); fCurrFont->RenderString( this, x, y, text );
} }
@ -559,6 +563,7 @@ void plDynamicTextMap::DrawWrappedString( uint16_t x, uint16_t y, const wchar
fCurrFont->SetRenderWrapping( x, y, width, height ); fCurrFont->SetRenderWrapping( x, y, width, height );
fCurrFont->SetRenderColor( fFontColor.ToARGB32() ); fCurrFont->SetRenderColor( fFontColor.ToARGB32() );
fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB ); fCurrFont->SetRenderFlag( plFont::kRenderIntoAlpha, fFontBlockRGB );
fCurrFont->SetRenderFlag( plFont::kRenderAlphaPremultiplied, fPremultipliedAlpha );
fCurrFont->RenderString( this, x, y, text, lastX, lastY ); fCurrFont->RenderString( this, x, y, text, lastX, lastY );
} }
@ -639,7 +644,7 @@ void plDynamicTextMap::FillRect( uint16_t x, uint16_t y, uint16_t width, uint
width = (uint16_t)(fWidth - x); width = (uint16_t)(fWidth - x);
// Gee, how hard can it REALLY be? // Gee, how hard can it REALLY be?
uint32_t i, hex = color.ToARGB32(); uint32_t i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
height += y; height += y;
if( height > fHeight ) if( height > fHeight )
height = (uint16_t)fHeight; height = (uint16_t)fHeight;
@ -664,7 +669,7 @@ void plDynamicTextMap::FrameRect( uint16_t x, uint16_t y, uint16_t width, uin
height = (uint16_t)(fHeight - y); height = (uint16_t)(fHeight - y);
// Shouldn't be much harder // Shouldn't be much harder
uint32_t i, hex = color.ToARGB32(); uint32_t i, hex = fPremultipliedAlpha ? color.ToARGB32Premultiplied() : color.ToARGB32();
uint32_t *dest1, *dest2; uint32_t *dest1, *dest2;
dest1 = GetAddr32( x, y ); dest1 = GetAddr32( x, y );
@ -699,6 +704,9 @@ void plDynamicTextMap::DrawImage( uint16_t x, uint16_t y, plMipmap *image, Dr
else if( method == kImgSprite ) else if( method == kImgSprite )
opts.fFlags = plMipmap::kCopySrcAlpha; opts.fFlags = plMipmap::kCopySrcAlpha;
if( fPremultipliedAlpha )
opts.fFlags |= plMipmap::kDestPremultiplied;
Composite( image, x, y, &opts ); Composite( image, x, y, &opts );
/// HACK for now, since the alpha in the mipmap gets copied straight into the /// HACK for now, since the alpha in the mipmap gets copied straight into the
@ -737,6 +745,9 @@ void plDynamicTextMap::DrawClippedImage( uint16_t x, uint16_t y, plMipmap *im
else if( method == kImgSprite ) else if( method == kImgSprite )
opts.fFlags = plMipmap::kCopySrcAlpha; opts.fFlags = plMipmap::kCopySrcAlpha;
if( fPremultipliedAlpha )
opts.fFlags |= plMipmap::kDestPremultiplied;
opts.fSrcClipX = srcClipX; opts.fSrcClipX = srcClipX;
opts.fSrcClipY = srcClipY; opts.fSrcClipY = srcClipY;
opts.fSrcClipWidth = srcClipWidth; opts.fSrcClipWidth = srcClipWidth;
@ -883,6 +894,7 @@ void plDynamicTextMap::Swap( plDynamicTextMap *other )
// Swap DTMap info // Swap DTMap info
SWAP_ME( bool, fHasAlpha, other->fHasAlpha ); SWAP_ME( bool, fHasAlpha, other->fHasAlpha );
SWAP_ME( bool, fPremultipliedAlpha, other->fPremultipliedAlpha );
SWAP_ME( bool, fShadowed, other->fShadowed ); SWAP_ME( bool, fShadowed, other->fShadowed );
SWAP_ME( Justify, fJustify, other->fJustify ); SWAP_ME( Justify, fJustify, other->fJustify );

6
Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h

@ -113,14 +113,14 @@ class plDynamicTextMap : public plMipmap
plDynamicTextMap(); plDynamicTextMap();
plDynamicTextMap( uint32_t width, uint32_t height, bool hasAlpha = false, uint32_t extraWidth = 0, uint32_t extraHeight = 0 ); plDynamicTextMap( uint32_t width, uint32_t height, bool hasAlpha = false, uint32_t extraWidth = 0, uint32_t extraHeight = 0, bool premultipliedAlpha = false );
virtual ~plDynamicTextMap(); virtual ~plDynamicTextMap();
CLASSNAME_REGISTER( plDynamicTextMap ); CLASSNAME_REGISTER( plDynamicTextMap );
GETINTERFACE_ANY( plDynamicTextMap, plMipmap ); GETINTERFACE_ANY( plDynamicTextMap, plMipmap );
void Create( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth = 0, uint32_t extraHeight = 0 ); void Create( uint32_t width, uint32_t height, bool hasAlpha, uint32_t extraWidth = 0, uint32_t extraHeight = 0, bool premultipliedAlpha = false );
void SetNoCreate( uint32_t width, uint32_t height, bool hasAlpha ); void SetNoCreate( uint32_t width, uint32_t height, bool hasAlpha );
virtual void Reset( void ); virtual void Reset( void );
@ -221,7 +221,7 @@ class plDynamicTextMap : public plMipmap
uint32_t *IAllocateOSSurface( uint16_t width, uint16_t height ); uint32_t *IAllocateOSSurface( uint16_t width, uint16_t height );
void IDestroyOSSurface( void ); void IDestroyOSSurface( void );
bool fHasAlpha, fShadowed; bool fHasAlpha, fPremultipliedAlpha, fShadowed;
Justify fJustify; Justify fJustify;
plString fFontFace; plString fFontFace;

63
Sources/Plasma/PubUtilLib/plGImage/plFont.cpp

@ -334,7 +334,9 @@ void plFont::IRenderString( plMipmap *mip, uint16_t x, uint16_t y, const wcha
{ {
if( fRenderInfo.fFlags & kRenderIntoAlpha ) if( fRenderInfo.fFlags & kRenderIntoAlpha )
{ {
if( ( fRenderInfo.fColor & 0xff000000 ) != 0xff000000 ) if( fRenderInfo.fFlags & kRenderAlphaPremultiplied )
fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32AlphaPremultiplied;
else if( ( fRenderInfo.fColor & 0xff000000 ) != 0xff000000 )
fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32Alpha; fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32Alpha;
else else
fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32FullAlpha; fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32FullAlpha;
@ -1021,6 +1023,65 @@ void plFont::IRenderChar8To32Alpha( const plFont::plCharacter &c )
} }
} }
void plFont::IRenderChar8To32AlphaPremultiplied( const plFont::plCharacter &c )
{
uint8_t *src = fBMapData + c.fBitmapOff;
uint32_t *destPtr, *destBasePtr = (uint32_t *)( fRenderInfo.fDestPtr - c.fBaseline * fRenderInfo.fDestStride );
int16_t x, y, thisHeight, xstart, thisWidth;
uint8_t srcA, srcR, srcG, srcB;
// Unfortunately for some fonts, their right kern value actually is
// farther left than the right edge of the bitmap (think of overlapping
// script fonts). Ideally, we should store the actual width of each char's
// bitmap and use that here. However, it really shouldn't make too big of a
// difference, especially since the dest pixels that we end up overlapping
// should already be in the cache. If it does, time to upgrade the font
// format (again)
thisWidth = fWidth;// + (int32_t)c.fRightKern;
if( thisWidth >= fRenderInfo.fMaxWidth )
thisWidth = fRenderInfo.fMaxWidth;
xstart = fRenderInfo.fClipRect.fX - fRenderInfo.fX;
if( xstart < 0 )
xstart = 0;
srcA = (uint8_t)(( fRenderInfo.fColor >> 24 ) & 0x000000ff);
srcR = (uint8_t)(( fRenderInfo.fColor >> 16 ) & 0x000000ff);
srcG = (uint8_t)(( fRenderInfo.fColor >> 8 ) & 0x000000ff);
srcB = (uint8_t)(( fRenderInfo.fColor ) & 0x000000ff);
y = fRenderInfo.fClipRect.fY - fRenderInfo.fY + (int16_t)c.fBaseline;
if( y < 0 )
y = 0;
else
{
destBasePtr = (uint32_t *)( (uint8_t *)destBasePtr + y*fRenderInfo.fDestStride );
src += y*fRenderInfo.fNumCols;
}
thisHeight = fRenderInfo.fMaxHeight + (int16_t)c.fBaseline;
if( thisHeight > (int16_t)c.fHeight )
thisHeight = (int16_t)c.fHeight;
for( ; y < thisHeight; y++ )
{
destPtr = destBasePtr;
for( x = xstart; x < thisWidth; x++ )
{
uint32_t a = src[ x ];
if (a != 0)
{
if (srcA != 0xff)
a = (srcA*a + 127)/255;
destPtr[ x ] = ( a << 24 ) | (((srcR*a + 127)/255) << 16) | (((srcG*a + 127)/255) << 8) | ((srcB*a + 127)/255);
}
}
destBasePtr = (uint32_t *)( (uint8_t *)destBasePtr + fRenderInfo.fDestStride );
src += fWidth;
}
}
void plFont::IRenderCharNull( const plCharacter &c ) void plFont::IRenderCharNull( const plCharacter &c )
{ {

2
Sources/Plasma/PubUtilLib/plGImage/plFont.h

@ -116,6 +116,7 @@ class plFont : public hsKeyedObject
// value between the renderColor and the destColor and // value between the renderColor and the destColor and
// leave the alpha as-is // leave the alpha as-is
// This flag has no effect on monochrome fonts // This flag has no effect on monochrome fonts
kRenderAlphaPremultiplied = 0x00001000, // Destination has color values premultiplied by alpha
}; };
enum Flags enum Flags
@ -231,6 +232,7 @@ class plFont : public hsKeyedObject
void IRenderChar8To32( const plCharacter &c ); void IRenderChar8To32( const plCharacter &c );
void IRenderChar8To32Alpha( const plCharacter &c ); void IRenderChar8To32Alpha( const plCharacter &c );
void IRenderChar8To32FullAlpha( const plCharacter &c ); void IRenderChar8To32FullAlpha( const plCharacter &c );
void IRenderChar8To32AlphaPremultiplied( const plCharacter &c );
void IRenderCharNull( const plCharacter &c ); void IRenderCharNull( const plCharacter &c );
public: public:

22
Sources/Plasma/PubUtilLib/plGImage/plMipmap.cpp

@ -1746,6 +1746,18 @@ void plMipmap::Composite( plMipmap *source, uint16_t x, uint16_t y, plMipmap:
for( pY = (uint16_t)srcHeight; pY > 0; pY-- ) for( pY = (uint16_t)srcHeight; pY > 0; pY-- )
{ {
memcpy( dstPtr, srcPtr, srcRowBytesToCopy ); memcpy( dstPtr, srcPtr, srcRowBytesToCopy );
if( options->fFlags & kDestPremultiplied )
{
// multiply color values by alpha
for( pX = 0; pX < srcWidth; pX++ )
{
srcAlpha = ((dstPtr[ pX ] >> 24) & 0x000000ff);
dstPtr[ pX ] = ( srcAlpha << 24 )
| (((((dstPtr[ pX ] >> 16) & 0xff)*srcAlpha + 127)/255) << 16)
| (((((dstPtr[ pX ] >> 8) & 0xff)*srcAlpha + 127)/255) << 8)
| (((((dstPtr[ pX ] ) & 0xff)*srcAlpha + 127)/255) );
}
}
dstPtr += dstRowBytes >> 2; dstPtr += dstRowBytes >> 2;
srcPtr += srcRowBytes >> 2; srcPtr += srcRowBytes >> 2;
} }
@ -1777,7 +1789,15 @@ void plMipmap::Composite( plMipmap *source, uint16_t x, uint16_t y, plMipmap:
{ {
srcAlpha = options->fOpacity * ( ( srcPtr[ pX ] >> 16 ) & 0x0000ff00 ) / 255 / 256; srcAlpha = options->fOpacity * ( ( srcPtr[ pX ] >> 16 ) & 0x0000ff00 ) / 255 / 256;
if( srcAlpha != 0 ) if( srcAlpha != 0 )
dstPtr[ pX ] = ( srcPtr[ pX ] & 0x00ffffff ) | ( srcAlpha << 24 ); {
if( options->fFlags & kDestPremultiplied )
dstPtr[ pX ] = ( srcAlpha << 24 )
| (((((srcPtr[ pX ] >> 16) & 0xff)*srcAlpha + 127)/255) << 16)
| (((((srcPtr[ pX ] >> 8) & 0xff)*srcAlpha + 127)/255) << 8)
| (((((srcPtr[ pX ] ) & 0xff)*srcAlpha + 127)/255) );
else
dstPtr[ pX ] = ( srcPtr[ pX ] & 0x00ffffff ) | ( srcAlpha << 24 );
}
} }
dstPtr += dstRowBytes >> 2; dstPtr += dstRowBytes >> 2;
srcPtr += srcRowBytes >> 2; srcPtr += srcRowBytes >> 2;

13
Sources/Plasma/PubUtilLib/plGImage/plMipmap.h

@ -234,11 +234,14 @@ class plMipmap : public plBitmap
enum CompositeFlags enum CompositeFlags
{ {
kForceOpaque = 0x0001, // Copy src pixels raw, force dest alphas to opaque kForceOpaque = 0x0001, // Copy src pixels raw, force dest alphas to opaque
kCopySrcAlpha = 0x0002, // Copy the src pixels raw, including alphas, overwrite dest kCopySrcAlpha = 0x0002, // Copy the src pixels raw, including alphas, overwrite dest
kBlendSrcAlpha = 0x0004, // Blend src pixels onto dest using src alpha, dest alpha = src alpha kBlendSrcAlpha = 0x0004, // Blend src pixels onto dest using src alpha, dest alpha = src alpha
kMaskSrcAlpha = 0x0008, // Same as copySrcAlpha, but dest is untouched when src alpha = 0 kMaskSrcAlpha = 0x0008, // Same as copySrcAlpha, but dest is untouched when src alpha = 0
kBlendWriteAlpha= 0x0010 // Like default (0), but writes dest alpha values kBlendWriteAlpha = 0x0010, // Like default (0), but writes dest alpha values
kDestPremultiplied = 0x0020, // Dest has color premultiplied by alpha
// (src always assumed nonpremultiplied for now)
}; };
class CompositeOptions class CompositeOptions

18
Sources/Plasma/PubUtilLib/plPipeline/DX/plDXPipeline.cpp

@ -7211,12 +7211,26 @@ void plDXPipeline::IHandleFirstStageBlend()
fD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); fD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
if( fLayerState[0].fBlendFlags & hsGMatState::kBlendInvertFinalAlpha ) if( fLayerState[0].fBlendFlags & hsGMatState::kBlendInvertFinalAlpha )
{ {
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA ); if( fLayerState[0].fBlendFlags & hsGMatState::kBlendAlphaPremultiplied )
{
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
}
else
{
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA );
}
fD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA ); fD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
} }
else else
{ {
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); if( fLayerState[0].fBlendFlags & hsGMatState::kBlendAlphaPremultiplied )
{
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
}
else
{
fD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
}
fD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); fD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
} }
break; break;

Loading…
Cancel
Save