RenderTexture FadeOut problem

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.

Does this new code work?

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