Qt实现 QOpenGL绘制彩色三角形

QOpenGL入门教程(一)——OpenGL渲染管线 前言 这是本教程的第一个篇章,你是否已经迫不及待的想动手写代码了?真是太可惜了,这一篇章我们并不会涉及到Qt和代码,而是说一些有用并且有意思的事情。 没有进行思考就直接上手写代码会让你产生一些“先入为主”的错误观念,它们将成为你之后学习过程中的阻碍,因此,身体放松,然后沉住气,认真看完这一章,到之后你真正学习的代码时候就会发现自己tm跟开了挂一样:“卧槽,原来OpenGL这么简单!!!?” 能够看到这篇文章,说明你大概率也是一名程序开发者,你为什么来学OpenGL呢?是因为兴趣使然,还是工作需要呢?如 阅读详情

目录

1、QOpenGL介绍

2、效果

3、主要代码介绍:

4、全部代码:


1、QOpenGL介绍

QOpenGLWidget类封装了opengl,比起原生的opengl,使用起来很方便。只需要让子类继承QOpenGLWidget。

OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。(摘自维基百科)

其实OpenGL是把图像数据和几何数据发送给电脑显卡,进行一系列处理后,把图形显示到屏幕上进行展示。

QOpenGLWidget允许在平台支持的情况下使用不同的OpenGL版本和配置文件,只需通过setFormat()设置请求的格式即可。

可以根据自己电脑所支持的opengl版本进行兼容性设置。

QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
this->setFormat(format);

QOpenGLWidget还提供了三个函数来方便我们处理业务。分别是
paintGL():绘制渲染opengl场景,update的时候会自动调用
resizeGL() :设置opengl的大小,resize的时候调用
initializeGL() :提供初始化opengl需要的环境的接口,在resizeGL或者paintGL之前会被调用一次。

2、效果

3、主要代码介绍:

1、着色器装载

void MyQOpengl::InitShader()
{
    //顶点着色器
    QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vSrc =
            "in vec4 vPosition;                        \n"
            "in vec4 vColor;                           \n"
            "out vec4 color;                           \n"
            "void main() {                             \n"
            "   color = vColor;                        \n"
            "   gl_Position = vPosition;               \n"
            "}                                         \n";
    vShader->compileSourceCode(vSrc);

    //片段着色器
    QOpenGLShader *fShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fSrc =
            "in vec4 color;                             \n"
            "out vec4 fColor;                           \n"
            "void main() {                              \n"
            "   fColor = color;                         \n"
            "}                                          \n";
    fShader->compileSourceCode(fSrc);

    //着色器程序
    _pShaderProgram = new QOpenGLShaderProgram;
    _pShaderProgram->addShader(vShader);
    _pShaderProgram->addShader(fShader);

    _pShaderProgram->link();
    _pShaderProgram->bind();
}

这里我们需要创建一个顶点着色器和片段着色器,然后通过addShader装载它们,所谓着色器就是像素被渲染时执行的程序,在GPU中执行的程序。const char *vSrc字符串是opengl着色器语言(OpenGL Shading Language)即GLSL。通过这些语言来描述给GPU。

而顶点就是我们图形的几个顶角,片段就是几个顶点包围起来的全部像素点,通过对以上进行渲染,就能得到我们需要的图形和颜色。

2、顶点描述

下面描述的是三角形的三个顶点

//顶点位置
GLfloat vertices[] = {
   -0.5f, -0.5f,   //left
   0.0f, 0.5f,     //top
   0.5f, -0.5f,    //right
};

如下图所示:

3、顶点颜色

对三个顶点进行颜色的描述,分别表示r、g、b,我们知道,通过r、g、b的组合可以组合出任何我们想要的颜色

GLfloat colors[] = {
   1.0f, 0.5f, 0.2f,   //r g b
   1.0f, 0.5f, 0.2f,
   1.0f, 0.5f, 0.2f,
};

4、QOpenGLBuffer _vbo用于管理OpenGL的缓存对象,流程是create()创建缓存对象--bind()绑定对象关联的缓存到OpenGL环境

--allocate()分配缓存空间--setAttributeBuffer()填充数据。

_vbo.create();
_vbo.bind();
_vbo.allocate(vertices, 18*sizeof(GLfloat));

GLuint vPosition = _pShaderProgram->attributeLocation("vPosition");
_pShaderProgram->setAttributeBuffer(vPosition, GL_FLOAT, 0, 2, 0);
glEnableVertexAttribArray(vPosition);

4、全部代码:

头文件:

#ifndef MYQOPENGL_H
#define MYQOPENGL_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>

class MyQOpengl : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit MyQOpengl(QWidget *parent = 0);

    void InitShader();

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram *_pShaderProgram;
    QOpenGLBuffer _vbo;
};

#endif // MYQOPENGL_H

cpp

#include "myqopengl.h"
#include <QDebug>

MyQOpengl::MyQOpengl(QWidget *parent)
    : QOpenGLWidget(parent)
{
}

void MyQOpengl::initializeGL()
{
    // 为当前环境初始化OpenGL函数
    initializeOpenGLFunctions();

    InitShader();
}

void MyQOpengl::InitShader()
{
    //顶点着色器
    QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vSrc =
            "in vec4 vPosition;                        \n"
            "in vec4 vColor;                           \n"
            "out vec4 color;                           \n"
            "void main() {                             \n"
            "   color = vColor;                        \n"
            "   gl_Position = vPosition;               \n"
            "}                                         \n";
    vShader->compileSourceCode(vSrc);

    //片段着色器
    QOpenGLShader *fShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fSrc =
            "in vec4 color;                             \n"
            "out vec4 fColor;                           \n"
            "void main() {                              \n"
            "   fColor = color;                         \n"
            "}                                          \n";
    fShader->compileSourceCode(fSrc);

    //着色器程序
    _pShaderProgram = new QOpenGLShaderProgram;
    _pShaderProgram->addShader(vShader);
    _pShaderProgram->addShader(fShader);

    _pShaderProgram->link();
    _pShaderProgram->bind();
}
void MyQOpengl::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
}

void MyQOpengl::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.2f, 0.3f, 0.3f,1.0f);

    //顶点位置
    GLfloat vertices[] = {
        -0.5f, -0.5f,   //left
        0.0f, 0.5f,     //top
        0.5f, -0.5f,    //right
    };

    _vbo.create();
    _vbo.bind();
    _vbo.allocate(vertices, 18*sizeof(GLfloat));

    GLuint vPosition = _pShaderProgram->attributeLocation("vPosition");
    _pShaderProgram->setAttributeBuffer(vPosition, GL_FLOAT, 0, 2, 0);
    glEnableVertexAttribArray(vPosition);


    // 顶点颜色
    GLfloat colors[] = {
        1.0f, 0.5f, 0.2f,   //r g b
        1.0f, 0.5f, 0.2f,
        1.0f, 0.5f, 0.2f,
    };

    _vbo.write(6*sizeof(GLfloat), colors, 12*sizeof(GLfloat));
    GLuint vColor = _pShaderProgram->attributeLocation("vColor");
    _pShaderProgram->setAttributeBuffer(vColor, GL_FLOAT, 6*sizeof(GLfloat), 3, 0);
    glEnableVertexAttribArray(vColor);

    // 绘制
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

通过以上代码实现QOPenGL绘制了一个橘色的三角形,具体的API这里不进行过多讨论,主要是熟悉opengl的绘图流程,后面再专门对相关的接口进行探讨,以上。

Qt中的OpenGL 也叫可编程管线,提供了更多的灵活性,更高的效率,更重要的是可以更深入的理解图形编程。其中,顶点着色器和片段着色器需要自己去编写,几何着色器可选择性编写,有这三个可以编辑的部分,即为可编程管线(管线可以理解为一个处理流程)。Ps:状态机是一种理论模型,用于描述一个系统在不同时间点的行为和状态转移规律。OpenGL自身是一个巨大的状态机上下文(Context)通常把OpenGL上下文比作一个大的结构体,包含很多子集:当前状态只有一份。 阅读详情

相关推荐

Qt+OpenGL基础教程

基于Qt与OpenGL的UR3机械臂仿真与控制程序的先行文,介绍了如何画出一个可以变换视角的坐标系。

mai0026的博客 1万+

QT+ OpenGL学习

本篇完整工程见gitee:https://gitee.com/turbolove/qtopengl.git 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主。什么是openglopen graphics library 他是一个由Khronos组织制定并且维护的规范opengl核心是一个c库,同时也支持多种语言的派生。

turbolove的博客 6535

【QT】——OpenGL学习(一)

OpenGL简介 OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。 这个接口由近350个不同的函数调用组成,用来绘制从简单的图形比特到复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。 OpenGL的高效实现(利用了图形加速硬件)存在于Windows,部分UNIX平台

vhcjgc的博客 8339

qt中对OpenGL函数的引入(shader,vao,vbo)

前言:本片使用vs2019编写代码,原因是qt creator中对资源的引入和删除较为麻烦,且今后主要还是要使用vs2019这种比较全面的编程软件较为长久。当然qt creator可以作为编程的辅助工具,在ui设计中更为方便,qt帮助文档也可以解决很多问题。 QT代替原有的部分gl默认库 在qt框架中使用OpenGL,即用qt窗口框架代替glfw窗口设计,用qt中的QOpenGLFunctions_4_5_Core(也可以为其他版本)代替glad来做OpenGL函数的管理。 故在vs2019中不再需要对.

Elsa的迷弟 3141

QOpenGL入门教程(二)—— 第一个QOpenGLWidget程序

终于到了实际操作的环节了,这一章我们要做的是: 创建OpenGL窗口 创建并编写着色器程序 为着色器程序装配顶点数据 启动渲染管线进行绘图 第一步:创建新项目 首先,我们使用Qt创建一个常规的QWidget项目,建议不要勾选ui设计器(个人习惯,笔者不太习惯于使用ui来设计) 第二步:创建QOpenGLWidget并实现三个虚函数 QOpenGLWidget Qt5.4之前,Qt可以通过一个QGLWidget类来创建OpenGL窗口,但由于opengl的发展,在5.4版本的时候,Qt提供

ItaLink 1万+

Qt OpenGL编程常用类

功能:提供跨平台的 OpenGL ES 2.0+ / OpenGL 1.5+ 函数访问(避免直接使用平台相关的函数指针)。OpenGL 要求:需 OpenGL 3.0+ 或 OpenGL ES 3.0+(或通过扩展支持):默认支持 OpenGL ES 2.0+ 和 OpenGL 1.5+,更高版本功能需通过。功能:Qt 中封装 OpenGL 纹理操作的类,用于创建和管理纹理对象。:OpenGL 调用必须在拥有上下文的线程中执行(通常为主线程)。:OpenGL 调用必须在拥有上下文的线程中(通常为主线程)。

深之JohnChen的专栏 1644

Qt QPainter 完全指南:从画线到绘制复杂图形

本文介绍了Qt中QPainter的核心原理与应用实践。QPainter作为Qt的2D绘图引擎,采用画家模型设计,通过状态机管理绘制属性,支持坐标变换、裁剪、混合模式等高级功能。文章详细解析了QPainter的绘制流程、坐标系统、基本图形绘制方法(线条、矩形、文本等),以及QPainterPath、Transform等高级特性。同时深入剖析了Qt绘图系统的三层架构(QPainter-QPaintDevice-QPaintEngine)和双缓冲机制。最后通过一个完整的仪表盘控件示例,展示了如何利用QPainte

红军不怕远征难,万水千山只等闲 651

Qt OpenGL(二十)——Qt OpenGL 核心模式版本

在之前的OpenGL教程(1~19)中,采用的方式都是固定渲染管线,也就是OpenGL3.2版本之前的写法,但是OpenGL从3.2版本开始,就鼓励使用核心模式进行开发了,其目的就是为了提高效率,增加编程的灵活性。 从本篇开始,我把核心模式方法的写法分享给大家,主要还是借助以Qt开发。

ifeng12358的博客 4565

1.第一个OpenGL Demo

本文详细介绍了如何在Qt中配置OpenGL项目,还介绍了OpenGL相关重要概念,并实现一些基础的绘制功能。

2401_83279529的博客 525

最佳量化交易的计算机操作系统

本文在Creative Commons许可证下发布   我经常被问到的一个问题是:用哪种计算机操作系统和计算软件进行量化交易的理论研究和代码实现?   我想把这个问题简化,从挑选的计算软件和计算库来反推最佳使用的计算机操作系统。简而言之,就是在本文撰写的时候而言,如果你想进行基于任何严肃的数学理论和金融量化交易研究理论,这里特指机器学习或者深度学习。并且需要在本地研究机器上使用桌面版本,...

evilqliang的博客 2306

ADS负载牵引仿真避坑指南:从零开始搞定Loadpull模板设置

本文是一份针对ADS负载牵引仿真的深度避坑指南,详细解析了Loadpull模板从初始化配置到结果解读的全过程。文章重点阐述了如何根据设计目标灵活设置扫描圆、采样点等关键参数,以解决仿真不收敛、结果不完整等常见问题,并指导读者在功率与效率之间做出理性权衡,最终提取出用于匹配网络设计的最优负载阻抗。

weixin_29234423的博客 594

【小沐学QT】QT学习之OpenGL开发笔记

Qt提供了与OpenGL实现集成的支持,使开发人员有机会在更传统的用户界面的同时显示硬件加速的3D图形。Qt有两种主要的UI开发方法:QtQuick和QtWidgets。它们的存在是为了支持不同类型的用户界面,并建立在针对每种类型进行了优化的独立图形引擎上。可以将在OpenGL图形API中编写的代码与Qt中的这两种用户界面类型结合起来。当应用程序有自己的OpenGL相关代码时,或者当它与基于OpenGL的第三方渲染器集成时,这可能很有用。Qt OpenGL模块包含方便类,使这种类型的集成更容易、更快。

爱看书的小沐 6070

瑞芯微RK3568开发板实战:Android11系统parameter.txt文件配置全解析(附常见问题排查)

本文深入解析了瑞芯微RK3568开发板在Android 11系统下parameter.txt文件的配置要点与实战技巧。作为BootLoader启动阶段的核心蓝图,该文件决定了硬件初始化、分区布局及电源管理。文章详细拆解了身份标识、GPIO控制(PWR_HLD)、命令行参数及分区表等关键字段的配置逻辑,并针对RK3568平台与Android 11特性提供了专项适配策略,最后附带了启动失败、分区异常等常见问题的深度排查方法。

php55的博客 895

Qt OpenGL(01) 概述

OpengGL 参考教程 和 Qt OpengGL 框架

读书笔记 1661

IEDA激活码失效?教你5分钟快速续期的方法

本文针对IEDA激活码失效问题,提供了一套从快速应急到深度排查的完整解决方案。文章不仅详解了5分钟快速续期与清理缓存等应急方法,更深入剖析了授权机制、离线激活流程,并指导如何构建可持续的授权管理策略,帮助开发者彻底解决激活困扰,确保开发环境稳定。

a0b1c2d3的专栏 273

基于RK3588与FPGA的SDI视频处理系统:从MIPI CSI-2输入到DSI输出的全链路解析

本文深入解析了基于RK3588与FPGA的SDI视频处理系统全链路。系统利用FPGA作为高速接口转换与流管理核心,将SDI信号转换为MIPI CSI-2数据流送入RK3588进行智能图像处理与AI分析,处理结果再通过MIPI DSI回传,最终由FPGA控制编码为SDI输出,实现了专业视频接口与强大算力的高效协同。

s1t2u3的博客 666

基于Qt的OpenGL(一):OpenGL理论及QOpenGLWidget

框架:OpenGL3.3、Qt 5.12.3MinGW(3.2以前是传统模式(固定管线模式-已被丢弃),3.3是现在模式(可编程管线)) 优势:安装简单,Qt已经封装好了,如GLFW和GLAD。自己有支持OpenGL的窗口。 介绍:OpenGL是Open Graphics Library的缩写,它是由Khronos组织制定并维护的一个规范。OpenGL的核心库是用C语言编写,但同时也支持多种语言的派生。 核心模式:3.3以后版本新推出的模式,也叫现在模式或可编程模式。 GPU渲染是一个流水线:比如输入一大

认真努力,做一只会飞的毛毛虫。 9465

官网下载STM32系列芯片的产品选型手册

官方提供了产品选型手册,便于工程师们进行产品选型。 那么,在哪下载"产品选型手册"呢?请看下文。

Weber Zhou 的博客 1万+

Qt中使用OpenGL的三种方式

3. 继承QOpenGLWidget 与QOpenGLExtraFunctions。2. 继承QOpenGLFunctions类可直接使用OPENGL函数。通过使用QOpenGLContext来操作OPENGL函数。1.继承QOpenGLWidget并重写基类如下函数。在OPENGL中使用Shader。直接使用OPENGL函数。

7353

【EB-02】TC397 Tresos 最小工程配置

主要设置McalLibPublishedInformation 参数,会根据ResourceM配置的芯片自动加载。可以看到再工程目录中生成了output文件夹,里面由这些模块生成的头文件,编译脚本和epc文件。如果选择生成swcd,可以生成xxx_Bswmd.arxml给别的工具使用。如果没有Error和Problems就可以点击生成代码。点击工程校验看看工程是否由错误。

libuping2023的博客 324

华为OD新系统机试真题 2026.5.10 - 美观的灯笼

华为OD新系统机试真题【美观的灯笼】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【美观的灯笼】

qq_45776114的博客 640

QML画三角形代码

源代码 import QtQuick 2.5 Canvas {     id: canvasId     property color triangleColor: "#474747"     width: parent.width; height: parent.height     contextType: "2d"     onPaint: {         context.l...

Qt君 4672

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

QOpenGLWidget

一、描述 QOpenGLWidget 类是一个用于渲染 OpenGL 图形的小部件。 QOpenGLWidget 提供了显示集成到 Qt 应用程序中的 OpenGL 图形的功能。它使用起来非常简单:自定义类继承它并像其他 QWidget 子类一样使用,还可以选择使用 QPainter 和标准 OpenGL 渲染命令。 QOpenGLWidget 提供了三个方便的虚函数,可以在子类中重新实现这些虚函数来执行典型的 OpenGL 任务: paintGL():渲染 OpenGL 场景,每当需要更新小部件时

友善啊,朋友的博客 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

QT OpenGL基础学习——旋转立方体

第一个QOpenGLWidget程序 学习内容: 创建OpenGL窗口 创建并编写着色器程序 为着色器程序装配顶点数据 启动渲染管线进行绘图 这个小程序我是在该博主这里学的: QT中创建OpenGL窗口 学习网址: VAO与VBO 着色器 运行结果 ...

weixin_46636063的博客 1429

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

QT学习(17):QT中OpenGL的简单使用

0,1,3对应顶点数组中第一行、第二行、第四行,为一个三角形,1,2,3同理,两个三角形即一个矩形。顶点数组vertices:四个顶点数据,每一行对应一个顶点,有八个float数值,分别为坐标(3),颜色(3),纹理(2)。:加工顶点数据,把顶点坐标进行平移、旋转、缩放等各种变换操作,修改各种顶点数据,比如纹理坐标,法向量等。VBO,Vertex Buffer Objects顶点缓冲区,一个元素对应一个顶点数据。0、顶点数据:CPU将顶点数据传入GPU,包括顶点的坐标、颜色、法向量、纹理坐标等。

qq_45088122的博客 3134

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

通过前两篇文章的学习,我们先来小试牛刀,找找成就感!

bmseven的博客 1543
上一篇: PyQt实现 计数器--快速掌握python开发桌面软件
下一篇: Qt之QListWidget实战
Qt上位机开发
Qt上位机开发 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄9年 9664粉丝 178原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值