I am attempting to create an application which uses Boost::Thread in order to complete a task. I need the program to load data in the background while displaying the data which has currently been loading.
Currently I have a list of Objects which all have Update and Render methods. In the update function if something needs to load I am attempting to create a thread for the loading. This way I can continuously render without delays from loading. The render only needs to be blocked from occurring when the data is finished loading and being setup for use (binding a texture in OpenGL)
If I want to create a thread of the Update function in Object I have to declare it as a static method correct? Since static methods are unable to access the non-static members of the Object how do I block the Render method when I need.
I thought this was where I would use a scoped_lock mutex. Everything I have attempted so far does not seem to work. Making the mutex a member of the Object does not work as the static method does not have access. If I make the mutex static outside of the class I'm confused as to how that will work with multiple update threads running at once. I'd assume things would become very confusing in that situation.
Thanks for all your help.
//Code taken from Object::Update()
if(discardLevel != prevDiscardLevel)
prevDiscardLevel = discardLevel;
//LoadTexture is a static method of Object
boost::thread updateThread(boost::bind(&LoadTexture, texture, glTex, discardLevel));
//Code taken from Object::updateThread()
void Object::LoadTexture(Texture* Tex, GLuint &texData, int dLevel)
Tex->LoadTexture(dLevel); //Load specific textures data
glBindTexture(GL_TEXTURE_2D, texData); //Bind the texture for use
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Tex->GetWidth(),
Tex->GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, Tex->GetTexture());
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//Code taken from Object::Render()
glTranslatef(transform.x3y0, transform.x3y1, transform.x3y2);
Instead of creating what you're now discovering to be a spaghetti of threads for each object, I'd look into batching the render calls and not calling render on each object. I think you'll find that threads are used in games for things like loading levels, playing music, etc. Large tasks that don't require much synchronization.
I can batch render calls. That's no problem.
Originally Posted by medievalelks
My issue is loading content in the background and still continuously render. For what I am doing I can not preload everything.
One rule of multithreading is that no object can protect itself from access by multiple threads. Generally, the code (or object, or whatever) that acts on an object A needs to also protect object A. This means, in practice, that the code will lock some mutex before acting on the object.
One way to handle the problem of loading and rendering in separate threads will go something like this (in pseudocode)
The point is that the loader thread gets data from somewhere and copies it to a location (eg a queue) that can subsequently be accessed by the rendering thread. The operation of copying to or from that "location" (by either thread) must be protected by a mutex. The render thread repetitively retrieves data from that location. Once the rendering thread has data to render, it renders it.
// loading thread
while (loading) // loading will be set to false when no more data to load
// rendering thread
while (rendering) // rendering will be set to false when nothing to render (or when the display closes down)
There are all sorts of enhancements to this scheme to optimise performance. But the rule of thumb is that the time spent with a mutex locked by any thread must be minimised, and the mutex must be grabbed by any thread accessing the shared "location". That is why the operation of loading data (eg from file) and rendering it (eg to screen) normally will be unprotected by the mutex -- if everything is protected by the mutex, may as well do everything sequentially in one thread.