OpenGL的学习之路

Qt如何创建OpenGL的渲染窗口?

类比GLFW库,Qt提供了OpenGL的渲染窗口类QOpenGLWidget:

1、重写initializeGL()和resizeGL()函数来设置OpenGL状态并提供透视图转换。

2、重写paintGL()来绘制3D场景,只调用OpenGL函数。

3、还可以使用QPainter将2D图形绘制到QOpenGLWidget子类上。在paintGL()中,不是发出OpenGL命令,而是构建一个用于部件的QPainter对象(注意QPainter没调用OpenGL渲染)。

Qt如何实现OpenGL函数绑定?

类比GLAD库,Qt不直接调用OpenGL函数,而是通过QOpenGLFunctions这一实例来进行函数调用,这种调用方法主要有以下两种:

1、直接从OpenGLContext::functions()中获取

 QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
 f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

2、继承QOpenGLFunctions

 class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
 {
     ...
     void initializeGL() override
     {
         initializeOpenGLFunctions();
         glClearColor(...);
         ...
     }
     ...
 };

示例代码:

1、创建MyOpenGLWidget.h

#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
 
#include <QtOpenGLWidgets/QtOpenGLWidgets>
 
 
class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    MyOpenGLWidget();
protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;
};
 
#endif // MYOPENGLWIDGET_H

2、创建MyOpenGLWidget.cpp

#include "myopenglwidget.h"
 
MyOpenGLWidget::MyOpenGLWidget() {
    //设置上下文属性
    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 3); //OpenGL 版本号3.3
    format.setProfile(QSurfaceFormat::CoreProfile);// 核心模式
    this->setFormat(format);
}
 
void MyOpenGLWidget::initializeGL(){
    //绑定OpenGL函数指针?类似GLAD库的作用?
    initializeOpenGLFunctions();
}
 
void MyOpenGLWidget::paintGL(){
    //由于继承了QOpenGLFunctions,可以直接使用OpenGL中的函数
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}
 
void MyOpenGLWidget::resizeGL(int w, int h){
 
}

3、调用MyOpenGLWidget类

#include "mainwindow.h"
 
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    _myOpenGLWidget = new MyOpenGLWidget;
    this->setCentralWidget(_myOpenGLWidget);
    //设置窗口大小
    this->setGeometry(0,0,800,600);
}
 
MainWindow::~MainWindow() {
    if(_myOpenGLWidget)delete _myOpenGLWidget;
}

上一篇:Keepalived


下一篇:IP地址:网络还是设备的标识符?