Loading screen using thread (multiple contexts)

Started by CreativeMD, March 09, 2015, 15:45:14

Previous topic - Next topic

CreativeMD

Hello,

i'm trying to add a loading screen to minecraft, this screen should show up while the game is starting (loading textures etc.).
So i have to have one context for each thread. Never did something like this before and having problems to do this.

What i have tried so far:

Before the loading screen thread is started do:
Display.releaseContext();
and this in the started thread:
draw = new SharedDrawable(Display.getDrawable());
draw.makeCurrent();
Using this way both can load, but the display is not bound to the thread's context, so as a result the window freeze (no loading screen).

If i add something like this to the thread:
Display.makeCurrent();
the game crashes as soon as the game tries to use the GLContext for loading textures etc.

What i'm doing wrong? This cannot be that complicated. I know that multithreading is difficulty using LWJGL, but this is just a simple loading screen (a background texture and some texts).

Thanks for helping previously  ;D

spasi

See this demo, it's an example of how to do this in LWJGL. Afaict, the difference from what you're doing is that the SharedDrawable must be created on the main thread, then made current on the secondary thread. Also, you shouldn't ever need to call Display.releaseContext().

broumbroum

However, if you intend to have a "loading screen", so called, then there is at least the option to make use of asynchronous buffer transfers as described in OpenGL books. See for instance section 28.6 http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf . This also describes Multithreading and Shared Contexts. All code presented in this article is reasonably portable to LWJGL.

My advice is to use working threads for tasks like loading texture files into direct buffers (BufferUtils, NIO) which you can upload to the OpenGL buffers from within the single rendering thread (glBufferSubData).

This avoids the use of Shared OpenGL Contexts whose advantages arent obvious (see from article above), respectively for the OpenGL drivers specifications. Both NVidia and AMD's drivers arent much eager in these features.

CreativeMD

It is not that easy to find out, how to do it.
I tried to make something like this:

main thread:
Display.create((new PixelFormat()).withDepthBits(24));
shared = new SharedDrawable(Display.getDrawable());


loading screen (another thread):
mc.shared.makeCurrent();

while(active)
{
   Display.update();
}


But the window freezes, doing i'm something wrong? I'm not rendering anything yet, but i don't think this is necessary.

spasi

Display.update should be called on the main thread, not the secondary.

CreativeMD

What??? But i can't add this to the main thread. Is there a way to update the screen not in the main thread?

spasi

You cannot. If you want to render and display stuff from two different threads you have to create two different windows. LWJGL 2.x does not support that, but LWJGL 3 does (Minecraft uses 2.x).

CreativeMD

Oh, thanks for helping. I would have spend years for this ;D