I’m developing an application that has many different devices and assets to initialize, which takes about 10 seconds in overall.
With ofThread it is possible to initialize everything (devices, images and videos) in background except the 3D objects that are also imported at start up.
So far I’m not figuring out how to solve this problem, once I know that OpenGL is not multi-threaded and the texture cannot be created in a separate thread.
How can I load a 3D model in a separate thread? Is it possible?
Thank you in advance.
it’s not possible to load gl resources on a different thread what you can do is not load them in setup and instead load them in update one for each update call till all of them are loaded. at the same time while they are being loaded you can show a progress bar so the application doesn’t seem to be hanged
Thank you for your answer, it’s a good tip.
Nevertheless, my idea consisted in having an animated circle loader bar and with your suggestion it becomes impossible once the animation FPS would be controlled by the speed that each 3D object is loaded.
I appreciate a lot your help and is the best I have, so I’ll take it.
Just for curiosity, a video game, loads the 3D assets at start up and they have animated loaders as I would like to.
How do they do it so?
what takes usually more time is loading things from disk (or sd cards in mobile) to cpu memory, then loading those resources into video memory is not that slow so you can load things into memory from a thread and then in update check when they have been loaded and upload them to video memory.
another option is to use the native gui elements to show the progress bar if you are in mobile which usually run in their own thread.
there’s ways to load textures and even vbos from a different thread using things like pbo’s but i think it’s over complicated just to be able to show a circle spinning
Haha… I agree with you obviously that it’s over complicated just to be able to show a circle spinning, but that was just a picture what I really want to do. To be more precise I would like to have a circle loader with some sentences flying with welcome (like in MacOSX) and loading status messages, like “Initializing GPS” and “Loading assets”.
I know that what takes much more time is to read data from disk to cpu memory, cause I do this trick with ofVideoPlayer. Firstly I create a texture in the main thread, then I load the data to memory and send each frame pixels on update to the graphic card (ofTexture).
My problem is that I don’t know how to do it with 3D objects, cause they can have multiple textures and I can’t access the pixels in memory each frame to send to the graphic card.
Do you know about any sample code that loads the data first and then upload to video memory?
Thank you very much for your time and support.
with ofxAssimpModelLoader you can load the 3d model in an ofBuffer and then load the model using that buffer instead of passing the path but that will only load the model from disk not every texture so it probably won’t help that much unless your model file is really big
the only way to load every resource in a different thread would be to modify ofxAssimpModelLoader to do it
It will help for sure. My application loads 5 3D objects with around 8 and 10M each.
I’ll also take a look to the add-on and try to read the textures to a buffer too and apply them later, that would be great for further projects.
I’ll let you know my results.
Thank you once again.
Just a quick update. I only had time to get back to the project today and basically so far, I hacked the assimp add-on and it is loading either the 3D object file (.dae in my case) and the texture image in a loader thread, mapping the image into a texture and set it as the 3D object texture.
It works well and the objects are drawn as expected but I had to load the model, which basically means, create the vertexes, meshes and vbo in the main thread, otherwise it won’t work. I took some time to read about the topic and there are a lot of people that suggest to use multiple context as described in the following sentence.
“The basic strategy is to build an OpenGL context for each worker thread that will do loading such that the contexts share objects (display lists, etc.) with the main rendering thread’s OpenGL context.”
My question is : does OpenFrameworks have some high level methods to do this or I will have to implement it from the scratch?
I would also like to ear your opinion about this approach, if you don’t mind.
yes there’s other options for some kind of resources like textures with pbos but i think another context is the only thing that works for any kind of resource.
and no OF doesn’t have any high level call to create a new context you need to use OS level calls to open it
Thank you for the feedback.
Sorry if this is a silly question but I can’t find a proper answer.
When related with shared contexts it is always mentions that it works for any kind of resource, as you also mentioned.
What resource truly means? Are vertexes and meshes resources?
I followed this tutorial but with no success so far :
If I call the hacked loadModel (no texture loading) method inside the thread even with the loader context set as active it won’t work and that is why I’m asking if vertexes, meshes and vbos are considered resources.
in GL terms, vbos, textures… but yes vertices are stored in meshes in OF which are uploaded as vbos usually
i think all data can be shared among contexts what you can’t share are objects like fbos or shaders which don’t contain data
Thanks for all your help.
Now its up to me to make it work.
I’ll let you know and share the code if i succeed.