Results 1 to 7 of 7

Thread: QGLWidget: problem with very large images

  1. #1
    Join Date
    Sep 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default QGLWidget: problem with very large images

    Hi,

    I'm using a QGLWidget to display images in a media player. Everything has been working fine until recently I came across a corner case: I was asked to support panoramic images that are about 256x10496. Once I tried loading an image up, the whole screen flashes once, the QGLWidget displays all black, and message comes up at the bottom of my screen saying:

    "The color scheme has been changed to Windows 7 Basic. A running program isn't compatible with certain visual elements of Windows."

    The openGL code i'm using takes the image (which is formatted as an array of unsigned shorts(16 bits per pixel)) and converts it to a 2D texture, using glTexImage2D(), and renders it to the screen. A previous version of my software used QPainter on a QLabel (we switched for performance reasons and so we could take advantage of OpenGL's support of 16 bit per pixel image formats instead of needing to crush it down to 8bpp), and for some reason this handles the large image formats no problem. At first it seemed to me that the OpenGL code was causing the problem by overwhelming the max viewport dimension size of the video card (which was 8192), and that QPainter was getting around this by only attempting to draw what was in the QScrollArea's viewport. However, when I tried using a QPainter in the case of large images instead of the OpenGL code (all still within the QGLWidget class), the same thing kept happening. Why does the QPainter on a QLabel accept very large images with no problem while QPainter on a QGLWidget does not?

    Example:
    Qt Code:
    1. MyClass::paintGL()
    2. {
    3. glClear( GL_COLOR_BUFFER_BIT );
    4.  
    5. glDisable(GL_DEPTH_TEST);
    6.  
    7. unsigned int testWidth = 256;
    8. unsigned int testHeight = 10496;
    9. unsigned int testBpp = 16;
    10. unsigned int colorIncr = (65536/testWidth);
    11.  
    12. unsigned short* testPattern = new unsigned short[testWidth*testHeight];
    13. unsigned int color = 0;
    14. for(unsigned int i = 0; i < testWidth*testHeight; ++i){
    15. testPattern[i] = color;
    16. color += colorIncr;
    17. if(color >= 65536)
    18. color = 0;
    19. }
    20.  
    21. if(useOpenGL){
    22. //OpenGL method: doesn't work
    23. GLvoid* pixels = (GLushort*)testPattern;
    24. glEnable(GL_TEXTURE_2D);
    25. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    26.  
    27.  
    28. GLuint myFrameTexture;
    29. glGenTextures(1, &myFrameTexture);
    30. glBindTexture(GL_TEXTURE_2D, (myFrameTexture));
    31. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    32. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    33. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    34. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    35.  
    36. glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
    37. testWidth, testHeight,
    38. 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, pixels);
    39. float startX = 0.0f;
    40. float startY = 0.0f;
    41. float endX = testWidth;
    42. float endY = testheight;
    43.  
    44. glBegin(GL_QUADS);
    45. glTexCoord2f(0.0,1.0);
    46. glVertex2f(startX, startY);
    47. glTexCoord2f(0.0,0.0);
    48. glVertex2f(startX, endY);
    49. glTexCoord2f(1.0,0.0);
    50. glVertex2f(endX, endY);
    51. glTexCoord2f(1.0,1.0);
    52. glVertex2f(endX, startY);
    53. glEnd();
    54.  
    55. glDisable(GL_TEXTURE_2D);
    56. glDeleteTextures(1, &myFrameTexture);
    57. }else{
    58. //QPainter method, also doesn't work.
    59. QPainter p(this);
    60. p.scale(testWidth, testHeight);
    61. QImage* image = new QImage(testWidth, testHeight,
    62. QImage::Format_Indexed8);
    63. image->setNumColors(256);
    64. for(int i = 0; i < 256; i++)
    65. image->setColor(i, QRGB(i,i,i));
    66. //get 8bpp version of test pattern
    67. unsigned char* test8bpp = new unsigned char[testHeight*testWidth];
    68. for(int i = 0; i < (testHeight*testWidth); i++){
    69. test8bpp[i] = testPattern[i] >> 8;
    70. }
    71. for(int i = 0; i < testHeight; i++){
    72. unsigned char* row = image->scanLine(i);
    73. memcpy(row, test8bpp+(i*testWidth), testWidth);
    74. }
    75. p.drawImage(0,0,*image);
    76. delete [] test8bpp;
    77. }
    78. delete [] testPattern;
    79. }
    To copy to clipboard, switch view to plain text mode 

    Sorry for the long winded code example. One thing to note here is that the QPainter code called from within paintGL does work with large image formats when it is placed inside of a widget which subclasses QLabel instead of QGLWidget and inside the "paintEvent()" function. I have also tested the QPainter code with normal sized images (less than 8192 in both dimensions) and it properly displays those images, but when I give either the OpenGL or QPainter code inside of a QGLWidget an image with dimensions exceeding 8192, it makes an all white or all black box of that size, and windows switches to basic color mode.

    I realize this is a pretty ridiculous corner case at the moment, but nonetheless I still need to handle it. Any input/suggestions would be appreciated.

    Thanks.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGLWidget: problem with very large images

    The problem probably is caused by your OpenGL implementation (or rather hardware) not able to handle such large textures. Check that using appropriate GL calls and cut the image to several pieces to compensate.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Sep 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGLWidget: problem with very large images

    Thanks for the reply. I had previously tried cutting it down into several pieces when I thought the limitation was imposed on the size of the single texture, but when I split it into several pieces it still gave the same behavior. I believe this is due to a limitation on the overall viewport size, not the size of individual textures. But my main question is actually concerning the QPainter implementation. The QPainter code seems to work on large image files if you place it inside a QLabel using the paintEvent call, but not in a QGLWidget. I was wondering why this would work in one case and not the other, since it would be preferable for me to stick with the QGLWidget and just have an if case which uses a QPainter inside paintGL() if possible.

    here's the QPainter bit. This works if it's inside paintEvent in a QLabel subclass, and does not work if it's inside paintGL() in a QGLWidget subclass. (By works i mean displays large format images, both will display images with dimensions less than 8192 pixels in height and width.)
    Qt Code:
    1. QPainter p(this);
    2. p.scale(testWidth, testHeight);
    3. QImage* image = new QImage(testWidth, testHeight,
    4. QImage::Format_Indexed8);
    5. image->setNumColors(256);
    6. for(int i = 0; i < 256; i++)
    7. image->setColor(i, QRGB(i,i,i));
    8. //get 8bpp version of test pattern
    9. unsigned char* test8bpp = new unsigned char[testHeight*testWidth];
    10. for(int i = 0; i < (testHeight*testWidth); i++){
    11. test8bpp[i] = testPattern[i] >> 8;
    12. }
    13. for(int i = 0; i < testHeight; i++){
    14. unsigned char* row = image->scanLine(i);
    15. memcpy(row, test8bpp+(i*testWidth), testWidth);
    16. }
    17. p.drawImage(0,0,*image);
    18. delete [] test8bpp;
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGLWidget: problem with very large images

    Please provide a minimal compilable example reproducing the problem. I think you are incorrectly trying to place a huge GL widget in a small scroll area. Your gfx card probably won't be able to handle that. Instead you should probably subclass QAbstractScrollArea, set a GL viewport for it and adjust your rendering code to include scrollbars positions.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Sep 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGLWidget: problem with very large images

    Ok, I'll give that a try. I previously was under the impression that subclassing QAbstractScrollArea wouldn't work in the case of a QGLWidget because I needed to handle the draw call directly and I figured that drawing a small enough portion of the frame to fit in the viewport would screw up the ScrollArea's idea of how big the viewport widget was and thus make it assume it didn't need to display the scroll bars because the widget was already small enough. I'll give it a try though and see what happens. If that doesn't work i'll try to provide a more complete source example that you can run and test yourself.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGLWidget: problem with very large images

    You need to understand the difference between QScrollArea and QAbstractScrollArea.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    gitarooLegend (8th September 2011)

  8. #7
    Join Date
    Sep 2010
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGLWidget: problem with very large images

    Thanks wysota! Turns out I was over-thinking things a bit and trying to mess around too much with overriding the setViewport() function and the size related functions of my QGLWidget implementation. Took a bit of tinkering but subclassing QAbstractScrollArea and setting my QGLWidget as a child widget of the viewport solved the problem perfectly.

Similar Threads

  1. Replies: 6
    Last Post: 5th March 2010, 11:54
  2. QScrollArea not displaying large number of images
    By lpkincaid in forum Qt Programming
    Replies: 1
    Last Post: 31st May 2009, 09:58
  3. import large number of images
    By sriluyarlagadda in forum Qt Programming
    Replies: 5
    Last Post: 15th May 2008, 10:26
  4. Sending large datagrams(very large)
    By marcel in forum General Programming
    Replies: 1
    Last Post: 16th February 2008, 21:55
  5. Making 3D Images wuthout QGLWidget
    By ashishsaryar in forum Qt Programming
    Replies: 2
    Last Post: 15th February 2008, 09:18

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.