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.