Multithreaded mesh loading and 0xcc returned from glGenVertexArrays

Started by
6 comments, last by TheChubu 9 years ago

Hi again all.

I'm a bit of a n00b when it comes to multi threading but thought I may be able to take advantage of it for mesh loading using Assimp. Meshes are made up of sub-meshes, so I thought if I divided the number of meshes up between cores for scaleability and let the threads do their thing there wouldn't be a problem.

Reading from the Assimp Scene object isn't a problem, but the generation of Vertex Array Objects on the open gl side is an issue.


GLuint InitVAO(){
	GLuint VAO;
	glGenVertexArrays(1, &VAO);
	return VAO;
}

In the above case, when called from each thread I get 0xcc generated for each submesh. This is obviously bad! Is there something about opengl not being threadsafe that I don't know about? As I said, I'm a bit n00bish with multithreading so sorry if this is a facepalm-able question

Advertisement

When you create an OpenGL context, it's only active on the thread that you created it on. If you make GL calls on a different thread, they'll be using a different context (or an uninitialized one / no context if you haven't created or activated a context on that thread!).

Thanks. Is there any way of sharing a context across threads? I imagine if you create multiple contexts across multiple threads, then created resources will be available only on that thread i.e


//I create a VAO on thread1
glCreateVertexArray(1,&myVAO)

//I try to use the created resource in another thread,
//but openGL will get very upset and not know what I'm talking about as it
//is a seperate context
glBindVertexArray(myVAO);


Am I barking mad?

You can't use the same context in multiple threads at the same time. You can "release" a context and "bind" it to another thread but that obviously makes you unable to use it in the original thread. You can however use multiple contexts and have them share resources with each other wich is propably what you want.

https://www.opengl.org/wiki/OpenGL_and_multithreading

..and to add to what others have mention and by no means to insult your intelligence. This is one of the gotcha's when it comes to OpenGL, multiple context and multithreading and it seems like your understanding of GL context wrt to threads of execution is limited. I would forgo the multi-threading of the GL object creation for now and start with just threading the actual data loading itself first. Either approach is going to require a fair understanding of not only thread synchronization, but OpenGL object ownership and sharing etc. Multithreading is not as simple as just throwing some task on an thread or 2 and it just works, so just work on getting the non-GL resource loading first and then work on GL part after.

..and to add to what others have mention and by no means to insult your intelligence. This is one of the gotcha's when it comes to OpenGL, multiple context and multithreading and it seems like your understanding of GL context wrt to threads of execution is limited. I would forgo the multi-threading of the GL object creation for now and start with just threading the actual data loading itself first. Either approach is going to require a fair understanding of not only thread synchronization, but OpenGL object ownership and sharing etc. Multithreading is not as simple as just throwing some task on an thread or 2 and it just works, so just work on getting the non-GL resource loading first and then work on GL part after.

I definitely agree. It was an important lesson so I'm glad it only took about 40 minutes of coding to really discover this. With regards to the actual loading Assimp does all of that in via


Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(directory + fileName,flags);

and the parts I was trying to multithread depend on opengl object creation for buffers and textures. I don't really want to go through the tedium of "rolling my own" importer to parse various 3d file formats so I will have to make do with my code as it stands. Thanks!

VAO cannot be shared across multiple context, as far as I can remembered, same as FBO.

VBO and texture however, can be shared.

I found this link very useful when I worked on multi-thread with multi-context.

http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf

You could always load the mesh data into main memory from different threads, then hand the pointers to the OpenGL context owner thread and let that one do the GPU uploading.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

This topic is closed to new replies.

Advertisement