使用 cocos2d::RenderTexture 和 setVirtualViewport 捕获屏幕区域

Capturing an area of the screen with cocos2d::RenderTexture and setVirtualViewport

cocos2d-x版本:3.16

我想捕获屏幕的一个区域,并将其保存为 PNG 文件。最好的方法是使用 RenderTexture,捕获特定区域应该使用 setVirtualViewport 方法。文档说:

void setVirtualViewport   (
      const Vec2 & rtBegin,
      const Rect & fullRect,
      const Rect & fullViewport 
  )   

Used for grab part of screen to a texture.

Parameters

  • rtBegin The position of renderTexture on the fullRect.
  • fullRect The total size of screen.
  • fullViewport The total viewportSize.

我有以下代码,设计分辨率为1920*1080(我简化了代码以显示在这里,并将值作为常量):

unsigned int SIZE_X = 960;
unsigned int SIZE_Y = 540;
unsigned int POS_X = 100;
unsigned int POS_Y = 100;

RenderTexture* texture = RenderTexture::create(SIZE_X, SIZE_Y);
texture->setVirtualViewport(Vec2(POX_X, POS_Y),
                            Rect(0, 0, 1920, 1080),
                            Rect(0, 0, SIZE_X, SIZE_Y));

texture->begin();
this->visit();
texture->end();

texture->saveToFile("test.png", Image::Format::PNG);

我尝试了很多不同的参数组合,但无论我做什么,最多捕获矩形0、0、SIZE_X、SIZE_Y的像素,剩下的就是填充透明像素。偏移量也是错误的(它受屏幕尺寸和捕获区域之间的比率影响,尽管它不应该)。

下面是模型场景的上述代码的结果,其中红色表示透明像素:

我用红色显示的所有像素都是空的,它们不应该是空的,并且偏移量是错误的:(50, 50) 而不是 (100, 100)

你知道如何正确使用setVirtualViewport吗?他们的方法有问题还是我做错了什么?

或者,您是否有其他解决方案来捕获屏幕区域并将其保存为图像或 cocos2d::Sprite? (不移动Scene的内容)

因为我似乎不明白函数 setVirtualViewport 是如何工作的,或者这个函数可能有问题,这是我想出的一个解决方案,它做同样的事情,即使它可能效率不高:

  • RenderTexture 中捕获整个屏幕。
  • 更改由RenderTexture生成的Sprite的位置,即使它不属于场景所以不可见,将其放在区域的开头你想要的 (0,0).
  • 创建第二个 RenderTexture 您要捕获的尺寸。
  • 访问精灵以在第二个中渲染它 RenderTexture

代码如下:

unsigned int SIZE_X = 960;
unsigned int SIZE_Y = 540;
unsigned int POS_X = 100;
unsigned int POS_Y = 100;

RenderTexture* screenCapture = RenderTexture::create(1920, 1080);

screenCapture->begin();
this->visit();
screenCapture->end();

RenderTexture* areaTexture = RenderTexture::create(SIZE_X, SIZE_Y);
areaTexture->begin();
screenCapture->getSprite()->setPosition(Vec2(960 - POS_X, 540 - POS_Y));
screenCapture->getSprite()->visit();
areaTexture->end();

AreaTexture->saveToFile("test.png", Image::Format::PNG);