NullPointer exception in StandardGame.initSystem() with DISPLAY_CANVAS mode

Since this is my first post, let me start off by saying that jme looks great!  I have been a Java3D user in the past, and then gave up on it because of its slow performance and lack of input support besides AWT (using java.awt.Robot is a real pain  :D).  Its Behavior classes were also very annoying.  Jme, on the other, hand is a much cleaner design and offers many features that even other popular indie engines such as Torque don't offer.  As a Java developer myself, thanks for making good quality games in Java a reality. 



I did notice the following bug in com.jmex.game.StandardGame:



When StandardGame.DISPLAY_SYSTEM is DISPLAY_CANVAS, line 249 : "camera = display.getRenderer().createCamera(display.getWidth(), display.getHeight());" always throws a NullPointerException because display.getRenderer() is null.  I looked deeper into the source code, and I noticed that LWJGLDisplaySystem.createCanvas does not initialize the renderer (only LWJGLDisplaySystem.createWindow does).  So, the line display.createRenderer(new LWJGLRenderer(settings.getWidth(),settings().getHeight())); should be added after the canvas is initialized.  Or the renderer should be initialized in LWJGLDisplaySystem.createCanvas.



I have been using the latest version from HEAD.

The renderer is created by DisplaySystem's initForCanvas method.  This is split out so that initialization can happen in the right thread (the thread responsible for repainting the canvas).

I'm on a different pc at the moment and don't have the source code in front of me, but should StandardGame be calling DisplaySystem.initForCanvas, or should I be calling that before constructing a StandardGame?

I don't personally use standard game, but you'd want to call it after the display system is created and before anything that needs access to the renderer.  You'll also need to call it in the proper thread as noted above.

Since StandardGame is a final class and doesn't provide any callbacks during initialization, I think that there is indeed a bug in StandardGame, and DisplaySystem.initForCanvas should be called after the canvas is created in StandardGame.initSystem.

I'll try to get a look at this soon…if you'd like to submit a patch that would be helpful.

I may be able to get around to this later tonight.  Where would you like me to post the patch?

In here is fine. Either an actual patch or just reference what lines of code you added and where.

I tried inserting DisplaySystem.initForCanvas both before and after the canvas was created, and now I get a NullPointerException during the creation of the renderer.  It seems that the display is still not completely initialized.  I am trying to create a level editor tool by wrapping the canvas in a JPanel and then adding that to a JFrame that I have complete control over, so that I can add a menu bar and other controls to the frame.  Is it possible to only create a canvas to render into without creating the default native window that is created with DisplaySystem.createWindow ?  What initialization steps do I need to take to make this happen?  I do not have to use StandardGame.  I am using it now because it seemed liked the simplest way to get things up and running quickly.  If there is a tutorial or example that already explains this?  If so, please point me in the right direction.



Thanks!   

This is something I don't have any real experience with, and is why I haven't tried to add support to StandardGame until recently.  We definitely need support added to StandardGame for this, but we first need someone that knows how to do it in the first place to be able help write it. :slight_smile:

You need to call initForCanvas() in the initGL() method of AWTGLCanvas (LWJGL class), I am not sure exactly where does jME makes the call though.

It's called in the doSetup method of SimpleCanvasImpl and SimplePassCanvasImpl

I did a search for the callers of the "createCanvas" method in the jme project and found some good examples of AWT/Swing integration, including applets.  "jmetest.util.JMESwingTest" provides a good example.  I see that using canvas's requires a completely different design from the "AbstractGame" framework since you are relying on openGL to utilize AWT to drive your updating and rendering in a typical repaint operation.  The "game loop" is in LWJGLCanvas.paintGL(), where it calls the update and render methods for a "JMECanvasImplementor" object that you must assign using canvas.setImplementor.  Therefore, I recommend that the canvas option should be removed from StandardGame since its seems very problematic to try to integrate it cleanly.