Home | History | Annotate | Download | only in testapp
      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
     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 
     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
    118     void loadModel(String path) {
    119         mLoadingScreen.showLoadingScreen(true);
    120         mActiveScene.destroyRS();
    121         mSceneManager.loadModel(path, mLoadedCallback);
    122     }
    123 
    124     public void onActionDown(float x, float y) {
    125         mTouchHandler.onActionDown(x, y);
    126     }
    127 
    128     public void onActionScale(float scale) {
    129         mTouchHandler.onActionScale(scale);
    130     }
    131 
    132     public void onActionMove(float x, float y) {
    133         mTouchHandler.onActionMove(x, y);
    134     }
    135 
    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 
    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 
    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 
    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 
    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