当前位置: 首页 > news >正文

13. OPenGL与QT界面元素交互控制图形渲染

1. 说明:

前面文章中讲到的 OPenGL 渲染都是在页面加载完成即立刻渲染的,如果向控制图形渲染的时间,可以在QT界面中添加一些元素来进行控制。此时需要用到OPenGL当中的makeCurrent(),update(),doneCurrent()函数。
效果展示:

opengl与qt交互

2. 步骤一:

在myopenglwidget.h文件中添加一个枚举,放置要绘制的图形类型,同时声明三个函数,分别为drawShape(),clearGraphic(),setWireFrame(),方便主界面上的元素调用,相应代码如下:
myopenglwidget.h:

#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H#include <QObject>
#include <QWidget>#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>class MyOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{Q_OBJECT
public://添加图形类型枚举enum Shape{None,Rect,Circle,Triangle};explicit MyOpenGLWidget(QWidget *parent = nullptr);//添加三个辅助函数void drawShape(Shape shape);void clearGraphic();void setWireFrame(bool wireFrame);protected:virtual void initializeGL() override;virtual void resizeGL(int w, int h) override;virtual void paintGL() override;signals:private://定义一个中间变量Shape m_shape;
};
#endif // MYOPENGLWIDGET_H

3. 步骤二:

对上面的三个辅助函数进行设计,其中每触发一个函数,都应该让OPenGL重新绘制,此时应调用 update() 函数,而在更新视图之前,需要记录当前的视图是什么样的,所以还需要在此之前调用 makeCurrent() 函数,视图更新结束后,需要告知OPenGL已经绘制完毕,此时需要调用 doneCurrent() 函数,相应代码如下:
myopenglwidget.cpp:

#include "myopenglwidget.h"unsigned int VBO,VAO;
//添加一个索引控制器
unsigned int EBO;//定义一个全局的着色器控制器
unsigned int shaderProgram;float vertices[] = {-0.5f,-0.5f,0.0f,0.5f,-0.5f,0.0f,0.0f,0.5f,0.0f
};//使用4个顶点数据绘制两个三角形
float vertices2[] = {0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f
};//添加索引数据
unsigned int indices[]={0,1,3,1,2,3
};MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) :  QOpenGLWidget(parent)
{}
//绘制图形辅助函数
void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{makeCurrent();//记录当前视图m_shape = shape;update();//视图更新doneCurrent();//结束视图更新
}
//清空函数
void MyOpenGLWidget::clearGraphic()
{makeCurrent();drawShape(MyOpenGLWidget::None);makeCurrent();glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);update();doneCurrent();
}
//设置线框模式函数
void MyOpenGLWidget::setWireFrame(bool wireFrame)
{makeCurrent();if(wireFrame){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//以线框模式绘制图形}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//以填充模式绘制图形}update();doneCurrent();
}void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions();shaderProgram = glCreateProgram();//void glGenVertexArrays(GLsizei n, GLuint *arrays)生成顶点数组对象名称// n: 要产生的VAO对象的数量// arrays: 存放产生的VAO对象的名称glGenVertexArrays(1,&VAO);// void glGenBuffers(GLsizei n,GLuint *buffers)生成顶点缓冲对象// n: 要产生的VBO对象的数量// arrays: 存放产生的VBO对象的名称glGenBuffers(1,&VBO);//初始化索引器glGenBuffers(1,&EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof (indices),indices,GL_STATIC_DRAW);//绑定VAO和VBOglBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//在VBO中存入顶点数据glBufferData(GL_ARRAY_BUFFER,sizeof (vertices2),vertices2,GL_STATIC_DRAW);//告诉VAO怎么在VBO中拿数据glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof (float),(void*)0);//开启第一个VAOglEnableVertexAttribArray(0);//用完之后解除绑定(信息已经被记录下来了)glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);
}void MyOpenGLWidget::resizeGL(int w, int h)
{Q_UNUSED(w);Q_UNUSED(h);}void MyOpenGLWidget::paintGL()
{glClearColor(0.5f,0.9f,0.4f,1.0f);glClear(GL_COLOR_BUFFER_BIT);//在渲染前只需开启对应的VAO即可glBindVertexArray(VAO);//switch判断 m_shape 的类型,进行不同图形的绘制switch (m_shape) {case Rect:glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,&indices);break;default:break;}
}

4. 步骤三:

在主界面中添加三个按钮,分别用来绘制,清空,设置线框模式,并相应其clicked信号,调用对应的函数即可,相应代码如下:
myopenglwidget.h:

#ifndef LEARNOPENGL_H
#define LEARNOPENGL_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class LearnOpenGL; }
QT_END_NAMESPACEclass LearnOpenGL : public QMainWindow
{Q_OBJECTpublic:LearnOpenGL(QMainWindow *parent = nullptr);~LearnOpenGL();private slots://三个按钮的槽函数void on_btn_drawRect_clicked();void on_btn_Clear_clicked();void on_btn_setFrame_clicked();private:Ui::LearnOpenGL *ui;
};
#endif // LEARNOPENGL_H

myopenglwidget.cpp:

#include "learnopengl.h"
#include "ui_learnopengl.h"LearnOpenGL::LearnOpenGL(QMainWindow *parent): QMainWindow(parent), ui(new Ui::LearnOpenGL)
{ui->setupUi(this);setCentralWidget(ui->openGLWidget);}LearnOpenGL::~LearnOpenGL()
{delete ui;
}void LearnOpenGL::on_btn_drawRect_clicked()
{ui->openGLWidget->drawShape(MyOpenGLWidget::Rect);//调用绘制图形
}void LearnOpenGL::on_btn_Clear_clicked()
{ui->openGLWidget->clearGraphic();//调用清空图形
}bool frame = true;
void LearnOpenGL::on_btn_setFrame_clicked()
{ui->openGLWidget->setWireFrame(frame);//调用线框模式frame = !frame;
}

相关文章:

13. OPenGL与QT界面元素交互控制图形渲染

1. 说明&#xff1a; 前面文章中讲到的 OPenGL 渲染都是在页面加载完成即立刻渲染的&#xff0c;如果向控制图形渲染的时间&#xff0c;可以在QT界面中添加一些元素来进行控制。此时需要用到OPenGL当中的makeCurrent(),update(),doneCurrent()函数。 效果展示&#xff1a; ope…...

高通平台开发系列讲解(USB篇)libuvc详解

文章目录 一、什么是UVC二、UVC拓扑结构三、libuvc的预览时序图沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍libuvc。 一、什么是UVC UVC,全称为:USB video(device) class。 UVC是微软与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标…...

ICC2:set_route_opt_target_endpoints

route_opt阶段通过指定endpoint/driver pin list的方式执行incremental优化。 set_route_opt_target_endpoints [-setup_endpoints file] [-setup_endpoints_collection pin_list] [-hold_endpoints file] [-hold_endpoints_collection pin_list] [-ldrc_objects fil…...

5、小程序面试题

1, 小程序页面有哪些生命周期函数onLoad: 页面加载onReady: 页面初次渲染完成onShow: 页面显示onHide: 页面隐藏onUnload: 页面卸载2, 一页小程序页面有哪些文件组成,分别有什么作用.wxml: 使用微信框架设计的一套组件构建页面结构.wxss: 用于设置页面样式, 和css基本一致.js :…...

Java特殊操作流

6 特殊操作流 6.1 标注输入输出流 System类中有两个静态的成员变量&#xff1a; public static final InputStream in&#xff1a;标准输入流&#xff0c;通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源public static final PrintStream out&#xff1a;标准输…...

如何用SCRM销售管理系统管理销售和做销售管理

每一家企业都在找适合自己公司的销售管理方法&#xff0c;实现销售目标和努力提高业绩。 我们常说&#xff0c;做好销售管理有很多路径和方法&#xff0c;但我们不知道从哪里开始&#xff1f;每个阶段我们该怎么办&#xff1f;如何有效管理销售团队&#xff1f;好的企企业微信…...

分享117个HTML婚纱模板,总有一款适合您

分享117个HTML婚纱模板&#xff0c;总有一款适合您 117个HTML婚纱模板下载链接&#xff1a;https://pan.baidu.com/s/1cC3I5cfh91-KmQj4nfSoPA?pwd9hod 提取码&#xff1a;9hod Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 import os import shutil import …...

VIVADO2022 sdk 工程创建流程

正点原子uart历程复现 create block design&#xff08;起名 为System&#xff09; -> open block design -> 号/IP catalog 中搜索zynq 双击打开&#xff0c; 将和pl相关的时钟都干掉 再auto 布线一下 把herarchy中的sources 中的system.bd右键、 无脑下一步导出 如…...

【MyBatis】源码学习 02 - Java 元注解以及 MyBatis @Param 注解分析

文章目录前言参考目录学习笔记1、Java 注解1.1、Java 元注解1.2、Java ElementType 枚举值1.3、自定义注解2、Param 注解分析2.1、Param 注解2.2、测试方法2.3、流程分析&#xff08;重点&#xff1a;ParamNameResolver&#xff09;前言 本文内容对应的是书本第 7 章的内容&am…...

贪心算法-蓝桥杯

一、贪心算法的优缺点优点&#xff1a;1.容易理解:生活常见。2.操作简单:在每一步都选局部最优。3.效率高: 复杂度常常是O(1)的。缺点&#xff1a;1.局部最优不一定是全局最优。二、例子: 最少硬币问题硬币面值1、2、5。支付13元&#xff0c;要求硬币数量最少。贪心法: (1) 5元…...

zookeeper 复习 ---- chapter03

zookeeper 复习 ---- chapter03如何创建 zookeeper 对象 要求&#xff1a; 1&#xff1a;知道这几个构造参数 2&#xff1a;知道每一个参数的含义 ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) ZooKeeper(String connectString, int sessionTimeout…...

1.PostgreSQL

文章目录LIMITWITH 和RECURSIVEPostgreSQL 约束PostgreSQL AUTO INCREMENT&#xff08;自动增长&#xff09;PostgreSQL PRIVILEGES&#xff08;权限&#xff09;GRANT语法LIMIT SELECT * FROM COMPANY LIMIT 3 OFFSET 2;WITH 和RECURSIVE WITH RECURSIVE t(a,b) AS (VALUES (…...

buu [UTCTF2020]basic-crypto 1

题目描述&#xff1a; 01010101 01101000 00101101 01101111 01101000 00101100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110111 01100101 00100000 01101000 01100001 01110110 01100101 00100000 0…...

火山引擎数智平台的这款产品,正在帮助 APP 提升用户活跃度

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 你有没有关注过 APP 给你推送的消息&#xff1f; 出于提升用户活跃度的考虑&#xff0c;APP 会定期在应用内面向用户进行内通推送&#xff0c;推送形式既包括 APP …...

记录每日LeetCode 2341.数组能形成多少数对 Java实现

题目描述&#xff1a; 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返回一个下标…...

Ant Design Chart词云图

什么是词云图&#xff1f;词云图&#xff0c;也叫文字云&#xff0c;是对网络文本中出现频率较高的“关键词”予以视觉上的突出&#xff0c;出现越多&#xff0c;显示的字体越大&#xff0c;越突出&#xff0c;这个关键词也就越重要。让浏览者通过词云图一眼就可以快速感知最突…...

mysql索引

索引 mysql索引&#xff1a; 在MySQL中&#xff0c;索引是存储引擎实现的&#xff0c;所以没有统一的索引标准&#xff0c;不同存储引擎的索引工作方式也不一样&#xff0c;也不是所有的存储引擎都支持所有类型的索引即使是多个存储引擎都支持同一种类型的索引&#xff0c;他…...

Java中怎样将数据对象序列化和反序列化?

程序在运行过程中&#xff0c;可能需要将一些数据永久地保存到磁盘上&#xff0c;而数据在Java中都是保存在对象当中的。那么我们要怎样将对象中的数据保存到磁盘上呢?这时就需要使用Java中的对象序列化。对象的序列化(Serializable)是指将一个Java对象转换成一个I/O流中字节序…...

ffmpeg filter的理解

ffmpeg filter的理解 filter的简介 从整体看&#xff0c;filte rgraph包含filter chain&#xff0c;而filter chain又包含了filter&#xff0c;所以可以分为是三个层次去理解。 filterfilter chainfilter graph filter graph是链接多个filter的有向图。它可以包含循环&#…...

炔活化的生物素化试剂773888-45-2,Alkyne-Biotin,炔基生物素

【产品描述】炔活化的生物素化试剂&#xff0c;可通过铜催化的点击反应与叠氮化物反应&#xff0c;产生稳定的三唑键&#xff0c;生物素炔烃在结构上与生物素炔烃相同。用于通过点击化学制备各种生物素化共轭物的生物素炔烃。Alkyne activated biotinylation reagents can prod…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...