Trying to load textures on seperate thread, cannot bind context.

I’ve been trying non stop for 2 days now and I’m about ready go insane over this problem. I’m trying to load textures on an alternate thread, allowing the main thread to display an animated loader to display progress. I’m aware of the issues this can lead to, but I’ve been reading around a lot (on this forum, mostly) and it sounds like it’s possible.

The problem I’m having, is that no matter what I do, when I call GLContext.makeCurrent() in my loader thread with my shared context, I get one of 2 errors.

Here’s a few things I’ve tried:
GLPbuffer buf = GLDrawableFactory.getFactory().createGLPbuffer( new GLCapabilities(), null, 1, 1, mContext);
mLoaderThread.context = buf.getContext();
mLoaderThread.start();

(mLoaderThread run())
mContext.makeCurrent(); -Error

Exception in thread “Thread-4” javax.media.opengl.GLException: wglShareLists(0x10000, 0x30001) failed: error code 0
at com.sun.opengl.impl.windows.WindowsGLContext.create(WindowsGLContext.java:136)
at com.sun.opengl.impl.windows.WindowsGLContext.makeCurrentImpl(WindowsGLContext.java:150)
at com.sun.opengl.impl.windows.WindowsPbufferGLContext.makeCurrentImpl(WindowsPbufferGLContext.java:102)
at com.sun.opengl.impl.GLContextImpl.makeCurrent(GLContextImpl.java:134)
at pixelgame.core.CLoaderThread.run(CLoaderThread.java:55)

GLContext context = canvas.createContext( canvas.getContext() );
mLoaderThread.context = buf.getContext();
mLoaderThread.start();

(mLoaderThread run())
mContext.makeCurrent();-Error

Exception in thread “Thread-4” javax.media.opengl.GLException: Surface already locked
at com.sun.opengl.impl.windows.WindowsOnscreenGLDrawable.lockSurface(WindowsOnscreenGLDrawable.java:157)
at com.sun.opengl.impl.windows.WindowsOnscreenGLContext.makeCurrentImpl(WindowsOnscreenGLContext.java:57)
at com.sun.opengl.impl.GLContextImpl.makeCurrent(GLContextImpl.java:134)
at pixelgame.core.CLoaderThread.run(CLoaderThread.java:51)

I’ve also tried making my loading thread a GLCanvas object, and giving it an animator the same way my main thread is created. Without Threading.disableSingleThreading(), this would work, but the loader would block the main thread. When I tried using Threading.disableSingleThreading(), it started throwing the first error again. I’ve also tried creating the shared context in my constructor directly after creating the canvas, but this led to the same errors.

Obviously I don’t know how to properly set up a shared GLContext and make it current on a thread. Any ideas what I could be doing wrong?

IMHO it’s much, much easier to keep all of your opengl calls on one thread and ignore the makeCurrent stuff, as it’s horrendously error prone and tends to uncover bugs and quirks in drivers.

You can still do all the heavy lifting (like reading the image off disk and decoding it into RGBA bytes) in a seperate thread, and just keep the texture upload in the gl thread. That’s pretty quick anyway, and if you have really big textures you can split them over multiple frames if you need to. This is what I do for texture loading and it doesn’t impact the framerate at all.

Alright Orangy Tang, I’m convinced. If it’s really that unsafe then I suppose I don’t want it in my applet. I managed to get some pretty decent load times using your method.

Thanks ;D!

+1, I do 3D model loading and texture loading on a separate thread and update a variable flag that tracks when they are done. I then force a canvas display update and it checks if that flag is set to then take appropriate action - such as creating 3D objects, binding the textures, etc.

+another, I do the same thing, as Orangy originally advised my long ago. :slight_smile: