This tutorial will help you setup a basic 3D scene in Android using the Rajawali 3D library. There are not a lot of tutorials out there for the more recent versions of the framework, and there are some changes you need to be aware of.

In the past, Rajawali worked by allowing you to render 3D and 2D scenes in an extended activity and then later in an extended fragment. A lot has changed since then and since their last official release, 0.9. Rajawali now uses two classes, RajawaliSurfaceView and RajawaliTextureView to display the renderer to the user.

If you have no clue what I am talking about, then that’s fine. This tutorial assumes you don’t know much.

Start the Project

Let’s start by making a project. Open up Android Studio and click on “New Project….” in the File Menu. Let’s call our project “RajawaliBasicProject”.

Next we can just choose the default Android Version and choose “Blank Activity” as our activity. We can keep the name “MainActivity” as our activity name.

Get Rajawali From Maven and into your Android Studio Project

Next, we want to to get Rajawali into our project. We are going to do this using Maven. This should work for the latest version of Rajawali, but you might have to change out your version for another one. If you cannot find the version, try looking in the RajawaliExamples gradle dependencies in Github or from where they host the Maven package.

In your build.gradle (Project: RajawaliBasicProject) file, we need to add a few lines.

// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } jcenter() } }

Notice the addition of mavenCentral() and maven { url “https://oss.sonatype.org/content/repositories/snapshots/” }. This will allow Android Studio to connect to this Maven Server to retrieve a library.

Now we need to add a line to build.gradle (Module: app).

dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.0.0' compile 'org.rajawali3d:rajawali:1.0.186-SNAPSHOT@aar' }

This is where my note from earlier about retrieving the build version might come in handy. We added the line compile ‘org.rajawali3d:rajawali:1.0.186-SNAPSHOT@aar’.

Now we should see a note at the top asking you the sync the gradle. Click Sync Now and it should build. If it does not, you might want to recheck your code.

Setting Up Our Scene

We are going to make a simple scene of the Earth rotating much like the older, basic Rajawali tutorial on their Github, only with their new code. First, we need to extend the Rajawali Renderer class. Let’s create a new class where our MainActivity is.

Name the class Renderer.

First, after public class Renderer we add extends RajawaliRenderer to make our class a subclass of RajawaliRenderer. Android Studio is going to yell at you a bit to tell you that you also need to implement some methods that the interface demands. It also might yell at you a bit about importing RajawaliRenderer. If you don’t have auto importing turned on, then you will need to add the import statements. Let’s fix these issues.

package com.clintonmedbery.rajawalibasicproject; import android.view.MotionEvent; import org.rajawali3d.renderer.RajawaliRenderer; public class Renderer extends RajawaliRenderer { public void onTouchEvent(MotionEvent event){ } public void onOffsetsChanged(float x, float y, float z, float w, int i, int j){ } }

Now it is probably yelling at you about a default constructor and an initScene() method. Let’s start off by adding our constructor. We need a variable to hold our context as well, so we will add that.

public Context context; public Renderer(Context context) { super(context); this.context = context; setFrameRate(60); }

Next we need to add some variables for our scene and get our picture. Feel free to use any texture you want, but you can find the earth texture here. Let’s add a Sphere object and a DirectionLight object to our scene.

private DirectionalLight directionalLight; private Sphere earthSphere;

And let’s go ahead and add our texture to the project. Right click on the res folder and click on New > Android Resource Directory and put in drawable-nodpi like the image below.





You can now drag the image to your folder. If you do not see the new directory (I didn’t on my Mac), then you might have to right click the res folder and click on Reveal in Finder and copy the file manually. It should show up in Android studio when you do. Windows will probably have a similar option like Reveal in Explorer.

Now we are ready to build our scene. We will do this in a new method called initScene(). Let’s create that method and get our lighting set up.

public void initScene(){ directionalLight = new DirectionalLight(1f, .2f, -1.0f); directionalLight.setColor(1.0f, 1.0f, 1.0f); directionalLight.setPower(2); getCurrentScene().addLight(directionalLight); }

This will be called when we start the renderer. We set directionalLight to a new DirectionalLight and we adjust the color and the power. Then we add it to our scene.

Next, we want to set up the material for our Sphere. Add these lines after the code for adding our directionalLight.

Material material = new Material(); material.enableLighting(true); material.setDiffuseMethod(new DiffuseMethod.Lambert()); material.setColor(0); Texture earthTexture = new Texture("Earth", R.drawable.earthtruecolor_nasa_big); try{ material.addTexture(earthTexture); } catch (ATexture.TextureException error){ Log.d("DEBUG", "TEXTURE ERROR"); }

First we create a new Material called material. We enable lighting on it and give it a material type of Diffuse (material types are outside the scope of this blog post). We then set its color.

Then we create a new Texture called texture and give it our earth picture in the constructor. Then we add texture to material in a try-catch block to avoid any errors. Now we have our material ready to go.

Finally, we instantiate our Sphere and give it the material we just created. We add it to the scene, and set the camera back so we can view the scene.

earthSphere = new Sphere(1, 24, 24); earthSphere.setMaterial(material); getCurrentScene().addChild(earthSphere); getCurrentCamera().setZ(4.2f);

Animating the Scene

Now we add a simple animation to the scene using an onRender method. This will make our Earth rotate.

@Override public void onRender(final long elapsedTime, final double deltaTime) { super.onRender(elapsedTime, deltaTime); earthSphere.rotate(Vector3.Axis.Y, 1.0); }

Rendering the Scene in Our MainActivity

That should be it for our simple scene. Now we need to go to MainActivity and render it there. First, we need to add a renderer to the activity. Then, we need to add some code to onCreate. Here is what you should have at the top of MainActivity.

Renderer renderer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final RajawaliSurfaceView surface = new RajawaliSurfaceView(this); surface.setFrameRate(60.0); surface.setRenderMode(IRajawaliSurface.RENDERMODE_WHEN_DIRTY); // Add mSurface to your root view addContentView(surface, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT)); renderer = new Renderer(this); surface.setSurfaceRenderer(renderer); }

The main thing to focus on here is the RajawaliSurfaceView. This class extends GLSurfaceView and let’s you add our Renderer to it, making it appear in our activity. We are able to set up some variables for our surface, and instantiate our Renderer scene and add it to the surface.

That’s it! Let’s run the program and see what we get.

The Earth should rotate and you should be good to go! If not, please feel free to ask any questions here or on the Rajawali Google+ community. You can also find the source code on Github here:

RajawaliBasicProject