JSR-231 1.0.0 released!

JSR-231 (Java Bindings for OpenGL) is finally in the Early Draft Review stage! This is the first official publicly visible draft of the forthcoming JSR-231 APIs. You can download the specification here:

http://jcp.org/en/jsr/detail?id=231

The spec is basically the javadoc target of the JSR-231 branch of the JOGL workspace. The only packages covered by the spec are javax.media.opengl and javax.media.opengl.glu. The others are “utility” packages not guaranteed to be shipped by any particular implementor of the JSR-231 APIs.

The specification is fairly minimal, primarily covering the cross-platform exposure of the GLContext and GLDrawable abstractions. The current JOGL callback model, which is similar to GLUT’s, is also supported through the GLAutoDrawable API. All of the concrete OpenGL widgets and drawables shipped with the JSR-231 implementation (GLCanvas, GLJPanel, and GLPbuffer) implement the GLAutoDrawable interface. If desired, end users can use the GLDrawable and GLContext APIs directly to either grab the underlying OpenGL context from one of the existing widgets, or can easily create their own OpenGL widgets supporting different, non-callback rendering models like game loops.

All of the APIs have been implemented and tested on all of JOGL’s supported platforms. There are some known issues on certain kinds of machines like Mac PowerBook laptops, but by and large the new code base is more robust than the current JOGL 1.1.1 release. Exciting new functionality like the Java2D/JOGL bridge, previously mentioned on this forum, is built in to the new implementation. There are some new demos in the jogl-demos workspace which show off the new functionality and performance enhancements.

While most JOGL applications will require very few changes to work under the new APIs, some application changes will definitely be necessary, and there are many cosmetic and some semantic changes to the APIs. We will try to provide a definitive list of the differences between the current JOGL APIs and the new JSR-231 APIs soon. A few key points:

[] All non-core APIs like the Animator have been moved into the com.sun.opengl.utils package. We aim to populate this package with utilities like texture loaders, screen grabbers, etc. Help from the community would be greatly appreciated.
[
] APIs which accept a void* argument on the C side now accept java.nio.Buffer on the Java side rather than overloadings for each primitive array type. Some APIs like glVertexPointer require that this Buffer be direct; others, like glTexImage2D, do not. If the buffer must be direct, this is specified in the API. JOGL applications which used to call these APIs by passing in primitive arrays can be converted to the new API by using Buffer.wrap(). This change was done to reduce the explosion of overloadings for various APIs.
[] APIs which accept a strongly-typed C primitive pointer argument like int are expanded to two overloadings, one taking an IntBuffer and optionally one taking an int[]. If the API requires a persistent pointer, only the IntBuffer variant will be generated, and the passed buffer must be direct. If not, both overloadings will be generated, and the IntBuffer may be direct or not.
[] The positions of passed Buffers are now significant; the pointer passed down to C is the address of the current element in the Buffer rather than the beginning of the Buffer. This decision was informed by the LWJGL project so as to avoid needing to create slices of Buffers. Please provide feedback on this stylistic change.
[
] Access to the GLU library has changed. Rather than being attached to the GLDrawable, a GLU object can now be instantiated at any point in the program, and the GL object does not need to be passed to all of the methods. The GLU routines which use OpenGL require only that an OpenGL context is current at the point where they are called. The GLUT library has been refactored similarly.
[] All of the OpenGL extensions which were folded into 1.1, 1.2, and 1.3 have been excluded during the glue code generation process. This eliminates some pretty useless extensions like glVertexPointerEXT and on the whole seems like the right thing to do. It does imply that these extensions will not be callable if the host’s OpenGL implementation is not at least OpenGL 1.3 compliant; however, an OpenGL 1.3 implementation is not required in order to run applications using only OpenGL 1.1 or 1.2 APIs.
[
] Vertex Buffer Object and Pixel Buffer Object support has been changed. APIs affected by these extensions now have two overloadings generated, one for use when the extension is enabled (accepting a Java long in place of a C pointer like void*) and one for when it is disabled (accepting a Buffer in place of a C pointer). Checks are performed at run-time to ensure that arbitrary pointers can not be constructed by end users and passed in to the OpenGL implementation.

Nightly builds and new Java Web Start binaries are coming on line and should be available within a day or two. We will post updates to this forum when they are available. The JSR-231 branch of the JOGL tree will also soon be merged on to the main trunk, at which point all JOGL development going forward will be on the new APIs.

The Early Draft Review period is scheduled to last for roughly a month, followed by the public review period. Compared to the length of time the JSR has been underway, we realize that this is a relatively short period of time in which changes to the specification can be made. Please provide your feedback on the new APIs and spread the word to others that the specification is in the review phase.

We are looking forward to a speedy review process and getting the final APIs in the hands of developers and end users. Thanks in advance for your help.

This is really good news! I’m looking forward to testing
out the binaries on a branch of my app made specifically
for this.

.rex

Great, so basically to be conformant, one must “just” implement the javax.media.opengl./glu. packages?
Some comments this far:

  • As this is an implementation that everybody can implement, references to JOGL should go
  • The Threading class is a bit… awkward - and very much JOGL specific.
  • The specs dont mention anything about threading behaviour
  • The JSR doesn’t solve the fullscreen issues
  • No mentions of what must, should, may be implemented to be conformant
  • Adding utility into com.sun seems like a bad way, since it’s not guarenteed to exist. If there are some std utilities then it should be in javax.media.opengl.util.*

I’ll look into it more when I have some time

Hi Ken,

Below is my initial feedback from a quick look
at the API spec:

  • javax.media.opengl.GLDrawable.createContext(…)
    Didn’t specify behaviour if parameter is null, or
    can be null.

  • javax.media.opengl.GLDrawable.swapBuffers()
    Specification can easily be tightened to
    say that it will do nothing if called on
    a GLAutoDrawable, instead of undefined results.

  • javax.media.opengl.GLContext
    Must release() be called before destroy()?
    What happens if release() is called after destroy()?

  • javax.media.opengl.GLDrawableFactory
    createExternalGLContext() is a little misleading:
    it seems to imply a new GLContext is being created.
    getExistingGLContext(), wrapExternalGLContext() or
    createGLContextFromExisting() sounds more intuitive.
    The fact that this function accesses an existing
    context should be reflected in the method name.

.rex

The jsr seems to be very much tied to the current reference implementation. As an example, the documentation for GLCanvas contains quite a few implementation details (addNotify, removeNotify, update, …) which might only be relevant for the reference implementation. GLDrawable#setRealized seems to fall under this category too (haven’t checked how this is used in practice yet).
IMO if the spec wants to mandate that there should be at least a heavyweight and a lightweight GLDrawable implementation, the javadoc should reflect only that. (i.e. abstract class GLCanvas extends Canvas implements GLDrawable). Or does this cause problems when actually using the api?
Also, is there a way for a non AWT binding (read lwjgl :)) to implement the jsr or does the jsr only cover AWT based bindings? The GLDrawableFactory seems to limit this.

Edit:
Since BufferUtils won’t be part of the spec, it might be useful to mention byte ordering in the javax part somewhere. It should say that this is either implementation dependent or that Buffers are assumed to have ByteOrder.nativeOrder() as order.

This is kinda minor, but I noticed there’s no public default GLCanvas constructor.
It would be really nice to have one as a convenience for small test apps.


public GLCanvas()
{
    this(new GLCapabilities(), new DefaultGLCapabilitesChooser(), null, GraphicsEnvironment.getDefaultScreenDevice());
}

I may possibly try to contribute with a Blender importer/exporter for a simple ascii scene format similar to obj for models:


m triangle
v  1.0 0.0 0.0
v 0.0 1.0 0.0
v 0.0 0.0 0.0 
vn 0.0 0.0 1.0
f  1/1 2/1 3/1

And something like this for scenes:


ob x
m triangle
push
p 0 0 0
r 0 0 0 0
s 1 1 1
prop type emitter
prop set torchfire

Don’t even need to mess with something like antlr for this. A binary encoder can also be done.

I have a couple nits that I’ve noticed in trying to port some code to use the new JSR-231 codebase:

  • GLJPanel.paintComponent() should be protected, not public.

  • Regarding GLJPanel.shouldPreserveColorBufferIfTranslucent()… Ideally GLJPanel would clear the color buffer conditionally for the user, but I guess that can’t be done due to the whole GLEventListener architecture. So my only remaining complaint is about the name. As it’s written now, it sounds like you’re asking whether the GLJPanel should preserve the color buffer, but it’s really the application’s responsibility. How about one of the following names instead:

    • GLJPanel.isColorBufferClearRequiredWhenNonOpaque()
    • GLJPanel.isColorBufferInitializedExternally()

I realize those names aren’t great, but I’m having trouble coming up with something better. There must be something better than the way the method name is currently worded though :slight_smile:

  • Also from the GLJPanel docs:
    “This class can not be instantiated directly; use GLDrawableFactory to construct them.”

Does this mean that one is not allowed to subclass a GLJPanel? I’ve been working on creating a simplified version of GLJPanel (a subclass of GLJPanel) that makes it easier for Swing/Java2D developers to jump into the world of JOGL. This line from the docs makes it sound like I’m doing something bad/unallowed. If GLJPanel (and GLCanvas) cannot be instantiated directly, perhaps they should be marked final (although I’m not suggesting this should be the case)?

  • From GLCanvas docs:
    “Overridden from Canvas to prevent Java2D’s clearing of the canvas from interfering with the OpenGL rendering.”

To clarify, it’s not Java2D that is clearing the canvas; it’s AWT that triggers this. Also, there are a few other places (like in the GLJPanel docs) that mention Java2D. This might be accurate for Swing/AWT components where Java2D is involved in the painting process, but what about a LWJGL or SWT implementation where that might not be the case? I just want to make sure the JSR-231 spec is not being overly restrictive here (and that it is not mentioning implementation details in the spec).

Thanks,
Chris

Hi,
“Should” and “If” are good name convention for method name in GLJPanel.shouldPreserveColorBufferIfTranslucent()? I agree it sounds awkward. I agree with Matzon also that opengl related com.sun packages be in javax.media.opengl.utils.

  • glut -> javax.media.opengl.glut
  • cg -> javax.media.opengl.cg
  • animators, BuffertUtils -> javax.media.opengl.util.animator
    -> javax.media.opengl.util.bufferwrapper?
  • no doc on GLUquadric
  • no nurbs
  • no full screen

What do I need to do to get GL/GLU to have code completion in IDEs like eclipse or netbeans?

ALSO, (off topic) Xtrans demo doesn’t work: jnlp file has this property set improperly:

<property name="sun.java2d.opengl" value="True"/>

“True” should be all lower case? - AK77

Personally, I prefer com.sun.opengl, since these classes can cahnge frequently from one version to another, in contrast to javax stuff, which should be backword compatible as OpenGL is. On the other hand a sperate jar file would a good idea, when other javax.media.opengl implementaions (not from SUN) occur.

Yes, that’s correct. The TCK (Technology Compatibility Kit, which will decide what the conformance tests will be) is still to be developed. We anticipate a fairly loose TCK which will basically just verify all of the class and method signatures. This would imply that a vendor could legally stub out the implementation of the GLCanvas or GLJPanel and have the GLDrawableFactory throw an exception upon instantiation of those classes, although this would be an exceedingly poor implementation of the spec and we might tighten up the TCK to guard against this. The intent is to provide the GLCanvas and GLJPanel as the baseline implementations while allowing vendors to extend GLDrawableFactory.getGLDrawable() to support alternative toolkits, etc.

There aren’t all that many references to JOGL in the javadoc but they will be removed.

Dealing with multithreading is a fact of life for any library interfacing with the AWT. We have refined JOGL’s threading model over several releases and I believe the Threading class is the best and most minimal way of handling it. If you have a better suggestion I’d be glad to hear it.

Where specifically do you see a need for more detail? Overview documentation for the entire javax.media.opengl package is certainly lacking at this point, but I believe several places in the Javadoc specifically discuss the fact that exceptions may be thrown later than expected due to multithreading behavior.

Mustang has solved the full-screen issues on X11 platforms as well as improving the Windows full-screen behavior when the Java2D DirectDraw pipeline is disabled (e.g., when the GDI or OpenGL pipelines are enabled). Mac OS X already has a workable full-screen implementation for the AWT and Apple is working on fixing remaining issues with it.

It’s also possible to provide a new implementation of the GLDrawableFactory.getGLDrawable() method in a JSR-231 compliant implementation which would accept some other kind of Object (say, a game mode String such as in GLUT) and which would provide a full-screen GLDrawable completely decoupled from the AWT.

All of the visible APIs in the Javadoc must be implemented. This is standard practice for Java APIs. See my comment above about the TCK.

I disagree. These APIs are not tightly coupled to the rest of the implementation and having them in a separate namespace removes backward compatibility restrictions and allows them to evolve more freely. They could also be provided in a separate jar file.

I’ve tightened up the specification here. Please look at the javadoc from tomorrow’s nightly build (linked from the JOGL home page under “Current nightly build”).

This is an undesirable change as we don’t want to introduce magic behavior of swapBuffers depending on who is calling it. I’ve changed the spec to read that it is called automatically for GLAutoDrawables when auto buffer swapping is enabled and in this case should not be called by the end user.

release() should be called before destroy(). Currently the implementation of destroy() will throw a GLException if the context is current. This could be specified better or destroy() could be changed to automatically call release(), but I’d like to avoid as much “automatic” behavior of the low-level APIs as possible. I’ve added more text to the specification of destroy(); it could be more tightly specified. Calling release() after destroy() will cause a GLException to be thrown indicating that the context is not current.

The problem I see with this change is that it creates a new GLContext object, even though that object happens to refer to an existing, underlying OpenGL context. If you call it twice with the same OpenGL context current you will get back two different GLContext objects. wrapExternalGLContext might work but I don’t like the difference in name from the createGLCanvas, createGLJPanel, and createGLPbuffer APIs. If you have more thoughts on this please post them.

The javadoc for these methods may be a little misleading. These are overridden from the parent class (Canvas) and as such these methods are already implicitly present. We could delete the javadoc, causing it to be inherited from the superclass, but I’m not sure that’s a better solution.

The setRealized() method is the key to allowing the GLDrawables returned from GLDrawableFactory.getGLDrawable() to be used to implement new Canvas subclasses supporting OpenGL. I don’t anticipate removing or changing this method. It is unfortunate that the presence of that method pollutes the APIs for GLCanvas, GLJPanel and GLPbuffer, but I think this is a relatively small price to pay for the power of being able to create new heavyweight OpenGL widgets. For what it’s worth, this has come up in the expert group and we decided to leave it as is.

We could make these classes abstract but I don’t see a strong advantage in doing so. They are in the end concrete subclasses of the AWT and Swing widgets and have the minimal amount of functionality required to support the GLEventListener callback mechanism, which is still the recommended programming paradigm. Users not desiring this can make their own widgets.

It is possible to add bindings for other window system toolkits through the GLDrawableFactory.getGLDrawable() API. Since that takes an arbitrary Object as target you could potentially pass in an SWT widget, mode string, LWJGL DisplayMode, etc. However, the JSR requires baseline support for an AWT and a Swing widget. Personally I think the spec is useless without them but I’m sure some people will have other opinions about that. The fact remains that the AWT and Swing are the standard widget toolkits for Java so this spec is going to support them by default.

Actually there is no such assumption. It’s up to the end user to format the data correctly in their Buffers; JOGL ignores the byte order of Buffers passed in. We could certainly add clarification of this in the package documentation, which still needs to be written. If you could file a bug about this with the JOGL Issue Tracker I’d appreciate it.

There are no public GLCanvas constructors, period. The GLCanvas and GLJPanel can only be instantiated through the GLDrawableFactory, and there is a convenience method in GLDrawableFactory which accepts just a GLCapabilities argument (and which can be passed null). Note that it is now possible to subclass GLCanvas and GLJPanel, but in this case we require calling the more complex constructor to ensure that subclassers think about the arguments being passed up.

That would be nice, but I think that full scene loaders should probably go in higher-level toolkits like Xith3D. Lower-level things like texture loaders and screen grabbers are our current top priorities for the utils package.

Thanks for catching that. It’s been fixed and the change will show up in the javadoc from tonight’s nightly build.

I agree that the current method name is somewhat unfortunate, but I’m not sure these other suggestions are a significant improvement. I gave some thought to whether this method should not only be conditionalized on whether the Java2D/JOGL bridge is enabled, but also on whether the widget is currently translucent (i.e., setOpaque(false) has been called), but thought these semantics would be too complicated. Still, if you think of a simple, concise name and semantic I’ll be glad to change it. I’ll continue to give this more thought as well.

No, it means that the constructors are protected and can’t be called directly by application code. They can however be called by subclasses. One of the goals of the JSR was to support subclassing GLCanvas and GLJPanel, and the semantics of doing so have been thought through fairly completely I think. We could change the wording if you have a suggestion on how it should read.

I’ve changed the GLCanvas’s documentation appropriately and removed the Java2D references in GLJPanel’s javadoc in favor of Swing. Let me know what you think about the changes.

As I’ve stated above I agree with this but don’t think the suggestions to date are much better. If you have a better one please post it.

[quote]I agree with Matzon also that opengl related com.sun packages be in javax.media.opengl.utils.

  • glut -> javax.media.opengl.glut
  • cg -> javax.media.opengl.cg
  • animators, BuffertUtils -> javax.media.opengl.util.animator
    -> javax.media.opengl.util.bufferwrapper?
    [/quote]
    We’re not going to specify the Cg binding or GLUT port in the JSR. Cg is not fully cross-platform and is evolving too quickly to consider standardizing a binding for it. The other utility classes have no dependencies on the JSR-231 implementation and could be shipped in a separate jar file if desired. Given that the implementation is open-source (BSD licensed) anybody should feel free to do this in a fork of the workspace.

The methods operating on GLU quadric objects are in the GLU interface, just as in the C API.

This is too large a piece of work to handle in the first implementation of the JSR and it’s of dubious benefit as most people who need NURBS libraries seem to write their own. We’ll look into supporting this in a future revision of the JSR.

Full-screen is supported by the underlying JDK. The full-screen support in Mustang is much improved over previous releases and should address all outstanding issues.

I don’t know; someone else should be able to help with this.

“True” enables debugging output from Java2D to the console. The XTrans demo works fine for me with the current Mustang build installed as my handler for the application/x-java-jnlp-file MIME type in Mozilla / Firefox.

My point here was that implementation details seem to be leaking through into the specification. If the idea is to define a specification that anyone can implement , then I still believe that the specification should show as little implementation specific information as possible. Currently the spec says “method x is overrided for this and this reason”. To me that’s a detail of how the RI decided to improve performance and not something that should be in the specification.
This is also why I agree with Matzon that the Threading class is kind of weird. Of course you have to deal with threading somehow, but what’s exposed now is the way the RI decided to tackle the problem, which may or may not be applicable to other possible implementations.

That would be my point. There should be a public GLCanvas constructor. There’s no reason for there not to be.

I’ve changed the documentation for the overridden methods in GLCanvas and GLJPanel to be more generic and to indicate what subclasses must do for correctness if they override these methods. Take a look at tonight’s nightly javadoc and see if they look any better.

[quote]This is also why I agree with Matzon that the Threading class is kind of weird. Of course you have to deal with threading somehow, but what’s exposed now is the way the RI decided to tackle the problem, which may or may not be applicable to other possible implementations.
[/quote]
The Threading class is the most minimal way we could come up with to work around existing, pervasive issues with multithreading in the current set of OpenGL drivers on all platforms. If it were not exposed in the API then end users wanting to use the more advanced functionality in the spec like manual GLContext manipulation would have no way of doing so in a compatible way with the implementation. Other implementations of this spec could feel free to return false from Threading.isSingleThreaded() and have the simplest possible implementation of the other methods in the class.