nlraley's picture

Exception loading texture from background worker thread.

I currently am loading the tiles for the background as the user pans their view in my world in a background worker thread.

The background worker thread loads the Bitmap file from disk, sets the BitmapData, and locks the bits.

Then upon completion of this thread I call a method from the main thread, which has the OpenGL context, to load the texture from the bitmap that was loaded in the background worker thread.

Here is the load texture call:

public void LoadTexture()
    bool tryLock = Monitor.TryEnter(this, 10000);
        if (tryLock)
            if (BmpLoaded)
                GLTexture = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, GLTexture);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, BMPData.Width, BMPData.Height, 0,
                    OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, BMPData.Scan0);
                Loaded = true;
    catch (Exception e)
        //  Call PulseAll to wake up any threads waiting for lock on queue
        //  Exit the TryEnter

This same code works perfectly fine for textures loaded on start up. But when the user pans their view and it starts to load additional textures along the outside of their POV, I get an invalid parameter exception in the LoadTextures call above. Any ideas what might be causing this?


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nlraley's picture

I'd also note that it still isn't loading those textures either for some reason.

AmzBee's picture

I'm still getting to grips with OpenTK, but something that occurred to me after reading your post is that as far as I know OpenGL is not thread-safe, which means when you make a GL call outside of your main thread, all sorts of nasties can happen as your trying to call a context (that in the background worker does not exist).

Now considering what your after, something like the MakeCurrent() function does not really seem like it suits your needs, constantly switching the context to a background worker just seems the wrong way to do it. Instead perhaps you could have the bitmap load in the background thread, then call a delegate that passes the bitmap through to your main GameWindow thread where then the bitmap can be safely uploaded.

It's only an idea, but hope it helps!


Stupid_2D's picture

Isnt OpenGL a statemachine?
Can think of many problems when working with asynchronous threads.

Rather let your thread call the openGL stuff from the maintrhead.