Qt 5.5 QOpenGLWidget链接错误未连接任何OpenGL调用

7

我尝试使用Qt 5.5.1构建一个简单的OpenGL应用程序,一切都很好,直到我尝试使用像glClearColor这样的OpenGL本地函数调用。

小部件实际上编译并产生黑屏,但是在我尝试使用任何OpenGL本地函数之后,它甚至无法链接,而是产生错误:

glwidget.cpp:10: error: undefined reference to '_imp__glClearColor@16'

这是.pro文件:

            QT       += core gui opengl

            CONFIG   += windows

            greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

            TARGET = Vehicle_simulation

            TEMPLATE = app

            SOURCES += main.cpp\
                    simulation.cpp \
                glwidget.cpp

            HEADERS  += simulation.h \
                glwidget.h

            FORMS    += simulation.ui

我正在使用桌面版的Qt mingw492_32 kit。 奇怪的是,我在lib文件夹中没有找到libQtOpenGL.so。我的QT安装有问题吗?我尝试多次重新安装它,但没有帮助。我在哪里可以下载这个特定的库?
将其链接到项目中可以解决问题,但我似乎找不到它的任何地方。
问题在于QT安装中缺少openGL模块,而不是我无法链接它。

@genpfault,不想挑剔,但是重复建议是错误的。我找到了问题的源头,这是因为QT默认使用ANGLE进行构建,它仅支持openGL ES,而不支持桌面openGL。为了解决这个问题,我必须使用openGL对QT Core进行自定义构建。如果有人遇到这个问题,我很乐意回答问题。 - Dávid Tóth
在打开一个编译和链接的OpenGL示例项目后,我找到了问题的源头,它不是链接错误,而是我使用了错误的GLWidget实现。我会尽快发布我的答案,一旦我能够对其进行足够的编译思考。 - Dávid Tóth
1个回答

9

我偶然打开了一个示例程序,想看一下它的实现方式;结果发现同样的 QOpenGLWidget 已经在新的示例程序中实现了。

经过一番分析,我成功地找到了问题所在。

QT有一个内部的openGL实现和原生的openGL支持。我使用的小部件继承自QOpenGLWidget,但是openGL函数调用(例如glClearColor)尝试访问Qt中的原生openGL实现。因为这些内容没有包含在我的Qt构建中,所以项目无法构建。

要解决这个问题,必须运行自定义的Qt核心构建,或者使用Qt提供的openGL包装器。

最终,我使用了Qt包装器,这也是示例程序Cube所使用的。用于实现小部件的类(在我的实现中称为GLWidget)不仅必须继承自QOpenGLWidget,还必须继承自QOpenGLFunctions。后者在我的实现中缺失了。以下是其源代码:

glwidget.h(初始版):

#ifndef GLWIDGET_H
#define GLWIDGET_H


#include <QOpenGLFunctions>
#include <QOpenGLWidget>

class GLWidget : public QOpenGLWidget
{
    Q_OBJECT

public:
    explicit GLWidget(QWidget *parent);

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

#endif // GLWIDGET_H

glwidget.h(修复版):

#ifndef GLWIDGET_H
#define GLWIDGET_H


#include <QOpenGLFunctions>
#include <QOpenGLWidget>

class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit GLWidget(QWidget *parent);

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

#endif // GLWIDGET_H

注意!

在使用任何gl*函数之前,必须调用initializeOpenGLFunctions();函数,否则会出现非常晦涩的运行时错误。 例如:

void GLWidget::initializeGL(){
    initializeOpenGLFunctions();
    glClearColor(1,0,0,1);
}

希望这也能帮到其他人。

谢谢,它很有帮助。请考虑添加参考来源。 - Mohammad Tauqir
很高兴能够帮助!一个参考资料是以下问题:https://dev59.com/mo3da4cB1Zd3GeqP04Kj - 从那里我好奇看到它使用的类,查看了源代码,并尝试了各种尝试,直到它工作为止。 - Dávid Tóth
1
Qt 5之前的版本将OpenGL的导出库包含在构建中,而Qt 5拥有自己的包装器,其原则是正确性优先于性能,因此您需要调用类方法或包装器而不是库函数。这两种方法都有其优点。 - Swift - Friday Pie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接