how to double buffer with Qt and WGLWidget
-
I cannot copy paste from my work computer to here but am trying to show all the relevant details. Please try to accommodate typos.
paintGL() looks fundamentally like thisvoid C_GL_Strip_Chart::paintGL() { save_current_time() // gets and saves the system current time in nanoseconds if( ! paused and new_point_added ) { display_strip_chart(); update(); } };
That does not include performance monitoring that shows it is called at 60 Hz. The display looks as though it is getting painted with two screens: the expected points and a blank screen, alternating between the two. A very fast flicker.
display_strip_chart() { // showing the essence only glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glClear( GL_COLOR_BUFFER_BIT ); // white background glColor3f( 0.0, 0.0, 0.0 ); glBegin( GL_LINE_STRIP ); for( i = oldest, i <= newest; i ++ ) glVertex2dv( gl_vector[i].p); // circular buffer, but all that code is omitted. glend(); glFlush(); glMatrixMode( GL_PROJECTION ) glLoadIdentity(); update(); }
gl_vector is declared as:
struct gl_point { GLdouble p[2]; }; // p[0] = x which is time, p[1] = the Y value plotted. std::vector< gl_point > gl_vector;
The strip chart does show all the expected points and does scroll as desired. But it flickers badly.
What code is needed to implement double buffering? -
Hi,
What version of Qt are you using ?
On what platform ? -
Get rid of the update() calls in your paint methods. They are redundant. Also read the section about threading in QOpenGLWidget.
-
@Kent-Dorfman
We are using Centos Linux, version 7.
Unfortunately, (very) we are using Qt3. That is something I cannot overcome. A number of people have done Qt work here but most have moved on and I am the first to use OpenGL within Qt in a Linux environment. This is my first exposure to both of them.
I removed update() from everywhere but paintGL(). Deleting it from there stops all the QGLWidget updates while everything else seems to be fine.Is there something I could look at to see how often Qt is doing a update/paint/draw? Just maybe that would provide a clue.
-
if it is Qt3 then I cannot be much more help. Probably would have been a good idea to mention that in the initial post. Good luck!
As a test you might port your code to Qt5 just to test whether the problem is version specific. It is also sometimes beneficial to be able to show when you run up against a wall in legacy software and can justify that it won't get fixed without an update to a supported platform.
-
Ouch... Then you should start by running the Qt OpenGL examples to see if they are running properly. This should rule out graphic stack related problem.
It should also give you some hints about how to implement custom QGLWidget based application.
-
@SGaist I did implement the example GL application in the book “C++ GUI Programming with QT3” It worked rather well, was very smooth. As I look at the strip chart app and from a post on the Khronos forum, it occurs to me that maybe it is really double buffering. The screen appears to alternate between a blank screen and my drawn data. I don't know how to access the "other" buffer.
Yes I understand about Qt3 being really old. I appreciate your replies just the same. Thank you. -
First thing I would do is not call update from paintGL. You shouldn't need that.
Can you start from one of the working example and there implement just your drawing in there ?
-
@SGaist When paintGL() does not have update(), nothing will paint. paintGL() gets called one time on startup and never again. Still, following your concept I worry that there is something I am missing in this whole concept. I will continue thinking on it and trying new things as I think of them.
I don't know if I can put the GL widget from the strip chart into the demo app. I will look at that possibility. -
My suggestion is to rather change the rendering code of the example step by step to become your chart rendering.
-
I have apparently solved the flicker problem. update() was removed from everywhere except paintGL(). That one does need to be tickled on a regular basis. Once done, paintGL() runs at 60 Hz. I do not completely understand how this works. Maybe as I continue working this the light will brighten.
I created an update_glortho() which makes a system call to get the current clock time and calls GLortho(), the openGL function that sets all the clipping. That controls the vertical scaling and moving the chart according to time. Using that means the app does not do any explicit scaling. The replies from SGaist were instrumental in getting my focus in the right place. And it does appear that Qt is handling the double buffering behind the scenes.
Now I know a bit more about graphics and quite a bit more about how versatile Qt and OpenGL are.Thank you for your time and patience.