PDA

View Full Version : qglwidget not always drawing



spraff
22nd June 2009, 14:52
Hi, here's the code I'm working from:

class GLTest : public QGLWidget {
Q_OBJECT
public:
GLTest (QWidget * = NULL);
protected:
void initializeGL ();
void resizeGL (int, int);
void paintGL ();
};

GLTest :: GLTest (QWidget * parent) : QGLWidget (parent) {
QGLFormat f = format();
f.setDoubleBuffer (true);
setFormat (f);
}

void GLTest :: initializeGL () {
glClearColor (0.0, 0.0, 0.0, 0.0);
}

void GLTest :: resizeGL (int w, int h) {
glViewport (0, 0, (GLint)w, (GLint)h);
}

void GLTest :: paintGL () {
glClear (GL_COLOR_BUFFER_BIT);

glColor3f (1,0,0);
glBegin (GL_QUADS);
glVertex2f (0, 0);
glVertex2f (150, 0);
glVertex2f (150, 50);
glVertex2f (0, 50);
glEnd ();

swapBuffers ();
};


The red-on-black is drawn as expected, but only when the window is being resized. The rest of the time the display shows lingering artefacts of e.g. moved window borders.

Why isn't the image persistent?

Thanks

h0nki
23rd June 2009, 01:33
I think you have to call paintGL() by yourself (i.e. by a QTimer).

spraff
24th June 2009, 16:34
With this code, the problem is more evident.



int main (...) {
// ...
GLTest * gl_test = new GLTest ();
gl_test -> resize (300,300);
gl_test -> show ();
QTimer :: singleShot (1000, gl_test, SLOT(update()) );
}


After a second, the window is painted correctly. However as soon as anything disturbs it, another window passing in front for example, the image is destroyed.

The problem with using a timer to trigger a refresh is that in between refreshes the image can be destroyed. If the update is happening at 0.2 frames per second the window SHOULD be able to repaint itself without updating in-between frames.

Forced updates are a hack, not a solution, and this isn't OpenGL-specific -- ordinary windows do not have to perform a full-depth repaint every time the mouse passes over them!

What have I got wrong?

ricardo
24th June 2009, 20:44
I think you have to call paintGL() by yourself (i.e. by a QTimer).

updateGL(); and only if your objects are animated. In your static example you do not need any timer.

Qt should redraw (ie, call updateGL automatically) every time you move a window over your program.

I don't see any mistake on your code. Maybe you do not set up a view properly.
Try clearing also Z-Buffer
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
And double buffer is activated by default, so remove that code, is useless.

Another suggestion, glViewport modifies your proyection matrix, try to write this:
glViewport (0, 0, (GLint)w, (GLint)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho or perspective

And do not forget to load default identy matrix every time you draw something:
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f (1,0,0);
...