• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011-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 TestAppRS {
37 
38     private static String modelName = "orientation_test.dae";
39     private static String TAG = "TestAppRS";
40     private static String mFilePath = "";
41 
42     int mWidth;
43     int mHeight;
44 
45     boolean mUseBlur;
46 
47     TestAppLoadingScreen mLoadingScreen;
48 
49     // Used to asynchronously load scene elements like meshes and transform hierarchies
50     SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() {
51         public void run() {
52             prepareToRender(mLoadedScene);
53         }
54     };
55 
56     // Top level class that initializes all the elements needed to use the scene graph
57     SceneManager mSceneManager;
58 
59     // Used to move the camera around in the 3D world
60     TouchHandler mTouchHandler;
61 
62     private Resources mRes;
63     private RenderScriptGL mRS;
64 
65     // Shaders
66     private FragmentShader mPaintF;
67     private FragmentShader mLightsF;
68     private FragmentShader mLightsDiffF;
69     private FragmentShader mAluminumF;
70     private FragmentShader mPlasticF;
71     private FragmentShader mDiffuseF;
72     private FragmentShader mTextureF;
73     private VertexShader mGenericV;
74 
75     Scene mActiveScene;
76 
77     // This is a part of the test app, it's used to tests multiple render passes and is toggled
78     // on and off in the menu, off by default
toggleBlur()79     void toggleBlur() {
80         mUseBlur = !mUseBlur;
81 
82         mActiveScene.clearRenderPasses();
83         initRenderPasses();
84         mActiveScene.initRenderPassRS(mRS, mSceneManager);
85 
86         // This is just a hardcoded object in the scene that gets turned on and off for the demo
87         // to make things look a bit better. This could be deleted in the cleanup
88         Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
89         if (plane != null) {
90             plane.setVisible(!mUseBlur);
91         }
92     }
93 
init(RenderScriptGL rs, Resources res, int width, int height)94     public void init(RenderScriptGL rs, Resources res, int width, int height) {
95         mUseBlur = false;
96         mRS = rs;
97         mRes = res;
98         mWidth = width;
99         mHeight = height;
100 
101         mTouchHandler = new TouchHandler();
102 
103         mSceneManager = SceneManager.getInstance();
104         // Initializes all the RS specific scenegraph elements
105         mSceneManager.initRS(mRS, mRes, mWidth, mHeight);
106 
107         mLoadingScreen = new TestAppLoadingScreen(mRS, mRes);
108 
109         // Initi renderscript stuff specific to the app. This will need to be abstracted out later.
110         FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight);
111         initPaintShaders();
112 
113         // Load a scene to render
114         mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback);
115     }
116 
117     // When a new model file is selected from the UI, this function gets called to init everything
loadModel(String path)118     void loadModel(String path) {
119         mLoadingScreen.showLoadingScreen(true);
120         mActiveScene.destroyRS();
121         mSceneManager.loadModel(path, mLoadedCallback);
122     }
123 
onActionDown(float x, float y)124     public void onActionDown(float x, float y) {
125         mTouchHandler.onActionDown(x, y);
126     }
127 
onActionScale(float scale)128     public void onActionScale(float scale) {
129         mTouchHandler.onActionScale(scale);
130     }
131 
onActionMove(float x, float y)132     public void onActionMove(float x, float y) {
133         mTouchHandler.onActionMove(x, y);
134     }
135 
createFromResource(int id, boolean addCubemap, Type constType)136     FragmentShader createFromResource(int id, boolean addCubemap, Type constType) {
137         FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
138         fb.setShaderConst(constType);
139         fb.setShader(mRes, id);
140         fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
141         if (addCubemap) {
142             fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection");
143         }
144         FragmentShader pf = fb.create();
145         pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
146         if (addCubemap) {
147             pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
148         }
149         return pf;
150     }
151 
initPaintShaders()152     private void initPaintShaders() {
153         mGenericV = SceneManager.getDefaultVS();
154 
155         ScriptField_CameraParams camParams = new ScriptField_CameraParams(mRS, 1);
156         Type camParamType = camParams.getAllocation().getType();
157         ScriptField_LightParams lightParams = new ScriptField_LightParams(mRS, 1);
158 
159         mPaintF = createFromResource(R.raw.paintf, true, camParamType);
160         // Assign a reflection map
161         TextureCube envCube = new TextureCube("sdcard/scenegraph/", "cube_env.png");
162         mPaintF.appendSourceParams(new TextureParam("reflection", envCube));
163 
164         mAluminumF = createFromResource(R.raw.metal, true, camParamType);
165         TextureCube diffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png");
166         mAluminumF.appendSourceParams(new TextureParam("reflection", diffCube));
167 
168         mPlasticF = createFromResource(R.raw.plastic, false, camParamType);
169         mDiffuseF = createFromResource(R.raw.diffuse, false, camParamType);
170         mTextureF = SceneManager.getTextureFS();
171 
172         FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
173         fb.setObjectConst(lightParams.getAllocation().getType());
174         fb.setShader(mRes, R.raw.plastic_lights);
175         mLightsF = fb.create();
176 
177         fb = new FragmentShader.Builder(mRS);
178         fb.setObjectConst(lightParams.getAllocation().getType());
179         fb.setShader(mRes, R.raw.diffuse_lights);
180         mLightsDiffF = fb.create();
181 
182         FullscreenBlur.initShaders(mRes, mRS);
183     }
184 
initRenderPasses()185     void initRenderPasses() {
186         ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables();
187         int numDraw = allDraw.size();
188 
189         if (mUseBlur) {
190             FullscreenBlur.addBlurPasses(mActiveScene, mRS, mTouchHandler.getCamera());
191         }
192 
193         RenderPass mainPass = new RenderPass();
194         mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
195         mainPass.setShouldClearColor(true);
196         mainPass.setClearDepth(1.0f);
197         mainPass.setShouldClearDepth(true);
198         mainPass.setCamera(mTouchHandler.getCamera());
199         for (int i = 0; i < numDraw; i ++) {
200             mainPass.appendRenderable((Renderable)allDraw.get(i));
201         }
202         mActiveScene.appendRenderPass(mainPass);
203 
204         if (mUseBlur) {
205             FullscreenBlur.addCompositePass(mActiveScene, mRS, mTouchHandler.getCamera());
206         }
207     }
208 
addShadersToScene()209     private void addShadersToScene() {
210         mActiveScene.appendShader(mPaintF);
211         mActiveScene.appendShader(mLightsF);
212         mActiveScene.appendShader(mLightsDiffF);
213         mActiveScene.appendShader(mAluminumF);
214         mActiveScene.appendShader(mPlasticF);
215         mActiveScene.appendShader(mDiffuseF);
216         mActiveScene.appendShader(mTextureF);
217     }
218 
prepareToRender(Scene s)219     public void prepareToRender(Scene s) {
220         mSceneManager.setActiveScene(s);
221         mActiveScene = s;
222         mTouchHandler.init(mActiveScene);
223         addShadersToScene();
224         RenderState plastic = new RenderState(mGenericV, mPlasticF, null, null);
225         RenderState diffuse = new RenderState(mGenericV, mDiffuseF, null, null);
226         RenderState paint = new RenderState(mGenericV, mPaintF, null, null);
227         RenderState aluminum = new RenderState(mGenericV, mAluminumF, null, null);
228         RenderState lights = new RenderState(mGenericV, mLightsF, null, null);
229         RenderState diff_lights = new RenderState(mGenericV, mLightsDiffF, null, null);
230         RenderState diff_lights_no_cull = new RenderState(mGenericV, mLightsDiffF, null,
231                                                           ProgramRaster.CULL_NONE(mRS));
232         RenderState glassTransp = new RenderState(mGenericV, mPaintF,
233                                                   ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null);
234         RenderState texState = new RenderState(mGenericV, mTextureF, null, null);
235 
236         initRenderPasses();
237 
238         mActiveScene.assignRenderState(plastic);
239 
240         mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$");
241 
242         mActiveScene.assignRenderStateToMaterial(paint, "^Paint");
243         mActiveScene.assignRenderStateToMaterial(paint, "^Carbon");
244         mActiveScene.assignRenderStateToMaterial(paint, "^Glass");
245         mActiveScene.assignRenderStateToMaterial(paint, "^MainGlass");
246 
247         mActiveScene.assignRenderStateToMaterial(aluminum, "^Metal");
248         mActiveScene.assignRenderStateToMaterial(aluminum, "^Brake");
249 
250         mActiveScene.assignRenderStateToMaterial(glassTransp, "^GlassLight");
251 
252         mActiveScene.assignRenderStateToMaterial(lights, "^LightBlinn");
253         mActiveScene.assignRenderStateToMaterial(diff_lights, "^LightLambert");
254         mActiveScene.assignRenderStateToMaterial(diff_lights_no_cull, "^LightLambertNoCull");
255         mActiveScene.assignRenderStateToMaterial(texState, "^TextureOnly");
256 
257         Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
258         if (plane != null) {
259             plane.setRenderState(texState);
260             plane.setVisible(!mUseBlur);
261         }
262 
263         long start = System.currentTimeMillis();
264         mActiveScene.initRS();
265         long end = System.currentTimeMillis();
266         Log.v("TIMER", "Scene init time: " + (end - start));
267 
268         mLoadingScreen.showLoadingScreen(false);
269     }
270 }
271