【问题标题】:Undefined reference to gl functions when using QGLWidget使用 QGLWidget 时对 gl 函数的未定义引用
【发布时间】:2013-08-24 14:33:02
【问题描述】:

我正在尝试将我的旧 Qt/OpenGL 游戏从 Linux 移植到 Windows。 我正在使用 Qt Creator。 它立即编译良好,但在链接阶段出现了很多错误,例如undefined reference to 'glUniform4fv@12'

我尝试链接更多库-lopengl32 -lglaux -lGLU32 -lglut -lglew32,但结果相同。

Qt 默认也使用-lQt5OpenGLd

我将 QGLWIdget 包括在内:

#define GL_GLEXT_PROTOTYPES
#include <QGLWidget>

我也尝试过使用 GLEW,但它与 Qt(或 QOpenGL?)冲突。

我怎样才能摆脱那些未定义的引用? 还有其他我必须链接到的库吗?

提前致谢。

汤姆西

【问题讨论】:

  • Windows 只是不会在其 opengl32.dll 中导出任何超出 GL1.1 的内容。你所做的#define GL_GLEXT_PROTOTYPES 是一个 hack,它甚至不能保证在 Linux 上工作,但它永远不会在 Windows 上工作。您需要在运行时手动或通过一些帮助程序库(如 glew)查询函数指针。但是,我对 Qt 及其 GL 小部件的了解还不够,无法为这个问题提供真正的答案。

标签: c++ qt opengl linker qglwidget


【解决方案1】:

Windows 不提供 OpenGL 1.1 之后引入的任何 OpenGL 函数的原型。 您必须在运行时解析指向这些函数的指针(通过GetProcAddress -- 或者更好的是QOpenGLContext::getProcAddress,见下文)。


Qt 为简化这项工作提供了出色的推动力:

  • QOpenGLShaderQOpenGLShaderProgram 允许您管理着色器、着色器程序及其制服。 QOpenGLShaderProgram 提供了很好的重载,允许您无缝传递QVector&lt;N&gt;DQMatrix&lt;N&gt;x&lt;N&gt; 类:

    QMatrix4x4 modelMatrix = model->transform();
    QMatrix4x4 modelViewMatrix = camera->viewMatrix() * modelMatrix;
    QMatrix4x4 modelViewProjMatrix = camera->projMatrix() * modelViewMatrix;
    ...
    program->setUniform("mv", modelViewmatrix);
    program->setUniform("mvp", modelViewProjMatrix);
    
  • QOpenGLContext::getProcAddress() 是一个独立于平台的函数解析器(与 QOpenGLContext::hasExtension() 结合使用以加载特定于扩展的函数)

  • QOpenGLContext::functions() 返回一个 QOpenGLFunctions 对象(由上下文拥有),它作为公共 API 提供 OpenGL 2 (+FBO) / OpenGL ES 2 之间的公共子集。¹它将为您解析幕后的指针,所以你所要做的就是调用

    functions->glUniform4f(...);
    
  • QOpenGLContext::versionFunctions&lt;VERSION&gt;() 将返回一个QAbstractOpenGLFunctions 子类,即与VERSION 模板参数匹配的子类(如果无法满足请求,则返回NULL):

    QOpenGLFunctions_3_3_Core *functions = 0;
    functions = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
    if (!functions) 
         error(); // context doesn't support the requested version+profile
    functions->initializeOpenGLFunctions(context);
    
    functions->glSamplerParameterf(...); // OpenGL 3.3 API
    functions->glPatchParameteri(...); // COMPILE TIME ERROR, this is OpenGL 4.0 API
    
  • 作为一种替代方法,您可以从QOpenGLFunctionsX 制作您的“绘图”类/inherit/。你可以像往常一样初始化它们,但是这样你可以保留你的代码:

    class DrawThings : public QObject, protected QOpenGLFunctions_2_1
    {
        explicit DrawThings(QObject *parent = 0) { ... }
        bool initialize(QOpenGLContext *context)
        {
            return initializeOpenGLFunctions(context);
        }
        void draw()
        {
            Q_ASSERT(isInitialized());
            // works, it's calling the one in the QOpenGLFunctions_2_1 scope...
            glUniform4f(...); 
        }
    }
    

¹QtOpenGL 模块中还有“匹配”类,即QGLContextQGLFunctions。如果可能,请避免在新代码中使用 QtOpenGL,因为它将在几个版本中被弃用以支持 QOpenGL* 类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-05
    • 2011-09-19
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多