Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Latest commit

 

History

History
584 lines (466 loc) · 31.1 KB

eclipse_jme3_android_jnindk.md

File metadata and controls

584 lines (466 loc) · 31.1 KB
title
Eclipse + jME3 + Android + JNI/NDK

Eclipse + jME3 + Android + JNI/NDK

This guide will show you how to effectively set up your Eclipse environment for not only a basic JME3 project, but an Android project, an assets project, and a JNI project (including the ability to build for Android through NDK).

While you do not have to create a project of each type to use Eclipse and this guide, note that the Android and JNI projects do require having a base Eclipse project to be applicable using this guide.

The code samples provided in this guide should work for any IDE, but setting up/configuring your IDE to do what Eclipse does in this particular guide may require some creative workarounds.

Please note that projects that use Android UI elements or are created using Eclipse can not be ported to iOS. See this page on how to create a cross-platform project using the jME SDK that can also be edited in the Eclipse IDE. This saves you the setup work outlined below.

Setting up JME3

I will assume you already have downloaded (and built, if necessary) the JME3 binaries. If not, either download the latest SDK release, engine build (recommended for new users), or take a quick detour over to this guide to build from source (recommended for advanced users).

One directory you should have on hand (or know where to find) is the location of the resulting library (JAR) files.

For the various methods of obtaining the libraries (as described above), the path is usually in one of the following places:

  • SDK: [SDK Install Dir]/jmonkeyplatform/libs
  • Nightly: /libs
  • Source: [SDK Dir]/sdk/build/cluster/libs

Throughout the course of this guide, do not copy JAR files to any project directory - leave them in their original spots so they can be easily updated for when a JME3 update comes out or when you rebuild the source.

Workspace

If you are unfamiliar with Eclipse and how it lays out/stores its configuration, one of the first things that you should be aware of is that almost all settings that are set at a workspace-level (i.e. through Window → Preferences) are stored in the workspace.

You can select your workspace either by starting Eclipse (if the initial prompt is enabled) or by navigating to File → Switch Workspace → Other.

Eclipse: Switch Workspace

For this guide, we're going to create a new folder called JMonkey in our C:\ drive, however this folder can be anywhere on your drive (the same applies for users of other operating systems). We will also switch to it as a workspace.

Base JME3 Project (Desktops)

Prerequisites:

  • JME3 (downloaded/extracted/built/installed) libraries located

It's time to create our base JME3 project, which is actually relatively easy. Go to File → New → Java Project.

NOTE: If you don't see Java Project, you are more than likely in a perspective other than Java or Java EE. Simply select Project… and then select Java → Java Project from the window that appears.

Give your project a name (we'll call ours JMEclipse-Base) and click Finish. The project should show up in the Project Explorer pane on the left.

First, we need to configure our build path. Right click the new project entry and go to Build Path → Configure Build Path, and then select the Libraries tab.

There are a number of libraries you're going to need to include, as the 'core' JME3 system requires them.

There will be many libraries in the previously identified libs folder that aren't initially used. Certain aspects of JME3 (for instance, collision detection) will require the appropriate JAR if your code requires that functionality. However, it is highly recommended you do NOT include every JAR in the libs folder due to the fact that exporting them all when they are not needed will result in a huge jar file (~60MB).

Click Add External JARs…, navigate to the JME3 libs folder (see Setting up JME3 if you're not sure where this is), and select each of the following:

  • jME3-core.jar
  • jME3-desktop.jar
  • jME3-jogl.jar
  • jME3-lwjgl-natives.jar
  • jME3-lwjgl.jar
  • jogl-all.jar
  • lwjgl.jar
  • vecmath.jar

Add the JARs, hit OK, and you've successfully set up the base JME3 build path for your project.

The last bit that must be added are assets. Note that while the SDK has a single way of managing your assets, assets can be handled in a number of ways in other IDEs.

The rule for assets is that their files must be on the build path. This means that you can either include the inner folders directly in your project, or you can create a separate project (and thus, a separate JAR) for your assets.

Alternatively, you can keep them in the local directory if you do not wish to package them with the JAR, though this may not be desirable for certain deployments (such as applets, Android apps, or JNLPs).

To include your assets within your base project, follow the Assets section without creating a new project. However, do note that this will make the process of including these assets in your Android project, if you create one, much harder.

Finally, the SDK creates a base source file for you that ends up being the main JME3 entry point. Since we're using Eclipse, we'll have to manually create that file.

Right click your project, go to New → Class, and fill out the appropriate information:

  • Package: your package name (i.e. com.jme3.test)
  • Name: the class name (i.e. MyGame)
  • Superclass: com.jme3.app.SimpleApplication

Then hit Finish. This will create and open the new class file. Eclipse should have automatically inserted the method “simpleInitApp()” for you. This is where all of your game's start up code will go.

Finally, create a main function as the Java entry point:

public static void main(String[] args) {
    MyGame app = new MyGame();
    app.start();
}

Running

Running your JME3 project is quite simple in Eclipse. You can either create a Java run configuration or you can simply hit CTRL + F11 to run the project (if Eclipse doesn't know what to do, it will ask).

Packaging

Packaging your JME3 project is also very straightforward. Assuming you heeded the warning stated earlier about not including every JAR in the libs folder, you should be able to right click your base JME3 project, go to Export…, select Java → Runnable JAR file, specify an output location and click Finish.

If you have assets set up as a JAR, make sure to read the Packaging section under Assets.

Assets Project

Each JME project has a set of assets that are used to load textures, models, and other resources used by your game.

As mentioned earlier, assets can be located/included in one of several ways. This section will describe how to include your project's assets through the use of a separate JAR file, which has the added advantage of allowing you to update assets without needing to update the JAR itself. If you have a dynamic class-path system set up, this could be very useful.

First, create another generic project by going to File → New → Project… → General → Project and giving it a name (we'll call ours JMEclipse-Assets).

We create a General (non-Java) project for cleanliness because our assets will not require any special build settings or the like.

For new users, it's a good idea to add the initial JME3 folders that the SDK creates, as they are referenced by many other guides on the web. To do this, for each of the following right click on the assets project and go to New → Folder, type in the name listed, and hit Finish:

  • Interface
  • MatDefs
  • Materials
  • Models
  • Scenes
  • Shaders
  • Sounds
  • Textures

Although this specific structure is what the JMonkeyEngine SDK generates upon the creation of a new project, it is by no means the only way to structure your project. All asset loading methods will work with folder names other than those listed above.

Packaging

Packaging your assets is also a simple process. Right click the assets project and click Export… and then select Java → Jar file. It will show a list of files you can export; make sure to uncheck all files such as .classpath, .project, and any .jardesc files you may have created. As well, ensure only the resources and assets you want to export are checked.

Check Export generated class files and resources, select a destination for the JAR file, and check Compress the contents of the JAR file, Add directory entries, and Overwrite existing files without warning. Click Finish.

Optionally, you can click Next and specify a .jardesc file by checking Save the description of this JAR in the workspace and specifying a location for a .jardesc file. That way you can simply double-click the .jardesc file and easily re-export your assets when they change (remember, always refresh your project before exporting!).

Android Project

Prerequisites:

  • JME3 (downloaded/extracted/built/installed) libraries located
  • JME3 Base Project created (as described above)
  • Android SDK downloaded and the Android 8 (2.2) target installed (higher API versions work too but may limit compatibility when deploying)
  • Assets compiled into a JAR (see Packaging under Assets)

The Android project is a slightly more involved setup project, but is still quite simple, even for new users.

To start, create another Android project by going File → New → Project… → Android → Android Application Project.

Fill out the following information and then click Next:

  • Application Name: name of your application (i.e. JMEclipse Test Project)
  • Project Name: name of the project in the workspace (i.e. JMEclipse-Android)
  • Package Name: name of the base package, preferably the same as the one used in the base project (we'll re-use com.jme3.test)
  • Minimum Required SDK: API 8 (Must be AT LEAST SDK 8 for OpenGLES2 and JNI)

Most of the lower options are defaulted based off of your ADT configuration and should work as-is.

After clicking Next, uncheck Create activity (JME3 provides a base activity class). You can check/uncheck Create custom launcher icon at your own preference.

Make sure that Mark this project as a library is unchecked and hit Finish (or Next if you chose to create a custom launcher icon; this will take you to a customization page, after which you will be forced to finish).

First, we need to set up our build path. Surprisingly enough, it's much easier than the base project, though it is done a little differently.

At the time of this guide's writing, the latest release of the ADT/Eclipse plugin creates a libs folder within your project structure. This special folder automatically includes all of its contents on the build path.

Normally, you would drop the JAR files directly into this folder. However, this is undesirable as future releases/builds of JME3 would require you to re-copy all of the JAR files. Instead, we will simply link them.

For each of the following, right click the libs folder within your Android project and go to New → File, click Advanced », check Link to file in the file system, click Browse…, navigate to the JME3 libs folder (as identified in the Setting up JME3 section above), double click the listed JAR file, and then click Finish:

  • jME3-android.jar
  • jME3-core.jar

There will be many libraries in the previously identified libs folder that aren't initially used. Certain aspects of JME3 (for instance, collision detection) will require the appropriate JAR if your code requires that functionality. However, it is highly recommended you do NOT include every JAR in the libs folder due to the fact that exporting them all when they are not needed will result in a huge jar file (~60MB).

As well, repeat the above step for your compiled assets JAR (see Packaging under Assets).

Now that the core JME3 libraries have been added, we'll need to include our base project's code. To do this, right click on the Android project and go to Build Path → Configure Build Path, select the Projects tab, click Add, and select the base project (in our case, JMEclipse-Base).

Lastly, select the Order and Export tab. Ensure that your base project (i.e. JMEclipse-Base), Android Private Libraries, Android Dependencies, and optionally Google APIs (if you have that target enabled) are checked. This step is important, or your project's libraries/assets will NOT be exported into the end APK.

Click OK, and your project's build path will be set up.

The next step is to create the application's activity and edit AndroidManifest.xml to configure the project to actually use our JME3 project.

First, right click on the Android project and go to New → Class, entering the following information and hitting Finish:

  • Package: your application package (it's best to use the package specified in the project creation dialog; for this guide, we'll re-use com.jme3.test)
  • Name: the activity class' name (i.e. JMEclipseActivity)
  • Superclass: com.jme3.app.AndroidHarness

This will create a new activity class. In the resulting file, create a default constructor and add the following code:

public JMEclipseActivity()
{
	// Set the application class to run
	appClass = "com.jme3.test.MyGame";
 
	// Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems
	eglConfigType = ConfigType.BEST;
 
	// Exit Dialog title & message
	exitDialogTitle = "Quit game?";
	exitDialogMessage = "Do you really want to quit the game?";
 
	// Choose screen orientation
	screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 
	// Invert the MouseEvents X (default = true)
	mouseEventsInvertX = true;
 
	// Invert the MouseEvents Y (default = true)
	mouseEventsInvertY = true;
}

Pay close attention to the values above; appClass MUST be the full package + class name of the class in your base project that extends SimpleApplication (for advanced users, this is actually a subclass of com.jme3.app.Application).

Running

Running your Android project is just like running any other Android project. Assuming you've set up your build path correctly as instructed above, your application should deploy to any device/emulator and run as expected.

Packaging / Deploying

Packaging your Android project is too vast to entirely cover in this guide. As this step is different for each project, I will simply link to this guide to signing and exporting your APK as it outlines the most common steps to exporting you Android application to be uploaded directly to Google Play (fmly. App Market).

Native (JNI + NDK) Project

Prerequisites:

  • JME3 Base Project created (as described above)
  • At least one configured toolchain for compiling on desktop platforms (Cygwin/MinGW/MSVC/GCC/etc.)
  • Familiarity with JNI and how native libraries are included in a Java application's architecture (this section will assume you do)
  • JDK for Java 6 or above

If additionally building for Android:

  • Android SDK downloaded and the Android 8 (2.2) target installed (higher API versions work too but may limit compatibility when deploying)
  • Android NDK downloaded
  • Optional: NDK Eclipse plugin installed (although I haven't seen a real need for it quite yet - it's mainly for building/launching native Activities)

It should be mentioned that this section will not go into C/C++ best practices, sample code, or any details about the inner workings of JNI; instead, this section simply shows you how to set up the environment/configurations to create a near-seamless build environment for including your native code in both your base project as well as your Android project (if you've created one).

Building JNI is actually quite straightforward (assuming you know how the C/C++ build process works). Even for Android, the NDK provides a slick system for building/including your compiled binaries in your project.

First, create a new C/C++ project by going to File → New → Project… → C/C++ → C++ Project and clicking Next, giving it a name (we'll use JMEclipse-Native), expanding Shared Library and selecting Empty Project, then selecting a toolchain (select the most appropriate for compiling on your immediate desktop/platform, even if you plan on compiling for Android). Click Finish.

Next, we need to configure our build settings. Right click the native project, click Properties and go to C/C++ Build → Settings. Select the Build Artifact tab, ensure the drop down menu says Shared Library, and change the Artifact name field to what you want to call your eventual JNI module.

What you call your artifact is VERY important to how Java loads your library. For instance, linux dynamic library (.SO) objects require that the library have the “lib” prefix. Keep this in mind when specifying an artifact name.

If you plan on building for Android, you must include an Android makefile in your project. In order for the build process to be as seamless as possible, this guide sets it up unlike most tutorials instruct.

To do this, simply create a new file in your native project called Android.mk and set it up accordingly.

Even though the native project is not the Android project's directory, keep the LOCAL_PATH variable set to my-dir. This is important!

Next, we need to create a configuration for the Android target.

This step is only relevant/possible if you have the NDK Eclipse plugin installed. Otherwise, you will need to install awk/make (using Cygwin if on Windows) and build through the command line manually.

To do this, right click your native project, click Properties, and go to C/C++ Build → Tool Chain Editor. For the configuration, click Manage Configurations… and create new configuration(s) based on the current default configurations, putting “Android” in the name. Lastly, click OK.

For each of the Android configurations you just created, select them in the Configuration drop down menu, set Current toolchain to Android GCC, set Current builder to Android Builder, then click Select Tools…, remove everything from the right side and replace the last item with Android GCC Compiler. Click Apply and then OK.

After the toolchains have been set up, go to C/C++ Build and select the Builder Settings tab. For each of the Android configurations, select them in the Configuration drop down menu and change the Build directory to the Android project directory by clicking Workspace… and selecting the Android project (in our case it'd be JMEclipse-Android).

The last step in the Android setup is to create a symlink called jni (case sensitive) inside your Android project root that points to the root of your native project:

  • Windows: CMD prompt → cd path\to\Android\projectmklink /J jni path\to\native\project
  • Linux/Mac: Terminal → cd path/to/Android/projectln -sv path/to/native/project jni

What this has essentially done is created a separate project for C/C++ building while tricking the Android project into thinking the source files are located directly in the Android project itself. With this configuration scheme, you can easily build regular shared libraries for desktop platforms as well as build/install the Android libraries using the NDK without the need to have a copy of the source code inside of the jni folder of an Android project. By setting the workspace for the Android builder and creating a link, it executes the NDK builder inside your Android project while serving the source files as if they existed in the jni folder.

Lastly, some additional include paths need to be added. Within the properties window, go to C/C++ General → Paths and Symbols and select the Includes tab.

Under Languages, select GNU C++ (or the correct C++ equivalent) and then Add…. Specify the absolute path to your JDK's include folder, check Add to all configurations, and hit OK.

For Windows platforms, repeat the above step for the win32 directory within the JDK's include folder.

After hitting OK, you are now set to write your JNI code.

Building

Building your native project is fairly straightforward.

First, right click the native project, go to Build Configurations, select the configuration you want to build, and then right click the native project again and select Build Project. Short of packaging, that's all there is to it.

Packaging / Deploying

Packaging and deploying your native libraries is a two-sided topic. For Android, the NDK build script installs these for you, and they are packaged directly into the APK. For desktop applications, however, there are a multitude of ways to package your libraries - all of which are too vast to be included in this guide.

These libraries, however, are simply JNI libraries and should be loaded as such. A simple web search will explain how JNI works and how to load these libraries.