Search code examples
c++multithreadingopenglglfwimgui

Calling std::thread() around a function works differently


Is there any reason why this code here:

int main(int argc, char* argv[])
{

    Main::Init();
    std::thread worker(Main::Mainloop);
    worker.join();
    Main::Free();

    return 0;
}

should work differently to this code here:

int main(int argc, char* argv[])
{

    Main::Init();
    Main::Mainloop();
    Main::Free();

    return 0;
}

Noting that the Main class is defined as a singleton, here is the code: main.h

#pragma once

#ifndef MAIN_H
#define MAIN_H


#include "window.h"


#include "mainloop.h"


 

class Main    ///Singleton
{
public:
    Main(const Main&) = delete;
    Main(Main&&) = delete;
    Main& operator=(const Main&) = delete;
    Main& operator=(Main&&) = delete;



private:
    Main();


    static Main& Get_Instance();


    friend int main(int argc, char* argv[]);


    static void Mainloop();
    static void Init();
    static void Free();


};



#endif // MAIN_H

The first example above fails to initialise one ofGLFW, GLEW, and ImGui which are what I am using for my program. I was trying to split up the initialisation of the program but then i ran into this issue. When I dug farther I reached this point which doesn't really make any sense why it shouldn't work. Basically it either throws an exception or ImGui spams me with many errors during runtime saying:

failed to compile vertex shader!
failed to compile fragment shader!
failed to link shader program! (with GLSL `#version 460`)

yet the window opens up and I only get these during runtime with the thread example. Not with the other one.


Solution

  • All of those libraries in some way interact with OpenGL and therefore are very sensitive to what thread they're being executed on. The current OpenGL context is thread-specific; each thread has its own current context, and a context can only be current within one thread at any time.

    Creating a GLFW window creates an OpenGL context. If you then switch to another thread, that context will not be current in that thread unless you tell GLFW to make it current in that thread.