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. Migration from QGLWidget to QOpenGLWidget?

Migration from QGLWidget to QOpenGLWidget?

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 3.1k 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.
  • A Offline
    A Offline
    Alain38 0
    wrote on last edited by
    #1

    Hi,
    I'm still in my problems to migrate an application written in Qt4.8.4 (so using QGLWidget) to a version in QT5. Due to the numerous problems we have by using the Qt5 version of QGLWidget, we have decided to make a try by migrating them to QOpenGLWidget. BUt I'm still facing a problem.

    In the QT 4.8.4 version we created a special QGLWidget that is never displayed. But it is shared between all our OpenGL widgets using the syntax QGLWidget(QWidget *parent = Q_NULLPTR, const QGLWidget *shareWidget = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()).

    With QOpenGLWidget this syntax no more exist. It is replaced by the notion of shared QOpenGLContext. But, to be effective (.i.e. gives the ability to create OpenGL objects), the QOpenGLContext seems to require a QSurface. And this is where my problem stands. Because, when my application calls an OpenGL function it does not know if a QOpenGLWidget has already been displayed (so a current context is present), or not (so a QOffscreenSurface is required with an explicit call to context()->makeCurrent(Surface)). Does it exist a clue to solce this problem without having to check the state of the current context before calling OpenGL functions?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Can you provide a minimal sample that shows your setup ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Alain38 0
        wrote on last edited by
        #3

        Hi,
        This is the partial code of the shared QGLWidget (in 4.8.4):

        //----------------------------------------------------------------------------
        SharedGLWidget::SharedGLWidget() : QGLWidget(), m_shaderDirectory("shaders/")
        //----------------------------------------------------------------------------
        {// SharedGLWidget()
                updateGL();
        }// SharedGLWidget()
        
        //----------------------------------------------------------------------------
        void SharedGLWidget::initializeGL()
        //----------------------------------------------------------------------------
        {// initializeGL()
                GLenum msg = glewInit();
        
                if (msg != GLEW_OK)
            {// check glew init
                astk::log::msg((const char *)glewGetErrorString(msg));
            }// check glew init  
        
                this->loadShader("Slice"          , m_sliceProgram);
                this->loadShader("Implant"        , m_implantProgram);
                this->loadShader("Color"          , m_colorProgram);
                this->loadShader("Depth"          , m_depthProg);
                this->loadShader("Texture2D_RGBA" , m_texture2DProgram);
                this->loadShader("VolumeRendering", m_vrProgram);
                this->loadShader("Contour"        , m_contourProgram);
                this->loadShader("Radio"          , m_radioProgram);
        
                // initial constant member of slice program
                unsigned int program = 0;;
                program = m_sliceProgram.programId();
                glUseProgram(program);
                glUniform1i(glGetUniformLocation(program, "tex2"), 8);
        
                glUniform1i(glGetUniformLocation(program, "tex3d0"), 0);
                glUniform1i(glGetUniformLocation(program, "tex3d1"), 1);
                glUniform1i(glGetUniformLocation(program, "tex3d2"), 2);
                glUniform1i(glGetUniformLocation(program, "tex3d3"), 3);
                glUniform1i(glGetUniformLocation(program, "tex3d4"), 4);
                glUniform1i(glGetUniformLocation(program, "tex3d5"), 5);
                glUniform1i(glGetUniformLocation(program, "tex3d6"), 6);
                glUniform1i(glGetUniformLocation(program, "tex3d7"), 7);
                glUseProgram(0);
        
                // initial constant member of radio program
                program = m_radioProgram.programId();
                glUseProgram(program);
                glUniform1i(glGetUniformLocation(program, "tex3d0"), 0);
                glUniform1i(glGetUniformLocation(program, "tex3d1"), 1);
                glUniform1i(glGetUniformLocation(program, "tex3d2"), 2);
                glUniform1i(glGetUniformLocation(program, "tex3d3"), 3);
                glUniform1i(glGetUniformLocation(program, "tex3d4"), 4);
                glUniform1i(glGetUniformLocation(program, "tex3d5"), 5);
                glUniform1i(glGetUniformLocation(program, "tex3d6"), 6);
                glUniform1i(glGetUniformLocation(program, "tex3d7"), 7);
                glUseProgram(0);
        
                // initial constant member of vrprogram
                program = m_vrProgram.programId();
                glUseProgram(program);
                glUniform1i(glGetUniformLocation(program, "tex3d0"), 0);
                glUniform1i(glGetUniformLocation(program, "tex3d1"), 1);
                glUniform1i(glGetUniformLocation(program, "tex3d2"), 2);
                glUniform1i(glGetUniformLocation(program, "tex3d3"), 3);
                glUniform1i(glGetUniformLocation(program, "tex3d4"), 4);
                glUniform1i(glGetUniformLocation(program, "tex3d5"), 5);
                glUniform1i(glGetUniformLocation(program, "tex3d6"), 6);
                glUniform1i(glGetUniformLocation(program, "tex3d7"), 7);
                glUseProgram(0);
        }// initializeGL()
        
        

        A global instance is created at the beginning, just before the first use of an OpenGL command:

                SharedGLWidget::getInstance()->makeCurrent();
                char * retPtr = (char *) glGetString(GL_EXTENSIONS);// Retrieve the whole extension list
        

        And each visible QGLWidget is created by:

        Display2DView::Display2DView(QWidget * p_parent) : QGLWidget(p_parent, SharedGLWidget::getInstance())
        {
        ...
        }
        

        Now, our application is a state-machine application. I.e. each state has its own GUI. The GUIs of the first steps do not have OpenGL widgets. But in the transition between them and the first state with OpenGL GUI, a lot of OpenGL processes (texture creation, preparation of the widgets) is performed with no OpenGL widget yet displayed.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Alain38 0
          wrote on last edited by
          #4

          OK,
          Application now seems to work. I have to run the unitary tests to be sure. If I have too many bad suprises with unitary tests, we will go back to Qt 4.8.4. And in every cases what I did is much more hacks that clean development.

          The major changes that created a lot of problems are:

          • In Qt4.8.4 when an QGLWidget is created, even if it is not displayed, an OpenGL context is created. So, all OpenGL operations are possible. In Qt5 to be able to use the OpenGL operation, with a QOpenGLWidget, the widget must be displayed, or linked to an off-screen surface,

          • In Qt4.8.4 when a QGLWidget is passed to every other QGLWidget, there is really a single OPenGL Context that is used. In Qt5, force the application to use shared contexts does not mean "a single context". And the impact is that OpenGL activated at one moment (in one context) are not necessarily activated globally. So application that runs well in QT4.8.4 does not necessarily work well with QT5,

          • And finally QGLWidget in QT5 and QGLWidget in QT4.8.4 are totally uncorrelated. This is the same class name, the same API. But QT has not only marked QGLWidget as deprecated. They also changed the whole implementation. Thus, an application working under Qt4.8.4 may encounter problems in QT5 due to unmanaged hidden QSurface.

          This is again a proof of an axiom that I well know: "Never change the version of frameworks in a product. Unless whether the current development step requires a full rewriting of the application".

          1 Reply Last reply
          0

          • Login

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