Textures and BufferedImage

We are trying to make something like XTrans (more or less) and we paint component in BufferedImage we then want to display
as textures on a GLCanvas. We use the Texture / TextureIO objects but we have very different performances according to the
BufferedImage type (we have it on MacOSx and windows on 3 different computers). With a TYPE_3BYTE_BGR we have something
incredibly fast (75 frames per seconds and more) but as soon as we add the alpha channel to have transparent BufferedImage
(for instance TYPE_4BYTE_ABGR ), performances fall to 15fps. What we do is very simple :

BufferedImage frimg = fr.getFrontImage();
TextureData frTextureData = TextureIO.newTextureData(frimg, false);
frtex[i].updateImage(frTextureData);
TextureCoords coords2 = frtex[i].getImageTexCoords();
frtex[i].enable();
frtex[i].bind();

gl.glBegin(GL.GL_QUADS);
gl.glTexCoord2f(coords2.right(), coords2.top());
gl.glVertex2i(0, 0);
gl.glTexCoord2f(coords2.left(), coords2.top());
gl.glVertex2i(fr.getWidth(), 0);
gl.glTexCoord2f(coords2.left(), coords2.bottom());
gl.glVertex2i(fr.getWidth(), fr.getHeight());
gl.glTexCoord2f(coords2.right(), coords2.bottom());
gl.glVertex2i(0, fr.getHeight());
gl.glEnd();

does somenone has an idea why alpha channel slow the update process so much ? can we do something ?

Fred

I’m not sure if it’s the problem you are encountering, but some formats are just plane faster than others.

Here’s an Nvidia document discussing some of the implications of just the component ordering, and I’ve seen similar documents discussing the different format types as well.

Hope it helps.

It’s true that some OpenGL texture formats are faster to upload than others, but I think what you’re encountering is conversion within the TextureIO classes of the BufferedImage data. Have you tried BufferedImage.TYPE_INT_ARGB_PRE (or even TYPE_INT_RGB instead of TYPE_3BYTE_BGR)? That should likely be the fastest option. Take a look at TextureData.java in the JOGL source tree. We should add more documentation to the TextureIO classes on what image formats are likely to be faster than others.

Out of curiosity, I had a look at the TextureData code. It seems that for 4BYTE_ABGR it goes through the slowest code path (createFromCustom). You have to do something with the data since OpenGL only supports RGBA and BGRA, not ABGR, but you can do this conversion much faster than via the image apis. I did this by grabbing the bytes directly from the DataBuffer and swizzling them in place.

If you can afford shaders, you can do the swizzling in fragment programs when you sample, that cost is definetly lower than doing it at init, but its a constant cost on a frame, so which is cheaper for you will depend on the application, but GPUs tend to have specialized swizzling hardware…

Edit: Just found GL_EXT_ABGR, maybe you could use that…

DP

darkprophet: There are issues with how the Texture classes are organized that currently make it not feasible to target EXT_ABGR. There’s a code path already in place but we don’t have an OpenGL context available to query whether we can actually use it, so it’s disabled.

pepijnve: Agreed that you could probably do the conversion faster than the imaging APIs. We did however want to avoid unnecessary code path duplication. Feel free to file a performance RFE in this area if your suggested approach yields very large speedups.

Thank you very much. I used the TYPE_INT_ARGB_PRE BufferedImage and could get high performances AND transparency on
my “rotating windows”
Here is a simple “hello-world” app using the jogl binding :
http://diamondspin.free.fr/dstour1-jogl/dstour1-jogl.jnlp

I just tested it on Mac Os X and Windows.
I still have to update the window content to refresh the texture

Thank you again

That’s a pretty neat demo. It looks like you’re already transforming some of the mouse events into 3D (or at least rotated / translated 2D) in order to detect when the mouse is clicked over the title bar. It would be cool if you could also interact with the radio buttons. Also, you need to add a more obvious way of quitting the demo. None of the keys I tried (escape, q, Q, Ctrl-Q, etc.) did it and I had to bring up the Task Manager and manually kill the process, which is not nice.