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

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 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.

    JKSHJ 1 Reply Last reply
    0
    • A Alain38 0

      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.

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on 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
      0
      • JKSHJ JKSH

        @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 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.

        JKSHJ 1 Reply Last reply
        0
        • A Alain38 0

          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.

          JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on 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

          JKSHJ 1 Reply Last reply
          0
          • A Offline
            A Offline
            Alain38 0
            wrote on 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 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
              • JKSHJ JKSH

                @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.

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on 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

                • Login

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