Separating the Window into its own Thread

Started by codelyoko373, October 23, 2021, 02:49:44

Previous topic - Next topic

codelyoko373

This is likely a super amateur question so please excuse me. I am incredibly new to engine development and am looking to create a small demo game using LWJGL just for fun. Essentially, I have been following a few tutorials and they all don't really cover threading and process everything on the main thread. I thought it would be ideal to split the Window process from the actual main game so you can move the window smoothly around (When windowed) and have the game still run fine (I also thought this may of be what actual game engines do so thought it would be ideal to implement). Though attempting it, I ran into a number of issues with mainly trying to handle GLFW functions which would constantly go out of context. Also objects would completely disappear as I am handling/rendering the VAO's on the Game thread which would run out of sync with the Window thread (like you'd expect) meaning the window would clear and swap the buffer before everything was rendered. It kinda wasn't something I thought of as I was making the changes but I am unsure how to fix it, if I even can.

Especially with the rendering the VAO's issue, It has made me question if this is actually something I should do? Is it something I should bother implementing and figuring out? Or is it simply going to be more hassle then it is worth?

jakethesnake

Your main thread can init and do all opengl stuff.
Your logic thread/threads can do logic and render all vertex data into a buffer.

The main thread can check if the logic thread has rendered something, lock the buffer, upload it, then unlock the buffer, then swap. You can also do a round robin of buffers to avoid locks and sleep.

//volatile - variable will never be optimized by the hotspot, and its real value visible to all threads.
volatile boolean lock = false;

//only one thread at a time can access this
synchronised boolean lock(){
      if (!lock){
            lock = true;
            return true;
      }
      return false;
} 

LWJGL THREAD
INIT();

while(gameShouldRun){
      while (!lock())
         sleep();
      prepAndUploadBuffer();
      uploadBuffers();
      swapAndStuff();
      lock = false;
}

UPDATE THREAD

while(gameShouldRun){
      updateGame();
       while (!lock())
         sleep();  
      putRenderDataIntoTheBuffer();
      lock = false;
}



spasi

See the Vorbis demo for an example of how to do this properly. The most important thing to get right is handling events on the main thread, which is required by GLFW (due to limitations on macOS mostly). Rendering should happen on a secondary thread.

Not sure about your VAO trouble, but one common issue that people have is trying to share VAOs between OpenGL contexts. VAOs are NOT shareable between contexts.