V4 RenderTexture PMA flag fix (#20153)

* This is to ensure the RenderTexture internal texture2D PMA flag is set to the correct value.
[CCSprite.cpp] Blending mode needs to be set based on the PMA flag of the texture if using Sprite::initWithTexture().

* [CCSprite.cpp] Removed redundant code related to blending mode and opacityModifyRGB when creating a sprite with a texture.
This commit is contained in:
rh101 2019-09-26 18:11:23 +10:00 committed by minggo
parent d3359c3e4a
commit 4ac3f94774
4 changed files with 27 additions and 29 deletions

View File

@ -196,7 +196,7 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, backend::PixelFormat fo
_texture2D = new (std::nothrow) Texture2D(); _texture2D = new (std::nothrow) Texture2D();
if (_texture2D) if (_texture2D)
{ {
_texture2D->initWithBackendTexture(texture); _texture2D->initWithBackendTexture(texture, CC_ENABLE_PREMULTIPLIED_ALPHA != 0);
_texture2D->setRenderTarget(true); _texture2D->setRenderTarget(true);
texture->release(); texture->release();
} }
@ -240,8 +240,14 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, backend::PixelFormat fo
#if defined(CC_USE_GL) || defined(CC_USE_GLES) #if defined(CC_USE_GL) || defined(CC_USE_GLES)
_sprite->setFlippedY(true); _sprite->setFlippedY(true);
#endif #endif
_sprite->setBlendFunc( BlendFunc::ALPHA_PREMULTIPLIED );
#if CC_ENABLE_PREMULTIPLIED_ALPHA != 0
_sprite->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED);
_sprite->setOpacityModifyRGB(true); _sprite->setOpacityModifyRGB(true);
#else
_sprite->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
_sprite->setOpacityModifyRGB(false);
#endif
// Disabled by default. // Disabled by default.
_autoDraw = false; _autoDraw = false;
@ -472,7 +478,7 @@ void RenderTexture::newImage(std::function<void(Image*)> imageCallback, bool fli
Image *image = new (std::nothrow) Image(); Image *image = new (std::nothrow) Image();
auto initCallback = [&, savedBufferWidth, savedBufferHeight, imageCallback](Image* image, const unsigned char* tempData){ auto initCallback = [&, savedBufferWidth, savedBufferHeight, imageCallback](Image* image, const unsigned char* tempData){
image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, true); image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, _texture2D->hasPremultipliedAlpha());
imageCallback(image); imageCallback(image);
}; };
auto callback = std::bind(initCallback, image, std::placeholders::_1); auto callback = std::bind(initCallback, image, std::placeholders::_1);

View File

@ -259,10 +259,6 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
_recursiveDirty = false; _recursiveDirty = false;
setDirty(false); setDirty(false);
_opacityModifyRGB = true;
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
_flippedX = _flippedY = false; _flippedX = _flippedY = false;
// default transform anchor: center // default transform anchor: center

View File

@ -222,7 +222,7 @@ bool Texture2D::hasPremultipliedAlpha() const
return _hasPremultipliedAlpha; return _hasPremultipliedAlpha;
} }
bool Texture2D::initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/) bool Texture2D::initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha)
{ {
CCASSERT(dataLen>0 && pixelsWide>0 && pixelsHigh>0, "Invalid size"); CCASSERT(dataLen>0 && pixelsWide>0 && pixelsHigh>0, "Invalid size");
@ -230,10 +230,10 @@ bool Texture2D::initWithData(const void *data, ssize_t dataLen, backend::PixelFo
MipmapInfo mipmap; MipmapInfo mipmap;
mipmap.address = (unsigned char*)data; mipmap.address = (unsigned char*)data;
mipmap.len = static_cast<int>(dataLen); mipmap.len = static_cast<int>(dataLen);
return initWithMipmaps(&mipmap, 1, pixelFormat, renderFormat, pixelsWide, pixelsHigh); return initWithMipmaps(&mipmap, 1, pixelFormat, renderFormat, pixelsWide, pixelsHigh, preMultipliedAlpha);
} }
bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh) bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha)
{ {
//the pixelFormat must be a certain value //the pixelFormat must be a certain value
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!"); CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
@ -341,7 +341,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
_maxS = 1; _maxS = 1;
_maxT = 1; _maxT = 1;
_hasPremultipliedAlpha = false; _hasPremultipliedAlpha = preMultipliedAlpha;
_hasMipmaps = mipmapsNum > 1; _hasMipmaps = mipmapsNum > 1;
return true; return true;
@ -441,10 +441,7 @@ bool Texture2D::initWithImage(Image *image, backend::PixelFormat format)
//pixel format of data is not converted, renderFormat can be different from pixelFormat //pixel format of data is not converted, renderFormat can be different from pixelFormat
//it will be done later //it will be done later
initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getPixelFormat(), renderFormat, imageWidth, imageHeight); initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getPixelFormat(), renderFormat, imageWidth, imageHeight, image->hasPremultipliedAlpha());
// set the premultiplied tag
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
return true; return true;
} }
@ -455,20 +452,14 @@ bool Texture2D::initWithImage(Image *image, backend::PixelFormat format)
CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now"); CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now");
} }
initWithData(tempData, tempDataLen, image->getPixelFormat(), imageWidth, imageHeight, imageSize); initWithData(tempData, tempDataLen, image->getPixelFormat(), imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
// set the premultiplied tag
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
return true; return true;
} }
else else
{ {
//after conversion, renderFormat == pixelFormat of data //after conversion, renderFormat == pixelFormat of data
initWithData(tempData, tempDataLen, imagePixelFormat, renderFormat, imageWidth, imageHeight, imageSize); initWithData(tempData, tempDataLen, imagePixelFormat, renderFormat, imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
// set the premultiplied tag
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
return true; return true;
} }
@ -570,7 +561,7 @@ bool Texture2D::initWithString(const char *text, const FontDefinition& textDefin
return ret; return ret;
} }
bool Texture2D::initWithBackendTexture(backend::TextureBackend *texture) bool Texture2D::initWithBackendTexture(backend::TextureBackend *texture, bool preMultipliedAlpha)
{ {
CC_SAFE_RETAIN(texture); CC_SAFE_RETAIN(texture);
CC_SAFE_RELEASE(_texture); CC_SAFE_RELEASE(_texture);
@ -578,6 +569,8 @@ bool Texture2D::initWithBackendTexture(backend::TextureBackend *texture)
CC_ASSERT(_texture); CC_ASSERT(_texture);
_pixelsWide = _contentSize.width = _texture->getWidth(); _pixelsWide = _contentSize.width = _texture->getWidth();
_pixelsHigh = _contentSize.height = _texture->getHeight(); _pixelsHigh = _contentSize.height = _texture->getHeight();
_hasPremultipliedAlpha = preMultipliedAlpha;
return true; return true;
} }

View File

@ -138,10 +138,11 @@ public:
@param pixelsWide The image width. @param pixelsWide The image width.
@param pixelsHigh The image height. @param pixelsHigh The image height.
@param contentSize The image content size. @param contentSize The image content size.
@param preMultipliedAlpha The texture has premultiplied alpha
* @js NA * @js NA
* @lua NA * @lua NA
*/ */
bool initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& contentSize) { return initWithData(data, dataLen, pixelFormat, pixelFormat, pixelsWide, pixelsHigh, contentSize);} bool initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& contentSize, bool preMultipliedAlpha = false) { return initWithData(data, dataLen, pixelFormat, pixelFormat, pixelsWide, pixelsHigh, contentSize, preMultipliedAlpha);}
/** Initializes with a texture2d with data. /** Initializes with a texture2d with data.
@ -152,10 +153,11 @@ public:
@param pixelsWide The image width. @param pixelsWide The image width.
@param pixelsHigh The image height. @param pixelsHigh The image height.
@param contentSize The image content size. @param contentSize The image content size.
@param preMultipliedAlpha The texture has premultiplied alpha
* @js NA * @js NA
* @lua NA * @lua NA
*/ */
bool initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& contentSize); bool initWithData(const void *data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& contentSize, bool preMultipliedAlpha = false);
/** Initializes with mipmaps. /** Initializes with mipmaps.
@ -164,8 +166,9 @@ public:
@param pixelFormat The image pixelFormat. @param pixelFormat The image pixelFormat.
@param pixelsWide The image width. @param pixelsWide The image width.
@param pixelsHigh The image height. @param pixelsHigh The image height.
@param preMultipliedAlpha The texture has premultiplied alpha
*/ */
bool initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh); bool initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha = false);
/** Update with texture data. /** Update with texture data.
@ -228,7 +231,7 @@ public:
bool initWithString(const char *text, const FontDefinition& textDefinition); bool initWithString(const char *text, const FontDefinition& textDefinition);
//TODO: minggo: is it resaonable? //TODO: minggo: is it resaonable?
bool initWithBackendTexture(backend::TextureBackend* texture); bool initWithBackendTexture(backend::TextureBackend* texture, bool preMultipliedAlpha = false);
void setRenderTarget(bool renderTarget); void setRenderTarget(bool renderTarget);
inline bool isRenderTarget() const { return _isRenderTarget; } inline bool isRenderTarget() const { return _isRenderTarget; }