引用引自qt帮助文档。

1.创建qt工程

创建主窗口,命名为mainwindow。

qt opengl 索引绘制_qt opengl 索引绘制

2.创建OpenGL窗口(重点)

在项目中添加c++文件 命名为OpenGLWidget

qt opengl 索引绘制_qt4_02


注意:OpenGL窗口需要用c++类引入,不可用ui文件中现有的OpenGLWidget,原因是OpenGL窗口不仅继承自OpenGLWidget,还继承自QOpenGLFunctions_4_5_Core。

QOpenGLFunctions_4_5_Core中包含OpenGL_4.5的核心库函数。

QOpenGLFunctions_4_5_Core:The QOpenGLFunctions_4_5_Core class provides all functions for OpenGL 4.5 core profile.

openglwidget.h

#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>

class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Core
{
public:
    OpenGLWidget(QWidget *parent = 0);

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

};

QOpenGLFunctions继承的是OpenGL_ES,有兴趣的同学自行研究。

The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.

继承QOpenGLWidget就可以实现在部件中绘图了。

最重要的,QOpenGLWidget有3个函数paintGL()、resizeGL()、和initializeGL(),通过重写这个3个函数,就可以实现OpenGL的初始化和绘制功能了。

initializeGL()的调用发生在另外两个函数之前,且只会被调用一次,在这个函数中可以对OpenGL进行初始化,如设置背景色(清除颜色缓冲区)、设置全局光照、变异和链接着色器、创建着色程序等;

resizeGL()的调用发生在窗口第一次出现和每一次窗口改变大小时,可以在这里设置视口和投影矩阵等;

paintGL()是绘制函数,用来绘制内容,它在每一次发生重绘事件时被调用。

openglwidget.cpp

#include "openglwidget.h"

OpenGLWidget::OpenGLWidget(QWidget *parent)
    :QOpenGLWidget(parent)
{

}

void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.5f, 0.0f, 1.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
}

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

}

void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

initializeOpenGLFunctions();
initializeOpenGLFunctions()是QOpenGLFunctions中的函数,在使用OpenGL API之前,必须先调用一次initializeOpenGLFunctions()函数,和使用glew访问现代OpenGL API一样,必须要先对glew库进行初始化。
这里要把initializeOpenGLFunctions()放在initializeGL()中的最后一行,都是不行的。

3.将OpenGL部件添加到主窗口部件中

主窗口部件用QMainWindow应该会更好。但QMainWindow继承自QWidget。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "openglwidget.h"
//在[现代OpenGL+Qt学习笔记之二:程序框架]中使用了前置声明

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    OpenGLWidget *glWidget;
};
#endif // MAINWINDOW_H

1.前缀声明:C++类的前置声明 前置声明总结:一般情况优先使用#include. 二般情况水平不够的我暂时不清楚。
2.添加OpenGL部件
设为私有类,当mainwindow被创建时,便会创建OpenGLWidget窗口类指针。

OpenGLWidget *glWidget;

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
//#include "openglwidget.h" //mainwindow.h头文件已经引入,cpp文件便不再需要引入

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    glWidget = new OpenGLWidget(this);//创建OpenGL窗口,设于this(主窗口)内。
    glWidget->resize(800,570);
    glWidget->move(0,30);
    glWidget->show();
}

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