Multithread question...

Hello,

I have a simple opengl window to load and to render a model.
And I wanted to do an infinite render loop in a separate thread.
I have only one rendering context.
The minimal scenario is :
[ol]
[li]Opengl is initialized and the model is loaded in the application (i.e. the main thread) [/li][li]I call my render() function in an infinite loop in a thread (using a BackgroundWorker) [/li][li]The application is closed in the main thread i.e. stop the render thread and free opengl resources [/li][/ol]

My question : is it possible to do opengl calls in the main thread, then in the render thread, then in the main thread, etc ?
NB : to go from the render thread to the main thread, the render thread is canceled (and restarted to render again).

I thought that I had only to call wglMakeCurrent(hdc, RenderingContext) when using the RC in a thread and to call wglMakeCurrent(NULL, NULL) to unsure that the RC is current only in one thread.

As I have got errors I ask the question to know if I have to change the application design or to search my mistaskes.

Thanks for your advices

Sounds like you’re on the right track. A context can only be current to one thread at a time, so the unbinding it from the prior thread (MakeCurrent(NULL)) may not be necessary, but I’d do it anyway.

Thanks for your answer.
So I searched in my code (other than openGL).
I am not sure that the BackGroundWorker is the right tool to start/cancel/restart my thread.
So I will try with a “real” thread.

Thanks.

This is not very wise organization. Why don’t you organize all rendering in a single (renderer) thread, load resources in the separate thread and leave the main thread for other stuff?

Hello Aleksandar,

Thanks for helping.
I wanted to have the maximun framerate. In single thread I had to use a timer (DispatcherTimer in my C# window) to allow time to mouse events.
So I tried to put my render() function in a thread.
This function is a member function in my COpenglRender class. It can access to the member variables (matrices, etc).
Some mouse events do not require to stop the thread : rotation, translation ; they update the member matrices.
Few events stop the thread :

  • when the window resizes to call glViewport
  • If I do picking to call glReadPixel

As I never used thread before I thought that it will be simple to start a thread to run a function.
In fact I am now learning how to synchronize threads…

Do you think that it is not the correct approach ?

I’m not familiar with C#. Maybe it would be useful to take a look at “3D Engine Design for Virtual Globes”, chapter 10 (Exploiting Parallelism in Resource Preparation). Authors did an excellent job and they used C#.

Apart from that, it is highly recommended to confine rendering to a single thread (your COpenglRender class). That thread should be managed by sending messages from the other threads (commands, signals that the resources are loaded and ready, requests, etc.). The best synchronization is by sending messages.

There is no benefit in splitting OpenGL calls into several threads since the parallelism is impossible. Maybe you could benefit from sending data to graphics card during rendering, but it is possible only on some NVIDIA platforms and under certain drivers, so the usage is very limited.

Thanks for your advices.
It is very useful to learn the right things.

Edit : I had a look to the chapter 10 that you recommanded. It is exactly what I need : explanations with code sample to see how to do in practice. :slight_smile: