Неопределенная ссылка на функции gl при использовании QGLWidget

Я пытаюсь перенести мою старую игру 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?).

Как я могу избавиться от этих неопределенных ссылок?
Есть ли какая-либо другая библиотека, на которую я должен ссылаться?

Заранее спасибо.

Tomxey

1

Решение

Windows не предоставляет прототипы каких-либо функций OpenGL, представленных после OpenGL 1.1. Вы должны разрешить указатели на эти функции во время выполнения (с помощью GetProcAddress — или лучше QOpenGLContext::getProcAddress, увидеть ниже).


Qt предлагает отличные возможности для облегчения этой работы:

  • QOpenGLShader а также QOpenGLShaderProgram позволяют вам управлять своими шейдерами, шейдерными программами и их униформой. QOpenGLShaderProgram предоставляет хорошие перегрузки, позволяющие беспрепятственно передавать QVector<N>D или же QMatrix<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 объект (принадлежит контексту), который предлагает в качестве публичного API общее подмножество между OpenGL 2 (+ FBO) / OpenGL ES 2.¹ Он разрешит указатели за кулисами для вас, поэтому все, что вам нужно сделать, это вызвать

    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, Вы можете инициализировать их как обычно, но таким образом вы можете сохранить свой код следующим образом:

    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(...);
    }
    }
    

Also Есть также «соответствующие» классы в QtOpenGL модуль, т.е. QGLContext а также QGLFunctions, Если возможно, избегайте использования QtOpenGL в новом коде, так как это будет устаревшим в нескольких выпусках в пользу QOpenGL* классы.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]