
Fast texture loading
Posted Friday, 6 November, 2009 - 20:08 by ebeckers inHi
I'm looking for the fastest way to load an image into a texture
At the moment I use 2 threads.
Thread 1 uses the C# Image.FromFile class to load the image into memory like this:
Bitmap _bitmap; BitmapData _bmpData; int _texture; void LoadImage() { _bitmap = new Bitmap(fileName); _bmpData = _bitmap.LockBits(new Rectangle(0, 0, _bitmap.Width, _bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); }
Thread 2 is the main thread which contains the renderloop.
It uses the GL.TexImage2D() to copy the image from memory into the texture.
void Render() { if (_bitmap != null) { GL.GenTextures(1, out _texture); GL.BindTexture(TextureTarget.Texture2D, _texture); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, _bmpData.Width, _bmpData.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, _bmpData.Scan0); _bitmap.UnlockBits(_bmpData); _bitmap.Dispose(); _bitmap = null; } // render the texture... }
However sometimes i need to load a couple of new textures and then the calls to GL.TexImage2D() are stalling the renderloop and so the FPS drops. Is there a better/faster way to do this? I read something about PBO's, but i think this is only helpfull if you need to update a texture with new pixel data and does not really improve the first-time loading.
Another option would be multi-threading so textures can be created and loaded into thread 1 while rendering takes place in thread 2. Is there any simple example based on GameWindow which shows how to do multi threading with openTK ?
Regards
Erwin


Comments
Re: Fast texture loading
1. Multithreading doesn't help you as stalling GPU pipeline by one thread will stop rendering by another.
2. PBO is really what you need. It's just a way to use async data transfer between GPU & CPU memory for textures.
Re: Fast texture loading
You can get multithreading to work by creating a second
GraphicsContextand loading the textures there. Contexts are shared by default in OpenTK, so you can use the texture from either context.You'll have to use SVN from trunk for that to work reliably, however (or wait for 1.0 beta 1). The code is trivial:
Once the loading is complete, you'll have to notify the first thread so that it can use the new texture.
1.0 beta 1 will also contain multithreading examples.
PBOs allow you to load data asynchronously from the same context and also work great - provided your driver supports them (i.e. you can forget about Intel cards).
Re: Fast texture loading
Hi
Thanks for you answer, i'm currently using the following code you suggested and this seems to work great.
One small problem however is that the 'hidden' window is not hidden. It becomes active in front of the
main window. Any suggestions would be welcome..
Re: Fast texture loading
This has been changed since 0.9.9-3 was released (the window no longer becomes visible automatically, in order to support this use case).
As a temporary workaround, you can set
Visible = falseafter creating the window.Re: Fast texture loading
Unfortunaly Visible=false; has no effect. The window stays visible and on top
(Note this is under ubuntu 9.10 and todays svn)
Re: Fast texture loading
Should be fixed in SVN rev. 2476 (window is not mapped until
Visible = trueis called).You need to call
ProcessEvents()forVisible = false;to have any effect.Re: Fast texture loading
Works great now
thanks for the quick fix!
However i still have 2 problems left:
1. Fullscreen mode is not working anymore when using shared contexts. If i put my main window in full screen, it stays in windowed mode
2. The shared contexts are not working under windows. Everything seems ok, no errors or exceptions but the textures loaded in thread #2 dont show when used from the renderloop in thread #1
Erwin
Re: Fast texture loading
Please file bug reports for those issues.
It would really help if you could test with a debug version of OpenTK.dll and attach the debug output to the bugs. (You can see this in the "application output" window in both Visual Studio and MonoDevelop, or you can create a debug trace listener as described here).
Re: Fast texture loading
I managed to get the sharedcontexts to work under windows by rearranging the order in which threads&contexts are created
Still fullscreen is a no go with shared contexts.
The debug output below shows that first the main (GameWindow) is created and set to fullscreen
After that the next NativeWindow is created with a new GraphicsContext on another thread
All looks good, however the GameWindow does not run in fullscreen mode
Re: Fast texture loading
Bug report please?
Seeing the issue in the bug tracker is a good motivation for fixing it (not to mention I will likely forget about the problem once this thread leaves the frontpage).