PDA

View Full Version : How to achieve vsync using only QPainter on a QGLWidget?



wings
28th June 2015, 08:00
In my app, I need to update a text after a certain number of vertical refresh cycles (yes, I'm talking about v blank sync). I've never done anything OpenGL before, but I read about Qt's OpenGL system from several places and I've managed to write a class derived from QGLWidget as shown here (http://stackoverflow.com/a/17167551/2243767). But unlike that stackoverflow answer, I've NOT USED paintGL,updateGL etc.. Instead, I've only overridden the paintEvent(QPaintEvent *) event and drawn the text purely using QPainter. But I'm not getting any "sync" effect. That is, my code is not triggering any update after ~16.6ms (I'm in a 60Hz setup). What happens, instead, is that my code update()s at random intervals like 5ms,1ms,23ms,17ms etc. And also the CPU usage is about 22%!! I know it (the high CPU usage) is because the timer updates at 0ms. But it was meant to mean "update ASAP", that is update as soon as vertical refresh occurs. But that thing is not happening. This is the code:



QGLFormat generateFormat()
{
QGLFormat fmt;
fmt.setAlpha(true);
fmt.setSampleBuffers(true);
fmt.setSwapInterval(1);
return fmt;
}

MyClass::MyClass(QWidget *parent) : QGLWidget(generateFormat(), parent)
{
if (format().swapInterval() == -1)
{
timer.setTimerType(Qt::PreciseTimer);
timer.setInterval(17);
}
else
timer.setInterval(0);
connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
timer.start();
}

void MyClass::paintEvent(QPaintEvent *e)
{
QPainter painter (this);
painter.drawText(e->rect(), Qt::AlignCenter, "text to be drawn");
}


What's wrong? I believe I've misunderstood something. But what is it?

P.S.: Please don't say I've gotta do some spooky low-level openGL. I'm more than happy with QPainter.