views:

1092

answers:

3

I want to make an opengl application that shows some 3d graphics and a command-line. I would like to make them separate threads, because they both are heavy processes. I thought that I could approach this with 2 different viewports, but I would like to know how to handle the threads in opengl.

According to what I've been reading, Opengl is asynchronous, and calling its functions from different threads can be very problematic. Is there a way that I could use to approach this problem? Ideally, I would like to draw the command line on top of the 3d graphics with some transparecy effect... (this is impossible with viewports I guess)

Is important that the solution is portable.

Thanks!

+1  A: 

You can't do it with 2 viewports.

Each OpenGL context must be used from the same thread in which it was created.

Two separate window handles, each with their own context, can be setup and used from two separate threads safely, but not 2 viewports in one window.


A good place to look at ideas for this is OpenSceneGraph. It does a lot of work with threading to help try to speed up handling and maintain a constant, high framerate with very large scenes.

I've successfully embedded it and used it from 2 separate threads, but OSG has many checks in place to help with this sort of scenario.

Reed Copsey
Then I will have to take a look inside OSG... I certainly don't want to embed the whole library for this functionality... thanks!
alvatar
For the most part, it's just a matter of making sure that you create the context on a thread, and use that thread for every single OGL call to that window/context. As long as you don't call any OGL calls using that context from a different thread, you'll be okay.
Reed Copsey
+2  A: 

Its possible you can achieve what you want to do using Overlays.
Overlays are a somewhat dated feature but it should still be supported in most setups. Basically an overlay is a separate GL Context which is rendered in the same window as another layer, drawing on top of whatever was drawn on the windows with its original context.
You can read about it here.

shoosh
+1  A: 

I think, rather than trying to create two threads to draw to the screen, you need to use the MVC pattern and make your model thread-safe. Then you can have one thread that grabs the necessary info from the model each frame and throws it on screen, and then two other threads, one for the graphics and one for the command-line, which manage only the model.

So for instance, you have a Simulation class that has your 3D graphics stuff, and then a CommandLine class that has your command line. Each of these classes does not use OpenGL at all; only manages the data, such as where things are in 3d-space, and in the case of the command-line a queue of the lines on-screen. Then the opengl thread can query thread-safe functions of these classes each frame, to get the necessary info. So for example, it grabs the positions of the 3d things, draws them on-screen, then grabs the lines to display on the command line and draws them.

Ricket
yes... but in very low frame rates (which are likely to happen), the command line becomes unmanageable, so you cannot easily issue the command to kill the model or reduce its complexity.
alvatar
Make sure both threads sleep no matter what, so that one doesn't starve the other. Handle input either through a buffer (in another thread) which can be polled in each of the two threads to find relevant keypresses, or just have the command line check input itself. I think it should run smooth then.
Ricket
Also, I believe threads can have priority; so you can make the command line thread a higher priority. The main thing is that the command line thread handles input, because it can run smooth while the model thread is running slowly and still be able to handle new commands and such.
Ricket