精华内容
下载资源
问答
  • OpenGL_Qt学习笔记之_01(创建一个OpenGL窗口) - tornadomeet - 博客园
  • qtopengl窗口的创建

    2021-07-30 21:59:35
    该笔记借鉴自 : “懂deeee珍惜”的 现代OpenGL+Qt学习笔记之二:程序框架 ...注意:OpenGL窗口需要用c++类引入,不可用ui文件中现有的OpenGLWidget,原因是OpenGL窗口不仅继承自OpenGLWidget,还继承自QOpenGLF

    该笔记借鉴自 :

    “懂deeee珍惜”的 现代OpenGL+Qt学习笔记之二:程序框架

    "爱种鱼的猫"的 QT中使用OpenGL(0)——创建一个窗口

    引用引自qt帮助文档。

    1.创建qt工程

    创建主窗口,命名为mainwindow。

    在这里插入图片描述

    2.创建OpenGL窗口(重点)

    在项目中添加c++文件 命名为OpenGLWidget
    在这里插入图片描述
    注意: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;
    }
    

    对窗口的操作在这里不做详细介绍,相关知识参照qt的博客。
    我的qt博客专题路径

    总结

    以上便完成了qt中对OpenGL窗口的引入
    下一章便解决qt中对OpenGL函数的引入。

    展开全文
  • Qt5.4之前,Qt可以通过一个QGLWidget类来创建opengl窗口,但由于opengl的发展,在5.4版本的时候,Qt提供了一个QGLWidget的现代替代品——QOpenGLWidget。因此,这个教程使用的是QOpenGLWidget来创建和管理窗口。 ...

    如果你是中途开始学习本教程的,即使你对OpenGL已经非常熟悉,请至少了解以下几个章节,因为Qt中提供了OpenGL的很多便捷操作,熟悉这些操作可以让我们在Qt中高效的使用OpenGL进行绘图。

    Qt-OpenGL的几个优势:

    1. Qt内嵌了opengl的相关环境,不需要我们自己来搭建,这对小白来说是很友好的。
    2. Qt和opengl都具有优良的跨平台特性,使用Qt做opengl开发可谓是强强联合。
    3. Qt可以轻松的控制窗口的各种处理事件以及窗口属性。
    4. Qt提供了opengl函数的C++封装,使得opengl原来的C风格API可以通过C++的面向对象技术来实现。
    5. Qt提供了十分完善的官方文档,有助于我们掌握QtOpenGL的各种细节。

    这个教程将完全使用Qt对openglAPI的C++封装,内容板块尽量与learnopengl保持一致。笔者会逐步的实现教程里的demo,尽可能的说明每一个操作细节。你可以在文章的右上角找到本节的索引目录,如果什么地方操作失败,你可以直接复制代码节点的代码,尝试运行一下,再对比一下自己的代码,看自己是否什么地方出问题了,如果还不能解决问题,可以在下方评论区留言,笔者看到一定第一时间解答。

    笔者对openGL了解不是很深,如果什么地方存在问题,希望朋友们能够详细指出。

    创建窗口

    QOpenGLWidget

    Qt5.4之前,Qt可以通过一个QGLWidget类来创建opengl窗口,但由于opengl的发展,在5.4版本的时候,Qt提供了一个QGLWidget的现代替代品——QOpenGLWidget。因此,这个教程使用的是QOpenGLWidget来创建和管理窗口。

     

    创建opengl窗口只需新建类继承于QOpenGLWidegt,再实现QOpenGL提供的三个虚函数,就可以完成opengl窗口的创建。

    1. initializeGL()—建立OpenGL的资源和状态。在第一次调用resizeGL()或paintGL()之前调用一次
    2. resizeGL()—设置OpenGL视口,投影等。每当调整Widget的大小时(第一次显示窗口Widget时会调用它,因为所有新创建Widget都会自动获得调整大小的事件)。
    3. paintGL()—渲染OpenGL场景,需要更新Widget时就会调用。

     

    QOpenGLExtraFunctions

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

     

    让我们开始直接操作吧!

    首先,我们使用Qt创建一个常规的QWidget窗口,建议不要勾选ui设计器(个人习惯,笔者不太习惯于使用ui来设计)

    如果你的Qt版本比较低,可能需要在pro文件中添加Qt += opengl

    在widget.h中包含头文件 <QOpenGLWidget> 、<QOpenGLExtraFunctions>

    修改Widget公有继承自这两个类

    重写 initializeGL()、resizeGL(int w,int h)、paintGL(),一般使用protected修饰

    完成后你的Widget.h应该是如下的样子:

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QOpenGLWidget>
    #include <QOpenGLExtraFunctions>
    class Widget : public QOpenGLWidget,public QOpenGLExtraFunctions
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    protected:
        virtual void initializeGL() override;
        virtual void resizeGL(int w,int h) override;
        virtual void paintGL() override; 
    };
    
    #endif // WIDGET_H
    

    再对函数进行实现,你的Widget.cpp应该是如下的样子

    (为了便于说明opengl函数来源于QOpenGLFunctions类,函数前我加了this指针,读者在写的时候可以省略)

    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QOpenGLWidget(parent)
    {}
    
    Widget::~Widget()
    {}
    
    void Widget::initializeGL()
    {
        this->initializeOpenGLFunctions();        //初始化opengl函数
    }
    
    void Widget::resizeGL(int w, int h)
    {
        this->glViewport(0,0,w,h);                //定义视口区域
    }
    
    void Widget::paintGL()
    {
        this->glClearColor(0.1f,0.5f,0.7f,1.0f);  //设置清屏颜色
        this->glClear(GL_COLOR_BUFFER_BIT);       //清除颜色缓存
    }
    

    然后我们运行我们的代码

    ok,大功告成,我们的opengl窗口创建完毕!

    QSurfaceFormat——关于opengl窗口的一些配置

    格式包括颜色缓冲区的大小(红色,绿色和蓝色)。alpha缓冲区的大小;深度和模板缓冲区的大小;以及用于多采样的每个像素的采样数。此外,该格式包含表面配置参数,例如OpenGL配置文件和用于渲染的版本,是否启用立体声缓冲区以及交换行为。

    注意:对上下文或窗口格式问题进行故障排除时,启用日志记录类别可能会有所帮助qt.qpa.gl。根据平台的不同,当涉及到OpenGL初始化以及QSurfaceFormat映射到的本机视觉或帧缓冲区配置时,这可能会打印有用的调试信息。

    实例,在构造函数中修改format

    Widget::Widget(QWidget *parent)
        : QOpenGLWidget(parent)
    {
        QSurfaceFormat format;
        format.setAlphaBufferSize(24);  //设置alpha缓冲大小
        format.setVersion(3,3);         //设置版本号
        format.setSamples(10);          //设置重采样次数,用于反走样
        //...
        this->setFormat(format);
    }
    

    终于创建了这个窗口,完整的代码如下

    main.h

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        return a.exec();
    }
    

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QOpenGLWidget>
    #include <QOpenGLExtraFunctions>
    class Widget : public QOpenGLWidget,public QOpenGLExtraFunctions
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    protected:
        virtual void initializeGL() override;
        virtual void resizeGL(int w,int h) override;
        virtual void paintGL() override;
    };
    
    #endif // WIDGET_H
    

    widget.cpp

    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QOpenGLWidget(parent)
    {}
    
    Widget::~Widget()
    {}
    
    void Widget::initializeGL()
    {
        this->initializeOpenGLFunctions();        //初始化opengl函数
    }
    
    void Widget::resizeGL(int w, int h)
    {
        this->glViewport(0,0,w,h);                //定义视口区域
    }
    
    void Widget::paintGL()
    {
        this->glClearColor(0.1f,0.5f,0.7f,1.0f);  //设置清屏颜色
        this->glClear(GL_COLOR_BUFFER_BIT);       //清除颜色缓存
    }
    

     

    展开全文
  • 很早就想学opengl的,一直没时间,今天心血来潮初步了解了下openglOpengl是对2D和3D图形支持很好,有非常多的优化函数,因为opengl的主要目标是图形功能函数上,所以它对图形界面的支持并不完善。...

    文章来源:http://www.cnblogs.com/tornadomeet/archive/2012/08/22/2651574.html

    很早就想学opengl的,一直没时间,今天心血来潮初步了解了下opengl

    Opengl是对2D3D图形支持很好,有非常多的优化函数,因为opengl的主要目标是图形功能函数上,所以它对图形界面的支持并不完善。当然了,作为一个跨平台的开源库,这是能理解的,因为每个平台开发界面用的工具不同,如果它只支持其一,那么私心也太重了,还不如节省精力放在核心的代码上。

    QtUI函数很多,它的Opengl封装很好,将opengl的函数和Qt的界面结合了起来,这主要是通过QtQGLWidget这个类来实现。所以一般我们开发opengl,且要用到Qt的界面时,这些类都可以从QGLWidget继承过来。

    本次试验是按照网络上NeHe写的最著名的opengl英文教程:http://nehe.gamedev.net/ 和对应的中文教程:http://www.owlei.com/DancingWind/ 的第一讲来学习的。当然也参考了网上对Nehe教程改编的Qt版:http://wenku.baidu.com/view/835b29fd941ea76e58fa04a2.html 

     

    本次试验的目的很简单,只是显示一个窗口,可以通过F1键值来切换全屏显示和普通屏显示,并当按下ESE键时退出程序。窗口的颜色背景和透视效果(其实该试验都没用上)等用opengl来实现,主要是为后面的学习写了个框架,其实这里主要是重写了3个函数:initializeGL();paintGL();resizeGL();3个函数都是QGLWidget内部的虚函数。

     

    程序运行时效果如下:

      

     

    程序代码如下:

    glwidget.h:

    复制代码
    #ifndef GLWIDGET_H
    #define GLWIDGET_H
    
    #include <QtOpenGL>
    #include <QWidget>
    
    namespace Ui {
    class GLWidget;
    }
    
    class GLWidget : public QGLWidget
    {
        Q_OBJECT
        
    public:
        explicit GLWidget(QGLWidget *parent = 0);
        ~GLWidget();
    
    protected:
        void initializeGL();
        void paintGL();
        void resizeGL(int width, int height);
        void keyPressEvent(QKeyEvent *e);
        bool fullscreen;
        
    private:
        Ui::GLWidget *ui;
    };
    
    #endif // GLWIDGET_H
    复制代码

     

    glwidget.cpp:

    复制代码
    #include "glwidget.h"
    #include "ui_glwidget.h"
    
    #include <QtGui>
    #include <QtCore>
    #include <QtOpenGL>
    
    GLWidget::GLWidget(QGLWidget *parent) :
        QGLWidget(parent),
        ui(new Ui::GLWidget)
    {
        ui->setupUi(this);
        fullscreen = false;
    
    }
    
    //这是对虚函数,这里是重写该函数
    void GLWidget::initializeGL()
    {
        setGeometry(300, 150, 640, 480);//设置窗口初始位置和大小
        glShadeModel(GL_FLAT);//设置阴影平滑模式
        glClearColor(0.5, 1.0, 0.2, 0);//改变窗口的背景颜色,不过我这里貌似设置后并没有什么效果
        glClearDepth(1.0);//设置深度缓存
        glEnable(GL_DEPTH_TEST);//允许深度测试
        glDepthFunc(GL_LEQUAL);//设置深度测试类型
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正
    }
    
    void GLWidget::paintGL()
    {
        //glClear()函数在这里就是对initializeGL()函数中设置的颜色和缓存深度等起作用
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();//重置当前的模型观察矩阵?不是很理解!
    }
    
    //该程序是设置opengl场景透视图,程序中至少被执行一次(程序启动时).
    void GLWidget::resizeGL(int width, int height)
    {
        if(0 == height)
            height = 1;//防止一条边为0
        glViewport(0, 0, (GLint)width, (GLint)height);//重置当前视口,本身不是重置窗口的,只不过是这里被Qt给封装好了
        glMatrixMode(GL_PROJECTION);//选择投影矩阵
        glLoadIdentity();//重置选择好的投影矩阵
       // gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//建立透视投影矩阵
        //glMatirxMode(GL_MODELVIEW);//以下2句和上面出现的解释一样
        glLoadIdentity();
    
    
    }
    void GLWidget::keyPressEvent(QKeyEvent *e)
    {
        switch(e->key())
        {
            //F1键为全屏和普通屏显示切换键
            case Qt::Key_F1:
                fullscreen = !fullscreen;
                if(fullscreen)
                    showFullScreen();
                else
                {
                    setGeometry(300, 150, 640, 480);
                    showNormal();
                }
                updateGL();
                break;
            //Ese为退出程序键
            case Qt::Key_Escape:
                close();
        }
    }
    
    GLWidget::~GLWidget()
    {
        delete ui;
    }
    复制代码

     

      程序里面有很多opengl的函数暂时还用不到,因为图形学领域不熟,有些函数功能暂时也不理解,以后慢慢会懂的。

      编译时,gluPerspective如下错误:

      C:\Users\Administrator\Desktop\tornadomeet\opengl\opengl_nehe_01\glwidget.cpp:46: error: C3861: gluPerspective找不到标识符。

      网上不少人都遇到过,貌似是Qt4.8以后的高级版本都不支持glu开头的函数了,是Nokia弄的bug,还是有什么原因故意这么弄的?据说Qt4.7.4还支持。对于我这种初学者,反正还没用到那个函数,可以不管,实在要用到时切换到4.7.4也行,还有,5.0据说9月份就要发行了,很期待。

     

    附录一

    因为是初学,可能有些同学不懂改怎样建立于opengl有关的工程,是用QtGUI工程,还是Qt控制台工程,或者是Qt空工程?网上貌似还没有找到比较好的介绍。下面我把我建立该工程的过程记下来(也许步骤不对,不过我这次就是这么弄的)

    开发环境:windows+Qt4.8.2+QtCreator2.5.1

    1.  打开QtCreator软件,进入File-->New File or Project,左边Projects选择Application,中间选择Qt Gui Application,如下图所示:

      

     

    2. 单击choose,进入下一个界面,自己填入工程名和目录(不能包含空格和中文路径)

    3. 单击next,进入下一界面,继续单击next,进入Class Information界面。类的名字自己设置,注意Base class(基类)一栏选择QWidget,不要选择QMainWidget或者QDialog,貌似我那2种试过,在本程序中修改比较大。如下图所示:

      

     

    4. 单击next进入下一界面,单击Finish完成操作。

    5. 打开glwidget.h文件,因为生成的文件该类是从QWidget类继承过来的,而我们是需要从QGLWidget中继承过来,所以把代码更改后如下:

    复制代码
    #ifndef GLWIDGET_H
    
    #define GLWIDGET_H
    
     
    
    #include <QtOpenGL/QtOpenGL>
    
    #include <QWidget>
    
     
    
    namespace Ui {
    
    class GLWidget;
    
    }
    
     
    
    class GLWidget : public QGLWidget
    
    {
    
      Q_OBJECT
    
      
    
    public:
    
      explicit GLWidget(QGLWidget *parent = 0);
    
      ~GLWidget();
    
      
    
    private:
    
      Ui::GLWidget *ui;
    
    };
    
     
    
    #endif // GLWIDGET_H
    复制代码

     

    6. 同理,glwidget.cpp文件也更改后如下:

    复制代码
    #include "glwidget.h"
    
    #include "ui_glwidget.h"
    
     
    
    GLWidget::GLWidget(QGLWidget *parent) :
    
      QGLWidget(parent),
    
      ui(new Ui::GLWidget)
    
    {
    
      ui->setupUi(this);
    
    }
    
     
    
    GLWidget::~GLWidget()
    
    {
    
      delete ui;
    
    }
    复制代码

     

      附录二

      实验工程code下载

    转载于:https://www.cnblogs.com/SunkingYang/p/11049243.html

    展开全文
  • QT平台下,通过创建openglwidget类,界面添加OpenGL窗口,显示简单三角形旋转,适合新手入门!
  • QtOpenGL之创建窗口Qt5

    2020-03-21 11:40:08
    这个教程是从一个国外的博主搬过来的,我做了一些简单翻译和简化工作,因为我发现目前存在的qtopengl的代码版本太低了,很难上手使用,因此我将在Qt5的基础上,说明下qtopengl的使用,并将文章作为自己的一些笔记,...

    这个教程是从一个国外的博主搬过来的,我做了一些简单翻译和简化工作,因为我发现目前存在的qtopengl的代码版本太低了,很难上手使用,因此我将在Qt5的基础上,说明下qtopengl的使用,并将文章作为自己的一些笔记,笔者能力有限,可能存在一些疏忽的地方,欢迎大家指证。

    在接下来的介绍中,已经默认读者掌握了Qt的 信号和槽的使用,并能简单的构建一些应用程序。注意这里不是opengl或qt的教程,而是这两者技术的结合。

    注意如果你对Opengl的知识还是不够了解,请移步这里至了解下基础知识,方便后面教程的理解。

     

    QOpenGLWindow

    QOpenGLWindow是一个新类,仅继承自基于Qt5Gui的类。 之所以重要,是因为它允许我们提供OpenGL抽象,而无需Qt5Widgets模块。 

    我们真正关心的只有QOpenGLWindow的是以下功能:

    initializeGL()
    resizeGL(int width,int height)
    paintGL()

    可以想象,这些功能使我们能够执行OpenGL逻辑。 实际上,这就是创建一个简单的OpenGL应用程序所需要的全部。

    QOpenGLFunctions 

    为方便起见,我们可以选择将QOpenGLFunctions与QOpenGLWindow一起子类化。在现代版本的Qt中,不需要GLEW,并且QOpenGLFunctions是可以使用OpenGL ES 2.0 API的结构。 (我们将简短地进行此操作。)

    注:此处的Opengl ES2.0是早期的版本,开放性不及3.3版本,此外3.3以后的版本更新都是在此基础上增加额外功能,因此我们这里使用的都是3.3以上的API接口,如果你是只老鸟就忽略吧

    你不需要子类来访问QOpenGLFunctions的功能,如果愿意,可以通过QOpenGLContext获取可用的功能。可以通过以下两种方式之一将其实例化为局部变量:

    QOpenGL函数示例C ++

    QOpenGLFunctions functions(QOpenGLContext::currentContext());
    functions.glFunctionHere();
    // or...
    QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
    functions->glFunctionHere();

    之所以默认为OpenGL ES 2.0,是出于兼容性方面的考虑,因此我们可以轻松地将产品移植到嵌入式平台(例如Android和iOS)。我们的示例将使用此函数上下文,但是我们也可以要求特定的函数上下文。 (例如QOpenGLFunctions_4_3_Core)

    这是很不错的,因为我们可以将自己限制为仅要支持的上下文。除了OpenGL ES 2.0 API,我们没有其他需要,因此我们将坚持使用QOpenGLFunctions类。

    创建一个窗口

    有了这些知识,我们将从创建OpenGL窗口开始。 多亏了Qt5,使该应用程序变得微不足道,因为跨平台OpenGL最难的部分已设置好。 (由于需要GLEW,因此特别涉及Windows。)这将为我们其他项目提供一个不错的起点。

    1,准备一个新项目(Qt5.4 GuiModule)

    首先,我们将创建一个新的Qt项目,没什么特别的-我通常选择Console Application并随需添加所需的内容。

     有一点我们需要注意的是,我们需要在我们的项目文件中添加一些东西,我们要把Qt5Gui的模块添加进去。

    原来的项目文件如:

    # ...
    QT       += core
    QT       -= gui
    # ...

    添加完Qt5Gui 模块后,我们需要编辑为如下:

    # ...
    QT       += core gui
    # ...

    现在我们可以使用QOpengl相关的类了,因为这是Qt5Gui模块的一部分。

    2.创建一个窗口类 

    接下来,我们需要用之前了解到的opengl类创建一个窗口类,首先新建一个类文件。

     然后我们编辑我们的windows.h文件如下:

    #ifndef WINDOW_H
    #define WINDOW_H
    
    #include <QOpenGLWindow>
    #include <QOpenGLFunctions>
    class Window : public QOpenGLWindow,
                   protected QOpenGLFunctions
    {
      Q_OBJECT
    
    // OpenGL Events
    public:
      ~Window();
    
      void initializeGL();
      void resizeGL(int width, int height);
      void paintGL();
      void teardownGL();
    
    private:
      // Private Helpers
      void printContextInformation();
    };
    
    #endif // WINDOW_H
    

    这里我们继承了两个类,从而以便于我们可以使用一些opengl的功能,但是有两个新内容我们有必要解释一下,

    • teardownGL()
      • 我们需要一个函数来执行清理的工作。如果 OpenGLWindow::makeCurrent()第一次被调用,清理工作会在析构中完成,但是我想要一个特殊的函数使得我们的接口清晰明显。
    • printContextInformation()
      • 此辅助函数将打印有关我们已获取的OpenGL上下文的信息,以用于调试目的。

     接下来我们实现我们的函数(window.cpp)

    #include "window.h"
    #include <QDebug>
    #include <QString>
    
    Window::~Window()
    {
      makeCurrent();//当基础平台窗口已被破坏时,这样可以确保析构函数中的OpenGL资源清理操作始终有效。
      teardownGL();
    }
    
    /*******************************************************************************
     * OpenGL Events
     ******************************************************************************/
    
    void Window::initializeGL()
    {
      // Initialize OpenGL Backend
      initializeOpenGLFunctions();
      printContextInformation();
    
      // Set global information
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    
    void Window::resizeGL(int width, int height)
    {
      (void)width;
      (void)height;
    }
    
    void Window::paintGL()
    {
      glClear(GL_COLOR_BUFFER_BIT);
    }
    
    void Window::teardownGL()
    {
      // Currently we have no data to teardown
    }
    
    /*******************************************************************************
     * Private Helpers
     ******************************************************************************/
    
    void Window::printContextInformation()
    {
      QString glType;
      QString glVersion;
      QString glProfile;
    
      // Get Version Information
      glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL";
      glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
    
      // Get Profile Information
    #define CASE(c) case QSurfaceFormat::c: glProfile = #c; break
      switch (format().profile())
      {
        CASE(NoProfile);
        CASE(CoreProfile);
        CASE(CompatibilityProfile);
      }
    #undef CASE
    
      // qPrintable() will print our QString w/o quotes around it.
      qDebug() << qPrintable(glType) << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")";
    }
    

     这是十分基本的步骤,这里仅有一个棘手的部分。

    • initializeGL()
      • QOpenGLFunctions::initializeOpenGLFunctions(), 在当前opengl上下文环境下执行初始化。
      • Window::printContextInformation() 这是我们自己编写的函数, 这会在输出台打印一些版本的信息。
      • glClearColor() 实际上继承于QOpenGLFunctions,这可以简单的设置清除的颜色
    • resizeGL()
      • 由于我们没有做任何复杂的图形,因此在此功能中我们什么也不做。
    • paintGL()
      • 同样,非常基本,我们只是使用在initializeGL()中设置的颜色清除背景色。
    • teardownGL()
      • 什么也不做, 我们还没有在GPU上分配任何资源。
    • printContextInformation()
      • 基于我们如何创建OpenGL上下文,我们可以访问OpenGL的不同版本和功能。 据我们所知,在控制台中打印版本非常有用(作为健全性检查)。

    快要完了,但还有一些工作。

    3.更新main.cpp来创建函数

    实际上,我前面没有提到另一个Qt5类。 QGuiApplication。 它不是特定于OpenGL的,因此我不愿意为它添加详细的说明。 现在,main.cpp中的默认功能包括创建一个QCoreApplication并运行它。

    我们将使用QGuiApplication进行更改(因为这就是我们所做的)。 在执行exec()之前,我们将创建并显示一个Window。

    
    #include <QGuiApplication>
    #include "window.h"
    
    int main(int argc, char *argv[])
    {
      QGuiApplication app(argc, argv);
    
      // Set OpenGL Version information
      // Note: This format must be set before show() is called.
      QSurfaceFormat format;
      format.setRenderableType(QSurfaceFormat::OpenGL);
      format.setProfile(QSurfaceFormat::CoreProfile);
      format.setVersion(3,3);
    
      // Set the window up
      Window window;
      window.setFormat(format);
      window.resize(QSize(800, 600));
      window.show();
    
      return app.exec();
    }
    

    这段代码不言自明。 QSurfaceFormat是我们设置请求的OpenGL版本的方式。 无需明确提供QSurfaceFormat,但这是检查我们的printContextInformation()函数功能的好方法。

    此时,您应该能够保存,构建和运行。 使用当前输入,您将看到获得的响应(如果您的计算机支持OpenGL 3.3)为:

    OpenGL 3.3(CoreProfile)

    对于我们所做的所有工作,您都应该拥有一个平淡无奇的窗户。

     

    尝试将CoreProfile更改为CompatibilityProfile,并在不同的版本号之间进行操作; 检查输出是否有意义。 NoProfile保留用于不包含核心/兼容性上下文请求的版本。

    源码链接

    展开全文
  • Qt 创建OpenGL窗口

    2015-04-08 15:59:45
    Qt 创建OpenGL窗口 一、创建项目工程 二、修改源代码 qtopenglwindow.h qtopenglwindow.cpp main.cpp 不用修改,运行后出现一个窗口:
  • QT平台下,读取二进制STL文件,显示在Opengl窗口,网上很多导入ACSII格式STL文件的教程,补充下导入显示二进制STL文件的教程。
  • 这是一个系列的文章,这个系列来自于github上的一个开源项目 https://github.com/chenzilin/qt-opengl ...还有就是git上的提交相比于之前增加了很多lesson,有助于想学习qt opengl的程序员更深入学习理解op
  • Qt OpenGL教程】01:创建一个OpenGL窗口

    万次阅读 热门讨论 2015-08-01 12:31:02
    在这个教程里,我们将在Qt Creator环境中创建OpenGL对象,它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出,它将是我们后面应用程序的基础框架。
  • OpenGL库:1、GLU;2、GLUT;3、GLUI;4、GLEW;...QT本身就带着opengl的几个相关头文件,用法:在.pro文件中添加:QT+=opengl 在.cpp文件中引入完整的OpenGL库: #include "mainwindow.h" #ifnde...
  • windows 10平台,Qt5+Qt Creator 4.9.1+ OpenGLQT 自带的OpenGL库) 2.Qt Creator 4.9.1创建Qt Widgets Application 3.pro工程文件配置 QT += core gui opengl LIBS+=-lopengl32 -lglu32 4.在main.cpp...
  • 今天正式进入Qt5.12 + OpenGL 3.x以上可编程管线的代码部分。 程序主要是参考learnopengl,更多关于OpenGL的说明也可参考他们的文章。 https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%...
  • 现代OpenGL+Qt学习笔记之五:OpenGL矩阵变换   主要是关于OpenGL中的矩阵变换,通过介绍一个点的变换过程,也可以帮助理解OpenGL的管线的执行过程。没有非常详细的数学和几何变换内容的介绍,好在QMatrix4x4已经帮...
  • Qt创建一个OpenGL窗口

    2019-12-18 22:30:56
    一直以来想结合Qt学习OpenGL,但是自己查了一些资料后还是比较困惑,最近在网上找到了两个资料链接,一个是NeHe的教程,相对来讲旧一些;另一个是https://learnopengl.com/。我的目的是在Qt开发过程中,如果需要用到...
  • 为了满足高级绘图的需求,在Qt中支持OpenGL接口和矢量图形...1、OpenGL是最开始在SGI公司推出的3D绘图编程接口,OpenGL具有绘制三维图形的各种函数,但不包括窗口系统或处理用户输入的函数。为了在Qt中使用OpenGL,Q
  • opengl-qt-glm-地月系.rar

    2020-07-09 11:43:08
    使用Opengl4.3,qt5.8,glm0.9.6.3实现的地球-月球效果,地球有纹理且有白天和夜晚的过渡效果、云层、有光照、可自转(需手动按鼠标在窗口中滑动),月球有纹理、可自转、公转。
  • Learn OpenGL with Qt——完美的Qt摄像机

    千次阅读 2020-05-10 13:02:56
    OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉,而不是场景在移动。 本节我们将会讨论如何在Qt中配置一个摄像机,并且将会...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,331
精华内容 2,532
关键字:

opengl窗口qt