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. Problem with QTest, QGlWidget, and Qt5
QtWS25 Last Chance

Problem with QTest, QGlWidget, and Qt5

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtestqglwidgetglreadpixelsqt5.5.1
7 Posts 2 Posters 2.2k 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 19 Jul 2018, 14:29 last edited by
    #1

    Hi,
    I have a a huge application initially developped under Qt4.8.4., so using QGlWidget. This application comes with millions of lines to test all parts from low-level (basic functions) to high-level. Now I have to migrate this application to a Qt5. As QGlWidget still exists, event if it is deprecated, I'm still using this class. So migration of the application was quite simple and works well. Unfortunately, for regulatory reasons I have to prove this, by running the associated tests. And all tests based on QGLWidget fail. I already spent two days to try to understand the problem. It seems that there is somewhere a QWindow, with a default size of 160*160, that is the origin of my problem.

    An example of test that fails is the following:

    • Create a QGlWidget of size 290*290 (this is the size of the widget in the application)
    • Place some objects in the widget,
    • Explicitely call paintGL to force the drawing,
    • Read the image using glReadPixels
    • Check the value of some particular pixels.

    The failure is on the glReadPixels. It only reads pixels in the area limited by the QWindow. To be sure of this I forced a call to processEvents() to have the display in the QWidget (and not only in the OpenGL frame buffer). Ans I show the image reduced to the QWindow. I have tried to force the size of the QWindow. In this case the display takes the whole QWidget (that is what I want). But glReadPixels performed after still only capture a 160*160 part of the image.

    Any idea of how quickly resolve this stupide problem? If I have to move to QOpenGLWidget, this will take months of developments, that will be an unacceptable cost for my boss.

    J 1 Reply Last reply 20 Jul 2018, 05:04
    0
    • A Alain38 0
      19 Jul 2018, 14:29

      Hi,
      I have a a huge application initially developped under Qt4.8.4., so using QGlWidget. This application comes with millions of lines to test all parts from low-level (basic functions) to high-level. Now I have to migrate this application to a Qt5. As QGlWidget still exists, event if it is deprecated, I'm still using this class. So migration of the application was quite simple and works well. Unfortunately, for regulatory reasons I have to prove this, by running the associated tests. And all tests based on QGLWidget fail. I already spent two days to try to understand the problem. It seems that there is somewhere a QWindow, with a default size of 160*160, that is the origin of my problem.

      An example of test that fails is the following:

      • Create a QGlWidget of size 290*290 (this is the size of the widget in the application)
      • Place some objects in the widget,
      • Explicitely call paintGL to force the drawing,
      • Read the image using glReadPixels
      • Check the value of some particular pixels.

      The failure is on the glReadPixels. It only reads pixels in the area limited by the QWindow. To be sure of this I forced a call to processEvents() to have the display in the QWidget (and not only in the OpenGL frame buffer). Ans I show the image reduced to the QWindow. I have tried to force the size of the QWindow. In this case the display takes the whole QWidget (that is what I want). But glReadPixels performed after still only capture a 160*160 part of the image.

      Any idea of how quickly resolve this stupide problem? If I have to move to QOpenGLWidget, this will take months of developments, that will be an unacceptable cost for my boss.

      J Offline
      J Offline
      JKSH
      Moderators
      wrote on 20 Jul 2018, 05:04 last edited by
      #2

      @Alain38-0 Can you show:

      1. Your test code from Qt 4?
      2. Your test code from Qt 5?

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      A 1 Reply Last reply 20 Jul 2018, 06:26
      0
      • J JKSH
        20 Jul 2018, 05:04

        @Alain38-0 Can you show:

        1. Your test code from Qt 4?
        2. Your test code from Qt 5?
        A Offline
        A Offline
        Alain38 0
        wrote on 20 Jul 2018, 06:26 last edited by
        #3

        Hi @JKSH ,
        test code is quit simple. The active part (other part contains confidential elements) is:

            unsigned char image[290*290 * 4];
            dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->makeCurrent();
            dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->paintGL();
            glReadPixels(0, 0, 290, 290, GL_RGBA, GL_UNSIGNED_BYTE, image);
        
        

        AxialView is a QGraphicView that contains a QGLWidget as background.

        J 1 Reply Last reply 20 Jul 2018, 07:02
        0
        • A Alain38 0
          20 Jul 2018, 06:26

          Hi @JKSH ,
          test code is quit simple. The active part (other part contains confidential elements) is:

              unsigned char image[290*290 * 4];
              dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->makeCurrent();
              dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->paintGL();
              glReadPixels(0, 0, 290, 290, GL_RGBA, GL_UNSIGNED_BYTE, image);
          
          

          AxialView is a QGraphicView that contains a QGLWidget as background.

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 20 Jul 2018, 07:02 last edited by JKSH
          #4

          @Alain38-0 said in Problem with QTest, QGlWidget, and Qt5:

              unsigned char image[290*290 * 4];
              dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->makeCurrent();
              dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->paintGL();
              glReadPixels(0, 0, 290, 290, GL_RGBA, GL_UNSIGNED_BYTE, image);
          
          

          AxialView is a QGraphicView that contains a QGLWidget as background.

          It's not clear: Where is this code being called from? I know that makeCurrent() and paintGL() can only be called by QGLWidget/QOpenGLWidget... Are you using a widget to update a different widget?

          Please provide a Short, Self Contained, Correct (Compilable), Example (http://www.sscce.org/ ). Remove the confidential and unnecessary elements, and give us a compilable example (including a main() function, a simple class, and an output display) that demonstrates the problem. Otherwise, it's difficult to understand the problem.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          J 1 Reply Last reply 23 Jul 2018, 23:20
          0
          • A Offline
            A Offline
            Alain38 0
            wrote on 20 Jul 2018, 07:05 last edited by
            #5

            In addition to my current problem, few new elements. First I found a partial workaround. Doing

                qApp->processEvents();
                dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->resize(290, 290);
                qApp->processEvents();
                dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->makeCurrent();
                dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->paintGL();
                qApp->processEvents();
            
            

            Before glReadPixels seems to solve the problem, but only the first time glReadPixels is called. In the same test function I have a second glReadPixels from the same view. For this second read I have an incoherency between what is displayed on the screen (that is right), and what is read by glReadPixels (that is the previous image).

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Alain38 0
              wrote on 23 Jul 2018, 13:50 last edited by Alain38 0
              #6

              Hi,
              I have found a similar problem in my application (so, this time this is not with QTest). I'm calling the below function:

              ///---------------------------------------------------------------------------------------
              unsigned char* AbstractDisplay2DPlanning::getImageBuffer(int& p_width, int& p_height)
              ///---------------------------------------------------------------------------------------
              {
                  // getImageBuffer(int &p_width, int &p_height)
                  this->m_scene->getBackground()->makeCurrent();
              
                  glDrawBuffer(GL_BACK);  // Drawing on the back buffer (invisible)
              
                  this->m_scene->getBackground()->paintGL();
                  m_scene->getBackground()->resize(this->size());
                  this->extPaintGL();
              
                  // Retrieve pixels
                  int     viewport[4];
                  glReadBuffer(GL_BACK);
                  glGetIntegerv(GL_VIEWPORT, viewport);
                  UChar*  pixelBuffer = new (std::nothrow) UChar[4 * viewport[2] * viewport[3]];
              
                  if (pixelBuffer != NULL)
                  {
                      // Read pixels
                      // Get the image in BGR mode just to ensure a right display in the design report (somewhere image is inverted from BGR to RGB
                      glReadPixels(0, 0, viewport[2], viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, pixelBuffer);
                  }// Read pixels
              
                  else
                  {
                      // Memory problem
                      viewport[2] = viewport[3] = 0;
                      INCAS_CRITICAL() << "Cannot allocate the buffer";
                  }// Memory problem
              
              #ifdef _DEBUG
                  QImage(pixelBuffer, viewport[2], viewport[3], QImage::Format_ARGB32).save("C:/Temp/ReadImage.png");
              #endif
              
                  glDrawBuffer(GL_FRONT_AND_BACK); // Restore normal drawing mode
              
                  p_width = viewport[2];
                  p_height= viewport[3];
              
                  return pixelBuffer;
              }// getImageBuffer(int &p_width, int &p_height)
              

              AbstractDisplay2DPlanning inherits from QGraphicsView. m_scene->background() is a QGLWidget that displays a lot of stuff. And extPaintGL() is a member of AbstractDisplay2DPlanning that is specific to each derived class. Its goal is to display additional elements using native OpenGL commands (i.e. not using the QOpenGLFunctions). Notice that, as all the code is based on QGLWidget, only native OpenGL commands are used.

              Below, the result image:
              0_1532353710484_ReadImage.png
              As you can see on it, only a 160x160 part of the OpenGL buffer has been read, instead of the 290x290 drawn part.

              1 Reply Last reply
              0
              • J JKSH
                20 Jul 2018, 07:02

                @Alain38-0 said in Problem with QTest, QGlWidget, and Qt5:

                    unsigned char image[290*290 * 4];
                    dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->makeCurrent();
                    dynamic_cast<Display2DScene*>(axialView.scene())->getBackground()->paintGL();
                    glReadPixels(0, 0, 290, 290, GL_RGBA, GL_UNSIGNED_BYTE, image);
                
                

                AxialView is a QGraphicView that contains a QGLWidget as background.

                It's not clear: Where is this code being called from? I know that makeCurrent() and paintGL() can only be called by QGLWidget/QOpenGLWidget... Are you using a widget to update a different widget?

                Please provide a Short, Self Contained, Correct (Compilable), Example (http://www.sscce.org/ ). Remove the confidential and unnecessary elements, and give us a compilable example (including a main() function, a simple class, and an output display) that demonstrates the problem. Otherwise, it's difficult to understand the problem.

                J Offline
                J Offline
                JKSH
                Moderators
                wrote on 23 Jul 2018, 23:20 last edited by
                #7

                @Alain38-0 said in Problem with QTest, QGlWidget, and Qt5:

                I have found a similar problem in my application

                Please provide a Short, Self Contained, Correct (Compilable), Example (http://www.sscce.org/ ). Remove the confidential and unnecessary elements, and give us a compilable example (including a main() function, a simple class, and an output display) that demonstrates the problem. Otherwise, it's difficult to understand the problem.

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                1 Reply Last reply
                1

                2/7

                20 Jul 2018, 05:04

                topic:navigator.unread, 5
                • Login

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