QML之QQuickFramebufferObject

1.应用场景

在以QML和C++混合编程的项目开发中遇到涉及到视频播放的需求,预研过程中发现如果直接使用QML中Image来一帧帧显示图像,导致帧率相当感人,在嵌入式ARM-Linux环境中可能仅有2-3帧/秒。在寻找相关解决方法时偶然看到Qt中QQuickFramebufferObject类可以结合QOpenglFunctions来显示图片解决该问题,实际开发完成后测试基于上述解决方法在同样嵌入式环境中可以达到15帧/秒以上的显示,效果达到目标设计。

2.使用原理

在Qt5.12.12助手中是这样介绍QQuickFramebufferObject类的:"QQuickFramebufferObject类是一个便利类,用于将使用帧缓冲区对象(FBO)的OpenGL渲染与Qt Quick集成。在大多数平台上,渲染将在专用线程上进行。因此,QQuickFramebufferObject类强制在项目实现和FBO渲染之间进行严格分离。所有项目逻辑,如QML所需的属性和UI相关辅助函数,都应位于QQuickFramesbufferObject子类中。所有与渲染相关的内容都必须位于QQuickFramebufferObject::Renderer类中。"

在介绍中可以看出该类继承OpenGL的FBO到Qt Quick中来,再结合QQuickFramebufferObject::Renderer类可以实现显示功能。

3.使用方法

好在Qt官方给出相关的例子,在例子中搜索FBO可以看到相关代码,以下结合例子介绍相关使用方法。

cpp 复制代码
// 1.继承QQuickFramebufferObject,重写createRender
class FboInSGRenderer : public QQuickFramebufferObject {
    Q_OBJECT
public:	
	// 继承QQuickFramebufferObject,并重写createRender函数
    Renderer *createRenderer() const {
    	// LogoInFboRender类继承与Renderer类,重新实现Renderer
    	return new LogoInFboRenderer();
    }
};
// 2.该类重新实现了render和createFramebufferObject函数
class LogoInFboRenderer : public QQuickFramebufferObject::Renderer {
public:
    void render() override {
    	// LogoRenderer继承qopenglfunctions
        logo.render();
        update();
    }
    QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override {
        QOpenGLFramebufferObjectFormat format;
        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        format.setSamples(4);
        return new QOpenGLFramebufferObject(size, format);
    }
    LogoRenderer logo;
};
// 3.opengl绘制图像
void LogoRenderer::render() {
	// 深度测试
    glDepthMask(true);
    // 清屏
    glClearColor(0.5f, 0.5f, 0.7f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // 纹理过滤设置
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glFrontFace(GL_CW);
    glCullFace(GL_FRONT);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    QMatrix4x4 modelview;
    modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
    modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
    modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
    modelview.scale(m_fScale);
    modelview.translate(0.0f, -0.2f, 0.0f);
	// shader程序绑定
    program1.bind();
    program1.setUniformValue(matrixUniform1, modelview);
    //绘制Qt图标
    paintQtLogo();
    // 解绑
    program1.release();
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    m_fAngle += 1.0f;
}
// 4.QML中注册
qmlRegisterType<FboInSGRenderer>("SceneGraphRendering", 1, 0, "Renderer");
// 5.QML中使用
    Renderer {
        id: renderer
        anchors.fill: parent
        anchors.margins: 10
        // The transform is just to show something interesting..
        transform: [
            Rotation { id: rotation; axis.x: 0; axis.z: 0; axis.y: 1; angle: 0; origin.x: renderer.width / 2; origin.y: renderer.height / 2; },
            Translate { id: txOut; x: -renderer.width / 2; y: -renderer.height / 2 },
            Scale { id: scale; },
            Translate { id: txIn; x: renderer.width / 2; y: renderer.height / 2 }
        ]
    }
相关推荐
Quz8 小时前
QML TextField 应用:自动关联与表单提交
qt
sycmancia10 小时前
Qt——自定义控件温度计
开发语言·qt
艾莉丝努力练剑11 小时前
【Qt:问题解决】Qt程序入口点错误修复:MinGW ABI兼容问题
java·服务器·开发语言·qt·文件系统·动静态库
邱邱玩编程21 小时前
读取位置 0x0000000000000000 时发生访问冲突 | QT | MFC
c++·qt·visualstudio
我是小灰灰吖1 天前
QT在线安装器使用指南:从下载到配置完整教程
linux·qt·ubuntu
C++ 老炮儿的技术栈1 天前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
我是小灰灰吖1 天前
Ubuntu 22.04 + Qt 6.9.3 应用程序打包与部署完整指南
qt·ubuntu
qq_401700411 天前
Qt自定义信号槽详解:带参发射 vs sender()获取,两种多信号关联方案全掌握
java·数据库·qt
郝学胜-神的一滴1 天前
Qt 高级编程 042:进度条从入门到自定义美化
开发语言·c++·qt·软件开发·用户界面
AI的探索之旅1 天前
嵌入式视觉学习路线:Qt + OpenCV + 工业相机,从零到综合项目
qt·opencv·学习