计算机图形学实践:结合Qt和OpenGL实现绘制彩色三角形
在Qt项目中结合OpenGL与CMake需要配置正确的依赖关系、链接库以及代码结构设计。以下是具体实现步骤和关键要点:
一、环境准备
- 安装Qt
确保安装包含OpenGL模块的Qt版本(如Qt OpenGL
、Qt OpenGLWidgets
组件)。 - 安装CMake
使用3.10及以上版本,并配置系统环境变量。
二、CMake配置
1. 基础配置
cmake_minimum_required(VERSION 3.10)
project(Qt_OpenGL_Project)# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 查找Qt组件
find_package(Qt6 COMPONENTS Core Gui Widgets OpenGL OpenGLWidgets REQUIRED)# 添加可执行文件
add_executable(${PROJECT_NAME} main.cpp)
2. 链接OpenGL与Qt库
# 链接Qt核心库
target_link_libraries(${PROJECT_NAME}Qt6::CoreQt6::GuiQt6::WidgetsQt6::OpenGLQt6::OpenGLWidgets
)# 链接系统OpenGL库(Windows需显式链接)
if(WIN32)target_link_libraries(${PROJECT_NAME} opengl32 glu32)
endif()
3. 启用OpenGL特性
若使用QCustomPlot等第三方库需启用OpenGL支持:
target_compile_definitions(${PROJECT_NAME} PRIVATE QCUSTOMPLOT_USE_OPENGL)
三、代码实现
1. 继承QOpenGLWidget
#include <QOpenGLWidget>
#include <QOpenGLFunctions>class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions {Q_OBJECT
public:explicit GLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}protected:void initializeGL() override {initializeOpenGLFunctions(); // 初始化OpenGL函数glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 设置背景色}void paintGL() override {glClear(GL_COLOR_BUFFER_BIT); // 清空缓冲区// 添加OpenGL绘制代码}void resizeGL(int w, int h) override {glViewport(0, 0, w, h); // 设置视口}
};
2. 主窗口集成
#include <QApplication>
#include <QMainWindow>int main(int argc, char *argv[]) {QApplication a(argc, argv);QMainWindow window;GLWidget glWidget;window.setCentralWidget(&glWidget);window.show();return a.exec();
}
四、常见问题解决
-
OpenGL函数未识别
- 确保继承
QOpenGLFunctions
并调用initializeOpenGLFunctions()
。 - 使用
QOpenGLExtraFunctions
获取更高版本API支持。
- 确保继承
-
Qt版本兼容性
- Qt6默认使用
QOpenGLWidget
替代旧版QGLWidget
,推荐使用新API。 - 若需兼容Qt5,修改CMake中
Qt6
为Qt5
并调整组件名称。
- Qt6默认使用
-
第三方库集成(如OpenCV)
在CMake中启用WITH_QT
和WITH_OPENGL
选项,确保OpenCV编译时支持Qt和OpenGL:find_package(OpenCV REQUIRED) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
五、高级配置
- 多平台适配
CMake自动处理不同平台的库依赖(如Linux下链接-lGL
,macOS下链接-framework OpenGL
)。 - 调试工具
使用qDebug()
输出OpenGL错误码,或借助glGetError()
检查错误。
通过以上步骤,Qt与OpenGL可在CMake项目中无缝集成,实现跨平台的图形渲染功能。建议参考Qt官方文档和OpenGL教程深入优化渲染逻辑。
下面利用QT和OpenGL画一个三角形
一、创建OpenGL绘制组件
- 继承QOpenGLWidget实现自定义绘制类:
// myopenglwidget.h
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:explicit MyOpenGLWidget(QWidget *parent = nullptr);void setTriangleColor(const QColor &color);protected:void initializeGL() override;void paintGL() override;private:GLuint VAO, VBO;QOpenGLShaderProgram *shaderProgram;QVector3D triangleColor = QVector3D(1.0f, 0.0f, 0.0f); // 默认红色
};
二、实现OpenGL初始化与绘制
// myopenglwidget.cpp
void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.1f, 0.1f, 0.1f, 1.0f);// 顶点数据(三角形位置)float vertices[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f, 0.5f, 0.0f};// 创建VAO/VBOglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 配置顶点属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// 创建着色器程序shaderProgram = new QOpenGLShaderProgram(this);shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,"#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main() {\n"" gl_Position = vec4(aPos, 1.0);\n""}");shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,"#version 330 core\n""out vec4 FragColor;\n""uniform vec3 ourColor;\n""void main() {\n"" FragColor = vec4(ourColor, 1.0);\n""}");shaderProgram->link();
}void MyOpenGLWidget::paintGL()
{glClear(GL_COLOR_BUFFER_BIT);shaderProgram->bind();shaderProgram->setUniformValue("ourColor", triangleColor);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);shaderProgram->release();
}void MyOpenGLWidget::setTriangleColor(const QColor &color)
{triangleColor = QVector3D(color.redF(), color.greenF(), color.blueF());update(); // 触发重绘
}
三、添加颜色选择按钮
// mainwindow.cpp
#include <QMainWindow>
#include <QPushButton>
#include <QColorDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{MyOpenGLWidget *glWidget = new MyOpenGLWidget(this);setCentralWidget(glWidget);// 创建颜色选择按钮QPushButton *colorBtn = new QPushButton("选择颜色", this);colorBtn->setGeometry(10, 10, 100, 30);connect(colorBtn, &QPushButton::clicked, [=](){QColor color = QColorDialog::getColor(Qt::red, this, "选择三角形颜色");if (color.isValid()) {glWidget->setTriangleColor(color);}});
}
四、运行效果
- 窗口显示灰色背景的红色三角形
- 点击"选择颜色"按钮弹出颜色选择对话框
- 选择颜色后三角形实时更新颜色
关键实现原理
- 着色器控制颜色:通过
uniform
变量传递颜色值到片段着色器 - 颜色转换:将Qt的QColor转换为OpenGL的归一化颜色值(0.0-1.0)
- 实时更新:调用
update()
触发OpenGL重绘
相关文章:
计算机图形学实践:结合Qt和OpenGL实现绘制彩色三角形
在Qt项目中结合OpenGL与CMake需要配置正确的依赖关系、链接库以及代码结构设计。以下是具体实现步骤和关键要点: 一、环境准备 安装Qt 确保安装包含OpenGL模块的Qt版本(如Qt OpenGL、Qt OpenGLWidgets组件)。安装CMake 使用3.10及以上版本&a…...

OpenCV 图形API(54)颜色空间转换-----将图像从 RGB 色彩空间转换到 HSV色彩空间RGB2HSV()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从 RGB 色彩空间转换为 HSV。该函数将输入图像从 RGB 色彩空间转换到 HSV。R、G 和 B 通道值的常规范围是 0 到 255。 输出图像必须是 8 位…...
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
统一HTTP请求代码 public class HttpCode {/*** 操作成功*/public static final int SUCCESS 200;/*** 对象创建成功*/public static final int CREATED 201;/*** 请求已经被接受*/public static final int ACCEPTED 202;/*** 操作已经执行成功,但是没有返回数据…...
#git pull 问题:cannot lock ref ‘xxx‘: ref xxx is at (commitID) but expected ‘xxx‘
问题描述:git在拉取远程代码时出现该提示,拉取失败,导致该问题可能是远程有本地没有跟踪过的(小写大写不同)重名的分支,git是不区分大小写的,所以比如有一个的分支原先是example1.0,…...

JavaWeb学习打卡-Day1-分层解耦、Spring IOC、DI
三层架构 Controller(控制层):接收前端发送的请求,对请求进行处理,并响应数据。Service(业务逻辑层):处理具体的业务逻辑。DAO(数据访问层/持久层)ÿ…...
PostgesSQL外部数据封装FDW
PostgesSQL外部数据封装FDW 1. FDW外部数据配置(单表)1.1 远端数据库创建测试表1.2 安装扩展postges\_fdw1.3 创建外部服务SERVER1.4 创建用户映射USER MAPPING1.5 创建远程表FOREIGN TABLE1.6 数据库更新测试 2. FDW外部数据配置(用户&#…...
redis相关问题整理
Redis 支持多种数据类型: 字符串 示例:存储用户信息 // 假设我们使用 redis-plus-plus 客户端库 auto redis Redis("tcp://127.0.0.1:6379"); redis.set("user:1000", "{name: John Doe, email: john.doeexample.com}"…...

基于 Electron、Vue3 和 TypeScript 的辅助创作工具全链路开发方案:涵盖画布系统到数据持久化的完整实现
基于 Electron、Vue3 和 TypeScript 的辅助创作工具全链路开发方案:涵盖画布系统到数据持久化的完整实现 引言 在数字内容创作领域,高效的辅助工具是连接创意与实现的关键桥梁。创作者需要一款集可视化画布、节点关系管理、数据持久化于一体的专业工具&…...

[Java · 铢积寸累] 数据结构 — 数组类型 - 增 删 改 查
🌟 想系统化学习 Java 编程?看看这个:[编程基础] Java 学习手册 在上一章中我们介绍了如何声明与创建数组,还介绍了数组的基本使用方式。本章我们将在上一章的基础上,拓展数组的使用方式(可能会涉及一些思…...

前端笔记-Axios
Axios学习目标 Axios与API交互1、Axios配置与使用2、请求/响应拦截器3、API设计模式(了解RESTful风格即可) 学习参考:起步 | Axios中文文档 | Axios中文网 什么是Axios Axios 是一个基于 Promise 的现代化 HTTP 客户端库,专…...
vue3数据响应式丢失的情况有哪些
在 Vue 3 中,响应式系统使用的是 Proxy 实现,相比 Vue 2 提升很大,很多 Vue 2 中的数据响应式陷阱都被解决了(比如数组索引、新增属性等),但依然存在一些可能导致“响应式丢失”的情况。 🚨 Vue…...
每日一练(4~23):特别数的和
算法:枚举 题目 题目描述 小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。 请问,在 1 到 n…...
AR行业应用案例与NXP架构的结合
1. 工业巡检AR头盔 场景示例:宁德核电基地使用AR智能头盔进行设备巡检,通过实时数据叠加和远程指导,将工作效率提升35%。头盔需处理传感器数据、图像渲染和低延迟通信1。 NXP架构支持: 协处理器角色:NXP i.MX RT系列M…...

C# 类型、存储和变量(值类型引用类型)
本章内容 C#程序是一组类型声明 类型是一种模板 实例化类型 数据成员和函数成员 预定义类型 用户定义类型 栈和堆 值类型和引用类型 变量 静态类型和dynamic关键字 可空类型 值类型引用类型 数据项的类型定义了存储数据需要的内存大小及组成该类型的数据成员。类型还决定了对象…...

智慧校园从配电开始:AISD300为校园安全加上智能防护罩
安科瑞刘鸿鹏 摘要 随着校园用电需求不断上升及其安全保障要求的提高,传统低压配电系统已逐渐难以满足现代校园的安全与智能化管理需求。本文基于安科瑞电气推出的AISD300系列三相智能安全配电装置,探讨其在校园电力系统中的应用优势及关键技术特性。…...
如何创建极狐GitLab 议题?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 创建议题 (BASIC ALL) 创建议题时,系统会提示您输入议题的字段。 如果您知道要分配给议题的值,则可…...
如何将极狐GitLab 合并请求导出为 CSV?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 导出合并请求为 CSV (BASIC ALL) 将从项目的合并请求中收集的所有数据导出到逗号分隔值(CSV)文件中。…...

一 、环境的安装 Anaconda + Pycharm + PaddlePaddle
《从零到一实践:系统性学习生成式 AI(NLP)》 一 、环境的安装 Anaconda Pycharm PaddlePaddle 1. Anaconda 软件安装 Anaconda 软件安装有大量的教程,此处不在说明,安装完成之后界面如下: 2. 创建 Anaconda 虚拟环境 Paddl…...

十倍开发效率 - IDEA插件之 Maven Helper
0X00 先看效果 第一个选项表示存在冲突的依赖,可以看到图片中 mysql 的连接依赖发生了冲突,在低版本的上面直接右键选择 Exclude,冲突的依赖就被解决掉了。 0X01 安装 在 Plugins 中直接搜索 Maven Helper,选择第一个进行安装&am…...
Go语言和Python 3的协程对比
Go语言和Python 3都支持协程(concurrent coroutines),但它们的实现机制、使用方式、调度方式和性能表现差异很大。下面是对比分析: 一、基本概念对比 特性Go 协程(goroutine)Python3 协程(asyn…...

人机共跑,马拉松人型机器人同跑
马拉松比赛对人形机器人来说,是一场对硬件极限的测试,涉及机械、传感器、能源管理等多个方面。用户问的是硬件方面的考察和改进,这意味着我的回答需要聚焦于硬件性能,而不是算法或软件的优化。 对人形机器人硬件的考研 机械结构与…...

策略模式:动态切换算法的设计智慧
策略模式:动态切换算法的设计智慧 一、模式核心:定义一系列算法并可相互替换 在软件开发中,常常会遇到需要根据不同情况选择不同算法的场景。例如,在电商系统中,根据不同的促销活动(如满减、折扣、赠品&a…...

uniapp微信小程序:WIFI设备配网之TCP/UDP开发AP配网
一、AP配网技术原理 1.1 配网模式选择 AP配网(SoftAP模式)是IoT设备配网成功率最高的方案之一 1、其核心原理: 设备端:启动AP模式(如SSID格式YC3000_XXXX,默认IP192.168.4.1)手…...

离线-DataX
基本介绍 DataX 是阿里云 DataWorks数据集成的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台,它是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源…...
在Ubuntu上查看PCL(Point Cloud Library)的版本
在Ubuntu上查看PCL(Point Cloud Library)的版本可以通过终端运行命令pcl_viewer --version来实现。该命令将显示PCL库的版本号。 另外,你也可以使用以下命令在终端中查看PCL的版本号: 方法一: dpkg -l | grep libpc…...
RESTful学习笔记(一)
Web发展 一、API 程序硬件接口(Application Programming Interface),是预先定义好的逻辑函数,软件系统不同组成部分衔接的约定,直接调用函数,无序访问代码细节,分为SDK和Web应用接口两类 SDK…...
【汽车ECU电控数据管理篇】S19文件格式解析篇章
一、S19格式是啥 在电控文件管理的初期阶段,我首次接触到的是 A2L 和 HEX 文件。其中,A2L 文件主要承担着描述性功能,它详细地描述了各种参数和配置等相关信息。而 HEX 文件则是一种刷写文件,其内部明确记录了具体的地址以及对应的…...

第5课:对象与类——JS的“信息收纳盒”
生活从不会亏待每一个努力向上的人,愿你带着满腔热忱,无畏前行,用汗水书写青春的华章,用拼搏铸就人生的辉煌,今日的每一份付出,都将是未来成功的基石! 欢迎来到「JavaScript 魔法学院」第 5 课…...

xshell 登录验证失败解决
产生原因:检查防火墙、selinux 、网络模式、对外是否能ping外网 systemctl status firewalld cat /etc/selinux/config #disabled ping 223.5.5.5 ping 8.8.8.8 ping www.baidu.com 一、检查网络连接 确认虚拟机是否在线: 首先,确保虚…...

AI 赋能 3D 创作!Tripo3D 全功能深度解析与实操教程
大家好,欢迎来到本期科技工具分享! 今天要给大家带来一款革命性的 AI 3D 模型生成平台 ——Tripo3D。 无论你是游戏开发者、设计师,还是 3D 建模爱好者,只要想降低创作门槛、提升效率,这款工具都值得深入了解。 接下…...