New TextureIO and Screenshot classes

This has been a long time in coming, but a new texture loader/writer framework was recently checked in to the JOGL workspace. The TextureIO and related classes are joint work with Chris Campbell from the Java2D team at Sun with input from Romain Guy from the Swing team at Sun.

TextureIO makes it easy to read in textures from disk and use them with OpenGL. It is flexible enough to support loading of textures in a background thread where an OpenGL context is not current, and then feed the resulting TextureData to OpenGL in your main rendering thread. It has support for reading back textures from the graphics card, optionally in a compressed format like DXTn, and writing them to files. Support for DirectDraw surface (DDS), SGI RGB, Targa (TGA), and all ImageIO-supported formats (JPEG, PNG, etc.) is included. Non-power-of-two textures are supported either via the OpenGL 2.0 extension or ARB_texture_rectangle. The TextureIO framework is pure Java.

There are two new demos in the jogl-demos workspace in the demos.texture package which show how to use the new APIs. The first is a simple loader and viewer for textures, and the second is a command-line converter which automatically compresses to DXT3 if possible. All of the other JOGL demos have been updated to use the new APIs rather than the specific loaders. Along the way a couple of bugs have been fixed in the demos’ use of textures which were hidden up until now.

The second utility which has also been a long time in coming is a Screenshot utility class which makes it easy to take a snapshot of the frame buffer or a pbuffer. There currently aren’t any demos of this class but it is pretty straightforward to use – one line of code at the end of your display() method to take a snapshot and write it to disk. The Screenshot class contains the fast screenshot function to Targa files contributed by Carsten Weisse as well as two other routines which take the screenshot to a BufferedImage and which save it to an ImageIO-supported file format.

Javadoc for the new utilities can be found in the browsable javadoc on the JOGL home page. The TextureIO classes will probably be moved into their own subpackage in a future build.

Please try out the new APIs and post with any comments. Hopefully they will make it easier to write compelling applications with JOGL.

Ken,
I am just a noobie but the new classes are great and they help to bridge the gap for people new to JOGL. One addition that might be useful is ALPHA values in the Screenshot. I know this is a minor issue, but I have seen few posts on the forum of people looking for a way to render offscreen with alpha values.
I have made a modified version of the screenshot to allow use alpha values. I am guessing the class would eventually use the type used in the drawable?
Jason

Thanks for the suggestion. Could you file a Patch with the Issue Tracker on the JOGL home page and attach your edits? You may need to be an Observer of the project to properly file and edit a bug.

I will do that what do I need to do to become an observer. Is there an approval process, or can I just set that up. I will look and see.
really the changes are very minor. I would assume you would want some way to make it adaptable in case you don’t need the alpha value you could save memory and possibly time.

Inside method readToBufferedImage I changed


BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);

to


BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);

And


   gl.glReadPixels(0, 0, width, height, GL.GL_BGR,
                    GL.GL_UNSIGNED_BYTE,
                    ByteBuffer.wrap(((DataBufferByte) image.getRaster().getDataBuffer()).getData()));

to


gl.glReadPixels(0, 0, width, height, GL.GL_ABGR_EXT,
                    GL.GL_UNSIGNED_BYTE,
                    ByteBuffer.wrap(((DataBufferByte) image.getRaster().getDataBuffer()).getData()));

Thanks
jason

The new textureIO class looks most promising, but threre are just a few things that I miss…

  1. A getMemsize() method in both Texture and TextureData that returns an estimate of the number of bytes used so that developers of texture caches can estimate the current usage of texture and buffer memory.

  2. Better user control of Texture parameters. Perhaps a TextureParameters class where users can supply prefered texture parameters. This for enabeling anisotropic filtering, using GL_LINEAR_MIPMAP_NEAREST instead of GL_LINEAR_MIPMAP_LINEAR or using another wrap mode than GL_CLAMP_TO_EDGE etc…

… and no, I have not found out how to use the issue tracker…

Rune

Thanks for your feedback. I’ve filed Issue 190 to track this. However:

I’ve done some reading on this topic and from what I understand it is strongly discouraged to try to do this kind of estimation in OpenGL applications. Some boards have very little on-board VRAM but can very effectively use main memory as texture memory, and estimating usage of texture memory leads to poor performance in these situations. It’s my understanding that this is the fundamental reason that OpenGL doesn’t have a mechanism for querying the amount of available texture memory like DirectX does. Do you have an example to the contrary?

I think you can do this with Texture.setTexParameteri(). Does that work for you?

Well, at least in my virtual globe application I really have to keep the useage of texture memory down to avoid filling up the non-garbage collected driver memory. As I can’t rely on java GC to collect unused textures (Soft or Weak refs did’nt quite give the wanted results) I have my own LRU scheme, and I need some hint of when to start throwing out textures. The limit is not necessarily based on the amount of video memory, but is user (or config file) configurable.

Ah! Sorry! Didn’t notice that in my first reading of the source. However, the AF is controled by a float parameter… and texture environment parameters could also be nice.

Rune

OK. We can easily provide this information.

Thanks for pointing this out. We definitely need to add more controls to the Texture class. Please feel free to edit the bug as well to point this out there.

hey, would a thumbnailer for the screen shot class be possible? it would remove the need to seft edit a screen shot to a size smaller for, say, the demo page or anyone who writes tutorials that have thumbnails. my request for feature… - ak-el

We could add something like this to ImageUtils but it should be something like three lines of Java2D code. Do you want to prototype it and file a Patch?

Three lines of Java2D code, heh? I should learn more of Java2D. unfortunately, at the moment i can’t prototype it given my inexperience. i hope you, or someone here would do it at their whim. – ka-el

Thanks to Romain Guy for an excellent patch, there is now a utility method in com.sun.opengl.util.ImageUtil for creating not just thumbnails but high-quality thumbnails. It should be present in tonight’s nightly build (1/25), or a subsequent build if for some reason tonight’s build fails.

beatiful! ;D