在QWidget中,可以使用QOpenglWidget调用opengl接口进行渲染,因为QWidget大部分控件都是依赖于平台的(cpu绘制),所以我们调用opengl的接口时不需要考虑opengl的context共享,所以相对简单。但是qml的渲染策略有所不同,在可以使用硬件加速的环境下,qml是把当前所有可视元素都“堆放”在一起,然后统一使用gpu渲染。所以如果我们想要在qml中使用opengl接口进行绘制,需要考虑调用的时机以及不同窗口之间资源的共享,下面提供一种方法。

想要在qml中使用,我们需要继承QQuickItem,现在我们定义一个MyCube 用来绘制一个立方体。

class CubeRender;
class MyCube : public QQuickItem
{Q_OBJECT
public:explicit MyCube(QQuickItem* parent = nullptr);protected slots:void sync();void cleanUp();private:CubeRender* m_render{nullptr};
signals:};

其中CubeRender 是对opengl接口的一个封装,稍后再解释。先看看quick的渲染流程:

这张图截取自官方文档,从中可以很清楚的看到,GUI线程调用updatePolish之后,会把qml的视图元素传入渲染线程,在数据传递过程中,GUI线程会被lock,当传递完毕,渲染线程会发射beforeRendering信号,解锁GUI线程,然后GUI线程去做别的工作,渲染线程则进行渲染工作。

一般opengl不支持跨线程调用,所以我们想创建opengl资源和使用相关的api都必须在渲染线程中用同步的方式调用。

所以,我们需要在渲染线程发出beforeSynchronizing的信号时创建我们的opengl资源,在渲染线程发出beforeRendering的时候调用绘制接口,需要注意的是,由于渲染线程和gui线程并非一个线程,所以在连接信号槽的时候,我们需要使用Qt::DirectConnection来强制同步。

下面我们来看一下中CubeRender:

class CubeRender: protected QOpenGLFunctions_4_5_Core
{
public:CubeRender();void initializeGL();void resizeGl(int w, int h);void render();protected:QOpenGLShaderProgram m_shaderProgram;
};

我这边是仿造QOpengWidget的形式对opengl接口进行了封装,主要有三个接口:

void initializeGL(); 用来初始化opengl资源,包括创建VBO,VAO以及链接shader。

void resizeGl(int w, int h);当窗口大小发生改变的时候调用,用来修改视口的大小以及重新生成相关的视图矩阵。

void render(); 进行绘制。值得注意的是,由于qml大部分控件都是调用opengl绘制的,而且opengl本质是一个状态机,所以在绘制前需要对VBO这些对象重新进行bind。

(可以参考opengl相关教程来理解这些操作。)

下面就比较简单了,我们在收到beforeSynchronizing信号的时候初始化opengl资源。

 connect(this,&QQuickItem::windowChanged,this,[this](QQuickWindow* window){if(window){connect(window,&QQuickWindow::beforeSynchronizing,this,&MyCube::sync,
Qt::DirectConnection);}},Qt::DirectConnection);void MyCube::sync()
{if(!m_render){m_render = new CubeRender;m_render->initializeGL();m_render->resizeGl(width(),height());
}

在收到beforeRendering的时候进行绘制:

       connect(window(), &QQuickWindow::beforeRendering, this, [this](){m_render->render();}, Qt::DirectConnection);

当窗口大小变化的重新调整视口大小:

           connect(this, &QQuickItem::widthChanged, this, [this](){m_render->resizeGl(this->width(), this->height());});connect(this, &QQuickItem::heightChanged, this, [this](){m_render->resizeGl(this->width(), this->height());});

接下来把MyCube注册成QML元素就可以使用了。

qmlRegisterType<MyCube>("cube.utility", 1, 0, "MyCube");

此外,还有一种方法是继承QQuickFramebufferObject,来进行opengl渲染。

如何在qml中使用opengl接口进行渲染相关推荐

  1. 如何在Python中创建OpenGL/Glut

    OpenGL(开放图形库)是一种跨语言.多平台的应用程序编程接口(API),用于绘制二维和三维计算机图形. API通常用于与图形处理单元(GPU)交互,以实现硬件加速渲染.OpenGL由Silicon ...

  2. jeesite如何已生成数据的数据源_如何在postman中自动生成接口请求数据,这个功能你需要知道,可结合浏览器和两大抓包工具使用...

    在做接口调试或测试时,请求中的每个参数都要按照接口文档填写到postman的对应位置中,很是麻烦.那是否有这样一个功能?可以帮我们自动生成接口数据,无需修改,直接发送请求就可以呢. 这里面我们需要借助 ...

  3. 如何在QML中使用不同的字体(font)

    在这篇文章中,我们将展示如何在我们的QML应用中使用不同的font.我们既可以使用本地应用带有的字体,也可以使用系统带有的字体.我们也展示了如何使用一个在网路上的字体. 为了使用字体,我们可以通过如下 ...

  4. 如何在Python中调用RNAfold接口,即RNA扩展包

    最近在做RNA蛋白质位点结合方向的研究,复现大佬代码的过程中,发现其用到了RNAfold的python接口包,其中主要用到了根据RNA序列生成二级结构的功能. RNAfold官网 链接: https: ...

  5. java map sortedmap,如何在Java中使用SortedMap接口?

    I have a Map What is the best way to keep the map sorted according to the float? Is SortedMap the be ...

  6. C#中使用OpenGL(API)创建OpenGL渲染环境

    在C#中调用1.1版本的OpenGL函数,但是光有OpenGL函数还不能绘制图形,就像一个画家,他即使拥有绘画的技巧,还有画笔和颜料,如果没有画布,他也没有地方画画.有了画布,画家还需要画板把画布支起 ...

  7. QT中使用OpenGL绘制图形

    Qt Creator中的3D绘图及动画教程(参照NeHe) 刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用Op ...

  8. (译)通过WebChannel/WebSockets与QML中的HTML交互

    来源:通过WebChannel/WebSockets与QML中的HTML交互 GitHub:八至 作者:狐狸家的鱼 本文链接:QML与HTML交互 在查询QML与HTML之间通信交互时资料很少,这篇文 ...

  9. Qt中使用OpenGL进行绘图

    Qt Creator中的3D绘图及动画教程(参照NeHe) 刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用Op ...

最新文章

  1. [模板][持续更新]欧拉回路与欧拉路径浅析
  2. R语言决策树、bagging、随机森林模型在训练集以及测试集的预测结果(accuray、F1、偏差Deviance)对比分析、计算训练集和测试集的预测结果的差值来分析模型的过拟合(overfit)情况
  3. 同一DIV内,两个行内块元素不对齐的解决方案
  4. 一体化机柜在县级支行机房标准化建设中的应用
  5. /etc/services
  6. 奥运加油,中国加油!!!
  7. c语言malloc calloc,C语言内存管理:malloc、calloc、free的实现
  8. linux使用gpio开一个线程,LINUX的gpio_request_one作用
  9. Spring Boot数据校验
  10. html里球是哪个单词,html tag是什么意思
  11. 干货:使用Fastapi开发自己的Mock server(附源码)
  12. fillrect不填充被覆盖的区域 mfc_纹理和图案填充
  13. 在训练期间保存检查点
  14. Request,Request.Form,Request.QueryString
  15. python求小数部分_python-numpy数组的小数部分
  16. 有关likely和unlikely??
  17. 《推荐系统实践》算法纯享(附代码链接)(三)—— 冷启动篇
  18. iptable端口重定向 MASQUERADE
  19. 俄勒冈大学计算机科学专业,美国俄勒冈大学计算机与信息科学博士后
  20. python之禅怎么读_混为一谈的读音

热门文章

  1. 1.素数和题目内容: 我们认为2是第一个素数,3是第二个素数,5是第三个素数,依次类推。 现在,给定两个整数n和m,0<n<=m<=200,你的程序要计算第n个素数到第m个素数之间所有的素数的和,
  2. 计算机系毕业祝福语,送给毕业生的祝福语
  3. java用jintellitype和jna两种方式实现鼠标键盘后台监听
  4. java基于ssm的房屋租赁出租管理系统
  5. 第14章 Salesforce标准对象
  6. Nginx架构模型及常用配置
  7. 微信朋友圈点赞的测试点
  8. Gerrit 创建分支
  9. 低代码,快速应用开发和数字转换
  10. 模糊逻辑控制器在matlab中调用,模糊逻辑控制器结构与设计(matlab).ppt