6

I’m drawing a simple scene with Open GL. I’ve subclassed QGLWidget and overriden paintGL(). Nothing fancy there:

void CGLWidget::paintGL()
 {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt (120.0, 160.0, -300.0, 0.0 + 120.0, 0.0 + 160.0, 2.0 - 300.0, 0.0, 1.0, 0.0);
    glScalef(1.0f/300.0f, 1.0f/300.0f, 1.0f/300.0f);
    glClear(GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(80.0, width()/(double)height(), 5.0, 100000.0);

    glMatrixMode(GL_MODELVIEW);
    glBegin(GL_POINTS);
    glColor3f(1.0f,0.6f,0.0f);
    glVertex3d(x, y, z);

    // ...drawing some more points...

    glEnd();

 }

I have a timer in main window which triggers updateGL() of GL widget. I’ve verified that it results in paintGL() being called. However, the actual picture on the screen is only updated very rarely. Even if I resize the window, scene is not updated. Why is that and how can I force it to update?

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • May I ask: Why do you initialize the projection and MV matrix twice in `paintGL`? Do you draw something in between? If not, you overwrite the first matrices with the second ones and you can move this code into `resizeGL` (projection) and `initializeGL` (model-view) – leemes Feb 21 '13 at 12:25
  • @leemes: No idea, actually... It's a bug, remnants of my trying to find projection and MV parameters that actually work. Fixed, thank you. – Violet Giraffe Feb 21 '13 at 12:37

2 Answers2

14

Don't call updateGL() from your timer, call update() instead to ensure that the view gets a paint event.

Pete
  • 4,784
  • 26
  • 33
  • It doesn't work, `paintGL()` is not called at all then. Tried calling both, too - also doesn't work. But thanks for the hint. – Violet Giraffe Feb 21 '13 at 12:35
  • Try sticking a breakpoint in QGLWidget::paintEvent and see if it gets there after calling update() and what happens after that. – Pete Feb 21 '13 at 13:03
  • It's only called when I resize the window. – Violet Giraffe Feb 21 '13 at 16:07
  • Have you set any window flags in the constructor of your view? update SHOULD cause you to get a paint event at some point in the near future after calling it, providing you are letting the event loop run correctly and you have not disabled updates on the widget. Not getting a paint event is your problem. – Pete Feb 21 '13 at 18:04
  • Thanks a lot, found the problem! Was actually just a logical problem on my part, but your answers helped :) – Violet Giraffe Feb 21 '13 at 19:02
  • What was the problem actually? I am having a similar problem and I couldn't figure it out. Thanks in advance. – BjkOcean Mar 21 '21 at 20:29
6

inside your CGLWidget constructor

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(10);

timer -> start(VALUE);

play with `VALUE 10 is just an example.

Adorn

Adorn
  • 1,403
  • 1
  • 23
  • 46
  • Hey, I have used this technique it works. Is there somehow I can immediately update the scene as soon as the previous scene is rendered because right now I have a bottleneck of 10ms from the timer. I can't go faster than that. – psiyumm May 08 '14 at 13:30
  • play with `VALUE 10 is just an example. if u put 1 there, it would be 1ms, point is not however, when you want to refresh the screen, point is when your scene is ready.. – Adorn May 12 '14 at 14:08
  • Exactly what I said. As soon as my scene is ready, I want update to be triggered. – psiyumm May 12 '14 at 14:33
  • then make sure if you really need a timer. also `timer(0)` will shoot out the timer immediately – Adorn May 12 '14 at 15:25
  • Well, this is what I need to know, how do I remove the timer from the application itself. I would prefer not using it. – psiyumm May 12 '14 at 16:23