TestAppRS.java revision c71343acc469db7ec351db2344032801e0e1b30a
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 17package com.android.testapp; 18 19import java.util.ArrayList; 20import java.util.HashMap; 21import java.util.Map; 22import java.util.Vector; 23 24import com.android.scenegraph.*; 25import com.android.scenegraph.SceneManager.SceneLoadedCallback; 26 27import android.content.res.Resources; 28import android.graphics.Bitmap; 29import android.graphics.BitmapFactory; 30import android.os.AsyncTask; 31import android.renderscript.*; 32import android.renderscript.Program.TextureType; 33import android.util.Log; 34 35// This is where the scenegraph and the rendered objects are initialized and used 36public 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 mAluminumF; 69 private FragmentShader mPlasticF; 70 private FragmentShader mDiffuseF; 71 private FragmentShader mTextureF; 72 private VertexShader mGenericV; 73 74 Scene mActiveScene; 75 76 // This is a part of the test app, it's used to tests multiple render passes and is toggled 77 // on and off in the menu, off by default 78 void toggleBlur() { 79 mUseBlur = !mUseBlur; 80 81 mActiveScene.clearRenderPasses(); 82 initRenderPasses(); 83 mActiveScene.initRenderPassRS(mRS, mSceneManager); 84 85 // This is just a hardcoded object in the scene that gets turned on and off for the demo 86 // to make things look a bit better. This could be deleted in the cleanup 87 Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); 88 if (plane != null) { 89 plane.setVisible(!mUseBlur); 90 } 91 } 92 93 public void init(RenderScriptGL rs, Resources res, int width, int height) { 94 mUseBlur = false; 95 mRS = rs; 96 mRes = res; 97 mWidth = width; 98 mHeight = height; 99 100 mTouchHandler = new TouchHandler(); 101 102 mSceneManager = SceneManager.getInstance(); 103 // Initializes all the RS specific scenegraph elements 104 mSceneManager.initRS(mRS, mRes, mWidth, mHeight); 105 106 mLoadingScreen = new TestAppLoadingScreen(mRS, mRes); 107 108 // Initi renderscript stuff specific to the app. This will need to be abstracted out later. 109 FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight); 110 initPaintShaders(); 111 112 // Load a scene to render 113 mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback); 114 } 115 116 // When a new model file is selected from the UI, this function gets called to init everything 117 void loadModel(String path) { 118 mLoadingScreen.showLoadingScreen(true); 119 mActiveScene.destroyRS(); 120 mSceneManager.loadModel(path, mLoadedCallback); 121 } 122 123 public void onActionDown(float x, float y) { 124 mTouchHandler.onActionDown(x, y); 125 } 126 127 public void onActionScale(float scale) { 128 mTouchHandler.onActionScale(scale); 129 } 130 131 public void onActionMove(float x, float y) { 132 mTouchHandler.onActionMove(x, y); 133 } 134 135 FragmentShader createFromResource(int id, boolean addCubemap, Type constType) { 136 FragmentShader.Builder fb = new FragmentShader.Builder(mRS); 137 fb.setShaderConst(constType); 138 fb.setShader(mRes, id); 139 fb.addTexture(TextureType.TEXTURE_2D, "diffuse"); 140 if (addCubemap) { 141 fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection"); 142 } 143 FragmentShader pf = fb.create(); 144 pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); 145 if (addCubemap) { 146 pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1); 147 } 148 return pf; 149 } 150 151 private void initPaintShaders() { 152 mGenericV = SceneManager.getDefaultVS(); 153 154 ScriptField_CameraParams camParams = new ScriptField_CameraParams(mRS, 1); 155 Type camParamType = camParams.getAllocation().getType(); 156 ScriptField_LightParams lightParams = new ScriptField_LightParams(mRS, 1); 157 158 mPaintF = createFromResource(R.raw.paintf, true, camParamType); 159 // Assign a reflection map 160 TextureCube envCube = new TextureCube("sdcard/scenegraph/", "cube_env.png"); 161 mPaintF.appendSourceParams(new TextureParam("reflection", envCube)); 162 163 mAluminumF = createFromResource(R.raw.metal, true, camParamType); 164 TextureCube diffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png"); 165 mAluminumF.appendSourceParams(new TextureParam("reflection", diffCube)); 166 167 mPlasticF = createFromResource(R.raw.plastic, false, camParamType); 168 mDiffuseF = createFromResource(R.raw.diffuse, false, camParamType); 169 mTextureF = SceneManager.getTextureFS(); 170 171 FragmentShader.Builder fb = new FragmentShader.Builder(mRS); 172 fb.setObjectConst(lightParams.getAllocation().getType()); 173 fb.setShader(mRes, R.raw.plastic_lights); 174 mLightsF = fb.create(); 175 176 FullscreenBlur.initShaders(mRes, mRS); 177 } 178 179 void initRenderPasses() { 180 ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables(); 181 int numDraw = allDraw.size(); 182 183 if (mUseBlur) { 184 FullscreenBlur.addBlurPasses(mActiveScene, mRS, mTouchHandler.getCamera()); 185 } 186 187 RenderPass mainPass = new RenderPass(); 188 mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f)); 189 mainPass.setShouldClearColor(true); 190 mainPass.setClearDepth(1.0f); 191 mainPass.setShouldClearDepth(true); 192 mainPass.setCamera(mTouchHandler.getCamera()); 193 for (int i = 0; i < numDraw; i ++) { 194 mainPass.appendRenderable((Renderable)allDraw.get(i)); 195 } 196 mActiveScene.appendRenderPass(mainPass); 197 198 if (mUseBlur) { 199 FullscreenBlur.addCompositePass(mActiveScene, mRS, mTouchHandler.getCamera()); 200 } 201 } 202 203 private void addShadersToScene() { 204 mActiveScene.appendShader(mPaintF); 205 mActiveScene.appendShader(mLightsF); 206 mActiveScene.appendShader(mAluminumF); 207 mActiveScene.appendShader(mPlasticF); 208 mActiveScene.appendShader(mDiffuseF); 209 mActiveScene.appendShader(mTextureF); 210 } 211 212 public void prepareToRender(Scene s) { 213 mSceneManager.setActiveScene(s); 214 mActiveScene = s; 215 mTouchHandler.init(mActiveScene); 216 addShadersToScene(); 217 RenderState plastic = new RenderState(mGenericV, mPlasticF, null, null); 218 RenderState diffuse = new RenderState(mGenericV, mDiffuseF, null, null); 219 RenderState paint = new RenderState(mGenericV, mPaintF, null, null); 220 RenderState aluminum = new RenderState(mGenericV, mAluminumF, null, null); 221 RenderState lights = new RenderState(mGenericV, mLightsF, null, null); 222 RenderState glassTransp = new RenderState(mGenericV, mPaintF, 223 ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null); 224 225 initRenderPasses(); 226 227 mActiveScene.assignRenderState(plastic); 228 229 mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$"); 230 231 mActiveScene.assignRenderStateToMaterial(paint, "^Paint"); 232 mActiveScene.assignRenderStateToMaterial(paint, "^Carbon"); 233 mActiveScene.assignRenderStateToMaterial(paint, "^Glass"); 234 mActiveScene.assignRenderStateToMaterial(paint, "^MainGlass"); 235 236 mActiveScene.assignRenderStateToMaterial(aluminum, "^Metal"); 237 mActiveScene.assignRenderStateToMaterial(aluminum, "^Brake"); 238 239 mActiveScene.assignRenderStateToMaterial(glassTransp, "^GlassLight"); 240 241 mActiveScene.assignRenderStateToMaterial(lights, "^LightBlinn"); 242 243 Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); 244 if (plane != null) { 245 RenderState texState = new RenderState(mGenericV, mTextureF, null, null); 246 plane.setRenderState(texState); 247 plane.setVisible(!mUseBlur); 248 } 249 250 long start = System.currentTimeMillis(); 251 mActiveScene.initRS(); 252 long end = System.currentTimeMillis(); 253 Log.v("TIMER", "Scene init time: " + (end - start)); 254 255 mLoadingScreen.showLoadingScreen(false); 256 } 257} 258