Home | History | Annotate | Download | only in testapp
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.testapp;
     18 
     19 import java.util.ArrayList;
     20 import java.util.HashMap;
     21 import java.util.Map;
     22 import java.util.Vector;
     23 
     24 import com.android.scenegraph.*;
     25 import com.android.scenegraph.SceneManager.SceneLoadedCallback;
     26 
     27 import android.content.res.Resources;
     28 import android.graphics.Bitmap;
     29 import android.graphics.BitmapFactory;
     30 import android.os.AsyncTask;
     31 import android.renderscript.*;
     32 import android.renderscript.Program.TextureType;
     33 import android.util.Log;
     34 
     35 // This is where the scenegraph and the rendered objects are initialized and used
     36 public class SimpleAppRS {
     37     SceneManager mSceneManager;
     38 
     39     RenderScriptGL mRS;
     40     Resources mRes;
     41 
     42     Scene mScene;
     43     Mesh mSimpleMesh;
     44     Mesh mSphereMesh;
     45     Mesh mCubeMesh;
     46 
     47     public void init(RenderScriptGL rs, Resources res, int width, int height) {
     48         mRS = rs;
     49         mRes = res;
     50         mSceneManager = SceneManager.getInstance();
     51         mSceneManager.initRS(mRS, mRes, width, height);
     52 
     53         mScene = new Scene();
     54 
     55         setupGeometry();
     56         setupColoredQuad();
     57         setupTexturedQuad();
     58         setupShadedGeometry();
     59         setupCamera();
     60         setupRenderPass();
     61 
     62         mSceneManager.setActiveScene(mScene);
     63 
     64         mScene.initRS();
     65         mRS.bindRootScript(mSceneManager.getRenderLoop());
     66     }
     67 
     68     private void setupGeometry() {
     69         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 3,
     70                                                          Mesh.TriangleMeshBuilder.TEXTURE_0);
     71 
     72         // Create four vertices with texture coordinates
     73         tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 0.0f);
     74         tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 0.0f);
     75         tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 0.0f);
     76         tmb.setTexture(1.0f, 1.0f).addVertex(1.0f, 1.0f, 0.0f);
     77 
     78         tmb.addTriangle(0, 1, 2);
     79         tmb.addTriangle(2, 3, 0);
     80         mSimpleMesh = tmb.create(true);
     81 
     82         // Load a file that constains two pieces of geometry, a sphere and a cube
     83         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.unit_obj);
     84         for (int i = 0; i < model.getIndexEntryCount(); i ++) {
     85             FileA3D.IndexEntry entry = model.getIndexEntry(i);
     86             if (entry != null && entry.getName().equals("CubeMesh")) {
     87                 mCubeMesh = entry.getMesh();
     88             } else if (entry != null && entry.getName().equals("SphereMesh")) {
     89                 mSphereMesh = entry.getMesh();
     90             }
     91         }
     92     }
     93 
     94     private void setupColoredQuad() {
     95         // Built-in shader that provides position, texcoord and normal
     96         VertexShader genericV = SceneManager.getDefaultVS();
     97         // Built-in shader that displays a color
     98         FragmentShader colorF = SceneManager.getColorFS();
     99         RenderState colorRS = new RenderState(genericV, colorF, null, null);
    100 
    101         // Draw a simple colored quad
    102         Renderable quad = mScene.appendNewRenderable();
    103         quad.setMesh(mSimpleMesh);
    104         // Our shader has a constant input called "color"
    105         // This tells the scenegraph to assign the following float3 to that input
    106         quad.appendSourceParams(new Float4Param("color", 0.2f, 0.3f, 0.4f));
    107         quad.setRenderState(colorRS);
    108     }
    109 
    110     private void setupTexturedQuad() {
    111         // Built-in shader that provides position, texcoord and normal
    112         VertexShader genericV = SceneManager.getDefaultVS();
    113         // Built-in shader that displays a texture
    114         FragmentShader textureF = SceneManager.getTextureFS();
    115         // We want to use transparency based on the alpha channel of the texture
    116         ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS);
    117         RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null);
    118 
    119         // Draw a textured quad
    120         Renderable quad = mScene.appendNewRenderable();
    121         quad.setMesh(mSimpleMesh);
    122         // Make a transform to position the quad
    123         CompoundTransform t = mScene.appendNewCompoundTransform();
    124         t.addTranslate("position", new Float3(2, 2, 0));
    125         quad.setTransform(t);
    126         // Our fragment shader has a constant texture input called "color"
    127         // This will assign an icon from drawables to that input
    128         quad.appendSourceParams(new TextureParam("color", new Texture2D(R.drawable.icon)));
    129         quad.setRenderState(texRS);
    130     }
    131 
    132     private FragmentShader createLambertShader() {
    133         // Describe what constant inputs our shader wants
    134         Element.Builder b = new Element.Builder(mRS);
    135         b.add(Element.F32_4(mRS), "cameraPos");
    136 
    137         // Create a shader from a text file in resources
    138         FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
    139         // Tell the shader what constants we want
    140         fb.setShaderConst(new Type.Builder(mRS, b.create()).setX(1).create());
    141         // Shader code location
    142         fb.setShader(mRes, R.raw.diffuse);
    143         // We want a texture called diffuse on our shader
    144         fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
    145         FragmentShader shader = fb.create();
    146         mScene.appendShader(shader);
    147         return shader;
    148     }
    149 
    150     private void setupShadedGeometry() {
    151         // Built-in shader that provides position, texcoord and normal
    152         VertexShader genericV = SceneManager.getDefaultVS();
    153         // Custom shader
    154         FragmentShader diffuseF = createLambertShader();
    155         RenderState diffuseRS = new RenderState(genericV, diffuseF, null, null);
    156 
    157         // Draw a sphere
    158         Renderable sphere = mScene.appendNewRenderable();
    159         // Use the sphere geometry loaded earlier
    160         sphere.setMesh(mSphereMesh);
    161         // Make a transform to position the sphere
    162         CompoundTransform t = mScene.appendNewCompoundTransform();
    163         t.addTranslate("position", new Float3(-1, 2, 3));
    164         t.addScale("scale", new Float3(1.4f, 1.4f, 1.4f));
    165         sphere.setTransform(t);
    166         // Tell the renderable which texture to use when we draw
    167         // This will mean a texture param in the shader called "diffuse"
    168         // will be assigned a texture called red.jpg
    169         sphere.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "red.jpg")));
    170         sphere.setRenderState(diffuseRS);
    171 
    172         // Draw a cube
    173         Renderable cube = mScene.appendNewRenderable();
    174         cube.setMesh(mCubeMesh);
    175         t = mScene.appendNewCompoundTransform();
    176         t.addTranslate("position", new Float3(-2, -2.1f, 0));
    177         t.addRotate("rotateX", new Float3(1, 0, 0), 30);
    178         t.addRotate("rotateY", new Float3(0, 1, 0), 30);
    179         t.addScale("scale", new Float3(2, 2, 2));
    180         cube.setTransform(t);
    181         cube.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "orange.jpg")));
    182         cube.setRenderState(diffuseRS);
    183     }
    184 
    185     private void setupCamera() {
    186         Camera camera = mScene.appendNewCamera();
    187         camera.setFar(200);
    188         camera.setNear(0.1f);
    189         camera.setFOV(60);
    190         CompoundTransform cameraTransform = mScene.appendNewCompoundTransform();
    191         cameraTransform.addTranslate("camera", new Float3(0, 0, 10));
    192         camera.setTransform(cameraTransform);
    193     }
    194 
    195     private void setupRenderPass() {
    196         RenderPass mainPass = mScene.appendNewRenderPass();
    197         mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
    198         mainPass.setShouldClearColor(true);
    199         mainPass.setClearDepth(1.0f);
    200         mainPass.setShouldClearDepth(true);
    201         mainPass.setCamera(mScene.getCameras().get(0));
    202         ArrayList<RenderableBase> allRender = mScene.getRenderables();
    203         for (RenderableBase renderable : allRender) {
    204             mainPass.appendRenderable((Renderable)renderable);
    205         }
    206     }
    207 }
    208