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 
init(RenderScriptGL rs, Resources res, int width, int height)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 
setupGeometry()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 
setupColoredQuad()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 
setupTexturedQuad()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 
createLambertShader()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 
setupShadedGeometry()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 
setupCamera()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 
setupRenderPass()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