I’m trying to use RenderTexture to fade out a layer with sprites. But I get strange result - the sprites on the layer are becoming whiter instead of ‘fading’. Here is my code:
Size size = this->getContentSize();
auto bk = this->getChildByTag(1);
auto sprite = bk->getChildByTag(2);
auto rt = RenderTexture::create((int)size.width, (int)size.height, Texture2D::PixelFormat::RGBA8888);
this->addChild(rt);
rt->setAutoDraw(true);
rt->begin();
bk->visit();
rt->end();
auto img = rt->getSprite();
img->setPosition(size.width / 2, size.height / 2);
//auto fadeOut = TintTo::create(.5, 50, 50, 50);
auto fadeOut = FadeOut::create(2.5);
auto done = CallFunc::create(std::bind([bk, sprite, rt] {
bk->removeFromParent();
//sprite->setVisible(false);
rt->removeFromParent();
}));
img->runAction(Sequence::create(fadeOut, done, nullptr));
I’m new to cocos2d, please point out what’s wrong with my code. Thanks!
Try adding this before you run your sequence:
rt->getSprite()->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
I ended up with creating a new sprite from the RenderTexture->getSprite()->getTexture:
void TestLayer::fadeMeOut()
{
Size mySize = this->getContentSize();
auto rt = RenderTexture::create((int)mySize.width, (int)mySize.height, Texture2D::PixelFormat::RGBA8888);
//this->addChild(rt);
rt->setPosition(mySize.width / 2, mySize.height / 2);
rt->setAutoDraw(true);
rt->begin();
_ccbiLayer->visit();
rt->end();
_ccbiLayer->setVisible(false);
auto img = Sprite::createWithTexture(rt->getSprite()->getTexture());
//img->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
img->setPosition(mySize.width / 2, mySize.height / 2);
img->setFlippedY(true);
this->addChild(img);
//auto fadeOut = TintTo::create(.5, 50, 50, 50);
auto fadeOut = FadeOut::create(1.5);
auto done = CallFunc::create(std::bind([this, img] {
img->removeFromParent();
this->removeFromParent();
}));
img->runAction(Sequence::create(fadeOut, done, nullptr));
}
I don’t have any idea about the BlendFunc thing. It makes no difference either I add the call or not.
Yes. It works in my test project.
@toojuice, I did this and although it fades out, when this line is called, the edges of the image suddenly become dark and then it fades out through a gray color. This is mostly noticeable on a white or light colored image on a medium or light background.
I had the same issue when I tried to make a sprite from the texture, as that is where the problem is.
Do you have a screenshot showing what you’re describing?
Here is a gif of it:
For the mean time, I opted for a hack to make it look good, which is having a bool to signify when the fade out should occur, and in the update() method a semi transparent white LayerColor is added to the rt:
void GameScene::update( float delta) {
rt->begin();
// ... some other layer visits() ...
if (_shouldFade) {
CCSize scratchSize = rt->getSprite()->getContentSize();
CCLayerColor *lc = CCLayerColor::create( ccc4( 255, 255, 255, 16), scratchSize.width, scratchSize.height );
lc->setBlendFunc( (ccBlendFunc) {GL_ZERO,GL_ONE_MINUS_SRC_ALPHA } );
lc->visit();
}
m_scratchableImage->end();
}
Changing the opacity GLubyte affects how long the fade takes, so 255 / ( 16 * 60 ) = 0.266 sec. It’s a pretty poor solution, but it looks the best for what I need
Are you using cocos2d-x v2.x? And you backported the code ssawgift posted?
That code snippet was from a v2.2 project, but the sample is in v3.2.
So is the code you’re using the same that ssawgift posted?
This smells a lot like the issue reported in this post, but that should have been fixed in v 3.2