Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 在OpenSceneGraph场景中显示Qt Quick内容_Opengl_Qtquick2_Openscenegraph - Fatal编程技术网

Opengl 在OpenSceneGraph场景中显示Qt Quick内容

Opengl 在OpenSceneGraph场景中显示Qt Quick内容,opengl,qtquick2,openscenegraph,Opengl,Qtquick2,Openscenegraph,我想在OpenSceneGraph场景中的虚拟屏幕上显示我的Qt Quick内容 我现在使用的方法效率很低: 使用FBO(FrameBufferObject)将Qt快速渲染到屏幕外曲面 使用QOpenGLFramebufferObject::toImage()下载像素 将像素上传到OSG 这就是GPU-CPU-GPU传输 一个合适的解决方案应该以某种方式利用现有的FBO,并且能够仅在GPU内部传输数据 有两种选择: 在Qt侧创建FBO,并在OSG侧使用其纹理 在OSG侧创建FBO并将其馈送到Q

我想在OpenSceneGraph场景中的虚拟屏幕上显示我的Qt Quick内容

我现在使用的方法效率很低:

  • 使用FBO(FrameBufferObject)将Qt快速渲染到屏幕外曲面
  • 使用QOpenGLFramebufferObject::toImage()下载像素
  • 将像素上传到OSG
  • 这就是GPU-CPU-GPU传输

    一个合适的解决方案应该以某种方式利用现有的FBO,并且能够仅在GPU内部传输数据

    有两种选择:

  • 在Qt侧创建FBO,并在OSG侧使用其纹理
  • 在OSG侧创建FBO并将其馈送到Qt快速渲染器
  • Qt部分正常。我对OSG完全迷茫了。有谁能给我一些建议吗?

    终于成功了

    总体思路:

  • 使用FBO快速渲染纹理-在internet上有一些可用

  • 在OpenSceneGraph中使用此纹理

  • 整个过程包括几个技巧

    上下文共享 要执行某些图形操作,我们必须初始化OpenGL全局状态,也称为上下文

    创建纹理时,上下文存储其id。id不是全局唯一的,因此当在另一个上下文中创建另一个纹理时,它可能会获得相同的id,但后面有不同的资源

    如果您只是将纹理的id传递给另一个渲染器(在不同的上下文中操作),希望它显示您的纹理,则最终会显示另一个纹理或黑屏或崩溃

    补救办法是上下文共享,这实际上意味着共享ID

    OpenSceneGraph和Qt抽象不兼容,所以您需要告诉OSG不要使用自己的上下文抽象。这是通过调用
    setupviewerambeddedinwindow

    代码:

    请记住,一次只能有一个活动上下文

    你的计划是:

    0. create osg::Texture out of QOpenGLFrameBufferObject::texture()
    1. make QtQuick context active
    2. render QtQuick to texture
    3. make primary (OSG) context active
    4. render OSG
    5. goto 1
    
    制作合适的osg::纹理 由于OSG和Qt API不兼容,您几乎无法按原样将
    QOpenGLFrameBufferObject
    链接到
    OSG::Texture2D

    QOpenGLFrameBufferObject具有返回opengl纹理id的
    QOpenGLFrameBufferObject::texture()
    方法,但osg::texture自己管理所有opengl内容

    类似于osg::Texture2D(uint-textureId)可以帮助我们,但它根本不存在

    让我们自己做一个

    osg::Texture
    由存储OpenGL纹理id和一些其他数据的
    osg::TextureObject
    支持。如果我们使用给定的纹理id构造
    osg::TextureObject
    ,并将其传递给
    osg::texture
    ,后者将使用它作为自己的纹理

    代码:


    完成演示项目

    void Widget::initializeGL()
    {
        QOpenGLContext* qmlGLContext = new QOpenGLContext(this);
        // ...
        qmlGLContext->setShareContext(context());
        qmlGLContext->create();
    }
    
    0. create osg::Texture out of QOpenGLFrameBufferObject::texture()
    1. make QtQuick context active
    2. render QtQuick to texture
    3. make primary (OSG) context active
    4. render OSG
    5. goto 1
    
    void Widget::createOsgTextureFromId(osg::Texture2D* texture, int textureId)
    {
        osg::Texture::TextureObject* textureObject = new osg::Texture::TextureObject(texture, textureId, GL_TEXTURE_2D);
        textureObject->setAllocated();
    
        osg::State* state = m_osgGraphicsContext->getState();
        texture->setTextureObject(state->getContextID(), textureObject);
    }