Merge "Adding a few more howto elements to scenegraph example."
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d
new file mode 100644
index 0000000..56eff04
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
index 621bfa36..fff6f34 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
@@ -34,9 +34,6 @@
 
 // This is where the scenegraph and the rendered objects are initialized and used
 public class SimpleAppRS {
-
-    private static String TAG = "SimpleAppRS";
-
     SceneManager mSceneManager;
 
     RenderScriptGL mRS;
@@ -44,6 +41,8 @@
 
     Scene mScene;
     Mesh mSimpleMesh;
+    Mesh mSphereMesh;
+    Mesh mCubeMesh;
 
     public void init(RenderScriptGL rs, Resources res, int width, int height) {
         mRS = rs;
@@ -54,7 +53,9 @@
         mScene = new Scene();
 
         setupGeometry();
-        setupRenderables();
+        setupColoredQuad();
+        setupTexturedQuad();
+        setupShadedGeometry();
         setupCamera();
         setupRenderPass();
 
@@ -68,6 +69,7 @@
         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 3,
                                                          Mesh.TriangleMeshBuilder.TEXTURE_0);
 
+        // Create four vertices with texture coordinates
         tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 0.0f);
         tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 0.0f);
         tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 0.0f);
@@ -76,36 +78,110 @@
         tmb.addTriangle(0, 1, 2);
         tmb.addTriangle(2, 3, 0);
         mSimpleMesh = tmb.create(true);
+
+        // Load a file that constains two pieces of geometry, a sphere and a cube
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.unit_obj);
+        for (int i = 0; i < model.getIndexEntryCount(); i ++) {
+            FileA3D.IndexEntry entry = model.getIndexEntry(i);
+            if (entry != null && entry.getName().equals("CubeMesh")) {
+                mCubeMesh = entry.getMesh();
+            } else if (entry != null && entry.getName().equals("SphereMesh")) {
+                mSphereMesh = entry.getMesh();
+            }
+        }
     }
 
-    private void setupRenderables() {
+    private void setupColoredQuad() {
         // Built-in shader that provides position, texcoord and normal
         VertexShader genericV = SceneManager.getDefaultVS();
         // Built-in shader that displays a color
         FragmentShader colorF = SceneManager.getColorFS();
-        // Built-in shader that displays a texture
-        FragmentShader textureF = SceneManager.getTextureFS();
         RenderState colorRS = new RenderState(genericV, colorF, null, null);
-        ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS);
-        RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null);
 
         // Draw a simple colored quad
         Renderable quad = mScene.appendNewRenderable();
         quad.setMesh(mSimpleMesh);
+        // Our shader has a constant input called "color"
+        // This tells the scenegraph to assign the following float3 to that input
         quad.appendSourceParams(new Float4Param("color", 0.2f, 0.3f, 0.4f));
         quad.setRenderState(colorRS);
+    }
+
+    private void setupTexturedQuad() {
+        // Built-in shader that provides position, texcoord and normal
+        VertexShader genericV = SceneManager.getDefaultVS();
+        // Built-in shader that displays a texture
+        FragmentShader textureF = SceneManager.getTextureFS();
+        // We want to use transparency based on the alpha channel of the texture
+        ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS);
+        RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null);
 
         // Draw a textured quad
-        quad = mScene.appendNewRenderable();
+        Renderable quad = mScene.appendNewRenderable();
         quad.setMesh(mSimpleMesh);
         // Make a transform to position the quad
         CompoundTransform t = mScene.appendNewCompoundTransform();
         t.addTranslate("position", new Float3(2, 2, 0));
         quad.setTransform(t);
+        // Our fragment shader has a constant texture input called "color"
+        // This will assign an icon from drawables to that input
         quad.appendSourceParams(new TextureParam("color", new Texture2D(R.drawable.icon)));
         quad.setRenderState(texRS);
     }
 
+    private FragmentShader createLambertShader() {
+        // Describe what constant inputs our shader wants
+        Element.Builder b = new Element.Builder(mRS);
+        b.add(Element.F32_4(mRS), "cameraPos");
+
+        // Create a shader from a text file in resources
+        FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+        // Tell the shader what constants we want
+        fb.setShaderConst(new Type.Builder(mRS, b.create()).setX(1).create());
+        // Shader code location
+        fb.setShader(mRes, R.raw.diffuse);
+        // We want a texture called diffuse on our shader
+        fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
+        FragmentShader shader = fb.create();
+        mScene.appendShader(shader);
+        return shader;
+    }
+
+    private void setupShadedGeometry() {
+        // Built-in shader that provides position, texcoord and normal
+        VertexShader genericV = SceneManager.getDefaultVS();
+        // Custom shader
+        FragmentShader diffuseF = createLambertShader();
+        RenderState diffuseRS = new RenderState(genericV, diffuseF, null, null);
+
+        // Draw a sphere
+        Renderable sphere = mScene.appendNewRenderable();
+        // Use the sphere geometry loaded earlier
+        sphere.setMesh(mSphereMesh);
+        // Make a transform to position the sphere
+        CompoundTransform t = mScene.appendNewCompoundTransform();
+        t.addTranslate("position", new Float3(-1, 2, 3));
+        t.addScale("scale", new Float3(1.4f, 1.4f, 1.4f));
+        sphere.setTransform(t);
+        // Tell the renderable which texture to use when we draw
+        // This will mean a texture param in the shader called "diffuse"
+        // will be assigned a texture called red.jpg
+        sphere.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "red.jpg")));
+        sphere.setRenderState(diffuseRS);
+
+        // Draw a cube
+        Renderable cube = mScene.appendNewRenderable();
+        cube.setMesh(mCubeMesh);
+        t = mScene.appendNewCompoundTransform();
+        t.addTranslate("position", new Float3(-2, -2.1f, 0));
+        t.addRotate("rotateX", new Float3(1, 0, 0), 30);
+        t.addRotate("rotateY", new Float3(0, 1, 0), 30);
+        t.addScale("scale", new Float3(2, 2, 2));
+        cube.setTransform(t);
+        cube.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "orange.jpg")));
+        cube.setRenderState(diffuseRS);
+    }
+
     private void setupCamera() {
         Camera camera = mScene.appendNewCamera();
         camera.setFar(200);