QGLWidget appears black in Windows 7

I wrote and tested some code in Windows XP (Qt 4.7.2) using Visual Studio 2010, and then tried it on another machine with Windows 7 installed.

The program opens QDialog and creates a QGLWidget, where I show webcam images (with some processing). Although images are displayed correctly in Windows XP, at the moment, when I test the program on a Windows 7 machine, QGLWidget turns black and the image does not appear. It is strange, however, that when I move around the window and it leaves the borders of the screen, the image is displayed for a moment and black when I stop moving again, which makes me think that the images are correctly received / processed (several times) and that it may be a problem with QTimer.

Relevant Code:

Initialization:

void GLVideo::initializeGL() { glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Some OpenCV processing // Here I declare the timer, might it be the problem? m_timer = new QTimer(this); connect( m_timer, SIGNAL(timeout()), this, SLOT(timeOutSlot()) ); m_timer->start( 33 ); } 

The slot that is called every timeout:

 void GLVideo::timeOutSlot() { ReceiveInfo(); LoadTextures(); } void GLVideo::LoadTextures() { // Get the image from the webcam ProcessCamera(); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D( GL_TEXTURE_2D, 0, 3, qImage->width(), qImage->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, qImage->bits()); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); updateGL(); } void GLVideo::resizeGL( int width, int height ) { height = height?height:1; glViewport( 0, 0, (GLint)width, (GLint)height ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } 

And finally, the widget's drawing function:

 void GLVideo::paintGL() { glPushAttrib(GL_ALL_ATTRIB_BITS) ; QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); glPopAttrib() ; glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, texture); glColor4f(1.0f,1.0f,1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.65f, 1.24f, -3.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.65f, 1.24f, -3.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.65f,-1.24f, -3.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.65f,-1.24f, -3.0f); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glPopMatrix(); // Some 2D drawing: } 

Any idea what I'm doing wrong? Can QTimer not call SLOT timeOutSlot?

+4
source share
3 answers

If your program runs on Windows XP, but not on Windows 7, I recommend that you check to see if there is a newer version of the display driver.

+3
source

You are using the OpenGL API outside of paintGL() , resizeGL() or initializeGL() .

When your slot is called, change any state to be able to draw a new frame, but not yet call the OpenGL API. Instead, call QWidget::updateGL() and execute the OpenGL calls in your reimplementation of paintGL() .

The problem you are facing is that outside of these three functions, your GL context is not current. In older OSs this may not be a problem, but any OS with a window manager linker will cause problems. For example, in your case, your program may have been the only OpenGL user under XP, so yours has always been the current context. But in Windows 7, the desktop itself uses, if not OpenGL, then Direct3D, i.e. the same equipment.

If you absolutely must call the OpenGL function outside of these three functions, you must first call QGLWidget::makeCurrent() , but note that this is not an idiomatic use.

Regarding creating a QTimer in initializeGL() : it is certainly more idiomatic to create this timer in the class constructor, but it should also be in initializeGL() .

+5
source

Hi I had a similar problem (black screen with an intermittently framed image) with the new NVIDIA (280.something) + Win7 drivers, I fixed this problem by removing the swapBuffers manual call at the end of my paintGL and setting setAutoBufferSwap (true) in the constructor - I hope that will help.

+3
source

All Articles