Skip to content

Commit ae993e6

Browse files
rh101minggo
authored andcommitted
Fix RenderTexture PMA setting (#20143)
* Added RenderTexture::saveToFileAsNonPMA() to save images without PMA. Set the PMA parameter to true when calling initWithRawData() inside RenderTexture::newImage(), since textures are PMA. Renamed Image::premultipliedAlpha() to Image::premultiplyAlpha() to better reflect it's action, and made it public. Added Image::reversePremultipliedAlpha() to allow the reversing of the PMA. Updated CCImage-ios.mm to set the correct bitmapInfo for PMA and non-PMA images before saving a file. Updated RenderTextureTest::RenderTextureSave() to cater for non-PMA file saving. * [CCImage-ios.mm] Fixed indentation. * Corrects the PMA setting on the internal Texture2D instance created by RenderTexture.
1 parent 4356cda commit ae993e6

File tree

3 files changed

+20
-29
lines changed

3 files changed

+20
-29
lines changed

cocos/2d/CCRenderTexture.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
253253
_texture = new (std::nothrow) Texture2D();
254254
if (_texture)
255255
{
256-
_texture->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h));
256+
_texture->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h), CC_ENABLE_PREMULTIPLIED_ALPHA != 0);
257257
}
258258
else
259259
{
@@ -267,7 +267,7 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
267267
_textureCopy = new (std::nothrow) Texture2D();
268268
if (_textureCopy)
269269
{
270-
_textureCopy->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h));
270+
_textureCopy->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h), CC_ENABLE_PREMULTIPLIED_ALPHA != 0);
271271
}
272272
else
273273
{
@@ -303,7 +303,11 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
303303
_texture->release();
304304
_sprite->setFlippedY(true);
305305

306-
_sprite->setBlendFunc( BlendFunc::ALPHA_PREMULTIPLIED );
306+
#if CC_ENABLE_PREMULTIPLIED_ALPHA != 0
307+
_sprite->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED);
308+
#else
309+
_sprite->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
310+
#endif
307311
_sprite->setOpacityModifyRGB(true);
308312

309313
glBindRenderbuffer(GL_RENDERBUFFER, oldRBO);
@@ -664,11 +668,11 @@ Image* RenderTexture::newImage(bool flipImage)
664668
savedBufferWidth * 4);
665669
}
666670

667-
image->initWithRawData(buffer, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, true);
671+
image->initWithRawData(buffer, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, _texture->hasPremultipliedAlpha());
668672
}
669673
else
670674
{
671-
image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, true);
675+
image->initWithRawData(tempData, savedBufferWidth * savedBufferHeight * 4, savedBufferWidth, savedBufferHeight, 8, _texture->hasPremultipliedAlpha());
672676
}
673677

674678
} while (0);

cocos/renderer/CCTexture2D.cpp

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -554,21 +554,19 @@ bool Texture2D::hasPremultipliedAlpha() const
554554
return _hasPremultipliedAlpha;
555555
}
556556

557-
bool Texture2D::initWithData(const void *data, ssize_t dataLen, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/)
557+
bool Texture2D::initWithData(const void *data, ssize_t dataLen, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha)
558558
{
559559
CCASSERT(dataLen>0 && pixelsWide>0 && pixelsHigh>0, "Invalid size");
560560

561561
//if data has no mipmaps, we will consider it has only one mipmap
562562
MipmapInfo mipmap;
563563
mipmap.address = (unsigned char*)data;
564564
mipmap.len = static_cast<int>(dataLen);
565-
return initWithMipmaps(&mipmap, 1, pixelFormat, pixelsWide, pixelsHigh);
565+
return initWithMipmaps(&mipmap, 1, pixelFormat, pixelsWide, pixelsHigh, preMultipliedAlpha);
566566
}
567567

568-
bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat pixelFormat, int pixelsWide, int pixelsHigh)
568+
bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha)
569569
{
570-
571-
572570
//the pixelFormat must be a certain value
573571
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
574572
CCASSERT(pixelsWide>0 && pixelsHigh>0, "Invalid size");
@@ -579,7 +577,6 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat
579577
return false;
580578
}
581579

582-
583580
auto formatItr = _pixelFormatInfoTables.find(pixelFormat);
584581
if(formatItr == _pixelFormatInfoTables.end())
585582
{
@@ -706,7 +703,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat
706703
_maxS = 1;
707704
_maxT = 1;
708705

709-
_hasPremultipliedAlpha = false;
706+
_hasPremultipliedAlpha = preMultipliedAlpha;
710707
_hasMipmaps = mipmapsNum > 1;
711708

712709
// shader
@@ -764,18 +761,14 @@ bool Texture2D::initWithImage(Image *image, PixelFormat format)
764761
PixelFormat renderFormat = image->getRenderFormat();
765762
size_t tempDataLen = image->getDataLen();
766763

767-
768764
if (image->getNumberOfMipmaps() > 1)
769765
{
770766
if (pixelFormat != image->getRenderFormat())
771767
{
772768
CCLOG("cocos2d: WARNING: This image has more than 1 mipmaps and we will not convert the data format");
773769
}
774770

775-
initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getRenderFormat(), imageWidth, imageHeight);
776-
777-
// set the premultiplied tag
778-
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
771+
initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getRenderFormat(), imageWidth, imageHeight, image->hasPremultipliedAlpha());
779772

780773
return true;
781774
}
@@ -786,10 +779,7 @@ bool Texture2D::initWithImage(Image *image, PixelFormat format)
786779
CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now");
787780
}
788781

789-
initWithData(tempData, tempDataLen, image->getRenderFormat(), imageWidth, imageHeight, imageSize);
790-
791-
// set the premultiplied tag
792-
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
782+
initWithData(tempData, tempDataLen, image->getRenderFormat(), imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
793783

794784
return true;
795785
}
@@ -800,18 +790,13 @@ bool Texture2D::initWithImage(Image *image, PixelFormat format)
800790

801791
pixelFormat = convertDataToFormat(tempData, tempDataLen, renderFormat, pixelFormat, &outTempData, &outTempDataLen);
802792

803-
initWithData(outTempData, outTempDataLen, pixelFormat, imageWidth, imageHeight, imageSize);
804-
793+
initWithData(outTempData, outTempDataLen, pixelFormat, imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
805794

806795
if (outTempData != nullptr && outTempData != tempData)
807796
{
808-
809797
free(outTempData);
810798
}
811799

812-
// set the premultiplied tag
813-
_hasPremultipliedAlpha = image->hasPremultipliedAlpha();
814-
815800
return true;
816801
}
817802
}

cocos/renderer/CCTexture2D.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,11 @@ class CC_DLL Texture2D : public Ref
226226
@param pixelsWide The image width.
227227
@param pixelsHigh The image height.
228228
@param contentSize The image content size.
229+
@param preMultipliedAlpha The texture has premultiplied alpha
229230
* @js NA
230231
* @lua NA
231232
*/
232-
bool initWithData(const void *data, ssize_t dataLen, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& contentSize);
233+
bool initWithData(const void *data, ssize_t dataLen, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, const Size& contentSize, bool preMultipliedAlpha = false);
233234

234235
/** Initializes with mipmaps.
235236
@@ -238,8 +239,9 @@ class CC_DLL Texture2D : public Ref
238239
@param pixelFormat The image pixelFormat.
239240
@param pixelsWide The image width.
240241
@param pixelsHigh The image height.
242+
@param preMultipliedAlpha The texture has premultiplied alpha
241243
*/
242-
bool initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh);
244+
bool initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, Texture2D::PixelFormat pixelFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha = false);
243245

244246
/** Update with texture data.
245247

0 commit comments

Comments
 (0)