当前位置:C++技术网 > 资讯 > osg 截图方法 osgautocapture

osg 截图方法 osgautocapture

更新时间: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) ;


完毕