PDA

View Full Version : Multithreading: Loader image while loading scene assets



zaldivar.alvarez
07-08-2016, 01:48 AM
Hi,
I'm trying to learn multi-threading programming with C++ and for that I was trying to implement a loader image while some assets are being loaded in an OpenGL scene.

The thing is, that I have only 2 threads: main and a sample one and this simple multi-threading code works fine (at least from the point of view of the CPU). However, my problem is that OpenGL seems not to be rendering whatever I created in the extra thread. For a better explanation of what I am doing I'll let you see my code here:

- First, the function that will run in a separate thread:



void loadingWork(std::atomic<bool> * signal, GameObjectManager* mngr)
{
mngr->GenerateGameObjects();
(*signal) = true;
}

// The GenerateGameObjects function encapsulates all the procedure of creating VAOs, VBOs, Textures. I mean, it sends all the required data of the models to the GPU.


- Second, the thread creation (located in main, after initializing my window, camera and shaders)



std::atomic<bool> threadFinished = false;
std::thread objectsGenerationThread(loadingWork, &threadFinished , gameobjectManager);
GameObject* loading = gameobjectManager->CreateOneGameObject("UILoading");
renderManager->GetRender2D()->Use();
frameRateController->SetTargetFrameRate(60.0f);
while (!threadFinished )
{
frameRateController->FrameStart();
renderManager->Clear();
loading->GetDefaultShader()->Enable2D();
loading->UpdateAllComponents();
loading->GetDefaultShader()->Disable2D();
SDL_GL_SwapWindow(mainWindow);
frameRateController->FrameEnd();
}
objectsGenerationThread.join();
loading->DestroyAllComponents();
delete loading;


- And that's it. This is the first time ever I tried multi-threading in an OpenGL program. I am using SDL to create my window and just in case I'll let you see this code (which is at the very beginning of my main)



if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Failed to init SDL\n";
return false;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
mainWindow = SDL_CreateWindow(programName.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL);
if (!mainWindow)
{
std::cout << "Unable to create window\n";
CheckSDLError(__LINE__);
return false;
}
mainContext = SDL_GL_CreateContext(mainWindow);
SetOpenGLAttributes();
SDL_GL_SetSwapInterval(1);
glewExperimental = GL_TRUE;
glewInit();


I am afraid that my issue has something to do with the OpenGL contexts, but not sure.

Hope somebody can give me some sight on this. I will appreciate any help!


Have a good one, guys.

---
MJ

GClements
07-08-2016, 04:01 AM
You need a context per thread, those contexts need to share data, and you need to make the context current in the thread where it's used.