Cocos2d-x v4 Inconsistent RenderTexture behaviour between Metal and OpenGL

Just wondering if anyone else has experienced this specific issue.

When a sprite is rendered to a RenderTexture, the output is inconsistent between the Metal and OpenGL renderers (the image is flipped on the Y axis).

For example, this code works on Windows and Android with the OpenGL renderer to show a sprite facing the correct way up (code is just the generated template project with the additions you see below in HelloWorldScene.cpp):

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");
    if (sprite == nullptr)
    {
        problemLoading("'HelloWorld.png'");
    }
    else
    {
        sprite->setFlippedY(true);
        sprite->setPosition(sprite->getContentSize() / 2);
        auto* renderTexture = RenderTexture::create(sprite->getContentSize().width, sprite->getContentSize().height, PixelFormat::RGBA8888);
        renderTexture->beginWithClear(0, 0, 0, 0);
        sprite->visit();
        renderTexture->end();

        auto* newSprite = Sprite::createWithTexture(renderTexture->getSprite()->getTexture());

        // position the sprite on the center of the screen
        newSprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

        // add the sprite as a child to this layer
        this->addChild(newSprite, 0);
    }

On Windows/Android (OpenGL backend), this is the output:
image

On Mac OS X and iOS (Metal backend):
image

It is something the Metal backend implementation that is causing this issue, and while I can hack around it by doing a check for OpenGL in my own code, it really should be fixed in the backend renderer.

The hack would be like this:

...
#if defined(CC_USE_GL) || defined(CC_USE_GLES)
 sprite->setFlippedY(true);
#endif
 sprite->setPosition(sprite->getContentSize() / 2);
        auto* renderTexture = RenderTexture::create(sprite->getContentSize().width, sprite->getContentSize().height, PixelFormat::RGBA8888);
// etc...

Just curious, which version of macOS are you having this problem in?

The issue was reproducible on all devices tested with Mac OS X 10.15 and iOS 8/10/11/12.

@R101 are you still having an issue? Did you create a GitHub issue for it? Tag me if needed…

I’m using the work-around for it for in my own code (check if it’s OpenGL then applying the flip Y etc, as shown in the initial post), but the the real issue needs to be fixed in the Cocos2-dx rendering code.

The issue on github is here.

Hey @R101 , Did you check CCRenderTexture.cpp?
It has this line _sprite->setFlippedY(true);
May be this line is causing the issue?
I am still on 3.17.2

The line you’re referring to is the one in RenderTexture::initWithWidthAndHeight(), correct? If so, I’m certain I tested it, and removing it causes other problems with the orientation on the Y axis when using OpenGL. It may be related to the issue, but that line is definitely needed in that section of code.

Version 3.17.2 uses OpenGL for all platforms, so it shouldn’t have this problem. The issue is with the Metal backend renderer in v4.

ya, i know that. Just told you to let you know, o/w i could have test it before replying here.