Hello there!

I could use a little help with an offscreen rendering procedure that needs to run in its own thread. I have already programmed a function that uses OpenGL commands to render a scene and to read the color and depth buffers into local buffers. However, right now this is all inside the draw() function of a QGLViewer and so the offscreen rendering happens whenever the gui is drawn. I need to figure out a way to separate the offscreen rendering into its own class that would run as a separate thread at a configurable frame rate.

After some research I can see that there are split opinions whether it makes sense to pursue this goal at all. Some argue that all OpenGL rendering should be in one thread, some argue that they don't, both giving arguments that seem legit. In my case, the configurable frequency is important so I would like it to be independent from the gui thread. On the other hand, this offscreen rendering, which is really an RGB-D camera simulator, is a data acquisition process that belongs into the deepest layers of the software and is as far from the gui as Sydney from New York. It sends a cold shiver down my spine to think I would have to embed this data pipeline into a gui component.

This was my first naive attempt:

Qt Code:
  1. // A thread object just to run things.
  2. class SimulatedCameraThread : public QThread
  3. {
  4. SimulatedCamera simulatedCamera; // This is actually a QGLViewer widget
  5. void init();
  6. void run();
  7. };
  8.  
  9. // Initialization function executed once after construction.
  10. void SimulatedCameraThread::init()
  11. {
  12. simulatedCamera.init();
  13. simulatedCamera.show(); // urgh!
  14. }
  15.  
  16. // The loop of the QThread.
  17. void SimulatedCameraThread::run()
  18. {
  19. // Run in an infinite loop and keep rendering.
  20. while (true)
  21. {
  22. simulatedCamera.update();
  23. msleep(100); // Here is where I can configure the frame rate.
  24. }
  25. }
  26.  
  27. // A widget class that encapsulates the OpenGL frame grabbing.
  28. class SimulatedCamera: public QGLViewer
  29. {
  30. void init();
  31. void grab();
  32. void draw();
  33. };
  34.  
  35. void SimulatedCamera::init()
  36. {
  37. glewInit();
  38. }
  39.  
  40. // Grabs a frame using OpenGL and writes it into memory.
  41. void SimulatedCamera::grab()
  42. {
  43. glMatrixMode(GL_PROJECTION);
  44. glPushMatrix();
  45.  
  46. // Bunch of OpenGL code that grabs a frame into a buffer.
  47.  
  48. glPopMatrix();
  49. glPopAttrib();
  50. }
  51.  
  52. // Override QGLViewer.
  53. void SimulatedCamera::draw()
  54. {
  55. grab();
  56. }
To copy to clipboard, switch view to plain text mode 

I derived a class from QThread and in its run() method I start an infinite loop where update() is called in succession with a sleep. With this I was aiming at simulating what the gui thread would do: calling update() on the widget whenever it needs to be redrawn. The simulated camera is inside the QThread and derives from QGLViewer, which itself is a subclass of QOpenGLWidget and so we can treat it as if it were a QOpenGLWidget for all purposes. By overriding draw(), I have control over the rendering. All of this works surprisingly well, were it not for having to call show() in the init() function of the QThread.
I found that if I don't call show(), update() does nothing, presumably because the widget is not visible. If I do call show, weird things happen when the gui opens, but it recovers and tadaa, the offscreen rendering works like a charm.

Now, guys, please, what do I do to get rid of the show()?