将 GLEW 与 QOpenGLWidget 一起使用

Posted

技术标签:

【中文标题】将 GLEW 与 QOpenGLWidget 一起使用【英文标题】:Using GLEW with QOpenGLWidget 【发布时间】:2017-10-08 12:57:01 【问题描述】:

我正在尝试在 Visual Studio 的 QOpenGLWidget 中使用 GLEW 和 QT。

一些细节:

Visual Studio 2013 Glew 2.0.0 x64 QT 5.6.2 x64

我在调用glewInit() 时不断收到“Missing GL version”错误。网上搜了很多,这个问题好像有时候是格式是怎么设置的(QSurfaceFormat),或者create()/makeCurrent()/doneCurrent()这个函数是怎么使用的。但我似乎找不到可行的解决方案。我对整个QOpenGLContext 的事情也有点困惑。

我设法在没有 GLEW 的情况下获得 QOpenGLWidget 工作,并使用“旧” gl 函数(glBegin()glEnd() 等...)。而且我还让 GLEW 与 GLFW3 一起工作。

我在下面的代码中似乎有什么误解吗?

我的 QOpenGLWidget 子类

MyGLWidget.h

#pragma once
#include <QWidget>
#include "GL\glew.h"
#include <QOpenGLWidget>
#include <gl/GLU.h>
#include <gl/GL.h>
#include <iostream>
#include "qopenglcontext.h"
#include "loadShader.h"

class MyGLWidget : public QOpenGLWidget

public:
   MyGLWidget(QWidget *parent = 0);
   ~MyGLWidget();

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

MyGLWidget.cpp

#include "MyGLWidget.h"

MyGLWidget::MyGLWidget(QWidget *parent)
   : QOpenGLWidget(parent)


   QSurfaceFormat glformat;
   glformat.setVersion(3, 2);
   glformat.setOption(QSurfaceFormat::DeprecatedFunctions);
   glformat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
   glformat.setProfile(QSurfaceFormat::CompatibilityProfile);
   QSurfaceFormat::setDefaultFormat(glformat);
   this->setFormat(glformat);

   create();
   makeCurrent();


MyGLWidget::~MyGLWidget()

void MyGLWidget::initializeGL()

   glewExperimental = TRUE;
   GLenum err = glewInit();
   if (GLEW_OK != err)
      std::cout << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err);
   
   doneCurrent();

   GLuint TextShader_ID = LoadShaders("Shaders/TextVertShader.vert", "Shaders/TextFragShader.frag");



void MyGLWidget::paintGL()

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


void MyGLWidget::resizeGL(int w, int h)

   //...

ma​​in.cpp

#include "OGLQT_test2.h"
#include <QtWidgets/QApplication>
#include "GL\glew.h"
#include <QOpenGLFunctions>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    OGLQT_test2 w;

    w.show();
    return a.exec();

OGLQT_test2.h

#pragma once
#include "GL\glew.h"
#include <QtWidgets/QMainWindow>
#include "ui_OGLQT_test2.h"
#include "qopenglcontext.h"

class OGLQT_test2 : public QMainWindow

    Q_OBJECT

public:
    OGLQT_test2(QWidget *parent = Q_NULLPTR);

private:
    Ui::OGLQT_test2Class ui;
;

OGLQT_test2.cpp

#include "OGLQT_test2.h"
#include "MyGLWidget.h"

OGLQT_test2::OGLQT_test2(QWidget *parent)
    : QMainWindow(parent)

    ui.setupUi(this);

    MyGLWidget* glwidget = new MyGLWidget(this);

    glwidget->setFixedHeight(400);
    glwidget->setFixedWidth(500);
    glwidget->move(50, 50);

    glwidget->initializeGL();
    glwidget->resizeGL(400,500);
    glwidget->paintGL();

【问题讨论】:

【参考方案1】:

看来你不能这样做:

glformat.setVersion(x, y);

与 GLEW。它适用于 QOpenGLFunctions,但显然不适用于 GLEW。您也可能无法做到这一点:

glformat.setOption(QSurfaceFormat::DeprecatedFunctions);
glformat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
glformat.setProfile(QSurfaceFormat::CompatibilityProfile);

尝试删除格式。

另外,我认为你在这里做的有点乱:

glwidget->initializeGL();
glwidget->resizeGL(400,500);
glwidget->paintGL();
    有一个简单的方法可以做到这一点,只需这样做:
glwidget->resize(400,500);
glwidget->show();
    resizeGL 是一个由resize 调用的事件initializeGL()paintGL()show 调用也是如此。 另一个是:
GLenum err = glewInit();
if (GLEW_OK != err)
   std::cout << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err);

doneCurrent();

现在你为什么要在这里打电话给doneCurrent

【讨论】:

以上是关于将 GLEW 与 QOpenGLWidget 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

带有 QOpenGLWidget 的 Qt 5.5,核心配置文件中的不可见三角形

如何在 Qt 中使用 GLEW?

GLEW glGenBuffers 段错误

将 GLEW 与 CMake 连接起来

如何使用着色器程序将 2D 场景放入 QOpenGLWidget 窗口?

无法将 Glew 与 Cmake 链接