2013-08-24 89 views
1

我试图将我的旧Qt/OpenGL游戏从Linux移植到Windows。 我正在使用Qt Creator。 它马上编好了,但在链接阶段给了很多错误,如undefined reference to '[email protected]'使用QGLWidget时对gl函数的未定义引用

我试图链接更多的库-lopengl32 -lglaux -lGLU32 -lglut -lglew32,但它给出了相同的结果。

Qt默认也使用-lQt5OpenGLd

我包括QGLWidget来绘图用:

#define GL_GLEXT_PROTOTYPES 
#include <QGLWidget> 

我使用GLEW也试过,但它使用Qt confilcts(或QOpenGL?)。

我该如何摆脱那些未定义的引用? 是否有其他图书馆,我必须链接到?

在此先感谢。

Tomxey

+2

Windows在其opengl32.dll中不会导出除GL1.1以外的任何内容。你所做的#define GL_GLEXT_PROTOTYPES是一种黑客,它甚至不能保证在Linux上工作,但它永远不会在windows上工作。您需要在运行时查询函数指针,可以手动或通过像glew这样的辅助库来查询。但是,我不太了解Qt,而且它是GL小部件,可以为这个问题提供真正的答案。 – derhass

回答

4

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


的Qt提供出色的推动者,以减轻这一工作:

  • QOpenGLShaderQOpenGLShaderProgram允许你管理你的着色器,着色器程序,并且将其制服。 QOpenGLShaderProgram提供了良好的重载允许您无缝通过QVector<N>DQMatrix<N>x<N>类:

    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对象(由上下文拥有),它提供了OpenGL 2(+ FBO)/ OpenGL ES 2之间的公共API.¹它将为您解决幕后指针,因此您只需调用

    functions->glUniform4f(...); 
    
  • QOpenGLContext::versionFunctions<VERSION>()会返回一个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。您可以initalize他们像往常一样,但这种方式,你可以保持你的代码,如:

    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*类。