diff options
Diffstat (limited to 'tests/RenderScriptTests/SceneGraph/src/com/android/testapp')
9 files changed, 1248 insertions, 0 deletions
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java new file mode 100644 index 0000000..420e133 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.List; + +import android.app.ListActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +/** + * A list view where the last item the user clicked is placed in + * the "activated" state, causing its background to highlight. + */ +public class FileSelector extends ListActivity { + + File[] mCurrentSubList; + File mCurrentFile; + + class DAEFilter implements FileFilter { + public boolean accept(File file) { + if (file.isDirectory()) { + return true; + } + return file.getName().endsWith(".dae"); + } + } + + private void populateList(File file) { + + mCurrentFile = file; + setTitle(mCurrentFile.getAbsolutePath() + "/*.dae"); + List<String> names = new ArrayList<String>(); + names.add(".."); + + mCurrentSubList = mCurrentFile.listFiles(new DAEFilter()); + + if (mCurrentSubList != null) { + for (int i = 0; i < mCurrentSubList.length; i ++) { + String fileName = mCurrentSubList[i].getName(); + if (mCurrentSubList[i].isDirectory()) { + fileName = "/" + fileName; + } + names.add(fileName); + } + } + + // Use the built-in layout for showing a list item with a single + // line of text whose background is changes when activated. + setListAdapter(new ArrayAdapter<String>(this, + android.R.layout.simple_list_item_activated_1, names)); + getListView().setTextFilterEnabled(true); + + // Tell the list view to show one checked/activated item at a time. + getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + populateList(new File("/sdcard/")); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + if (position == 0) { + File parent = mCurrentFile.getParentFile(); + if (parent == null) { + return; + } + populateList(parent); + return; + } + + // the first thing in list is parent directory + File selectedFile = mCurrentSubList[position - 1]; + if (selectedFile.isDirectory()) { + populateList(selectedFile); + return; + } + + Intent resultIntent = new Intent(); + resultIntent.setData(Uri.fromFile(selectedFile)); + setResult(RESULT_OK, resultIntent); + finish(); + } + +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java new file mode 100644 index 0000000..2e764e9 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java @@ -0,0 +1,187 @@ +/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.testapp;
+
+import java.util.ArrayList;
+
+import com.android.scenegraph.*;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+class FullscreenBlur {
+
+ static Allocation sRenderTargetBlur0Color;
+ static Allocation sRenderTargetBlur0Depth;
+ static Allocation sRenderTargetBlur1Color;
+ static Allocation sRenderTargetBlur1Depth;
+ static Allocation sRenderTargetBlur2Color;
+ static Allocation sRenderTargetBlur2Depth;
+
+ static FragmentShader mPF_BlurH;
+ static FragmentShader mPF_BlurV;
+ static FragmentShader mPF_SelectColor;
+ static FragmentShader mPF_Texture;
+ static VertexShader mPV_Paint;
+ static VertexShader mPV_Blur;
+
+ // This is only used when full screen blur is enabled
+ // Basically, it's the offscreen render targets
+ static void createRenderTargets(RenderScriptGL rs, int w, int h) {
+ Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
+ Type renderType = b.setX(w/8).setY(h/8).create();
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Color = Allocation.createTyped(rs, renderType, usage);
+
+ b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ renderType = b.setX(w/8).setY(h/8).create();
+ usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Depth = Allocation.createTyped(rs, renderType, usage);
+ }
+
+ static void addOffsets(Renderable quad, float advance) {
+ quad.appendSourceParams(new Float4Param("blurOffset0", - advance * 2.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset1", - advance * 0.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset2", advance * 1.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset3", advance * 3.5f));
+ }
+
+ static RenderPass addPass(Scene scene, Allocation color, Allocation depth) {
+ RenderPass pass = new RenderPass();
+ pass.setColorTarget(color);
+ pass.setDepthTarget(depth);
+ pass.setShouldClearColor(false);
+ pass.setShouldClearDepth(false);
+ pass.setCamera(scene.getCameras().get(1));
+ scene.appendRenderPass(pass);
+ return pass;
+ }
+
+ static void addBlurPasses(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ ArrayList<RenderableBase> allDraw = scene.getRenderables();
+ int numDraw = allDraw.size();
+
+ ProgramRaster cullNone = ProgramRaster.CULL_NONE(rs);
+ ProgramStore blendAdd = SceneManager.BLEND_ADD_DEPTH_NONE(rs);
+ ProgramStore blendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(rs);
+
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture, blendAdd, cullNone);
+ RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor, blendNone, cullNone);
+ RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH, blendNone, cullNone);
+ RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV, blendNone, cullNone);
+
+ // Renders the scene off screen
+ RenderPass blurSourcePass = addPass(scene,
+ sRenderTargetBlur0Color,
+ sRenderTargetBlur0Depth);
+ blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ blurSourcePass.setShouldClearColor(true);
+ blurSourcePass.setClearDepth(1.0f);
+ blurSourcePass.setShouldClearDepth(true);
+ for (int i = 0; i < numDraw; i ++) {
+ blurSourcePass.appendRenderable((Renderable)allDraw.get(i));
+ }
+
+ // Pass for selecting bright colors
+ RenderPass selectColorPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur0Color)));
+ selectColorPass.appendRenderable(quad);
+
+ // Horizontal blur
+ RenderPass horizontalBlurPass = addPass(scene,
+ sRenderTargetBlur1Color,
+ sRenderTargetBlur1Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getX());
+ horizontalBlurPass.appendRenderable(quad);
+
+ // Vertical Blur
+ RenderPass verticalBlurPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur1Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getY());
+ verticalBlurPass.appendRenderable(quad);
+ }
+
+ // Additively renders the blurred colors on top of the scene
+ static void addCompositePass(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ SceneManager.BLEND_ADD_DEPTH_NONE(rs),
+ ProgramRaster.CULL_NONE(rs));
+
+ RenderPass compositePass = addPass(scene, null, null);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuad", drawTex);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ compositePass.appendRenderable(quad);
+ }
+
+ static private FragmentShader getShader(Resources res, RenderScriptGL rs,
+ int resID, Type constants) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(rs);
+ fb.setShader(res, resID);
+ fb.addTexture(TextureType.TEXTURE_2D, "color");
+ if (constants != null) {
+ fb.setObjectConst(constants);
+ }
+ FragmentShader prog = fb.create();
+ prog.getProgram().bindSampler(Sampler.CLAMP_LINEAR(rs), 0);
+ return prog;
+ }
+
+ static void initShaders(Resources res, RenderScriptGL rs) {
+ ScriptField_FBlurOffsets_s blurConst = new ScriptField_FBlurOffsets_s(rs, 1);
+ VertexShader.Builder vb = new VertexShader.Builder(rs);
+ vb.addInput(ScriptField_VertexShaderInputs_s.createElement(rs));
+ vb.setShader(res, R.raw.blur_vertex);
+ mPV_Blur = vb.create();
+
+ mPF_Texture = getShader(res, rs, R.raw.texture, null);
+ mPF_Texture.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(rs), 0);
+ mPF_BlurH = getShader(res, rs, R.raw.blur_h, blurConst.getAllocation().getType());
+ mPF_BlurV = getShader(res, rs, R.raw.blur_v, blurConst.getAllocation().getType());
+ mPF_SelectColor = getShader(res, rs, R.raw.select_color, null);
+ }
+
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java new file mode 100644 index 0000000..8b032f7 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; +import android.view.MenuInflater; +import android.view.Window; +import android.net.Uri; + +import java.lang.Runtime; + +public class TestApp extends Activity { + + private TestAppView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new TestAppView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.pause(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.loader_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.load_model: + loadModel(); + return true; + case R.id.use_blur: + mView.mRender.toggleBlur(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private static final int FIND_DAE_MODEL = 10; + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == RESULT_OK) { + if (requestCode == FIND_DAE_MODEL) { + Uri selectedImageUri = data.getData(); + Log.e("Selected Path: ", selectedImageUri.getPath()); + mView.mRender.loadModel(selectedImageUri.getPath()); + } + } + } + + public void loadModel() { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_PICK); + intent.setClassName("com.android.scenegraph", + "com.android.scenegraph.FileSelector"); + startActivityForResult(intent, FIND_DAE_MODEL); + } + +} + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java new file mode 100644 index 0000000..b818833 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Element.Builder; +import android.renderscript.Font.Style; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + +// This is where the scenegraph and the rendered objects are initialized and used +public class TestAppLoadingScreen { + + private static String TAG = "TestAppLoadingScreen"; + + int mWidth; + int mHeight; + + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_test_app mScript; + + public TestAppLoadingScreen(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + // Shows the loading screen with some text + renderLoading(); + // Adds a little 3D bugdroid model to the laoding screen asynchronously. + new LoadingScreenLoaderTask().execute(); + } + + public void showLoadingScreen(boolean show) { + mScript.set_gInitialized(!show); + } + + // The loading screen has some elements that shouldn't be loaded on the UI thread + private class LoadingScreenLoaderTask extends AsyncTask<String, Void, Boolean> { + Allocation robotTex; + Mesh robotMesh; + protected Boolean doInBackground(String... names) { + long start = System.currentTimeMillis(); + robotTex = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot, + MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + robotMesh = entry.getMesh(); + } + + mScript.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS)); + + ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS); + b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + ProgramFragment pfDefault = b.create(); + pfDefault.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); + mScript.set_gPFBackground(pfDefault); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertexFixedFunction pvDefault = pvb.create(); + ProgramVertexFixedFunction.Constants va = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)pvDefault).bindConstants(va); + mScript.set_gPVBackground(pvDefault); + + long end = System.currentTimeMillis(); + Log.v("TIMER", "Loading load time: " + (end - start)); + return new Boolean(true); + } + + protected void onPostExecute(Boolean result) { + mScript.set_gRobotTex(robotTex); + mScript.set_gRobotMesh(robotMesh); + } + } + + // Creates a simple script to show a loding screen until everything is initialized + // Could also be used to do some custom renderscript work before handing things over + // to the scenegraph + void renderLoading() { + mScript = new ScriptC_test_app(mRS, mRes, R.raw.test_app); + mRS.bindRootScript(mScript); + } + + + public void setRenderLoop(ScriptC renderLoop) { + mScript.set_gRenderLoop(renderLoop); + Allocation dummyAlloc = Allocation.createSized(mRS, Element.I32(mRS), 1); + mScript.set_gDummyAlloc(dummyAlloc); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java new file mode 100644 index 0000000..8840d12 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2011-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import com.android.scenegraph.*; +import com.android.scenegraph.SceneManager.SceneLoadedCallback; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Program.TextureType; +import android.util.Log; + +// This is where the scenegraph and the rendered objects are initialized and used +public class TestAppRS { + + private static String modelName = "orientation_test.dae"; + private static String TAG = "TestAppRS"; + private static String mFilePath = ""; + + int mWidth; + int mHeight; + + boolean mUseBlur; + + TestAppLoadingScreen mLoadingScreen; + + // Used to asynchronously load scene elements like meshes and transform hierarchies + SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() { + public void run() { + prepareToRender(mLoadedScene); + } + }; + + // Top level class that initializes all the elements needed to use the scene graph + SceneManager mSceneManager; + + // Used to move the camera around in the 3D world + TouchHandler mTouchHandler; + + private Resources mRes; + private RenderScriptGL mRS; + + ScriptField_FShaderParams_s mFsConst; + ScriptField_FShaderLightParams_s mFsConst2; + ScriptField_VShaderParams_s mVsConst; + + // Shaders + private FragmentShader mPaintF; + private FragmentShader mLightsF; + private FragmentShader mAluminumF; + private FragmentShader mPlasticF; + private FragmentShader mDiffuseF; + private FragmentShader mTextureF; + private VertexShader mPaintV; + + private Allocation mDefaultCube; + private TextureCube mEnvCube; + private TextureCube mDiffCube; + + Scene mActiveScene; + + public TestAppRS() { + mUseBlur = false; + } + + // This is a part of the test app, it's used to tests multiple render passes and is toggled + // on and off in the menu, off by default + void toggleBlur() { + mUseBlur = !mUseBlur; + + mActiveScene.clearRenderPasses(); + initRenderPasses(); + mActiveScene.initRenderPassRS(mRS, mSceneManager); + + // This is just a hardcoded object in the scene that gets turned on and off for the demo + // to make things look a bit better. This could be deleted in the cleanup + Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); + if (plane != null) { + plane.setVisible(mRS, !mUseBlur); + } + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + + mTouchHandler = new TouchHandler(); + + mSceneManager = SceneManager.getInstance(); + // Initializes all the RS specific scenegraph elements + mSceneManager.initRS(mRS, mRes, mWidth, mHeight); + + mLoadingScreen = new TestAppLoadingScreen(mRS, mRes); + + // Initi renderscript stuff specific to the app. This will need to be abstracted out later. + initRS(); + + // Load a scene to render + mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback); + } + + // When a new model file is selected from the UI, this function gets called to init everything + void loadModel(String path) { + //String shortName = path.substring(path.lastIndexOf('/') + 1); + //shortName = shortName.substring(0, shortName.lastIndexOf('.')); + mLoadingScreen.showLoadingScreen(true); + mActiveScene.destroyRS(mSceneManager); + mSceneManager.loadModel(path, mLoadedCallback); + } + + public void onActionDown(float x, float y) { + mTouchHandler.onActionDown(x, y); + + //mSceneManager.getRenderLoop().invoke_pick((int)x, (int)y); + } + + public void onActionScale(float scale) { + mTouchHandler.onActionScale(scale); + } + + public void onActionMove(float x, float y) { + mTouchHandler.onActionMove(x, y); + } + + FragmentShader createFromResource(int id, boolean addCubemap) { + FragmentShader.Builder fb = new FragmentShader.Builder(mRS); + fb.setShaderConst(mFsConst.getAllocation().getType()); + fb.setShader(mRes, id); + fb.addTexture(TextureType.TEXTURE_2D, "diffuse"); + if (addCubemap) { + fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection"); + } + FragmentShader pf = fb.create(); + pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); + if (addCubemap) { + pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1); + } + return pf; + } + + private void initPaintShaders() { + ScriptField_VObjectParams_s objConst = new ScriptField_VObjectParams_s(mRS, 1); + ScriptField_VSParams_s shaderConst = new ScriptField_VSParams_s(mRS, 1); + + VertexShader.Builder vb = new VertexShader.Builder(mRS); + vb.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + vb.setShader(mRes, R.raw.shader2v); + vb.setObjectConst(objConst.getAllocation().getType()); + vb.setShaderConst(shaderConst.getAllocation().getType()); + mPaintV = vb.create(); + + mFsConst = new ScriptField_FShaderParams_s(mRS, 1); + mFsConst2 = new ScriptField_FShaderLightParams_s(mRS, 1); + + mPaintF = createFromResource(R.raw.paintf, true); + mPaintF.appendSourceParams(new TextureParam("reflection", mEnvCube)); + mAluminumF = createFromResource(R.raw.metal, true); + mAluminumF.appendSourceParams(new TextureParam("reflection", mDiffCube)); + + mPlasticF = createFromResource(R.raw.plastic, false); + mDiffuseF = createFromResource(R.raw.diffuse, false); + mTextureF = createFromResource(R.raw.texture, false); + + FragmentShader.Builder fb = new FragmentShader.Builder(mRS); + fb.setObjectConst(mFsConst2.getAllocation().getType()); + fb.setShader(mRes, R.raw.plastic_lights); + mLightsF = fb.create(); + + FullscreenBlur.initShaders(mRes, mRS); + } + + void initRenderPasses() { + ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables(); + int numDraw = allDraw.size(); + + if (mUseBlur) { + FullscreenBlur.addBlurPasses(mActiveScene, mRS); + } + + RenderPass mainPass = new RenderPass(); + mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f)); + mainPass.setShouldClearColor(true); + mainPass.setClearDepth(1.0f); + mainPass.setShouldClearDepth(true); + mainPass.setCamera(mActiveScene.getCameras().get(1)); + for (int i = 0; i < numDraw; i ++) { + mainPass.appendRenderable((Renderable)allDraw.get(i)); + } + mActiveScene.appendRenderPass(mainPass); + + if (mUseBlur) { + FullscreenBlur.addCompositePass(mActiveScene, mRS); + } + } + + private void addShadersToScene() { + mActiveScene.appendShader(mPaintF); + mActiveScene.appendShader(mLightsF); + mActiveScene.appendShader(mAluminumF); + mActiveScene.appendShader(mPlasticF); + mActiveScene.appendShader(mDiffuseF); + mActiveScene.appendShader(mTextureF); + mActiveScene.appendShader(mPaintV); + } + + public void prepareToRender(Scene s) { + mSceneManager.setActiveScene(s); + mActiveScene = s; + addShadersToScene(); + RenderState plastic = new RenderState(mPaintV, mPlasticF, null, null); + RenderState diffuse = new RenderState(mPaintV, mDiffuseF, null, null); + RenderState paint = new RenderState(mPaintV, mPaintF, null, null); + RenderState aluminum = new RenderState(mPaintV, mAluminumF, null, null); + RenderState lights = new RenderState(mPaintV, mLightsF, null, null); + RenderState glassTransp = new RenderState(mPaintV, mPaintF, + ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null); + + initRenderPasses(); + + mActiveScene.assignRenderState(plastic); + + mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$"); + + mActiveScene.assignRenderStateToMaterial(paint, "^#Paint"); + mActiveScene.assignRenderStateToMaterial(paint, "^#Carbon"); + mActiveScene.assignRenderStateToMaterial(paint, "^#Glass"); + mActiveScene.assignRenderStateToMaterial(paint, "^#MainGlass"); + + mActiveScene.assignRenderStateToMaterial(aluminum, "^#Metal"); + mActiveScene.assignRenderStateToMaterial(aluminum, "^#Brake"); + + mActiveScene.assignRenderStateToMaterial(glassTransp, "^#GlassLight"); + + mActiveScene.assignRenderStateToMaterial(lights, "^#LightBlinn"); + + Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); + if (plane != null) { + RenderState texState = new RenderState(mPaintV, mTextureF, null, null); + plane.setRenderState(texState); + plane.setVisible(mRS, !mUseBlur); + } + + mTouchHandler.init(mActiveScene); + + long start = System.currentTimeMillis(); + mActiveScene.initRS(mRS, mRes, mSceneManager); + long end = System.currentTimeMillis(); + Log.v("TIMER", "Scene init time: " + (end - start)); + + mLoadingScreen.showLoadingScreen(false); + } + + private void initRS() { + + FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight); + // Reflection maps from SD card + mEnvCube = new TextureCube("sdcard/scenegraph/", "cube_env.png"); + mDiffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png"); + initPaintShaders(); + + ScriptC_render renderLoop = mSceneManager.getRenderLoop(); + + mLoadingScreen.setRenderLoop(renderLoop); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java new file mode 100644 index 0000000..687f35b --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; + +public class TestAppView extends RSSurfaceView { + + public TestAppView(Context context) { + super(context); + mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); + } + + private RenderScriptGL mRS; + TestAppRS mRender; + + private ScaleGestureDetector mScaleDetector; + private static final int INVALID_POINTER_ID = -1; + private int mActivePointerId = INVALID_POINTER_ID; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new TestAppRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRender = null; + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) { + mScaleDetector.onTouchEvent(ev); + + boolean ret = false; + float x = ev.getX(); + float y = ev.getY(); + + final int action = ev.getAction(); + + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: { + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(0); + ret = true; + break; + } + case MotionEvent.ACTION_MOVE: { + if (!mScaleDetector.isInProgress()) { + mRender.onActionMove(x, y); + } + mRender.onActionDown(x, y); + ret = true; + break; + } + + case MotionEvent.ACTION_UP: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_CANCEL: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_POINTER_UP: { + final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) + >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + final int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + x = ev.getX(newPointerIndex); + y = ev.getY(newPointerIndex); + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(newPointerIndex); + } + break; + } + } + + return ret; + } + + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScale(ScaleGestureDetector detector) { + mRender.onActionScale(detector.getScaleFactor()); + return true; + } + } +} + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java new file mode 100644 index 0000000..4d30341 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.BufferedInputStream; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Element.Builder; +import android.renderscript.Font.Style; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + +import com.android.scenegraph.*; + +public class TouchHandler { + + private static String TAG = "TouchHandler"; + + public TouchHandler() { + } + + public void init(Scene scene) { + mCameraRotate = (CompoundTransform)scene.getTransformByName("CameraAim"); + mCameraDist = (CompoundTransform)scene.getTransformByName("CameraDist"); + + if (mCameraRotate != null && mCameraDist != null) { + mRotateX = mCameraRotate.mTransformComponents.get(2); + mRotateY = mCameraRotate.mTransformComponents.get(1); + mDist = mCameraDist.mTransformComponents.get(0); + } + } + + + private Resources mRes; + private RenderScriptGL mRS; + + float mLastX; + float mLastY; + + CompoundTransform mCameraRotate; + CompoundTransform mCameraDist; + + CompoundTransform.Component mRotateX; + CompoundTransform.Component mRotateY; + CompoundTransform.Component mDist; + + public void onActionDown(float x, float y) { + mLastX = x; + mLastY = y; + } + + public void onActionScale(float scale) { + if (mCameraDist == null) { + return; + } + mDist.mValue.z *= 1.0f / scale; + mDist.mValue.z = Math.max(20.0f, Math.min(mDist.mValue.z, 100.0f)); + mCameraDist.updateRSData(); + } + + public void onActionMove(float x, float y) { + if (mCameraRotate == null) { + return; + } + + float dx = mLastX - x; + float dy = mLastY - y; + + if (Math.abs(dy) <= 2.0f) { + dy = 0.0f; + } + if (Math.abs(dx) <= 2.0f) { + dx = 0.0f; + } + + mRotateY.mValue.w += dx*0.25; + if (mRotateY.mValue.w > 360) { + mRotateY.mValue.w -= 360; + } + if (mRotateY.mValue.w < 0) { + mRotateY.mValue.w += 360; + } + + mRotateX.mValue.w += dy*0.25; + mRotateX.mValue.w = Math.max(mRotateX.mValue.w, -80.0f); + mRotateX.mValue.w = Math.min(mRotateX.mValue.w, 0.0f); + + mLastX = x; + mLastY = y; + + mCameraRotate.updateRSData(); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs new file mode 100644 index 0000000..cb4e3d0 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs @@ -0,0 +1,99 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.testapp) + +#include "rs_graphics.rsh" +#include "test_app.rsh" + +// Making sure these get reflected +FBlurOffsets *blurExport; +VertexShaderInputs *iExport; +VShaderParams *vConst; +FShaderParams *fConst; +FShaderLightParams *fConts2; +VSParams *vConst2; +VObjectParams *vConst3; + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +rs_allocation gRobotTex; +rs_mesh gRobotMesh; + +rs_program_store gPFSBackground; + +rs_allocation gDummyAlloc; +rs_script gRenderLoop; + +bool gInitialized = false; + +float gRotate; + +void init() { + gRotate = 0.0f; +} + +static int pos = 50; +static float gRotateY = 120.0f; +static float3 gLookAt = 0; +static float gZoom = 50.0f; +static void displayLoading() { + if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) { + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gRobotTex); + + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + // Position our models on the screen + gRotateY += rsGetDt()*100; + rsMatrixTranslate(&matrix, 0, 0, -gZoom); + rsMatrixRotate(&matrix, 20.0f, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); + rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gRobotMesh); + } + + uint width = rsgGetWidth(); + uint height = rsgGetHeight(); + int left = 0, right = 0, top = 0, bottom = 0; + const char* text = "Initializing..."; + rsgMeasureText(text, &left, &right, &top, &bottom); + int centeredPos = width / 2 - (right - left) / 2; + rsgDrawText(text, centeredPos, height / 2 + height / 10); +} + +int root(void) { + rs_allocation nullAlloc; + if (!gInitialized) { + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + displayLoading(); + return 30; + } + + rsForEach(gRenderLoop, gDummyAlloc, nullAlloc); + + return 10; +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh new file mode 100644 index 0000000..2885ac5 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh @@ -0,0 +1,57 @@ +// Copyright (C) 2012 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.testapp) + +// Helpers +typedef struct VShaderParams_s { + rs_matrix4x4 model; + rs_matrix4x4 viewProj; +} VShaderParams; + +typedef struct VSParams_s { + rs_matrix4x4 viewProj; +} VSParams; + +typedef struct VObjectParams_s { + rs_matrix4x4 model; +} VObjectParams; + +typedef struct FShaderParams_s { + float4 cameraPos; +} FShaderParams; + +typedef struct FShaderLightParams_s { + float4 lightPos_0; + float4 lightColor_0; + float4 lightPos_1; + float4 lightColor_1; + float4 cameraPos; + float4 diffuse; +} FShaderLightParams; + +typedef struct FBlurOffsets_s { + float blurOffset0; + float blurOffset1; + float blurOffset2; + float blurOffset3; +} FBlurOffsets; + +typedef struct VertexShaderInputs_s { + float4 position; + float3 normal; + float2 texture0; +} VertexShaderInputs; |