How to position the RenderTexture?

How to position the RenderTexture?
0.0 0

#1

i want to save a node into an image. i used RenderTexture, it creates image with node but dimensions are full screen. i want only that part where node is laying.
i tried to give RenderTexture position and size of that node but didn’t get the result i want. Here is the image i get, i want only the white rectangle part. Can someone give me the code snippet.

using cocos2d-x 13.14.1

i have achieved my goal using openCV to crop out the image created by RenderTexture. But i want to minimize this overhead.


#2

The RenderTexture, by default, captures from the bottom-left of the screen and moving it does not affect that.

I don’t have code, but there are 2 ways I can think of doing this. First, when you create the RenderTexture, create it at the size of the Node. Then, either

  1. Move the Node so that its bottom-left corner is at the bottom-left of the screen. Begin the RenderTexture, visit the Node, then end the RenderTexture. If you need to move the Node back to where it was, call Director::getInstance()->getRenderer()->render() to force the Renderer to render and draw to the RenderTexture. (Not 100% about forcing the Renderer, but it should work.) Or,

  2. RenderTexture has a function called setVirtualViewport(). I can’t remember how to use it, but I’m pretty sure I have used it to capture only part of the screen before. Trying experimenting with that.

EDIT:
Ok, so the second option seems to work something like this:

auto winSize = Director::getInstance()->getWinSize();
auto winSizePixels = Director::getInstance()->getWinSizeInPixels();

auto size = node->getBoundingBox().size;
auto ap = node->getAnchorPoint();

renderTexture->setAutoDraw(false);
renderTexture->setKeepMatrix(true);

rt->setVirtualViewport(node->getPosition() - Vec2(size.width * ap.x, size.height * ap.y),
        Rect(0, 0, winSize.width, winSize.height),
        Rect(0, 0, winSizePixels.width, winSizePixels.height));

This will set the RenderTexture to capture the node no matter where on screen it is. Note: It’s possible that the visible origin might cause issues, so you may need to add Director::getInstance()->getVisibleOrigin() to the position of the viewport.


#3

love you man :slight_smile:
that works greatly. improved performance of my app, thank you very much.

it may be rude to ask here but i am having another problem, i have posted it here : Adding library via cocoapods returns Apple Match-O linker error
it will be awesome if you can take a look there and tell me some workaround.

much appreciated


#4

Super useful info :slight_smile: I had my own workarounds to get it to work, but this is a lot cleaner.


#5

I haven’t used CocoaPods, so I won’t be much help, but I will say that usually when you have a linker error like that it usually means it can’t find the implementation of a function, e.g. the .cpp file (for C++ projects.) I would say to make sure all the appropriate source files and library files have been included.


#6

its ok, i achieved my goal without cocoapods. Thanks anyway. :slight_smile:


#7

@grimfate I’m trying to use setVirtualViewport for another problem - I need to render a little wider than the screen size:

25

Green - is lets say 640x1136 iPhone 5 screen and black is part I want to render. In my game there are Sprite's on left and right parts of the screen and so I want to capture them too.
Final rendered image size should be say 700x300, so a bit wider that screen width 640.

But passing for example: Rect(-30.0, 0.0, winSize.width, winSize.height), just renders more only from right, so anyway it’s always renders from 0.0;0.0 and I need from negative coordinates…

@zhangxm Can you comment this too please?


#8

do you found the fix for these issue?
i meet the same problem, in cocos2dx V.2 where rendered saveToFile, its working without problem.
i already try disabling culling but still no luck.


#9

Yes SetVirtualViewport did the job
This is my code to save sprite to a file.

auto winSize = Director::getInstance()->getWinSize();
    auto winSizePixels = Director::getInstance()->getWinSizeInPixels();
    
    log("Root folder : %s",FileUtils::getInstance()->getWritablePath().c_str());
    
    auto size = drawSprite->getBoundingBox().size;
    auto ap = drawSprite->getAnchorPoint();
    
    auto renderTexture = RenderTexture::create(size.width,size.height);
    renderTexture->setAutoDraw(false);
    renderTexture->setKeepMatrix(true);
    
    renderTexture->setVirtualViewport(drawSprite->getPosition() - Vec2(size.width * ap.x, size.height * ap.y), Rect(0, 0, winSize.width, winSize.height),Rect(0, 0, winSizePixels.width,winSizePixels.height));
    //    for(int i = 0; i < 3 ; i++)
    //    {
    renderTexture->beginWithClear(1, 1, 1, 1);

    drawSprite->visit();
    renderTexture->end();


        std::string filename = StringUtils::format("drawImage.jpg");
    
    renderTexture->saveToFile(filename.c_str(), Image::Format::JPG,false,CC_CALLBACK_0(GTWrite::createDrawSprite, this));

#10

do you found the fix for these issue?
i meet the same problem, in cocos2dx V.2 where rendered saveToFile, its working without problem.
i already try disabling culling but still no luck.


#11

sorry i mean problem when save the sprite bigger than screen size


#12

Nope, no solution.


#13

but my code in cocos2dx 2.x is working correctly.

it’s strange if in old cocos working corectly but not in newer version.


#14

YEa, some changes probably were made without proper testing…
Check this also renderTexture saveToFile artifacts

It’s like a bug, and I haven’t faced it with older versions too.