diff options
Diffstat (limited to 'doc/userguide')
-rw-r--r-- | doc/userguide/index.html | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/doc/userguide/index.html b/doc/userguide/index.html new file mode 100644 index 000000000..47f5d095b --- /dev/null +++ b/doc/userguide/index.html @@ -0,0 +1,500 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<HTML> +<HEAD> +<TITLE>Jogl - User's Guide</TITLE> +</HEAD> +<BODY> + +<H1>Jogl - User's Guide</H1> + +<P> + +<UL> + + <LI> Overview + <LI> Creating a GLDrawable + <LI> Writing a GLEventListener + <LI> Using the Composable Pipeline + <LI> Multithreading Issues + <LI> Pbuffers + <LI> Platform notes + <UL> + <LI> All Platforms + <LI> Windows + <LI> Solaris, Linux (X11 platforms) + <LI> Macintosh OS X + </UL> + +</UL> + +<H2> Overview </H2> + +<P> + +Jogl is a Java programming language binding for the OpenGL 3D graphics +API. It supports integration with the Java platform's AWT and Swing +widget sets while providing a minimal and easy-to-use API that handles +many of the issues associated with building multithreaded OpenGL +applications. Jogl provides access to the latest OpenGL routines +(OpenGL 1.4 with vendor extensions) as well as platform-independent +access to hardware-accelerated offscreen rendering ("pbuffers"). Jogl +also provides some of the most popular features introduced by other +Java bindings for OpenGL like GL4Java, LWJGL and Magician, including a +composable pipeline model which can provide faster debugging for +Java-based OpenGL applications than the analogous C program. + +</P> +<P> + +Jogl was designed for the most recent version of the Java platform and +for this reason supports only J2SE 1.4 and later. It also only +supports truecolor (15 bits per pixel and higher) rendering; it does +not support color-indexed modes. Certain areas of the public APIs are +more restrictive than in other bindings; for example, the GLCanvas and +GLJPanel classes are final, unlike in GL4Java, and the GLContext class +is no longer exposed in the public API. These changes have been made +to keep the public API simple and because most of the programming +errors that have been seen with earlier Java/OpenGL interfaces, in +particular GL4Java, have been related to subclassing the OpenGL widget +classes and performing manual OpenGL context management. Several +complex and leading-edge OpenGL demonstrations have been successfully +ported from C/C++ to Jogl without needing direct access to any of +these APIs. However, all of these classes and concepts are accessible +at the Java programming language level in implementation packages, and +in fact the Jogl binding is itself written almost completely in the +Java programming language. There are only about fifty lines of +handwritten C code in the entire Jogl source base; the rest of the +native code is autogenerated during the build process by a new tool +called GlueGen, the source code of which is in the Jogl source +tree. Documentation for GlueGen is forthcoming. + +</P> + +<H2> Creating a GLDrawable </H2> + +<P> + +Jogl provides two basic widgets into which OpenGL rendering can be +performed. The GLCanvas is a heavyweight AWT widget which supports +hardware acceleration and which is intended to be the primary widget +used by applications. The GLJPanel is a fully Swing-compatible +lightweight widget which currently does not support hardware +acceleration but which is intended to provide 100% correct Swing +integration in the rare circumstances where a GLCanvas can not be +used. See <a href = +"http://java.sun.com/products/jfc/tsc/articles/mixing/">this +article</a> on <a href = "http://java.sun.com/products/jfc/tsc/">The +Swing Connection</a> for more information about mixing lightweight and +heavyweight widgets. + +</P> +<P> + +Both the GLCanvas and GLJPanel implement a common interface called +GLDrawable so applications can switch between them with minimal code +changes. The GLDrawable interface provides + +<UL> + + <LI> access to the GL and GLU objects for calling OpenGL routines + + <LI> the mechanism for registering GLEventListeners for performing + OpenGL rendering + + <LI> a <CODE>display()</CODE> method for forcing OpenGL rendering to + be performed + + <LI> exclusion methods (<CODE>setRenderingThread()</CODE>, + <CODE>setNoAutoRedrawMode()</CODE>) for controlling the + multithreading behavior of the widget + + <LI> AWT- and Swing-independent abstractions for getting and setting + the size of the widget and adding and removing event listeners + + <LI> a platform-independent mechanism for creating + hardware-accelerated offscreen surfaces (pbuffers) for performing + advanced rendering techniques + +</UL> + +</P> +<P> + +GLCanvas and GLJPanel instances are created using the factory methods +in GLDrawableFactory. These factory methods allow the user to request +a certain set of OpenGL parameters in the form of a GLCapabilities +object as well as optionally customize the format selection algorithm +by specifying a GLCapabilitiesChooser. + +</P> +<P> + +A GLCapabilities object specifies the OpenGL parameters for a +newly-created widget, such as the color, alpha,, z-buffer and +accumulation buffer bit depths and whether the widget is +double-buffered. The default capabilities are loosely specified but +provide for truecolor RGB, a reasonably large depth buffer, +double-buffered, with no alpha, stencil, or accumulation buffers. + +</P> +<P> + +An application can override the default pixel format selection +algorithm by providing a GLCapabilitiesChooser to the +GLDrawableFactory. The chooseCapabilities method will be called with +all of the available pixel formats as an array of GLCapabilities +objects; it should return an integer index into this array. The +DefaultGLCapabilitiesChooser attempts to provide a better +cross-platform selection algorithm than the WGL and GLX pixel format +selection algorithms. + +</P> + +<H2> Writing a GLEventListener </H2> + +<P> + +Applications implement the GLEventListener interface to perform OpenGL +drawing. When the methods of the GLEventListener are called, the +underlying OpenGL context associated with the drawable is already +current. The listener fetches the GL object out of the GLDrawable and +begins to perform rendering. + +</P> +<P> + +The <CODE>init()</CODE> method is called once, upon context +creation. (Hooks for context destruction, and support for context +recreation, are not yet implemented.) The <CODE>display()</CODE> +method is called to perform per-frame rendering. The +<CODE>reshape()</CODE> method is called when the drawable has been +resized; the default implementation automatically resizes the OpenGL +viewport so often it is not necessary to do any work in this method. +The <CODE>displayChanged()</CODE> method is designed to allow +applications to support on-the-fly screen mode switching, but support +for this is not yet implemented so the body of this method should +remain empty. + +</P> +<P> + +It is strongly recommended that applications always refetch the GL and +GLU objects out of the GLDrawable upon each call to the +<CODE>init()</CODE>, <CODE>display()</CODE> and <CODE>reshape()</CODE> +methods and pass the GL object down on the stack to any drawing +routines, as opposed to storing the GL in a field and referencing it +from there. The reason is that multithreading issues inherent to the +AWT toolkit make it difficult to reason about which threads certain +operations are occurring on, and if the GL object is stored in a field +it is unfortunately too easy to accidentally make OpenGL calls from a +thread that does not have a current context. This will usually cause +the application to crash. For more information please see the section +on multithreading. + +</P> + +<H2> Using the Composable Pipeline </H2> + +<P> + +Jogl supports the "composable pipeline" paradigm introduced by the +Magician Java binding for OpenGL. The DebugGL pipeline calls +<CODE>glGetError</CODE> after each OpenGL call, reporting any errors +found. It can greatly speed up development time because of its +fine-grained error checking as opposed to the manual error checking +usually required in OpenGL programs written in C. The TraceGL prints +logging information upon each OpenGL call and is helpful when an +application crash makes it difficult to see where the error occurred. + +</P> +<P> + +To use these pipelines, call <CODE>GLDrawable.setGL</CODE> at the +beginning of the <CODE>init</CODE> method in your GLEventListener. For +example, + +<PRE> +class MyListener implements GLEventListener { + public void init(GLDrawable drawable) { + drawable.setGL(new DebugGL(drawable.getGL())); + // ... + } + + // ... +} +</PRE> + +</P> + +<H2> Multithreading Issues </H2> + +<P> + +Jogl was designed to interoperate with the AWT, an inherently +multithreaded GUI toolkit. OpenGL, in contrast, was originally +designed in single-threaded C programming environments. For this +reason Jogl provides a framework in which it is possible to write +correct multithreaded OpenGL applications using the GLEventListener +paradigm. + +</P> +<P> + +If an application written using Jogl interacts in any way with the +mouse or keyboard, the AWT is processing these events and the +multithreaded aspects of the program must be considered. + +</P> +<P> + +OpenGL applications usually behave in one of two ways: either they +repaint only on demand, for example when mouse input comes in, or they +repaint continually, regardless of whether user input is coming in. In +the repaint-on-demand model, the application can merely call +<CODE>GLDrawable.display()</CODE> manually at the end of the mouse or +keyboard listener to cause repainting to be done. Alternatively if the +application knows the concrete type of the GLDrawable it can call +repaint() to have the painting scheduled for a later time. + +</P> +<P> + +In the continuous repaint model, the application typically has a main +loop which is calling <CODE>GLDrawable.display()</CODE> repeatedly, or +is using the Animator class, which does this internally. In both of +these cases the OpenGL rendering will be done on this thread rather +than the internal AWT event queue thread which dispatches mouse and +keyboard events. + +</P> +<P> + +Both of these models (repaint-on-demand and repaint continually) still +require the user to think about which thread keyboard and mouse events +are coming in on, and which thread is performing the OpenGL rendering. +OpenGL rendering <B>may not</B> occur directly inside the mouse or +keyboard handlers, because the OpenGL context for the drawable is not +current at this point (hence the warning about storing a GL object in +a field, where it can be fetched and accidentally used by another +thread). However, a mouse or keyboard listener may invoke +<CODE>GLDrawable.display()</CODE>. + +</P> +<P> + +It is generally recommended that applications perform as little work +as possible inside their mouse and keyboard handlers to keep the GUI +responsive. However, since OpenGL commands can not be run from +directly within the mouse or keyboard event listener, the best +practice is to store off state when the listener is entered and +retrieve this state during the next call to +<CODE>GLEventListener.display()</CODE>. + +</P> +<P> + +Furthermore, it is recommended that if there are long computational +sequences in the GLEventListener's <CODE>display</CODE> method which +reference variables which may be being simultaneously modified by the +AWT thread (mouse and keyboard listeners) that copies of these +variables be made upon entry to <CODE>display</CODE> and these copies +be referenced throughout display() and the methods it calls. This will +prevent the values from changing while the OpenGL rendering is being +performed. Errors of this kind show up in many ways, including certain +kinds of flickering of the rendered image as certain pieces of objects +are rendered in one place and other pieces are rendered elsewhere in +the scene. Restructuring the display() method as described has solved +all instances of this kind of error that have been seen with Jogl to +date. + +</P> +<P> + +In addition to correctness issues, there are also performance issues +to consider with multithreaded OpenGL applications. The OpenGL context +associated with a particular drawable can only be current on one +thread at a time. If multiple threads may be making the context +current then this implies that the context must be made current and +freed during each render; the overhead of these context operations may +be significant depending on the application. For this reason Jogl has +a built-in mechanism for optimizing the OpenGL context handling to the +efficiency of an analogous C application. + +</P> +<P> + +<CODE>GLDrawable.setRenderingThread</CODE> informs the Jogl library +that rendering to a particular drawable will only occur from the +specified thread. The intent is that the OpenGL context can be made +current and remain current on that thread until +setRenderingThread(null) is called. Unfortunately, due to +quality-of-implementation bugs in the X11 JAWT, this optimization had +to be made advisory; in other words, it was not possible to guarantee +that setRenderingThread would yield any faster OpenGL context handling +on these platforms. + +</P> +<P> + +In some situations, typically when an application is using pbuffers to +compute intermediate results, it is required that automatic redraws be +suspended for a particular drawable so that the application can +completely control when and where the display() method is called. For +this reason the <CODE>GLDrawable.setNoAutoRedrawMode()</CODE> method +was added; it is used not only by the Jogl implementation but also by +utility libraries such as gleem (included in the jogl-demos +distribution). We consider it unfortunate that it was necessary to +expose two APIs to express basically the same idea and hope that if +the JAWT implementation in the 1.5 platform has better locking +behavior that <CODE>GLDrawable.setNoAutoRedrawMode()</CODE> may be +able to be removed. + +</P> + +<H2> Pbuffers </H2> + +<P> + +Jogl exposes hardware-accelerated offscreen rendering (pbuffers) with +a minimal and platform-agnostic API. Several recent demos have been +successfully ported from C/C++ to Java using Jogl's pbuffer APIs. +However, the pbuffer support in Jogl remains one of the more +experimental aspects of the package and the APIs may need to change in +the future. + +</P> +<P> + +To create a pbuffer, create a GLCanvas and (assuming it reports that +it can create an offscreen drawable) make a pbuffer using the +<CODE>createOffscreenDrawable</CODE> API. Because of the multithreaded +nature of the AWT, the pbuffer is actually created lazily. For this +reason the application's main loop typically needs to detect when the +init() methods of all of the GLEventListeners for all of the offscreen +surfaces have been called. See the demonstrations such as the +ProceduralTexturePhysics demo for an example of this. + +</P> +<P> + +Additionally, pbuffers are only created when the parent GLCanvas's +display(), init(), or reshape() methods are called; in other words, it +may be necessary to manually "prime" the GLCanvas by calling display() +on it until it creates all of its requested pbuffers. Again, please +see the demonstrations for concrete examples of this. We hope that it +may be possible to hide many of these details in the future. + +</P> +<P> + +A pbuffer is used by calling its display() method. Rendering, as +always, occurs while the pbuffer's OpenGL context is current. There +are render-to-texture options that can be specified in the +GLCapabilities for the pbuffer which can make it easier to operate +upon the resulting pixels. These APIs are however extremely +experimental and not yet implemented on all platforms. + +</P> + +<H2> Platform Notes </H2> + +<H3> All Platforms </H3> + +<P> + +The following issues, among others, are outstanding on all platforms: + +</P> + +<UL> + +<LI> Sharing of textures and display lists between contexts has not +yet been exposed in the public API, though pbuffers always share +display lists with their parent widget. + +</UL> + +<H3> Windows </H3> + +<P> + +No outstanding issues at this time. + +</P> + +<H3> Solaris, Linux (X11 platforms) </H3> + +<UL> + +<LI> Pbuffer support has not yet been implemented in Jogl on X11 +platforms. + +</UL> + +<H3> Mac OS X </H3> + +<P> + +The Mac OS X port of Jogl, in particular the GL interface and its +implementation, can be used either with the provided GLCanvas widget +or with the Cocoa NSOpenGLView. In order to use it with Cocoa the +following steps should be taken: + +<UL> + +<LI> Instantiate a +<CODE>net.java.games.jogl.impl.macosx.MacOSXGLImpl</CODE> using the +public constructor taking no arguments. + +<LI> Upon the first render of your application, or whenever the +available OpenGL routines might have changed (because a window moved +from one screen to another) call the publicly-accessible method +<CODE>MacOSXGLImpl.resetGLFunctionAvailability()</CODE>. + +<LI> Only use the GL instance when the OpenGL context from the +NSOpenGLView is current. + +</UL> + +<B>NOTE:</B> the Cocoa interoperability has not yet been retested +since the GLCanvas was implemented. Please report any problems found +with using Jogl with an NSOpenGLView. + +</P> +<P> + +The following issues remain with the Mac OS X port: + +<UL> + +<LI> Due to bugs in the JAWT implementation on Mac OS X, some fairly +severe workarounds had to be put into the Jogl sources that impact +performance significantly. These bugs have been fixed by Gerard +Ziemski at Apple and the fixes will most likely show up in the Java +that ships with the second developer preview of Panther (10.3), at +which time the performance of OpenGL-based applications on OS X using +Jogl and the GLCanvas will increase. Still, with Developer Preview 1 +of Panther (released at JavaOne), resizing of GLCanvases does not work +and yields an application crash. This issue will be fixed with DP2. + +<LI> GLJPanel is not yet implemented on Mac OS X. + +<LI> Due to the mechanism by which the Cocoa graphics system selects +OpenGL pixel formats, the GLCapabilitiesChooser mechanism can not be +implemented on Mac OS X as on other platforms. In the future, the +chooser will be used and the capabilities array will contain exactly +the requested capablities. The underlying Cocoa pixel format selection +algorithm will then run to choose the best-fit visual. Currently the +capabilities of the underlying context are hardcoded. + +<LI> Pbuffers are not yet supported in the Mac OS X port of Jogl. +Pbuffers will first become visible to Mac OS X applications in the +Panther (10.3) release, at which time the pbuffer support will be +ported. + +</UL> + +</P> + +</BODY> +</HTML> |