更新时间:2019-02-01 13:24:12浏览次数:1+次
osg截图需要在单线程模式才能正常使用,否则会出现有时候正常,有时候只有一个颜色的图
为了确定截图时机是正确的,通常会使用 `Camera::setFinalDrawCallback`函数设置回调。
为了避开多线程渲染引起截图不确定性的问题,使用`viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);` 使得下次渲染循环使用单线程模式。切换以后记得还原原有的模式
回调函数
struct CaptureCallback :public osg::Camera::DrawCallback
{
CaptureCallback()
{
}
~CaptureCallback() {}
virtual void operator()(osg::RenderInfo& renderInfo) const
{
//读取像素信息抓图
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
auto& camera = *renderInfo.getCurrentCamera();
auto traits = camera.getGraphicsContext()->getTraits();
glReadBuffer(traits->doubleBuffer?GL_BACK:GL_FRONT);
_image->readPixels(pos[0], pos[1], size[0], size[1], _image->getPixelFormat(), _image->getDataType());
}
osg::Vec2i pos;
osg::Vec2i size;
osg::observer_ptr<osg::Image> _image;
mutable OpenThreads::Mutex _mutex;
};
调用进行截图
osg::ref_ptr<CaptureCallback> cb = new CaptureCallback();
cb->pos = pos;
cb->size = size;
cb->_image = _image;
camera.setFinalDrawCallback(cb);
auto viewer = dynamic_cast<osgViewer::ViewerBase*>(camera.getView());
auto oldModel = viewer->getThreadingModel();
viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
viewer->renderingTraversals();
viewer->setThreadingModel(oldModel);
camera.setFinalDrawCallback(nullptr);
通常截图完毕以后,我们会输出调试看看效果
#ifdef _DEBUG
osgDB::writeImageFile(*_image, u8"./SceneImage.png");
#endif // _DEBUG
当然,如果想获得整个屏幕,可以这样获取屏幕尺寸
//得到窗口系统接口
osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface();
//得到分辨率
//wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0) , width , height) ;
完毕
相关资讯