QT+OpenGL创建窗口

窗口搭建

(1)在QT中是不需要GLFW,GLAD的,如果是使用VS的话还得搭建。但是在QT中也有类似的函数来做这些事情。 

注:GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文、定义窗口参数以及处理用户输入,对我们来说这就够了。

因为OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现的。由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。所以任务就落在了开发者身上,开发者需要在运行时获取函数地址并将其保存在一个函数指针中供以后使用。取得地址的方法因平台而异,GLAD就是来解决这个繁琐的问题

(2)QT中代替GLFW,GLAD的方式

 

 

 

 (3)窗口搭建

 继承QMainWindow基类

 

 

 

 

 我们进入这个界面进行编辑,增加几个菜单栏

 

 结果如下:

 

 而且在QT中我们还可以设置样式信息,如下:

 

 结果:

 

现在基础窗口有了,我们还需要一个控件来展示opengl的数据,即OpenGLWidget(代替GLFW),拖动下面的控件到主窗体上:

 

当然,现在这个控件只占主窗口的中间部分,很难看,所以我们设置一下,让当前控件占满整个窗体:

 

 将给定的小部件设置为主窗口的中心小部件:void QMainWindow::setCentralWidget(QWidget *widget)

 现在QT中已经有了OpenGLWidget来代替VS中的GLFW保证它正确创建了OpenGL上下文并显示出一个简单的窗口来让我们随意使用,但是还缺少将代码的api函数指向本机的显卡函数的方案,在VS中可以使用GLAD,那么在QT中使用如下步骤来解决:

第一创建一个类,可以先简单的继承QWidget类

 

 

 下面我们改一下:

 

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>

 其中我们使用opengl3.3核心模式。然后继承类也都要进行更改:

 

 

 

 

 

 前面我们说过,要在QOpenGLWidget的三个函数中来渲染效果,所以我们已经继承了QOpenGLWidget类,那么我们可以通过这3个方法来实现我们想要的效果:

 

 在自己的定义的类中增加这3个函数:

 

 实现:

 走到这一步的时候还需要做一件事情,那就是提升窗口类:右键openglwidget-》提升为(promose to),输入我们自定义的类,点击添加,选中复选框,最后点击提升按钮。

 

 可以看到如下结果:

 

 (4)实现

通过前面步骤基本已经把想要的环境搭建起来了,下面就是正式通过代码来实现效果的时候了。

复制代码
#include "axbopenglwidget.h"

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

}

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

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

}

void AXBOpenGLWidget::paintGL()
{
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}
复制代码

 结果:

 

 注意:如果不加initializeOpenGLFunctions函数的话不成功的,因为没法调用显卡的函数来渲染。

 方法说明:

  1)void QOpenGLFunctions::initializeOpenGLFunctions()

为当前上下文初始化 OpenGL 函数分辨率。就是前文所说将QT里的函数指向本机显卡的函数。代替GLAD。
调用此函数后,QOpenGLFunctions 对象只能与当前上下文以及与其共享的其他上下文一起使用。 再次调用 initializeOpenGLFunctions() 以更改对象的上下文关联。

  2)QOpenGLWidget::initializeGL()

这个虚函数在第一次调用paintGL() 或resizeGL() 之前被调用一次。 在子类中重新实现它。
这个函数应该设置任何需要的 OpenGL 资源和状态。
无需调用 makeCurrent(),因为调用此函数时已完成。 但是请注意,在此阶段帧缓冲区尚不可用,因此请避免从此处发出绘图调用。 而是将此类调用推迟到 paintGL()。

  3)void QOpenGLWidget::makeCurrent()

官方解释:

通过使相应的上下文成为当前上下文并在该上下文中绑定帧缓冲区对象来准备为此小部件呈现 OpenGL 内容。
大多数情况下不需要调用这个函数,因为它是在调用paintGL()之前自动调用的。

 也可以说在重写的paintGL(),resizeGL(),initializeGL()方法之外的自定义的绘图函数里面想要调用opengl的标准API 的话需要先调用此方法

  4)void QOpenGLFunctions::glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

  glClearColor只起到Set的作用,并不Clear任何! 作用是,指定刷新颜色缓冲区时所用的颜色。所以,完成一个刷新过程是要 glClearColor(COLOR) 与 glClear(GL_COLOR_BUFFER_BIT) 配合使用。 

  前一个函数设置好要使用的最新的颜色,后者利用前一个函数设置好的颜色来更新窗口颜色

(5)在自定义的函数中实现效果

 我们1处右键添加QToolBar,在2处添加2个action,并拖动到3处:

 

 

 

 

 

 

 

 

 

 

 

1

posted @   安静点--  阅读(927)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示