Author

Raspberry PI


JavaFX game on Raspberry PI

posted Dec 25, 2012, 3:32 PM by noxo   [ updated Dec 26, 2012, 10:51 AM ]

Intro

There seems to be a lot of cool things happening on Java SE embedded world.

Java SE for ARM has now been there for while, but it has been lacking support for properly accelerated 2D graphics -- you could just dream running your AWT/Swing game in decent frame rates on embedded ARM platform. (**)

But that has just been solved by release of Java 8 ARM Early Access which includes JavaFX with OpenGL ES support on it. I have been reading that JavaFX is being recommended over AWT for creating UIs, and it seems like AWT is not going to be included in future releases of Java SE embedded.

So, sounds like there's a chance for running Java based 2D game in Raspberry PI with decent (30-40) FPS, why not try it? 

** [There were few lower level Java OpenGL wrapper libraries (like JOGL) already available for ARM accelerated graphics.]

The plan

I thought transforming my trusty old Asteroid Race Android game would be nice way of trying this out, because it's already Java, we just need to get rid of Android Graphics APIs and start using JavaFX instead.

Game will be developed+compiled in PC and then deployed to Raspberry PI for FPS analysis :)

Buildin' it 

I've put the full sources of JavaFX port available in GitHub  -- or you can just grab the prebuild JAR one from end of blog.

If you're planning to play with sources in Eclipse, make sure you need to add jfxrt.jar in classpath (Windows->Preferences->Available JREs->Edit). This game uses features of JavaFX 2.2, so check that you have right version. I used JDK 1.7.0_10 to compile and test it on PC.

To build the executable JAR file, I used javafxpackager which is included in JDK, so just run this command in Eclipse project folder after compiling project to produce the JAR file.

    javafxpackager -createjar -appclass org.noxo.Game -srcdir bin -outdir out -outfile asteroidhd.jar

Gameloop & JavaFX canvas

With 2d sprite based games I personally prefer more maintaining sprites/bitmaps and drawing them via graphics context, instead of using scene based graphics.

Starting from JavaFX 2.2 there has been support for this via Canvas class, so you can do the stuff almost in good-old-AWT-way, by getting reference to graphics context and then do the drawing using methods (drawImage, drawString..) provided.

One difference in JavaFX (vs AWT) is that drawing operations by graphics context should be done from JavaFX application thread.

One way of implementing game-update-render loop, could for example look like this:

class Game extends javafx.application.Application
{
    Canvas canvas = new Canvas(1280,720);
    AnimationTimer animTimer;
    
    public void start(Stage stage) {
        
        Group gameNode = new Group(canvas);
stage.setScene(new Scene(gameNode));
stage.show();

        animTimer = new AnimationTimer() {

        @Override
            public void handle(long arg0) {
                gameLoop();
            }
        };

        // start running gameloop in javafx application thread
        animTimer.start();
    }
        
    public void gameLoop() {
        updateGame();
        renderGame();
    }

    public void updateGame() {
                // update your game logics here
    }

    public void renderGame() {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        // draw your stuff using gc..
    }

    public static void main(String arg[]) {
        launch(arg);
    }
}


Installing to Raspberry PI

  • Have Raspberry PI with hard float Linux distribution installed on it
    • I had the 2012-12-16-wheezy-raspbian.zip installed from raspberrypi.org 
  • Configure GPU memory to 128MB 
    • Edit boot/config.txt => gpu_mem_256=128
    • Configuring this depends on board and Linux distro version
  • Change resolution to 720P (1280x720)
    • Edit boot/config.txt => hdmi_mode=4
  • Install Java 8 Early Access
    • Download from Oracle
    • Uncompress file anywhere (tar -xvf jdk-8-ea-b36e-linux-arm-hflt-29_nov_2012.gz)
  • Run the game
    • Push game .JAR file to Raspberry PI
    • Change in Java 8 folder (jdk-1.8.0/bin)
    • ./java -Djavafx.platform=eglfb -jar /JAR_FILE_LOCATION/asteroidhd.jar
I did include average FPS counter in game. Raspberry PI seems to be able to run this game with stable ~35 FPS after bit of a jitter at startup (didn't yet try to do any kind of optimization). I guess the lag at startup is due to cost of creating and initializing textures into GPU, but didn't yet try to profile it.

I really like the new cool features available via JavaFX, it seems to also support H264 and video streaming nowadays, which has been lacking in Java for a long time. I've also been reading plans to have high level-scene-based 3d support in JavaFX - that's really good news!

MonoGame + Raspberry PI + OpenGL ES 2.0

posted Aug 17, 2012, 2:34 AM by noxo   [ updated Oct 21, 2012, 8:19 AM ]

Intro

In this blog entry we'll build H/W accelerated version of MonoGame.Tetris example for  Raspberry PI.

Raspberry PI does not have HW OpenGL libraries for accelerated graphics, instead it has OpenGL ES 2.0 libraries (and ES 1.1 embedded in same libraries) for acceleration. However it's possible to run OpenGL applications on RPI, but rendering will fallback to software OpenGL renderer (Mesa).

By default MonoGame for Linux uses OpenGL and can be executed with few tricks, but performance is not good.

I've baked an experimental MonoGame (based on MonoGame 2.0) for OpenGL ES 2.0 based desktop environments, in practice implementation was only about mixing Android GLES and Linux versions of MonoGame, so I don't take any credits for this :)

Update 18/Aug:
There's now also fork of MonoGame 3d in GitHub. Start observing it, since it's based on forthcoming release on MonoGame which has a lots of new cool features :)

Update 17/Oct:
MonoGame 3d for RPI is now out, check out: http://www.youtube.com/watch?v=jwbYe6eoZgE&feature=youtu.be

Running prebuild accelerated Tetris

Here's a short checklist for running prebuild Tetris which is available as tetris_raspberry.gles2.zip at the end of this page.
  • Debian Squeeze (debian6-19-04-2012.img) installed on RPI
  • Mono Runtime 2.6.9 (apt-get install mono-runtime)
  • mesa opengl drivers (apt-get install mesa-common-dev)
After the required software has been installed start X, open terminal, and "cd" into directory that tetris_raspberry_gles2.zip is unpacked and type:

        mono Tetris.exe

Reason why I'm using the Debian 6 instead of 7/Wheezy is that Mono seems have issues handling floating points on ARMHF (hardware floating point architechture).

Building accelerated Tetris from scratch

I've been using MonoDevelop 3.0.3.5 and Windows 7 to build the project. 

Make sure build target is set to Net 3.5 in MonoGame and Tetris projects, since Mono 2.6 does not support Net 4.0.

First we need to checkout source code for the modules:
  • MonoGame for RPI (git clone https://github.com/noxo/MonoGame)
  • OpenTK (git clone https://github.com/mono/opentk) version OpenTK SVN seems not yet work
  • MonoGame Samples (git clone https://github.com/CartBlanche/MonoGame-Samples)
Compile MonoGame against OpenTK and then Tetris against MonoGame, if you were lucky there were no errors, just
lots of meaningless warnings :)

Copy the compiled binaries to Raspberry PI.

We need also to copy VideoCore GPU libraries to folder were compiled binaries are from /opt/vc/lib. Copy libEGL.so and libGLESv2.so.

Wait - small hack needed to VideoCore EGL driver

This step is not needed if you trying prebuild Tetris, since tetris_raspberry_gles2.zip already has patched libEGL.so included.

Default Raspberry PI VideoCore OpenGL ES drivers (/opt/vc/lib) does not support attaching into X11 surface, and
we need to tweak one  of GLES library (libEGL.so) file to get things working.
  • Push x11-hack-libegl.txt from end of this page to Rasberry PI
  • sh x11-hack-libegl.txt
  • copy patched libEGL.so from /opt/vc/lib to same directory as compiled Tetris binaries
This hack is not complete since it's hardcoded to create 800x600 window, so some work is still needed.

Now cross your fingers, and try executing Tetris.exe -- works for me :)

Stuff needed for sounds

MonoGame sound system is based on OpenAL, so if you plan to use xna.SoundEffect (even without invoking play),
the following stuff is needed:
  • OpenAL libraries (apt-get install libopenal-dev)
  • Load the sound kernel module (modprobe snd_bcm2835)
The last step is not necessarily needed on all distros, since sound module is probably preloaded.

That's it :)

1-2 of 2