|
Java OpenGL Frequently Asked Questions
Last Updated: 19th January 1999
Copyright (c)1998-1999 Alligator Descartes <descarte@arcana.co.uk>
Abstract:
The idea of writing OpenGL code is generally to use an optimized graphics
library in an optimal way to produce graphics quickly. The other bonus is
that by using OpenGL you get to use a nicely designed API that the
core code will operate portably across different operating systems.
Therefore, the idea of using Java, an interpreted and widely regarded as
having ``sluggish'' performance, language to do this from seems a little
strange.
The upside to this is that a good OpenGL and Java interface will allow you
to leverage features from Java, such as immediate portability ( Write Once,
Run Anywhere ), built-in multi-threading and ``network-awareness''.
This FAQ section is almost an FAQ in itself, so here's a short table of
contents:
- The Fallacies About Java or Dispelling common myths about Java
- The Stark Realities About Java or Re-inforcing some common myths about Java
- Java and OpenGL Implementations
- Whatever Happened to the Standards?
- Additional Java-Based OpenGL Code and Resources
The Fallacies About Java
Some fallacies about Java and Java / OpenGL that are worth clearing up:
- Java is not necessarily ``dog slow''. In general, there are three ways
in which Java code may be executed:
- Interpreted Bytecode
This technique is by far the slowest as it interprets each Java
``bytecode'' ( Java machine code, if you will ) byte-by-byte.
This is the baseline execution format and is supported by all
Java Virtual Machines ( JVMs ).
- JIT
JIT stands for ``Just-In-Time'' and essentially means that the
Java bytecode of a program is compiled at runtime into native
machine code. This produces some massive performance enhancements
over the Interpreted Bytecode method of execution. A good JIT-based
JVM can execute code at up to about 80-90% of compiled C/C++
applications. Most commercial JVMs supported by vendors have a
JIT-based JVM, although the quality of the speed enhancements varies
wildly.
- Compiled Java
This final option is present in certain Java IDEs and allows you to
produce an executable program from Java source code. This is obviously
not portable as the resultant executables are targetted for Windows
platforms only. However, the performance of these compiled programs
is very close to C/C++.
- Java is actually very stable. This is a fairly broad statement given that
there are many different ports for virtually every operating system under
the sun ( no pun intended ), but the baseline execution method of
interpreted bytecode generally produces consistently correct programs.
- ``You can't implement OpenGL in Java. There's no mapping for
''
Yes, you can. 8-)
The Stark Realities About Java
However, after saying that not all is bad with Java, there are some notable
problems and hurdles to allowing you to use OpenGL with Java.
- Portability
- Window- & Operating-System Differences
It's actually extremely straight-forward to produce ``core
language'' bindings for OpenGL in Java. That is, the functions
prefixed with gl*. However, abstracting window-system code in a
portable manner and making that code interact correctly with
Java is a big problem.
- OpenGL Implementation Differences
Code written against one OpenGL may fail against another. For
example, code that works perfectly happily under Mesa may crash
under Microsoft OpenGL. Or working code under Linux may crash on
Irix. Or, better still, code working on one Irix workstation may
crash on another....
- Different Java Virtual Machines
There are several popular Java Virtual Machines out there. Almost
every Java IDE ships with its own. Your code needs to work
seamlessly on each one.
- Incomplete Java Support
One of the major problems is that each JVM does not necessarily correctly
execute Java code or support needed features. For example, Netscape's
Java support I have found to be fairly poor and unstable. The reference
implementation is generally always correct, but does not have the
highest performance. And so on.....
- Access to Extensions
There's no library / DLL access in Java. There's no function jump table
access.
- Strong Typing
Java is a strongly typed language. How do you deal with all that lovely
raw memory and pointer code you've already got?
Java and OpenGL Implementations
There are two approaches to allowing programmers the ability to write OpenGL
code using Java. One is to rewrite OpenGL in Java. The second, and infinitely
more realistic, is to ``wrap'' a native OpenGL implementation with Java
classes using Java Native Methods.
However, someone has attempted the first option!
- JavaGL ( http://www.cmlab.csie.ntu.edu.tw/~robin/JavaGL/index.html )
This package is an implementation of OpenGL in 100% Pure Java. It
currently supports about 20% of OpenGL functions and has very few
examples. It also runs extremely slowly.
This package was last updated since July 22nd, 1997 and seems to have
been discontinued.
The second grouping of implementations has more entrants and it is worth
recounting a piece of history before I start enumerating.
In early 1997, Leo Chan of the University of Waterloo quickly put together
a set of unofficial Java OpenGL bindings for the JDK-1.0.2 that provided Java
classes that interfaced with a native OpenGL implementation. This code was
relatively unpredictable, supported about 50-60% of core OpenGL functions
and only run under X11 and UNIX. It also did not integrate with AWT or Swing,
but created its own top-level window instead. This original code was called
OpenGL4Java.
By September 1997, OpenGL4Java had been abandoned completely and had not
been upgraded in any real way.
However, by December 1997, several camps of developers had picked up the
original OpenGL4Java code, dusted it off and restarted work on it by
upgrading it to use the new Java Native Interface. With a lack of cohesion,
these camps started releasing nearly identical bindings all suffering from
identical problems.
By the present time, only two of these bindings survive in any form:
- jogl ( http://www.pajato.com/jogl )
This is probably the most advanced of the original OpenGL4Java bindings.
It supports about 60-70% of the core OpenGL functions and vaguely
support rendering into AWT-based Components ( I say vaguely because
the way in which jogl handles access to the underlying AWT windows is
highly dubious ). This package primarily supports UNIX, but is known
to work under Win32.
jogl has some fundamental limitations in that it cannot support
multiple window rendering. It does not handle texture-mapping. There's
no GLU support. There are only 3 demo programs and the developers state
that the majority of implemented functions have never been tested. jogl
does not work reliably with multi-threading.
jogl's architecture is that of a single monolithic class that defines all
the OpenGL and GLU *and* window system calls. Each method is declared
as static which means code might look like:
GL.glBegin( GL.GL_POLYGON );
GL.vertex( 0.25f, 0.25f );
GL.vertex( 0.25f, 0.75f );
GL.vertex( 0.75f, 0.75f );
GL.vertex( 0.75f, 0.25f );
GL.glEnd();
This architecture is extremely inflexible and affords no ability for
developer customisability or overriding.
jogl also has no tangible documentation.
jogl has not been updated since December 10, 1997. The mailing list has
no traffic on it. From past traffic, the developers did not appear too
responsive about problems or upgrades.
Update 16/01/99: I've been informed by one of the developers that jogl
is in fact a discontinued project.
- GL4Java ( http://www.jausoft.com )
This package is literally identical to jogl as it was developed from
jogl-0.6 and hacked about with. The two packages differ mainly in
that OpenGL functions in jogl have had the gl prefix stripped whereas
GL4Java leaves the prefix on. That's about the only differences.
GL4Java has exactly the same limitations as jogl listed above but does
have slightly better integration into AWT ( though not much ).
GL4Java has no useful documentation ( I don't class Javadoc-generated
files with no comments ``documentation'' ).
GL4Java appears to still be in progress. A non-Jausoft developer has
recently released an Apple Mac port of GL4Java, but no core work has
been done for months on the UNIX and Win32 codebase.
A second development track began in early 1998 when PFU decided they needed
a Java OpenGL binding for their internal projects. JSparrow was born.
- JSparrow ( http://www.will.or.jp/~jsparrow )
JSparrow uses a similar class structure to the OpenGL4Java clones
in that all window-system, GL, GLU and GLUT code is jammed into
one massive class.
JSparrow has the benefit that existing GLUT-based C/C++ can be
converted with Java with little effort. It also appears to support
a certain amount of multi-thread safeness although this and multi-window
rendering is a bit shaky ( Kept crashing when I tried it ).
JSparrow supports Windows 95/98/NT, Solaris and Linux to date with
plans to support other operating systems at some point in the future.
JSparrow is an on-going project.
The final track of development had begun in May 1997 when
Arcane Technologies Ltd. started development of the Magician Java OpenGL
Interface from scratch without reference to the OpenGL4Java code. This was
undertaken primarily because of the inherent architectural flaws in the
OpenGL4Java approach and the absence of any ``official'' Java OpenGL bindings.
Magician solves all of the problems and deficiencies present in the OpenGL4Java
derived bindings and offers a new architecture for OpenGL programming that
puts real power in the hands of OpenGL developers.
- Magician ( http://www.arcana.co.uk/products/magician )
Magician takes an entirely different approach to implementing OpenGL
for Java than the OpenGL4Java-derived packages. At the heart of
Magician is the notion of ``composable pipelines'' which allow you to
mix and match ways to access the underlying OpenGL.
For example, a class called CoreGL exists that defines all the core
OpenGL functions and hooks into the native OpenGL implementation. You
can calls methods within this class to draw stuff on the screen.
CoreGL gl_ = new CoreGL();
gl_.glBegin( GL.GL_POLYGON );
gl_.glVertex2f( 0.25f, 0.25f );
gl_.glVertex2f( 0.25f, 0.75f );
gl_.glVertex2f( 0.75f, 0.75f );
gl_.glVertex2f( 0.75f, 0.25f );
gl_.glEnd();
This looks sort of similar to OpenGL4Java. However, we also ship a
tracing pipeline that will print each method's name ( and optionally
the arguments too ) as it executes. To do this, we simply compose a
new pipeline from the trace class and the CoreGL class thusly
CoreGL gl_ = new CoreGL();
TraceGL tracegl_ = new TraceGL( gl_ );
gl_.glBegin( GL.GL_POLYGON );
gl_.glVertex2f( 0.25f, 0.25f );
gl_.glVertex2f( 0.25f, 0.75f );
gl_.glVertex2f( 0.75f, 0.75f );
gl_.glVertex2f( 0.75f, 0.25f );
gl_.glEnd();
Therefore, when this polygon is drawn, it will also print out:
glBegin()
glVertex2f()
glVertex2f()
glVertex2f()
glVertex2f()
glEnd()
as each method is called. Similarly, we also ship a profiling class
which you can mix in with these other classes. This class times each
OpenGL call in microseconds to allow you to spot ``hotspots'' in your
code.
Furthermore ( it just gets better, doesn't it? ), you can switch the
pipelines to use on the fly *at runtime* as they all implement the same
Java interface. For example,
GL gl_ = null;
CoreGL coregl_ = new CoreGL();
TraceGL tracegl_ = new TraceGL( coregl_ );
/** Set the pipeline to trace */
gl_ = tracegl_;
gl_.glBegin( GL.GL_POLYGON );
gl_.glVertex2f( 0.25f, 0.25f );
gl_.glVertex2f( 0.25f, 0.75f );
/** Switch tracing off */
gl_ = coregl_;
gl_.glVertex2f( 0.75f, 0.75f );
gl_.glVertex2f( 0.75f, 0.25f );
gl_.glEnd();
This would result in:
glBegin()
glVertex2f()
glVertex2f()
being printed as tracing was not enabled for the final calls.
Magician also seamlessly integrates into AWT and Swing allowing you to
embed components into your GUIs and applications ( and WWW pages! ) quickly
and easily.
Magician allows multiple simultaneous window rendering and internally
manages all OpenGL context activity to ensure you don't have to worry
about it. Just create your GUI, drop in a Magician component and write
your application code.
Magician is multi-thread-aware. You can take full advantage of Java's
built-in multi-threading capabilities to drive your software without
expending any effort. Magician just does it for you.
Magician supports 100% of OpenGL and GLU including tesselators, NURBS
and quadrics. We've also leveraged functionality from GLUT and added
a whole bunch of other utility classes of our own for you including
virtual trackballs, texture-map creation classes, timers and model
data readers.
Magician sidesteps the issue of removing or leaving the gl prefix.
We provide both ``straight'' OpenGL functions and overloaded polymorphic
methods without the suffix to ensure that both camps are happy.
Magician supports a wide variety of operating systems such as Linux,
Irix, Solaris, Windows95/98/NT, AIX, OS/2 and MacOS. Magician also
supports most common JVMs including Sun's JDK, Microsoft Java SDK and
Internet Explorer, Netscape Communicator and Symantec Cafe.
Magician ships with over 70 complete demonstration programs including
Java conversions of all the examples with the ``OpenGL Programming Guide''
by Mason Woo, Jackie Nieder and Tom Davis.
Magician ships with Javadoc-generated documentation that describes every
OpenGL call completely and all the arguments to each call. We also
ship a 120-page ``Magician Programmer's Guide'' detailing how to get the
most out of Magician programming and exactly how to use all the cool
stuff we've added.
Whatever Happened to the Standards?
Where did they go?! Has anyone seen them?
Actually, yes. The Java OpenGL standards were originally being developed by
Sun and SGI and a reference implementation using this standard was to be
produced by Sun and SGI.
However, after a long period of time, nothing's appeared. There have been no
public releases of any draft specifications either.
The reality is that during 1997, SGI have on and off been developing a set of
Java bindings for OpenGL which, by the end of December 1997, were about
75% complete but had no easy integration with AWT for actually drawing
anything. At this point, Sun were tasked with providing hooks into Java2D
that these bindings could use. However, because of whatever reasons, this
hasn't really happened yet. So, the SGI / Sun effort has completely stalled.
There has also been very little mention of the Java bindings at previous
OpenGL ARB meetings ( http://www.opengl.org/About/ARB.html for the minutes ).
( I would say, from a personal opinion, that the architecture adopted by the
SGI / Sun proposal is similar to the OpenGL4Java packages and does not afford
the same power as the Magician ``composable pipeline'' architecture. )
Arcane Technologies turned up at the June 1998 ARB meeting in London and did a
presentation on Magician. This seems to have shocked various people into
activity and a working group was quickly formed from Arcane Technologies,
SGI, Sun and some other interested companies to hammer out the first stage of
Java OpenGL bindings which will be the ``core'' OpenGL functions.
You can download Arcane's presentation as a self-running PowerPoint file
( that is, you don't need PowerPoint to view it ) from:
http://www.arcana.co.uk/products/magician/junarb.zip
The first three months of activity on the working group mailing list ( archived
at http://www.arcana.co.uk/products/magician/mailinglists/ ) was relatively
hectic and a Call For Proposals to define a Java OpenGL standard was released.
Three major designs and implementations were submitted:
- Magician
- JSparrow
- GL4Java and other OpenGL4Java clones ( not directly submitted )
The authors of JSparrow also turned up at the September 1998 ARB meeting and
did a short presentation and demonstration of JSparrow.
Over the next three months, discussions took place on the mailing list
concerning the pros and cons of each submission with Magician emerging as
the clear favourite to form the baseline implementation.
A further set of questions were issued by the ARB concerning each binding
to which replies for Magician and JSparrow were issued ( see
http://www.arcana.co.uk/products/magician/docs/issues and the mailing list
archives respectively ). Arcane attended the December 1998 ARB meeting in
which a long discussion of the pros and cons of Magician took place.
And that's the story so far!
Additional Java-Based OpenGL Code
Since the area of Java and OpenGL is relatively new and, until recently,
there's been no commercially robust offering, there's not much in this section
yet!
- ``Shapeshifter'' -- 100% Pure Java Port of the GLE Tubing and
Extrusion Library
( From the Arcane Technologies Ltd. Press Release )
Shapeshifter is an implementation of the GLE Tubing and Extrusion
Library written in 100% Pure Java. This library enables developers to
render complex extrusions, spirals and helicoid shapes quickly and
easily using OpenGL as the underlying rendering library.
Shapeshifter uses the Magician Java OpenGL Interface as its underlying
rendering layer which enables you to write fully-featured and portable,
high-performance 3D Java applications extremely easily that will run
on many different operating systems and browser environments with no
modification!
Shapeshifter also utilises the same ``composable pipeline'' architecture
used by Magician affording developers the ability to perform built-in
debugging and profiling in a runtime switchable way.
Shapeshifter is completely free to download and use and includes full
source code. Magician must be installed on your machine in order for
Shapeshifter to be used. Magician is not free software but may be
downloaded for personal use from the URL below.
Shapeshifter Download and Information:
http://www.arcana.co.uk/products/shapeshifter
- Unified Model Loader -- Arcane Technologies Ltd.
The Unified Model Loader is a set of Java classes that provide model
data reading, writing and manipulation functions making it extremely
simple for developers to load external data into their programs without
having to write a line of parser code!
The Unified Model Loader is downloadable for free with full source
code from:
http://www.arcana.co.uk/products/magician/model
|