Swing / jME integration

Hey Folks,



I’ve finished implementing a Swing / LWJGL integration in jME (not checked in yet, of course.) It runs fairly well, limited mostly by the speed of your card’s glReadPixel implementation. Because of this limitation, the fps will remain mostly constant on varying levels of scene complexity.



Part of the implementation includes a headless rendering path, which basically means jME can render to a completely offscreen context with nothing showing up on the screen. This is potentially useful for other applications, for example renderering directly to .mov or .mpg. Or rendering scenes that can’t run real time, such as for creating animated movies Pixar style, etc.



Included for this purpose are a few app classes:



BaseHeadlessApp (similar to BaseGame)

SimpleHeadlessApp (similar to SimpleGame)



The other classes are:

com.jme.util.JMEComponent (extends java.awt.Component and can plug right into JFrame, Frame, JPanel, or what have you…)

com.jme.util.HeadlessDelegate (handles communication between JMEComponents and Renderers)



Other classes have added methods:

DisplaySystem and it’s 2 subclasses

Renderer

LWJGLRenderer

LWJGLTextureRenderer



The basic flow goes like this…

The app calls a new DisplaySystem method called createHeadlessWindow. In the case of LWJGL, this sets up a standalone Pbuffer and sets it as the main context.

The JMEComponent has a thread that repaints itself every 50 ms (configurable). The class overrides paint and basically takes image data stored within itself and paints it over itself. This image data is scaled (or not… it’s configurable) to the size of the component.

The image data is copied into the JMEComponent in your update method via a call to a helper method in the HeadlessDelegate class mentioned above. I decided to go that way because this is the most expensive call and this way you can decide how often to call it. I use a “time since last called” limit method.



That’s the gist of it. Your own app basically (if extending SimpleHeadlessApp) has to only implement a few lines of code to get things going. I’ve put together a JMESwingTest class to show an example.

The concept seems solid to me. I do have one question though, it’s more of a design for later on question. Since this version renders to the PBuffer then to the swing component, while JOGL has it’s own swing component with a direct OpenGL context, how do you see this relationship when JOGL is implemented? Specifically, Swing integration will now be handled differently between the two APIs? These are questions, because I haven’t put enough thought into it to know one way or the other. Just thought I see if you knew the answer.



The headless rendering > movie file sounds really cool. I’d love to see a demo of that.

"mojomonk" wrote:
The concept seems solid to me. I do have one question though, it's more of a design for later on question. Since this version renders to the PBuffer then to the swing component, while JOGL has it's own swing component with a direct OpenGL context, how do you see this relationship when JOGL is implemented? Specifically, Swing integration will now be handled differently between the two APIs? These are questions, because I haven't put enough thought into it to know one way or the other. Just thought I see if you knew the answer.
Been thinking about this since you mentioned it yesterday on IM. I guess my answer is that if JOGL can support standalone Pbuffers (which is an OpenGL thing, so it should) then this method is "cross-implementation"... If you were targetting JOGL specifically though, you may want to use their GL Panel thing for greater speed.

As I said before, this method uses glPixelRead to grab the contents of GL. It's a tested method (see the venerable GL4Java) but obviously slower than regular opengl usage. :/ I don't think my Swing integration code will be our final product in this area, but at least one that works for now. We'll see though once we get some of the old hardware people out there trying it. :)
"mojomonk" wrote:
The headless rendering > movie file sounds really cool. I'd love to see a demo of that.
Me too... :) It's one of those "now it's possible, who has the time to do it" things... hehe. Maybe after the game.

One other thought for whenever we put this in… As with any new feature, I’m expecting a shake out period as more people try this feature. I know it’s off the beaten path, but if a handful of you would play with it and report issues or desires you come across, it would help a lot.

ok, sounds good to me.

in. fire away! The test class is jmetest.util.JMESwingTest