SilverLining for Android 1.0 Skies, 3D clouds, and weather for Android

- Main Page
- Related Pages
- Packages
- Classes
- Files

Integrating SilverLining into a Java-based Android App

Let's walk through the SilverLiningAndroidDemo to learn how to integrate SilverLining into a traditional, Java-based Android application. SilverLining itself is native code in order to provide the best performance, but we provide JNI interfaces, a simple Java class that wraps them, and an Android Library to make integration into your Java-based app easy.

## Building and Running the SilverLiningAndroidDemo

Let's start by getting the SilverLiningAndroidDemo up and running. We assume you already have the Android SDK installed and integrated into Eclipse using ADT, and have a device capable of running OpenGL ES 2.0 and Android 2.3.3 (API level 10) tethered to your development system.

### Adding SilverLiningAndroidLibrary to your workspace

SilverLining is provided as an Android Library to make integration as easy as possible into Java-based Android projects.

To add SilverLiningAndroidLibrary to your Eclipse workspace, you'll need to import it from our SDK. In Juno, you can do this using Import / Android / Existing Android Code into Workspace. In Indigo, choose File / New / Android Project, then select "create project from existing source", select the SilverLiningAndroidLibrary folder in our SDK, and specify a build target of at least Android 2.3.3.

You're now ready to reference the SilverLining Android Library from your app's project. Let's use our sample app as an example.

### Adding the SilverLiningAndroidDemo to your workspace

Just as you added SilverLiningAndroidLibrary to your workspace using Import / Android / Existing Android Code (Juno) or File / New / Android Project / Create Project from Existing Source (Indigo), do the same for the SilverLiningAndroidDemo folder in our SDK.

Right-click on the resulting SilverLiningDemoActivity in your workspace, and select Properties. From here, select the Android section. Under "Library", you should see a reference to ../SilverLiningAndroidLibrary that allows use of SilverLining in this demo Activity. If not, go ahead an add it in. This is the key step toward using SilverLining in an app.

### Running the SilverLiningAndroidDemo

Right-click the SilverLiningDemoActivity in your workspace, and select Run As / Android Application. If your device is properly tethered, you should see our sample app appear on your device:

The SilverLiningAndroidDemo running on a Kindle Fire

## Exploring Usage of the SilverLining class

Let's have a closer look at the SilverLiningDemoView class inside the demo activity's source.

You'll see that we import com.sundogsoftware.silverlining.* to bring in the code included in the SilverLiningAndroidLibrary. The complete JNI interface to SilverLining is available, but most of what you need is in the simplified SilverLining class. The Renderer class inside SilverLiningDemoView illustrates its usage.

- SilverLining is initialized in the onSurfaceCreated method. Here, we instantiate our mSilverLining member, and call Initialize() to pass in our license credentials (if any) and the AssetManager used to access SilverLining's resources, which should be included in the Resources directory of your assets folder.

- After initializing SilverLining, some cloud layers are added using the AddCirrusLayer, AddCumulusCongestusLayer, and AddStratusLayer methods. We also set the simulated location using SetLocation() and the simulated time using SetDate() and SetTime(). Ensure that your location and time zone are consistent, or that you're using GMT and a time zone offset of 0. We also add in a little wind for some visual interest.

- Each frame inside OnDrawFrame(), we pass our view and projection matrices to SilverLining using its SetMatrices() method. This allows SilverLining to draw it sky and clouds consistently with the rest of your scene.

- Also each frame, we call DrawSky() to draw the skybox, and DrawClouds() to draw the clouds, precipitation, and lens flare effects. Your own drawing should happen in between DrawSky() and DrawClouds().

For convenience, here's what the SilverLining intialization code looks like in the demo app:

    mSilverLining = new SilverLining();
    if (!mSilverLining.Initialize("User name", "License code", mAssets)) {
            Log.e(TAG, "Error initializing SilverLining.");
            return;
    }

    cirrusLayer = mSilverLining.AddCirrusLayer(8000.0f, 80000.0f);

    cumulusLayer = mSilverLining.AddCumulusCongestusLayer(3000.0f, 40000.0f, 0.5f);

    stratusLayer = mSilverLining.AddStratusLayer(1000.0f, 0.8f, 500.0f);
    stratusLayer.SetEnabled(false);

    mSilverLining.SetLocation(47.6097f, -122.3331f, 100.0f);
    mSilverLining.SetDate(2012, 7, 1);
    mSilverLining.SetTime(20, 0, 0, -8.0f, true);

    mSilverLining.SetWind(40.0f, 90.0f);

It's also possible to create cumulonimbus (thunderhead anvil clouds) and cirrocumulus clouds using similar methods. Precipitation effects are also available using SetSnow() and SetRain().

The frame update code looks like:

    if (mSilverLining != null) {
            mSilverLining.SetMatrices(mModelview, mProjection);

            mSilverLining.DrawSky();

            // Draw your objects here...

            mSilverLining.DrawClouds();
    }

## Java Integration Overview

To recap, integrating SilverLining into your own app consists of the following steps:

- Import the SilverLiningAndroidLibrary into your project, and create a library reference to it from your own Activity's project in your activity's Android project settings.

- Copy the SilverLining Resources folder from one of the samples in the SDK into your own assets folder.

- import the com.sundogsoftware.silverlining.SilverLining class into your code.

- use SilverLining.Initialize() at startup to tie SilverLining to your asset manager and validate your license code (invalid license codes will just result in SilverLining running in evaluation mode, which exits your app after 5 minutes per run.)

- Specify your simulated time, location, and weather conditions after initialization, using methods such as SetLocation(), SetDate(), SetTime(), AddCumulusCongestusLayer(), AddCirrusLayer(), SetRain(), etc.

- Each frame, update your view and projection matrices with SilverLining using the SetMatrices() method. Then, call DrawSky() to draw our skybox before your own geometry, and call DrawClouds() to draw our clouds after your own geometry.

That's all it takes to get up and running.

## Going Deeper

While the SilverLining class exposes the features most commonly used, there is a larger API available as well allowing for more advanced features. For example, localized cloud layers may be placed, specific visibility conditions may be specified, and wind may be simulated at specific altitudes.

Most of the C++ API for SilverLining is exposed to Java via JNI. If you explore the rest of the Java files inside com.sundogsoftware.silverlining, you'll see what's available. The best reference for these methods is SilverLining's C++ reference documentation, available at http://www.sundog-soft.com/docs/html/annotated.html .

The full JNI layer for SilverLining is automatically generated using a tool called SWIG. This allows us to keep the Java interface for SilverLining complete and up to date, but sometimes SWIG can do some non-intuitive things in the process by introducing its own data types to manage the differences between C++ and Java. It also strips out the comments in the C++ interface, making referring to the online C++ documentation above essential for advanced use of SilverLining for Android.

Inspection of the SilverLining.java class can provide some useful patterns. For example, SilverLining.SetMatrices() uses the helper methods new_double_array() and double_array_set_item() on the SWIG-generated SilverLiningAtmosphere class to convert a Java array of floats to a C++ pointer to 16 double-precision values like this:

            SWIGTYPE_p_double dProjection = SilverLiningAtmosphere.new_double_array(16);
            SWIGTYPE_p_double dModelview = SilverLiningAtmosphere.new_double_array(16);
            for (int i = 0; i < 16; i++)
            {
                    SilverLiningAtmosphere.double_array_setitem(dProjection, i, projection[i]);
                    SilverLiningAtmosphere.double_array_setitem(dModelview, i, modelView[i]);
            }
            mAtmosphere.SetProjectionMatrix(dProjection);
            mAtmosphere.SetCameraMatrix(dModelview);
            SilverLiningAtmosphere.delete_double_array(dProjection);
            SilverLiningAtmosphere.delete_double_array(dModelview);

Most of the SWIG-generated JNI interfaces are more straightforward. However, we're happy to provide guidance via support@sundog-soft.com if you get stuck.