OpenGL & Multithreading

Started by
6 comments, last by GKW 15 years, 10 months ago
Hi all I would like to load my textures and display lists in background within a separate thread. The OpenGL context is created in the main thread. But if I use any function to load textures or DLs, they all fail. This is probably because the context is in the main thread and other threads does not have a valid GL context. Does anyone know a solution to solve this problem? Can I switch the context or make the context valid for any thread? thx for your suggestions
------------------------<< deltasoft games >>Homepage: http://www.deltasoftgames.ch
Advertisement
You could create a separate context that shares resources and load them on that context. But whether that is successful or not depends on the hardware/drivers. The older the hardware/driver the less likely it is to work on multiple threads. You will probably be better of doing all the disk IO on a background thread and creating the textures on you main context. The disk IO should be the slowest part of loading a new texture.
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson
well, the disk I/O is not the problem, this works finde. but if load (compile) a display list with a big object, this takes a few ms and if i do that in the main thread, the player would notice that. well, this i can solve with vbo, because initializing a vbo is much faster than compiling a DL.

but i have still the problem with textures. when the thread has loaded all the data from disk to the RAM, i have to create the texture with GL functions which copies the data into video RAM. if i have large textures and load many of them in the main thread, the player will again notice that because the main thread will stuck for a moment.

the problem with OpenGL is (as far as i know) you can only have one thread with the current context (wglMakeCurrent()) and even if i switch the context in a other thread, the GL functions fail again. I don't know how OpenGL manages contextes with threads but i can't find a solution for that.

any other ideas...?
------------------------<< deltasoft games >>Homepage: http://www.deltasoftgames.ch
Quote:Original post by LPVOID_CH
but i have still the problem with textures. when the thread has loaded all the data from disk to the RAM, i have to create the texture with GL functions which copies the data into video RAM. if i have large textures and load many of them in the main thread, the player will again notice that because the main thread will stuck for a moment.

You can split the upload over several frames - both loading in individual mipmaps separately, or using glTexSubImage to upload a portion of a larger texture.
Assuming windows:

//create a second context
hglrc = wglCreateContext(mainWindowDC);

//share lists. this makes any gl objects created in the new context also available in the old one
wglShareLists(mainWindowContext, hglrc);

//from inside your second thread, activate the new context
wglMakeCurrent(mainWindowDC, hglrc);
Multiple threads and OpenGL (and DirectX likewise) almost certainly leads to desaster, don't do that.

Instead of uploading textures in a different thread, use pixel buffer objects (PBO). That way, the data is uploaded asynchronously, using as much bandwidth as the hardware has available at a time. It won't block, it won't burn extra CPU cycles, and it'll work reliably without any more synchronisation needed.

The nice thing about buffers (VBO and PBO likewise) is that it just works "magically".
i already used vbo's but did nothing with pbo. i'll try this with pbo's, i think this is a good way to solve the problem.

thx for your answers!
------------------------<< deltasoft games >>Homepage: http://www.deltasoftgames.ch
The problem I noticed with Shared Lists is that if you create a texture in the DLL, it will give it a texture number, say, number 1. If you create a texture on the another thread and bind it, it will not give you number 2, rather it will give you 1 again.

Now, I don't know if this is just my hardware (its fairly new <1yr) or my drivers. But when I tried using shared lists, I had nothing but headaches.
------------Anything prior to 9am should be illegal.
wglShareLists is supposed to be used before you've created any textures, vbos, display lists, etc. If you wglShareLists after creating a texture the results are implementation dependent.
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson

This topic is closed to new replies.

Advertisement