Qt+OpenGL入门教程(三)——绘制三角形

通过前两篇文章的学习,我想大家应该有了基本的理解,我们接下来实操一下。

创建Qt OpenGL窗口

QOpenGLWidget

QGLWidget是传统QtOpenGL模块的一部分,与其他QGL类一样,应该在新的应用程序中避免使用。相反,从Qt5.4开始,Qt推荐使用QOpenGLWidget和QOpenGL类。
QOpenGLWidget提供显示集成到Qt应用程序中的OpenGL图形的功能,使用起来非常简单。让类继承它,并像其他QWidget一样使用子类,额外可以选择使用QPainer和标准的OpenGL渲染命令。

QOpenGLWidget提供了三个方便的虚拟函数,可以在子类中重新实现这些函数来执行典型的OpenGL任务:

  • initializeGL():设置OpenGL呈现上下文,定义显示列表等。在第一次调用resizeGL()或paintGL()之前调用一次。
  • resizeGL():设置OpenGL视区、投影等。每当调整了大小时都会调用该视区(并且当它第一次显示时也会调用,因为所有新创建的小部件都会自动获得一个调整大小的事件)。
  • paintGL():渲染OpenGL场景。每当需要更新小部件时调用。

QOpenGLExtraFunctions

QOpenGLExtraFunctions类继承于QOpenGLFunctions,相较于QOpenGLFunctions,额外提供了对OpenGL ES 3.0、3.1和3.2 API的跨平台访问,如果我们需要在类中使用opengl函数,只需要使类继承于QOpenGLExtraFunctions,就能在内部通过this指针访问到OpenGL函数

QOpenGLShaderProgram

QOpenGLShaderProgram是Qt中用于管理OpenGL着色器程序的类。它封装了OpenGL的着色器对象(Shader Object)和着色器程序对象(Shader Program Object),提供了一种方便的方式来管理和使用着色器。

标准化设备坐标(Normalized Device Coordinates, NDC)

顶点着色器中处理过后,就应该是标准化设备坐标了,x、y和z的值在-1.0到1.0的一小段空间(立方体)。落在范围外的坐标都会被裁剪。下面代码中顶点数据的坐标就是使用该坐标。

在这里插入图片描述

源码

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)project(Day01 VERSION 0.1 LANGUAGES CXX)set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)// 注意添加OpenGL模块
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets OpenGL)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets OpenGL)set(PROJECT_SOURCESmain.cppwidget.cppwidget.h
)add_executable(Day01${PROJECT_SOURCES}shader.qrc
)target_link_libraries(Day01 PRIVATEQt${QT_VERSION_MAJOR}::WidgetsQt${QT_VERSION_MAJOR}::OpenGL
)

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QOpenGLShaderProgram>/*** 绘制窗口*/
class Widget : public QOpenGLWidget, protected QOpenGLExtraFunctions
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected:void initializeGL() override;void resizeGL(int w, int h) override;void paintGL() override;private:QOpenGLShaderProgram shaderProgram;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"Widget::Widget(QWidget *parent): QOpenGLWidget(parent)
{
}Widget::~Widget()
{
}void Widget::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);shaderProgram.create();shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl.vert");shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl.frag");shaderProgram.link();// 开启着色器程序的pos属性shaderProgram.enableAttributeArray("pos");
}void Widget::resizeGL(int w, int h)
{glViewport(0, 0, w, h);
}void Widget::paintGL()
{shaderProgram.bind();GLfloat vertices[] = {0.0f, 0.5f, 0.0f,0.5f, -0.5f, 0.0f,-0.5f, -0.5f, 0.0f,};// 设置顶点数据的数据来源,从vertices数组中读取,且每三个数据作为一个顶点数据(vec3)shaderProgram.setAttributeArray("pos", vertices, 3);glDrawArrays(GL_TRIANGLES, 0, 3);
}

gl.vert

in vec3 pos;void main(void)
{gl_Position = vec4(pos, 1.0);
}

gl.frag

void main(void)
{gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

结果展示:

在这里插入图片描述

在此我们就绘制成功啦!赶紧动手试试吧,不用太在意里面的细节,后面会更详细的讲解。

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

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

相关文章

YOLOv8结合SCI低光照图像增强算法!让夜晚目标无处遁形!【含端到端推理脚本】

这里的"SCI"代表的并不是论文等级,而是论文采用的方法 — “自校准光照学习” ~ 左侧为SCI模型增强后图片的检测效果,右侧为原始v8n检测效果 这篇文章的主要内容是通过使用SCI模型和YOLOv8进行算法联调,最终实现了如上所示的效果:在增强图像可见度的同时,对图像…

亿图图示如何绘制WBS分解?

什么是WBS分解&#xff1f; Wbs分解俗称工作分解结构法&#xff0c;就是把一个大项目按照原则分成多个小任务&#xff0c;再把每项小任务分解成具体的工作&#xff0c;然后把工作分到每人的工作中的一种分解方法。 如下图这里以开店KTV为例&#xff0c;项目是开店&#xff0c;小…

【QT入门】 QListWidget各种常见用法详解之列表模式

往期回顾 【QT入门】 Qt代码创建布局之setLayout使用-CSDN博客 【QT入门】 Qt代码创建布局之多重布局变换与布局删除技巧-CSDN博客 【QT入门】 QTabWidget各种常见用法详解-CSDN博客 【QT入门】 QListWidget各种常见用法详解之列表模式 QListWidget有列表和图标两种显示模式&a…

C++bitset类型

bitset类型 我们介绍了将整型运算对象当作二进制位集合处理的一些内置运算符。 标准库还定义了bitset类&#xff0c;使得位运算的使用更为容易&#xff0c;并且能够处理超过最长整型类型大小的位集合。bitset类定义在头文件bitset中。 定义和初始化bitset bitset类是一个类模…

朵米3.5客服系统源码,附带系统搭建教程

朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持&#xff08;如在线聊天、邮件、电话等&#xff09;&#xff0c;帮助企业建立与客户的实时互动。该系统具有智能分流功能&#xff0c;可以快速将客户请求分配给适当的客服人员&#xff0c;提高工作效率。…

协程库-锁类-实现线程互斥同步

mutex.h&#xff1a;信号量&#xff0c;互斥锁&#xff0c;读写锁&#xff0c;范围锁模板&#xff0c;自旋锁&#xff0c;原子锁 锁 **锁不能进行拷贝操作&#xff1a;**锁是用于管理多线程并发访问共享资源的同步原语。这些锁包括互斥锁&#xff08;mutex&#xff09;、读写锁…

【攻防世界】file_include (PHP伪协议+过滤器)

打开题目环境&#xff1a; 进行PHP代码审计&#xff0c;发现这是一个文件包含漏洞。 我们尝试利用PHP伪协议中的 php://filter来读取 check.php 中的内容。 构造payload 并提交&#xff1a; 发现payload被过滤掉了&#xff0c;我们就需要尝试使用不同的转换器。 PHP各类转换…

【面经】2023年软件测试面试题大全(持续更新)附答案

前阵子一位读者告诉我&#xff0c;某位大厂HR给他发了我之前做的面试题答案合集。 这个消息让我开心了一整天&#x1f602;&#xff0c;因为这说明我之前做的面试题系列真的能帮助到部分测试同学&#xff0c;也算是侧面得到了一种认可吧。 坚持可是我们程序员家族的优良传统&a…

未来购物新篇章:臻奶惠无人新零售

未来购物新篇章&#xff1a;臻奶惠无人新零售 随着科技的不断进步和消费者购物习惯的变化&#xff0c;无人新零售已经成为零售行业的一大趋势&#xff0c;它不仅重新定义了购物体验&#xff0c;也为零售行业带来了前所未有的变革。无人新零售&#xff0c;一种融合了AI技术、物…

Java程序运行的问题——异常

什么是异常? Java程序在运行时出现的问题就叫异常 jdk中将异常一新封装成了一个个的类&#xff0c;当出现问题时&#xff0c;就会创建异常对象&#xff0c;抛出异常信息&#xff08;问题原因、位置&#xff09; 1.异常 1.1异常的继承体系 Throwable 是所有错误&#xff08;…

Python控制浏览器——selenium模块

Python控制浏览器——selenium模块 目录 Python控制浏览器——selenium模块准备工作【1】安装selenium【2】安装浏览器驱动【3】测试驱动&#xff08;作者是Edge&#xff09; 导航和操作窗口导航返回前进刷新最大化窗口切换选项卡 查找和操作元素8种基本By定位方式[1]ID[2]Name…

关系(二)利用python绘制热图

关系&#xff08;二&#xff09;利用python绘制热图 热图 &#xff08;Heatmap&#xff09;简介 热图适用于显示多个变量之间的差异&#xff0c;通过颜色判断彼此之间是否存在相关性。 快速绘制 基于seaborn import seaborn as sns import pandas as pd import numpy as np i…

一个 hipsolver 特征值示例

1&#xff0c;原理 通过雅可比旋转&#xff0c;对对称矩阵计算特征值和特征向量&#xff1b; 通过初等正交变换&#xff0c;每次把其中一个非主对角元素消成零&#xff0c;最终只剩主对角线非零元素为特征值&#xff0c;同时把初等变换累积下来&#xff0c;构成特征向量。 2&a…

CAS(Compare And Swap)

目录 CAS概念 乐观锁与悲观锁 ABA问题 Unsafe类 ​编辑 原子类 基本类型原子类 原子引用类 原子数组 原子更新器类 原子累加器 CAS概念 CAS是Compare And Swap的缩写&#xff0c;中文翻译成&#xff1a;比较并交换&#xff0c;实现无锁并发时常用到的一种技术。它一…

element plus的el-image图片发布到nginx不显示

问题&#xff1a; <el-image alt""src"/img/month-b.png" class"card-icon"style"width: 89px;height: 89px;right: -7px;top: -5px;"/> 部署到nginx二级路由访问地址是&#xff1a; http://192.168.1.207/divided/# 这时候使用…

总结jvm中GC机制(垃圾回收)

前言 本篇博客博主将介绍jvm中的GC机制&#xff0c;坐好板凳发车啦~~ 一.GC相关 1.1回收栈内存 对于虚拟机栈&#xff0c;本地方法栈这部分区域而言&#xff0c;其生命周期与相关线程相关&#xff0c;随线程而生&#xff0c;随线程而灭。并且这三个区域的内存分配与回收具有…

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序

ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;可将模拟信号转换成对应的数字信号&#xff0c;便于存储与计算等操作。除电源线和地线之外&#xff0c;ADC只需要1根线与被测量的设备进行连接。 一、案例简介 该程序是基于…

github本地仓库push到远程仓库

1.从远程仓库clone到本地 2.生成SSH秘钥&#xff0c;为push做准备 在Ubuntu命令行输入一下内容 [rootlocalhost ~]# ssh-keygen -t rsa < 建立密钥对&#xff0c;-t代表类型&#xff0c;有RSA和DSA两种 Generating public/private rsa key pair. Enter file in whi…

Synchronized锁升级过程

无锁-->偏向锁---> 轻量级锁---->重量级锁 ①、从无锁到偏向锁&#xff1a; 当一个线程首次访问同步块时&#xff0c;如果此对象无锁状态且偏向锁未被禁用&#xff0c;JVM 会将该对象头的锁标记改为偏向锁状态&#xff0c;并记录下当前线程的 ID。此时&#xff0c;对…

Java进阶-反射的详解与应用

本文深入探讨了Java反射机制的核心概念、应用实例及其在现代Java开发中的重要性。文章首先介绍了反射的基本原理和能力&#xff0c;包括在运行时动态获取类信息、操作对象字段和方法的能力。随后&#xff0c;通过具体代码示例&#xff0c;展示了如何利用反射进行字段访问、方法…