Qt 开发 OpenGL 程序流程

        在用 Qt 开发 OpenGL 程序时,整体的工作流程分为几个关键步骤,最终目的是将数据传递给 GPU 并开始渲染。这一过程涉及到从代码编写到与着色器连接的多个操作,下面我将详细讲解每个步骤。

1. 设置 Qt 项目

        这个步骤是准备工作,你首先需要在 Qt 中创建一个 OpenGL 项目。通常你会选择 QOpenGLWidget 来作为渲染的画布。

        a. 创建项目:在 Qt Creator 中创建一个基于 Qt Widgets 的项目,或者选择 Qt Quick 项目(如果你使用 QML 进行图形界面开发)。

        b. 添加 OpenGL 支持:确保你的项目的 .pro 文件中包含了对 OpenGL 的支持:

QT += core gui opengl

2. 初始化 OpenGL 环境

        在 Qt 中,QOpenGLWidget 提供了一个方便的接口来管理 OpenGL 的上下文和渲染操作。

        在你创建的 Qt 应用中,重写 QOpenGLWidget 的 initializeGL()、resizeGL() 和 paintGL() 方法来进行 OpenGL 的初始化、大小调整以及绘制。

示例:

class MyOpenGLWidget : public QOpenGLWidget {Q_OBJECTprotected:void initializeGL() override {// 初始化 OpenGL 设置initializeOpenGLFunctions();glEnable(GL_DEPTH_TEST);  // 开启深度测试}void resizeGL(int w, int h) override {// 设置视口大小glViewport(0, 0, w, h);// 设置投影矩阵(比如透视投影)glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0);glMatrixMode(GL_MODELVIEW);}void paintGL() override {// 清空屏幕并绘制glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();// 绘制场景代码(如绘制一个三角形)}
};

3. 设置顶点数据

        这一步是数据准备的过程。你要定义顶点数据以及纹理坐标,并将它们 发送到 GPU。

        a. 使用顶点数组(vertices[])来存储几何数据(顶点位置)。

        b.  使用 glGenBuffers 和 glBindBuffer 来创建和绑定 VBO(顶点缓冲对象),然后将数据传送到 GPU。

示例:

GLuint VBO, VAO;
GLfloat vertices[] = {// 顶点坐标,按顺序排列-1.0f,  1.0f, 0.0f,-1.0f, -1.0f, 0.0f,1.0f, -1.0f, 0.0f,// ...
};// 创建 VAO(顶点数组对象)和 VBO(顶点缓冲对象)
glGenVertexArrays(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(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

4. 编写着色器代码

        在 OpenGL 中,着色器负责计算每个像素、顶点的颜色和位置。你需要编写顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。

        顶点着色器:负责处理顶点数据(如位置、颜色等)。

        片段着色器:负责计算每个像素的最终颜色。

        着色器代码一般是用 GLSL 语言编写的。

顶点着色器 (vertex_shader.glsl):

#version 330 core
layout(location = 0) in vec3 position;
void main() {gl_Position = vec4(position, 1.0);
}

片段着色器 (fragment_shader.glsl):

#version 330 core
out vec4 color;
void main() {color = vec4(1.0, 0.0, 0.0, 1.0);  // 渲染红色
}

5. 编译和链接着色器

        将编写的着色器代码加载到 OpenGL 中并编译成程序:

        a. 使用 glShaderSource() 将着色器代码传递给 OpenGL。

        b. 使用 glCompileShader() 编译每个着色器。

        c. 使用 glCreateProgram() 和 glAttachShader() 将编译后的着色器附加到程序中。

        d. 使用 glLinkProgram() 链接着色器程序。

示例代码:

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

6. 绘制场景

        在 paintGL() 中,你可以开始绘制使用这些着色器的物体。

        绑定相应的 VAO,并通过 glDrawArrays() 或 glDrawElements() 调用进行绘制。

示例:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);  // 绘制三角形
glBindVertexArray(0);

7. 调试和优化

        确保所有的 OpenGL 调用都正确无误,并且着色器没有编译错误。

        使用 OpenGL 的调试工具(如 glGetError())或图形调试工具(如 RenderDoc)来帮助调试渲染过程。

8. 与 GPU 开始绘制

        完成上述步骤后,OpenGL 会开始将数据上传到 GPU,并且 GPU 会根据着色器程序绘制结果。你可以看到渲染结果并根据需要进行交互式的更新。


总结流程:

  1. 创建 Qt 项目并启用 OpenGL 支持。
  2. 继承 QOpenGLWidget 并实现 initializeGL()、resizeGL() 和 paintGL()。
  3. 设置并传递顶点数据到 GPU。
  4. 编写顶点着色器和片段着色器。
  5. 编译和链接着色器。
  6. 使用着色器并开始绘制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

长短期记忆网络(LSTM)学习指南

长短期记忆网络(LSTM)学习指南 1. 定义和背景 长短期记忆网络(Long Short-Term Memory, LSTM)是一种递归神经网络(RNN)的变体,旨在解决传统RNN在处理长期依赖关系时遇到的梯度消失或爆炸问题。…

仿12306项目(4)

基本预定车票功能的开发 对于乘客购票来说,需要有每一个车次的余票信息,展示给乘客,供乘客选择,因此首个功能是余票的初始化,之后是余票查询,这两个都是控台端。对于会员端的购票,需要有余票查询…

第十二届蓝桥杯 异或数列

原题: https://www.acwing.com/problem/content/3424/ 题目大意: A、B两人的数初始值均为0,他们轮流从X数组中取数,可以将该数与自己的数或对方的数进行异或操作,A先手,当X中的数被取完的时候谁的数大谁…

微服务的认识与拆分

微服务架构通过将应用分解为一组小的、独立的服务来实现,每个服务围绕特定业务功能构建,并能独立部署与扩展。这种架构增强了开发灵活性、提高了系统的可维护性和扩展性,使得团队可以更快地响应变化和市场需求。 目录 认识微服务 单体架构 …

高效编程指南:PyCharm与DeepSeek的完美结合

DeepSeek接入Pycharm 前几天DeepSeek的充值窗口又悄悄的开放了,这也就意味着我们又可以丝滑的使用DeepSeek的API进行各种辅助性工作了。本文我们来聊聊如何在代码编辑器中使用DeepSeek自动生成代码。 注:本文适用于所有的JetBrains开发工具&#xff0c…

项目中同时使用Redis(lettuce)和Redisson的报错

温馨提示:图片有点小,可以放大页面进行查看... 问题1:版本冲突 直接上图,这个错表示依赖版本不匹配问题,我本地SpringBoot用的是2.7,但是Redisson版本用的3.32.5。 我们通过点击 artifactId跟进去 发现它…

Jackson 详解

目录 前言 Jackson 是 Java 生态中最流行的 JSON 处理库之一,广泛应用于 RESTful API、数据存储和传输等场景。它提供了高效、灵活的 JSON 序列化和反序列化功能,支持注解、模块化设计和多种数据格式(如 XML、YAML)。本文将详细介…

H.264,H.265,H.266标准技术改进

关于H.264,H.265,H.266相关资料链接: 标准及中文资料链接 视频编码中的主要技术 视频编码的目标是在保证视频质量的前提下,尽可能减少数据量。以下是视频编码中的核心技术: 块划分(Block Partitioning) 将视频帧划分…

clickhouse安装路径

《ClickHouse安装路径指南》 大家好,今天我们将一起学习如何在电脑上找到和理解ClickHouse的安装路径。这将帮助学生、科研人员以及任何对数据库技术感兴趣的人更好地管理他们的数据查询工作。 ClickHouse是一款列式存储数据库管理系统(DBMS&#xff09…

时序数据库 InfluxDB 3.0 版本性能实测报告:写入吞吐量提升效果验证

亮点总结: TSBS 测试表明,对于少于 100 万台设备的数据集,InfluxDB OSS 3.0 的数据写入速度实际上比 InfluxDB OSS 1.8 更慢。 对于 100 万台及以上设备的数据集,InfluxDB OSS 3.0 的数据写入性能才开始超过 InfluxDB OSS 1.8。…

AS32X601双核锁步MCU技术优势分析

AS32X601是国科安芯公司研制的一系列基于32位RISC-V指令集车规级MCU处理器芯片。主频高达180MHz,支持双核锁步架构,基于软错误防护技术加持,显著提高芯片安全性能。产品具有高安全、低失效、多IO、低成本、抗辐照等特点。 一、功能安全与可靠…

基于 LeNet 网络的 MNIST 数据集图像分类

1.LeNet的原始实验数据集MNIST 名称:MNIST手写数字数据集 数据类型:灰度图 (一通道) 图像大小:28*28 类别数:10类(数字0-9) 1.通过torchvision.datasets.MNIST下载并保存到本地…

电池综合测试仪:科技赋能,精准守护能源安全

在当今这个科技日新月异的时代,电池作为众多电子设备的心脏,其性能的稳定与高效直接关系到设备的运行质量与使用安全。随着电动汽车、可穿戴设备、储能系统等领域的快速发展,对电池性能的检测与评估提出了更高要求。在此背景下,电…

【Linux 22.4 ubuntu 安装cuda12.1 完整方案】

下载cuda12.1 官网网址 wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run sudo sh cuda_12.1.1_530.30.02_linux.run!import! 如果已经安装驱动,则不要选择dirver那项 添加环境变量 vim ~/.b…

实战案例分享:Android WLAN Hal层移植(MTK+QCA6696)

本文将详细介绍基于MTK平台,适配高通(Qualcomm)QCA6696芯片的Android WLAN HAL层的移植过程,包括HIDL接口定义、Wi-Fi驱动移植以及wpa_supplicant适配过程,涵盖STA与AP模式的常见问题与解决方法。 1. HIDL接口简介 HID…

Greenplum6.19集群搭建

一,安装说明 1.1环境说明 1、首先确定部署的环境,确定下服务器的端口,一般默认是22的端口; 2、当前这份文档是服务器处于10022端口下部署的(现场生产环境要求,22端口在生产环境存在安全隐患)&…

电商项目-秒杀系统(四)秒杀异步下单防止重复秒杀

一、 防止恶意刷单解决 在生产场景下,可能会有一些人会恶意访问当前网站,来进行恶意的刷单。这样会造成当前系统出现一些业务上的业务混乱,出现脏数据,或者造成后端访问压力大等问题。 一般要解决这个问题的话,前端可…

原生android 打包.aar到uniapp使用

1.原生安卓里面引入uniapp官方提供的包文件: uniapp-v8-release.aar 2.提供uniapp调用的接口,新建类文件继承UniModule, package com.dermandar.panoramal;import com.scjt.lib.certlib;import io.dcloud.feature.uniapp.annotation.UniJSM…

Android 多用户相关

Android 多用户相关 本文主要记录下android 多用户相关的adb 命令操作. 1: 获取用户列表 命令: adb shell pm list users 输出如下: Users:UserInfo{0:机主:c13} running默认只有一个用户, id为0 ,用户状态为运行 2: 创建新用户 命令: adb shell …

基于Spring Boot的高校就业招聘系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…