Currently i am starting my engine all over again, and now i want to make it a bit better
Well, one thing is, that i want to have a console, like Half-Life, which shows the process when a level gets loaded.
Now i have one problem (i think): My main-thread creates the OpenGL window and renders everything (ie. the console).
Another thread loads all level-data.
However this loading-thread also loads textures and creates the VBOs. But as far as i know OpenGL is not thread-save.
I mean, i could make a call to MakeCurrent (or whatever the function is called) to use the OpenGL context in that thread. But since the loading takes several seconds, the drawing thread will make the context quite often “current” for itself.
Could this make problems? From what i read in books, it shouldn´t work. However up to now my loading thread loads one texture, without making the context current, at all, and it doesn´t complain about any problems.
Will i run into problems, or does it just always work, as long as i don´t render anything (and only load stuff) ?
I am a bit confused about how to use OpenGL properly with more than one threads.
You don’t say what platform you’re running on, but my understanding is that on most platforms it’s OK to make OpenGL calls to the same context from different threads as long as those threads never issue calls simultaneously. That is, you need to use a mutex to ensure that your OpenGL calls are serialized.
Another possibility is to have your loading thread signal your drawing thread when the image for a texture is ready for upload, then have the drawing thread upload the texture. Since texture upload should be reasonably asynchronous with the CPU if the texture’s in the right format, that might be an easier option.
U should use GLFW for all plateform specific code and threads… http://glfw.sourceforge.net
This is simply not true. You always need to make the context current in the calling thread, and I have no idea why it works without a glXMakeCurrent or equivalent.
Furthermore, texture uploads to the OpenGL driver is not asynchronous for the simple reason that you could potentially change the pixel array right after the glTexImage2D call. This is the reason things like VBOs even exist.
The mem->mem copy from application to driver will be synchronous, but hardly time-consuming for a normal-sized texture. The actual upload to the card should be async (though I guess that usually happens at a later time anyway…)
If you’re on a Mac or certain Mesa drivers, you can use GL_APPLE_client_storage to avoid the app->driver copy
why do you have different threads for this anyway?
My first idea was to have different threads, so that my loading routine does not have to do any rendering (of the loading screen/console).
But, well, now i changed my mind. I don´t use a seperate loading thread anymore. It is a too complex thing, which doesn´t give me any real advantage.
I’m astonished that so many misinformations about multithreading with OpenGL floats around. Of course it is multithreading safe! (BTW, the GLAUX lib is not!)
It’s all explained in the manual of wglMakeCurrent:
"A thread can have one current rendering context. A process can have multiple rendering contexts by means of multithreading. A thread must set a current rendering context before calling any OpenGL functions. Otherwise, all OpenGL calls are ignored.
A rendering context can be current to only one thread at a time. You cannot make a rendering context current to multiple threads.
An application can perform multithread drawing by making different rendering contexts current to different threads, supplying each thread with its own rendering context and device context."
You can load textures in another thread with a different context on the same window in the background and use it later in another thread for your console rendering. All you need to do is to share the texture objects with wglShareLists before.
Though I would’t use multithreading if I can get the same result/performance without.
[This message has been edited by Relic (edited 08-01-2003).]