QT中使用OpenGL组件+简单三角形绘制(QT Creator实现)

写在前面:

QT中使用OpenGL有两种方法,其实也不叫方法,只是窗体表现形式

1、使用设计栏的OpenGL Widget并提升为一个自定义的widget类

2、直接定义一个OpenGL widget类

参考文献:你好,三角形 - LearnOpenGL CN

方法一

1、在设计界面添加一个OpenGL Widget组件

2、工程文件.pro中引入OpenGL Widget模块

QT       += core gui openglwidgets

3、创建一个自定义的widget类,继承于QOpenGLWidget , QOpenGLFunctions_3_3_Core,并重写三个opengl绘图函数

.h文件:

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QObject>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>

class MyWidget : public QOpenGLWidget , QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
signals:
};

#endif // MYWIDGET_H

.cpp文件

#include "mywidget.h"

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


}

void MyWidget::initializeGL()
{
    initializeOpenGLFunctions();
}

void MyWidget::resizeGL(int w, int h)
{
    // qDebug()<<"test";
}

void MyWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.2f, 0.4f, 0.1f, 1.0f);
}

4、设计界面里将原始OpengGL Widget组件提升为自定义的类

5、运行结果

方法二

1、创建一个QT设计界面类,我这里选的是widget

2、与方法一一致,改变继承关系、重写绘制函数

#ifndef MYWINDOW_H
#define MYWINDOW_H

#include <QWidget>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
namespace Ui {
class MyWindow;
}

class MyWindow : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    explicit MyWindow(QOpenGLWidget *parent = nullptr);
    ~MyWindow();
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
private:
    Ui::MyWindow *ui;
};

#endif // MYWINDOW_H
#include "mywindow.h"
#include "ui_mywindow.h"

MyWindow::MyWindow(QOpenGLWidget *parent)
    : QOpenGLWidget(parent)
    , ui(new Ui::MyWindow)
{
    ui->setupUi(this);
}

MyWindow::~MyWindow()
{
    delete ui;
}

void MyWindow::initializeGL()
{
    initializeOpenGLFunctions();
}

void MyWindow::resizeGL(int w, int h)
{

}

void MyWindow::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.2f, 0.4f, 0.1f, 1.0f);
}

3、实例化widget类对象,并显示

    MyWindow w;
    w.show();

4、结果

方法一进行三角形绘制案例

自定义widget类的声明:

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QObject>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>

class MyWidget : public QOpenGLWidget , QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
private:
    GLuint VBO; //顶点缓冲对象
    GLuint VAO; //顶点数组对象
    QOpenGLShaderProgram shaderProgram; // 着色器程序
signals:

};

#endif // MYWIDGET_H

自定义widget类的实现,附上超详细注释

#include "mywidget.h"

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


}

void MyWidget::initializeGL()
{
    initializeOpenGLFunctions();


    //声明三角形顶点数据
    GLfloat vertices[]=
    {    -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };

    // 生成并绑定顶点数组对象
    glGenVertexArrays(1, &VAO);//1表示对象个数
    glBindVertexArray(VAO);

    // 生成顶点缓冲对象
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO); //将标识符为 VBO 的缓冲对象绑定到 GL_ARRAY_BUFFER 目标上

    // 将顶点数据存储到VBO中
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

    // 指定顶点数组中每个顶点属性的数据格式
    //0 表示顶点属性数组中的第一个属性;3 表示每个顶点属性有三个浮点数;GL_FLOAT 表示每个组件是一个单精度浮点数
    //GL_FALSE 表示不进行归一化 ;3 * sizeof(GLfloat) 表示每个顶点属性之间相隔3个浮点数,即12个字节;(void*)0 表示从数组的开头开始
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);

    //启用指定索引的顶点属性数组.0 是顶点属性数组的索引
    glEnableVertexAttribArray(0);

    // 解绑VBO和VAO,将原先绑定在VAO、VBO的数据绑定到 0 上
    // 确保在后续的渲染或设置状态之前,没有任何缓冲或顶点数组对象处于活动状态
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);


    QOpenGLShader vertexShader(QOpenGLShader::Vertex);
    vertexShader.compileSourceFile(":/res/demo.vert");

    QOpenGLShader fragShader(QOpenGLShader::Fragment);
    fragShader.compileSourceFile(":/res/demo.frag");

    shaderProgram.addShader(&vertexShader);
    shaderProgram.addShader(&fragShader);
    //链接着色器程序
    shaderProgram.link();


}

void MyWidget::resizeGL(int w, int h)
{
    // qDebug()<<"test";
}

void MyWidget::paintGL()
{

    // 使用指定的清除颜色清除颜色缓冲区
    glClearColor(0.2f, 0.4f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // 激活着色器程序,准备进行绘制
    shaderProgram.bind();
    // 绑定之前创建的顶点数组对象
    glBindVertexArray(VAO);
    // 使用OpenGL函数绘制一个三角形,0 是指从顶点数组的第一个顶点开始绘制。3 是指绘制的顶点数量,这里是一个三角形
    glDrawArrays(GL_TRIANGLES,0,3);

    update();
}

这里我把顶点着色器和片段着色器程序放在资源文件里

片段着色器,用于处理片段(像素)的颜色

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}

顶点着色器,用于处理顶点数据

#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值