2013-08-24 91 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*類。