Java3D on Mac OS X

Here goes with my first seriously geeky blog. This would be a great use for categories!

There are several annoying things I can’t figure out with Java3D on 10.3. What’s even worse than not being able to figure something out at all is when you actually have figured it out, but so far the solution only works on Windows. Ugh!

My application uses a lot of very large images. Several of them are loaded from disk and are meshed together to form yet another large image, which is then applied as sub-image textures, one per terrain object.

The first problem relates to BufferedImages. ImageIO seems like the easiest way to load images in Java programatically and without relying on View-type components, but it returns only BufferedImages. BufferedImages on the mac seem to use direct memory buffers of some sort, which are apparently in limited supply, because I can’t run my app if my original images that go in to the mesh are BufferedImages. It complains about running out of direct buffered memory. I’ve read about this problem on the Apple java-dev mailing list, but the only workaround I saw was to use Images instead.

Images are the second problem. I’ve read in more than one place that Java3D uses lots of threads to do its work, and that faster and multi-processor machines often can experience strange app behavior due to threading issues. The methods I’ve tried to load Images, such as Toolkit.createImage(), are asynchronous, and some of the mac-specific behavior makes me suspect the image data isn’t all finished loading before the texture mesh is created. For example, the terrain tile that is textured with the first portion of the image to load shows up correctly, but the rest of the tiles show up with empty textures. I know it’s related to the meshed textures, because I can apply repeated small test images over all the terrain tiles, and they show up just as you would expect.

The problem with these asynchronous Images is their methods provided for listening for the image loading to complete, such as ImageListener() and MediaTracker, only seem to work when they’re used in subclasses of java.awt.Component. So I’m loading these images in a model portion of my application, and I’m trying to figure out a clean way to hand them over to some UI component to make sure they’re completely loaded before I hand them back to the model to be meshed. Yuck!

One possible solution I keep thinking of is to migrate to JAI, but I’ve heard its performance can actually be worse than javas, and the application was certainly not designed with JAI’s image source and sink model in mind. If you know of a really good JAI tutorial that’ll tell me how to load images into JAI, create a large tiled image out of them, and also how to mesh images together in JAI, please let me know. Seems like the learning curve on that API is pretty steep.

More than enough geeking for one day! I’d love some hints or even outright solutions to these, so send ’em if you got ’em!

This entry was posted in Uncategorized and tagged . Bookmark the permalink.