Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Failed to set an OpenGL version to 2.1 for Desktop

Failed to set an OpenGL version to 2.1 for Desktop

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 326 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8 Offline
    8 Offline
    8Observer8
    wrote on 27 Dec 2023, 00:33 last edited by 8Observer8
    #1

    Hi,

    I try to set an OpenGL version to 2.1 but the next example prints this result on my laptop:

    OpenGL version: 3.1.0 - Build 9.17.10.4459
    GLSL version: 1.40 - Intel Build 9.17.10.4459
    Vendor: Intel
    

    main.cpp

    #include <QtGui/QOpenGLFunctions>
    #include <QtGui/QSurfaceFormat>
    #include <QtOpenGLWidgets/QOpenGLWidget>
    #include <QtWidgets/QApplication>
    
    class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
    {
    public:
        OpenGLWidget()
        {
            QSurfaceFormat surfaceFormat;
            surfaceFormat.setMajorVersion(2);
            surfaceFormat.setMinorVersion(1);
            setFormat(surfaceFormat);
        }
    
    private:
        void initializeGL() override
        {
            initializeOpenGLFunctions();
            glClearColor(0.f, 1.f, 0.f, 1.f);
            qDebug() << "OpenGL version:" << (const char*) glGetString(GL_VERSION);
            qDebug() << "GLSL version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
            qDebug() << "Vendor:" << (const char*) glGetString(GL_VENDOR);
        }
    
        void paintGL() override
        {
            glClear(GL_COLOR_BUFFER_BIT);
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
        QApplication a(argc, argv);
        OpenGLWidget w;
        w.show();
        return a.exec();
    }
    

    pro

    QT += core gui openglwidgets widgets
    
    win32: LIBS += -lopengl32
    
    CONFIG += c++17
    
    SOURCES += \
        main.cpp
    
    TARGET = app
    

    I can activate the second video card (the discrete one) by adding this code on the top of the main.cpp file. The first line is for GeForce and the second one is for Radeon:

    #ifdef _WIN32
    #include <windows.h>
    extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
    extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
    #endif
    

    The output is:

    OpenGL version: 4.6.0 NVIDIA 391.35
    GLSL version: 4.60 NVIDIA
    Vendor: NVIDIA Corporation
    

    But I can set 3.0, 3.1, 3.2, and so on. For example:

            QSurfaceFormat surfaceFormat;
            surfaceFormat.setMajorVersion(3);
            surfaceFormat.setMinorVersion(3);
            setFormat(surfaceFormat);
    
    OpenGL version: 3.3.0 NVIDIA 391.35
    GLSL version: 3.30 NVIDIA via Cg compiler
    Vendor: NVIDIA Corporation
    

    Another question is: what is the strange version when I comment this line of code:

    int main(int argc, char *argv[])
    {
        // QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
    
    OpenGL version: 3.0 Mesa 11.2.2
    GLSL version: 1.30
    Vendor: VMware, Inc.
    
    C 1 Reply Last reply 27 Dec 2023, 02:38
    0
    • 8 8Observer8
      27 Dec 2023, 00:33

      Hi,

      I try to set an OpenGL version to 2.1 but the next example prints this result on my laptop:

      OpenGL version: 3.1.0 - Build 9.17.10.4459
      GLSL version: 1.40 - Intel Build 9.17.10.4459
      Vendor: Intel
      

      main.cpp

      #include <QtGui/QOpenGLFunctions>
      #include <QtGui/QSurfaceFormat>
      #include <QtOpenGLWidgets/QOpenGLWidget>
      #include <QtWidgets/QApplication>
      
      class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
      {
      public:
          OpenGLWidget()
          {
              QSurfaceFormat surfaceFormat;
              surfaceFormat.setMajorVersion(2);
              surfaceFormat.setMinorVersion(1);
              setFormat(surfaceFormat);
          }
      
      private:
          void initializeGL() override
          {
              initializeOpenGLFunctions();
              glClearColor(0.f, 1.f, 0.f, 1.f);
              qDebug() << "OpenGL version:" << (const char*) glGetString(GL_VERSION);
              qDebug() << "GLSL version:" << (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
              qDebug() << "Vendor:" << (const char*) glGetString(GL_VENDOR);
          }
      
          void paintGL() override
          {
              glClear(GL_COLOR_BUFFER_BIT);
          }
      };
      
      int main(int argc, char *argv[])
      {
          QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
          QApplication a(argc, argv);
          OpenGLWidget w;
          w.show();
          return a.exec();
      }
      

      pro

      QT += core gui openglwidgets widgets
      
      win32: LIBS += -lopengl32
      
      CONFIG += c++17
      
      SOURCES += \
          main.cpp
      
      TARGET = app
      

      I can activate the second video card (the discrete one) by adding this code on the top of the main.cpp file. The first line is for GeForce and the second one is for Radeon:

      #ifdef _WIN32
      #include <windows.h>
      extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
      extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
      #endif
      

      The output is:

      OpenGL version: 4.6.0 NVIDIA 391.35
      GLSL version: 4.60 NVIDIA
      Vendor: NVIDIA Corporation
      

      But I can set 3.0, 3.1, 3.2, and so on. For example:

              QSurfaceFormat surfaceFormat;
              surfaceFormat.setMajorVersion(3);
              surfaceFormat.setMinorVersion(3);
              setFormat(surfaceFormat);
      
      OpenGL version: 3.3.0 NVIDIA 391.35
      GLSL version: 3.30 NVIDIA via Cg compiler
      Vendor: NVIDIA Corporation
      

      Another question is: what is the strange version when I comment this line of code:

      int main(int argc, char *argv[])
      {
          // QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
      
      OpenGL version: 3.0 Mesa 11.2.2
      GLSL version: 1.30
      Vendor: VMware, Inc.
      
      C Offline
      C Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 27 Dec 2023, 02:38 last edited by Chris Kawa
      #2

      TL;DR - It's stupid but correct.

      A longer version and a bit of a history of OpenGL:

      Up to 2.1 OpenGL was additive and backward compatible. On Windows you used wglCreateContext and you got the highest the driver supported. Good times.

      3.0 introduced deprecation, meaning old stuff could be removed, so that simple model no longer worked. What they came up with was a WGL extension - WGL_ARB_create_context - it introduced wglCreateContextAttribsARB to specify which version you want. Because it's an extension you first had to have a valid context to get the extension from it. So you create a dummy context just to see if you can get the function to create the higher context. Silly workaround but ok. Nothing was removed at this point yet.

      3.1 actually removed stuff, but people wanted both the old and the new stuff, so what they came up with was another extension GL_ARB_compatibility. Pure 3.1 would only be the new stuff and the old removed stuff was brought back as an extension. Even sillier, but ok.

      3.2 couldn't go on like this. Some people wanted the new lean stuff without the old crud, so what they came up with was profiles: the Core profile would be the new stuff and Compatibility profile would be the new stuff but with that GL_ARB_compatibility extension, bringing back the old stuff too. The profile thing continues on up to 4.6, which was the last released spec.

      So what you get is correct.
      This gives you a Core 3.2 profile:

      surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
      surfaceFormat.setVersion(3, 2);
      

      This gives you a Compatibility 3.2 profile:

      surfaceFormat.setProfile(QSurfaceFormat::CompatibilityProfile);
      surfaceFormat.setVersion(3, 2);
      

      This gives you 3.1 without the back compat extension:

      surfaceFormat.setProfile(QSurfaceFormat::NoProfile);
      surfaceFormat.setOption(QSurfaceFormat::DeprecatedFunctions, false);
      surfaceFormat.setVersion(3, 1);
      

      This gives you 3.1 with back compat extension:

      surfaceFormat.setProfile(QSurfaceFormat::NoProfile);
      surfaceFormat.setOption(QSurfaceFormat::DeprecatedFunctions, true);
      surfaceFormat.setVersion(3, 1);
      

      This gives you 3.0:

      surfaceFormat.setProfile(QSurfaceFormat::NoProfile);
      surfaceFormat.setVersion(3, 0);
      

      Anything below version 3.0 will revert back to the old behavior - it will give you the highest supported version that is compatible i.e. either 3.0, 3.1 with that back compat extension or 3.2 and higher in Compatibility profile.

      In your case when requesting for 2.1 you get 3.1 with back compat extension on integrated Intel chip, 4.6 Compatibility profile on discrete NVIDIA gpu and 3.0 on MESA software driver.

      Another question is: what is the strange version when I comment this line of code:

      Qt supports multiple implementations of OpenGL - either provided by the driver, via ANGLE (OpenGL -> DirectX translation layer) or by software MESA library. AA_UseDesktopOpenGL means the hardware driver will be chosen if possible, otherwise you're getting the MESA software driver.

      1 Reply Last reply
      3
      • 8 8Observer8 has marked this topic as solved on 27 Dec 2023, 11:54
      • 8 Offline
        8 Offline
        8Observer8
        wrote on 27 Dec 2023, 22:27 last edited by 8Observer8
        #3

        Thanks a lot for detailed explanation!

        I rewrote my example to show OpenGL version on the window. I was build from one code base for Desktop, Redmi 4X, and Android Emulator:

        Window 10:

        51d43ba4-9d95-438f-8b36-d77c70267294-image.png

        Android on the physical device Redmi 4X. The device is connected by USB. It is faster way to run and debug than to run on Emulator. I use scrcpy to show a screen of device on laptop:

        654cc588-f8da-426b-9f9b-d91df1f08a2f-image.png

        Android Emulator:

        0baf2eed-983b-4612-aa45-59cbb85b91aa-image.png

        main.cpp

        // #ifdef _WIN32
        // #include <windows.h>
        // extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
        // extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
        // #endif
        
        #include <QtGui/QOpenGLFunctions>
        #include <QtGui/QSurfaceFormat>
        #include <QtOpenGLWidgets/QOpenGLWidget>
        #include <QtWidgets/QApplication>
        #include <QtWidgets/QLabel>
        #include <QtWidgets/QVBoxLayout>
        #include <QtWidgets/QWidget>
        
        class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
        {
            Q_OBJECT
        
        signals:
            void showInfoSignal(const QString &openGLVersion, const QString &shadingVersion, const QString &vendor);
        
        private:
            void initializeGL() override
            {
                initializeOpenGLFunctions();
                glClearColor(0.f, 1.f, 0.f, 1.f);
                QString version(QString("OpenGL version: %1").arg((const char*) glGetString(GL_VERSION)));
                QString shadingLanguageVersion(QString("GLSL version: %1").arg((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)));
                QString vendor(QString("Vendor: %1").arg((const char*) glGetString(GL_VENDOR)));
                emit showInfoSignal(version, shadingLanguageVersion, vendor);
            }
        
            void paintGL() override
            {
                glClear(GL_COLOR_BUFFER_BIT);
            }
        };
        
        class MainWindow : public QWidget
        {
            Q_OBJECT
        public:
            MainWindow()
            {
                setWindowTitle("OpenGL Version");
                resize(300, 300);
        
                m_openGLVersionLabel = new QLabel();
                m_shadingLanguageVersionLabel = new QLabel();
                m_vendorLabel = new QLabel();
                OpenGLWidget *openGLWidget = new OpenGLWidget();
        
                m_openGLVersionLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
                m_shadingLanguageVersionLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
                m_vendorLabel->setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
        
                QVBoxLayout *layout = new QVBoxLayout();
                layout->addWidget(m_openGLVersionLabel);
                layout->addWidget(m_shadingLanguageVersionLabel);
                layout->addWidget(m_vendorLabel);
                layout->addWidget(openGLWidget);
                setLayout(layout);
        
                connect(openGLWidget, &OpenGLWidget::showInfoSignal, this, &MainWindow::showInfoSlot);
            }
        
        private slots:
            void showInfoSlot(const QString &openGLVersion, const QString &shadingVersion, const QString &vendor)
            {
                m_openGLVersionLabel->setText(openGLVersion);
                m_shadingLanguageVersionLabel->setText(shadingVersion);
                m_vendorLabel->setText(vendor);
            }
        
        private:
            QLabel *m_openGLVersionLabel;
            QLabel *m_shadingLanguageVersionLabel;
            QLabel *m_vendorLabel;
        };
        
        #include "main.moc"
        
        int main(int argc, char *argv[])
        {
            // QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
            QApplication a(argc, argv);
            MainWindow w;
            w.show();
            return a.exec();
        }
        

        pro

        QT += core gui openglwidgets widgets
        
        win32: LIBS += -lopengl32
        
        CONFIG += c++17
        
        SOURCES += \
            main.cpp
        
        TARGET = app
        
        1 Reply Last reply
        0

        1/3

        27 Dec 2023, 00:33

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved