loading textures in another thread

hello, i want to load additional textures at runtime. and since i dont want to interrupt the current render loop, i try to load them in a separate thread.

now textures can only be loaded in a thread where an opengl context exists, right?

how can i start another thread with the same opengl context?

thanks!

For best robustness on all platforms I would recommend you not try to create OpenGL texture objects on a background thread. You can use the TextureIO classes in com.sun.opengl.util to load the data for the texture in a background thread and create the Texture object from the TextureData in your rendering thread.

If you absolutely need to do the loading in a background thread, you have two options. One is to create a small pbuffer sharing textures and display lists with your main window’s context, make the pbuffer’s context current on your background thread, and load the texture there. Once that operation completes, that texture ID will be valid in your main window. The second option is to fetch the GLContext out of the GLCanvas and manually make it current and release it on your background texture loading thread. This will cause the rendering thread to block during the texture load operation though.

thanks and sorry for the late reply.

now i am getting back to this, and since i am getting small blockings in my render thread on the call of
myTexture = TextureIO.newTexture(myBufferedImage); (which has to be done in the rendering thread)
i think i will try to implement your first solution.

so i guess with pbuffer you mean PixelBuffer, but i did not find this in the jogl package nor in the java ones. how do i create such a pbuffer?

thanks a lot!

One point: are you properly calling Texture.dispose() on unused texture objects? Have you considered using Texture.updateSubImage() to update existing OpenGL textures’ contents (note that the texture has to be allocated at the correct size first)? It’s the creation of the OpenGL texture object which is the slow part of that call, so if you can preallocate them and have a cache you should be able to update their contents fairly quickly at run time. As you point out, those updates would have to be done on your rendering thread.

[quote]so i guess with pbuffer you mean PixelBuffer, but i did not find this in the jogl package nor in the java ones. how do i create such a pbuffer?
[/quote]
Call GLDrawableFactory.canCreateGLPbuffer() to see whether you can create one and createGLPbuffer() to actually create it. If you don’t have pbuffer support available you may be able to make a 1x1 undecorated Frame, put a GLCanvas in it which shares textures with your main one, and put it in one corner of the screen where it should be inconspicuous. You can then fetch the context out of the second GLCanvas and make it current manually on a background thread.

no, not yet.

[quote]Have you considered using Texture.updateSubImage() to update existing OpenGL textures’ contents (note that the texture has to be allocated at the correct size first)? It’s the creation of the OpenGL texture object which is the slow part of that call, so if you can preallocate them and have a cache you should be able to update their contents fairly quickly at run time. As you point out, those updates would have to be done on your rendering thread.
[/quote]
you mean, i could reuse existing textures which are not needed anymore for the new textures?

thanks, what does it depend on if i am able to create such a pbuffer?

this is how i do it now:
in my game, the player walks on a tile-based terrain, where every tile holds a specific texture and of course i am only rendering tiles which are inside of the camera frustum plus some overhead. now as the players moves, new rows and columns of tiles become visible. the textures for the new tiles are loaded in another thread and when they are readily loaded as TextureData i get them by doing
myTexture = TextureIO.newTexture(TextureData_FromOtherThread); ( i had that wrong in my previous post)
and this seems to be the piece of code where i get small blockings, since its the part which has to be done on the rendering thread.

important update:

i take everything back what i said about myTexture = TextureIO.newTexture(TextureData_FromOtherThread); is blocking the render thread.

it just found out, that even if i leave away that last step, my renderthread seems to block occasionally, so it must happen somewhere in my loading routine, which is running in that other thread.
and that’s the weird thing, in my understanding, since it is definitely running in another thread, it should not block the rendering at all.

btw, my textures are not coming from disk, but are merely generated on the fly by some drawing functions, but these functions are running in the other thread.

anyone got an idea what the problem could be?

You may be leaking texture memory in this case.

Yes, as long as they’re the right size. updateSubImage does not change the texture’s allocated size, only its contents.

Mostly how recent a version of OpenGL is on the user’s computer.