Java 2D and JOGL: The Flip Side
The Hemingway Version
In my last blog entry,
Easy 2D/3D Mixing in Swing, my goal was to show Swing developers how easy
it can be to include 3D content in a desktop application via JOGL and OpenGL.
I think we've done a decent job of making things easier for that class of
developers, but what if we look at the problem from the other end of the
barrel? There are lots of JOGL/OpenGL developers that want to include Java 2D
elements in their applications. Historically it has been possible to include
Java 2D content in a JOGL application, but there haven't been any good
standard APIs to make this sort of integration convenient for developers.
Let's get the demo out of the way before getting into any of the details.
Here's a screenshot (click to enlarge), for the truly impatient reader:
Better yet, run the demo yourself (the app itself is sandboxed and only
requires JDK 5; here's the source code, with NetBeans project included):
The Faulkner Version
Ken Russell (the mastermind behind JOGL) promises me that he'll soon have a
blog of his own, which means I'll have to stop stealing all of his thunder.
In the meantime, let's look at some of the new convenience classes that
he's cooked up in the past few weeks (with some prodding from
James Gosling, and inspired by some
reader comments from my last blog).
These aren't new (they were added to Sun's JOGL implementation over 18
months ago), but it helps to mention them in the context of the newer
convenience classes. The
Texture class is a really nice
abstraction layer around an OpenGL texture object. It makes it very easy
for developers to use non-power-of-two sized images in OpenGL (historically
this has been tricky for OpenGL developers) and provides simple methods
for enabling and binding texture state. The
offers an extremely convenient API for loading image data from disk, the
network, or any other source into OpenGL texture memory.
(If you're into SAT-style analogies:
TextureIO is to
BufferedImage.) It even supports special
compressed texture formats, mipmapping, and other complex things that are
usually a nightmare for OpenGL developers.
The first of the three new convenience APIs found in the
com.sun.opengl.util.j2d package. This class builds on top
Texture class described above and provides a convenient
way for developers to dynamically render into an OpenGL texture using
Java 2D. From the following code snippet, it should be clear that you can
TextureRenderer instance just as you would a
// Create the TextureRenderer and render into it using Java 2D
TextureRenderer renderer = TextureRenderer(w, h, true);
Graphics2D g2 = renderer.createGraphics();
// and so on...
renderer.sync(0, 0, w, h);
// Now use it as you would any other OpenGL texture
Texture tex = renderer.getTexture();
Note that currently the
TextureRenderer class uses a
BufferedImage behind the scenes as backing store (but
that's just an implementation detail). This means
that when you're rendering into a
currently all goes through software routines. However, Ken and
I have some tricks up our sleeves: if all goes well in the next few weeks,
we may have an alternate codepath that leverages the JOGL/Java 2D bridge,
which will mean that all rendering into the
will be accelerated in hardware via the OpenGL-based Java 2D pipeline,
with no costly
BufferedImage-Texture copy steps required.
This could be an exciting development, so stay tuned.
Since the beginning of time, rendering text in OpenGL applications has been a
huge hassle for developers. There were some really hokey GLUT routines
that used ugly bitmap fonts with no support for antialiasing or non-Latin
text. In the Java world, crafty developers using
and LWJGL have figured out custom ways to
leverage Java 2D's high-quality font rendering in their applications. But
until this new
TextRenderer class came along, (as far as I know)
there was no easy/standard way to get access to the high quality,
antialiased text offered by Java 2D. It includes full Unicode support,
a really smart string/glyph caching algorithm, and clean APIs that allow
for both 2D and 3D rendering of text in a JOGL application (as you saw in
my demo above). Under the hood, it takes advantage of the aforementioned
Texture classes. Ken has
enough to declare it "the last word in text rendering" for JOGL apps,
and I think he's right. I can even imagine existing C-based OpenGL apps
being ported to Java and JOGL for this feature alone...
I didn't actually use this one in the above demo, but it's a really useful
and simple way to add a "heads-up display" to your JOGL application.
Imagine a flight simulator application: you could render the terrain and
all of your 3D content using JOGL, then you could use the new Overlay class
as a way to render the airplane's control panel using the high-quality
Java 2D APIs. It's really just an even more convenient wrapper around
the already convenient
To help explain how these new APIs fit together and how they layer on top
of OpenGL, I put together a pancake diagram showing how it all comes
(I don't have my charting software handy, so the following,
might I add beautiful, ASCII art diagram will have to suffice.)
| TextRenderer | Overlay |
| TextureRenderer - - | - - -> BufferedImage, Graphics2D
| Texture - - | - - -> TextureIO, ImageIO
| OpenGL textures |
That's all for now. In my next entry I'll have some exciting performance numbers to share in the context of the OpenGL-based Java 2D pipeline (hint: hardware accelerated BufferedImageOps).
In my ears: Sloan, "Never Hear The End Of It"
In my eyes: William Faulkner, "Absalom, Absalom!"
* It's a bit long and wordy,
but I'm still just as much of a slobbering fan of theirs as I was in
**... But sometimes
"long and wordy" can be a virtue.