What is the proper way of using multiple context for multithreading in OpenGL?

by Makogan   Last Updated January 12, 2018 17:13 PM

I am trying to parallelize a program I have made in OpenGL. I have fully tested the single threaded version of my code and it works. I ran it with valgrind and things were fine, no errors and no memory leaks, and the code behaved exactly as expected in all tests I managed to do.

In the single threaded version, I am sending a bunch of cubes to be rendered. I do this by creating the cubes in a data structure called "world", sending the OpenGL information to another structure called "Renderer" by appending them to a stack, and then finally I iterate through the queue and render every object.

Since the single threaded version works I think my issue is that I am not using the multiple OpenGL contexts properly.

These are the 3 functions that pipeline my entire process:

The main function, which initializes the global structures and threads.

int main(int argc, char **argv)
{
    //Init OpenGL
    GLFWwindow* window = create_context();

    Rendering_Handler = new Renderer();

    int width, height;
    glfwGetWindowSize(window, &width, &height);
    Rendering_Handler->set_camera(new Camera(mat3(1), 
        vec3(5*CHUNK_DIMS,5*CHUNK_DIMS,2*CHUNK_DIMS), width, height));

    thread world_thread(world_handling, window);

    //Render loop
    render_loop(window);
    //cleanup

    world_thread.join();

    end_rendering(window);
}

The world handling, which should run as it's own thread:

void world_handling(GLFWwindow* window)
{
    GLFWwindow* inv_window = create_inv_context(window);
    glfwMakeContextCurrent(inv_window);

    World c = World();
    //TODO: this is temprorary, implement this correctly
    loadTexture(Rendering_Handler->current_program, *(Cube::textures[0]));

    while (!glfwWindowShouldClose(window))
    {
        c.center_frame(ivec3(Rendering_Handler->cam->getPosition()));
        c.send_render_data(Rendering_Handler);

        openGLerror();
    }

}

And the render loop, which runs in the main thread:

void render_loop(GLFWwindow* window)
{
    //Set default OpenGL values for rendering
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glPointSize(10.f);

    //World c = World();

    //loadTexture(Rendering_Handler->current_program, *(Cube::textures[0]));
    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();
        Rendering_Handler->update(window);

        //c.center_frame(ivec3(Rendering_Handler->cam->getPosition()));
        //c.send_render_data(Rendering_Handler);

        Rendering_Handler->render();

        openGLerror();
    }
}

Notice the comments on the third function, if I uncomment those out and then comment out the multi-threading statemnts on the main function (i.e single thread my program) everything works.

I don't think this is caused by a race condition, because the queue, where the OpenGL info is being put before rendering, is always locked before being used (i.e whenever a thread needs to read or write to the queue, the thread locks a mutex, reads or writes to the queue, then unlocks the mutex).

Does anybody have an intuition on what I could be doing wrong? Is it the OpenGL context?



Related Questions



Check if thread has OpenGL context

Updated June 28, 2016 08:05 AM

Multithreading problem in openGL?

Updated November 14, 2016 07:34 AM