1

我试图在我的 Qt 程序中将 OSG 场景渲染为图像。参考 SnapImageDrawCallback 的例子(https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg45360.html)。

class SnapImageDrawCallback : public osg::CameraNode::DrawCallback { 
public:
        SnapImageDrawCallback()
        {
                _snapImageOnNextFrame = false;
        }

        void setFileName(const std::string& filename) { _filename = filename; }
        const std::string& getFileName() const { return _filename; }

        void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag;}
        bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; }

        virtual void operator () (const osg::CameraNode& camera) const
        {
                if (!_snapImageOnNextFrame) return;

                int x,y,width,height;
                x = camera.getViewport()->x();
                y = camera.getViewport()->y();
                width = camera.getViewport()->width();
                height = camera.getViewport()->height();

                osg::ref_ptr<osg::Image> image = new osg::Image;
                image->readPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE);

                if (osgDB::writeImageFile(*image,_filename))
                {
                        std::cout  << "Saved screen image to  `"<<_filename
                         <<"`"<< std::endl;
                }

                _snapImageOnNextFrame = false;
        }

protected:

        std::string _filename;
        mutable bool        _snapImageOnNextFrame;


};

我将此设置为 osg::Viewer 的相机的 FinalDrawCallback,但我因空白图像而失败,并在调用图像时收到此警告“警告:在 State::apply() 开始时检测到 OpenGL 错误'无效操作'”-> readPixels,我的 osgViewer::Viewer 嵌入在 QQuickFramebufferObject 中。任何人都可以提供一些建议吗?

4

2 回答 2

2

不确定给你正确的指针,你应该提供更多关于你的设置和你所追求的细节。

作为一般说明,如果您尝试使用 OSG 渲染到 QtQuick 小部件中,最好的方法是让 osg 在单独的共享 GL 上下文中渲染到 FBO,然后将 FBO 内容复制回 qtquick 小部件。我前段时间测试过这种方法,请参见此处的代码: https ://github.com/rickyviking/qmlosg

另一个类似的项目在这里:https ://github.com/podsvirov/osgqtquick

于 2016-05-20T08:12:39.067 回答
0

你可以使用 pbo

ext->glGenBuffers(1, &pbo);
ext->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
ext->glBufferData(GL_PIXEL_PACK_BUFFER_ARB, _width*_height*4, 0, GL_STREAM_READ);

glReadPixels(0, 0, _width, _height, _pixelFormat, _type, 0);

GLubyte* src = (GLubyte*)ext->glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB,
                                              GL_READ_ONLY_ARB);
    if(src)
    {
        memcpy(image->data(), src, _width*_height*4);

        ext->glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
    }
    ext->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
于 2021-08-31T08:40:25.443 回答