summaryrefslogtreecommitdiffstats
path: root/tests/RenderScriptTests/SceneGraph/src
diff options
context:
space:
mode:
authorAlex Sakhartchouk <alexst@google.com>2011-12-08 11:39:14 -0800
committerAlex Sakhartchouk <alexst@google.com>2011-12-08 11:39:14 -0800
commita7a211b8a68a7d3f5ff4409aa286db07f96c0550 (patch)
tree411b4721ebb7e42aca30b415b11ec1b9f6893509 /tests/RenderScriptTests/SceneGraph/src
parent8030bfd9c8956bd94ccda5ee4643a4c375338303 (diff)
downloadframeworks_base-a7a211b8a68a7d3f5ff4409aa286db07f96c0550.zip
frameworks_base-a7a211b8a68a7d3f5ff4409aa286db07f96c0550.tar.gz
frameworks_base-a7a211b8a68a7d3f5ff4409aa286db07f96c0550.tar.bz2
Sample scene graph
Change-Id: I65b210b770121ac02c5857b48d2ec0d053133dd6
Diffstat (limited to 'tests/RenderScriptTests/SceneGraph/src')
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java81
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java528
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java145
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java118
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Drawable.java178
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableBase.java39
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableGroup.java47
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FileSelector.java110
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java70
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java57
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java60
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java39
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java116
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java93
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java260
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraph.java115
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java74
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java629
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphView.java152
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java127
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java47
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java89
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java54
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TouchHandler.java122
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java88
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java57
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs44
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs28
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs296
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph.rs90
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs111
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh179
32 files changed, 4243 insertions, 0 deletions
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java
new file mode 100644
index 0000000..d220df9
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java
@@ -0,0 +1,81 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScriptGL;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Camera extends SceneGraphBase {
+
+ Transform mTransform;
+ float mFOV;
+ float mNear;
+ float mFar;
+
+ ScriptField_Camera_s mField;
+
+ public Camera() {
+ mFOV = 60.0f;
+ mNear = 0.1f;
+ mFar = 100.0f;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ }
+ public void setFOV(float fov) {
+ mFOV = fov;
+ }
+
+ public void setNear(float n) {
+ mNear = n;
+ }
+
+ public void setFar(float f) {
+ mFar = f;
+ }
+
+ ScriptField_Camera_s getRSData(RenderScriptGL rs) {
+ if (mField != null) {
+ return mField;
+ }
+
+ mField = new ScriptField_Camera_s(rs, 1);
+ ScriptField_Camera_s.Item cam = new ScriptField_Camera_s.Item();
+ cam.horizontalFOV = mFOV;
+ cam.near = mNear;
+ cam.far = mFar;
+ cam.transformMatrix = mTransform.getRSData(rs).getAllocation();
+ cam.name = getStringAsAllocation(rs, getName());
+ mField.set(cam, 0, true);
+
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
new file mode 100644
index 0000000..c7caf8d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
@@ -0,0 +1,528 @@
+/*
+ * 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.scenegraph;
+import com.android.scenegraph.CompoundTransform.TranslateComponent;
+import com.android.scenegraph.CompoundTransform.RotateComponent;
+import com.android.scenegraph.CompoundTransform.ScaleComponent;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.HashMap;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class ColladaParser {
+ static final String TAG = "ColladaParser";
+ Document mDom;
+
+ HashMap<String, LightBase> mLights;
+ HashMap<String, Camera> mCameras;
+ HashMap<String, ArrayList<ShaderParam> > mEffectsParams;
+ HashMap<String, Texture2D> mImages;
+ HashMap<String, Texture2D> mSamplerImageMap;
+ Scene mScene;
+
+ String toString(Float3 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z;
+ return valueStr;
+ }
+
+ String toString(Float4 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z + " " + v.w;
+ return valueStr;
+ }
+
+ public ColladaParser(){
+ mLights = new HashMap<String, LightBase>();
+ mCameras = new HashMap<String, Camera>();
+ mEffectsParams = new HashMap<String, ArrayList<ShaderParam> >();
+ mImages = new HashMap<String, Texture2D>();
+ }
+
+ public void init(InputStream is) {
+ mLights.clear();
+ mCameras.clear();
+ mEffectsParams.clear();
+
+ long start = System.currentTimeMillis();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ mDom = db.parse(is);
+ } catch(ParserConfigurationException e) {
+ e.printStackTrace();
+ } catch(SAXException e) {
+ e.printStackTrace();
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", " Parse time: " + (end - start));
+ exportSceneData();
+ }
+
+ Scene getScene() {
+ return mScene;
+ }
+
+ private void exportSceneData(){
+ mScene = new Scene();
+
+ Element docEle = mDom.getDocumentElement();
+ NodeList nl = docEle.getElementsByTagName("light");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element l = (Element)nl.item(i);
+ convertLight(l);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("camera");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element c = (Element)nl.item(i);
+ convertCamera(c);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("image");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element img = (Element)nl.item(i);
+ convertImage(img);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("effect");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element e = (Element)nl.item(i);
+ convertEffects(e);
+ }
+ }
+
+ // Material is just a link to the effect
+ nl = docEle.getElementsByTagName("material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertMaterials(m);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("visual_scene");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element s = (Element)nl.item(i);
+ getScene(s);
+ }
+ }
+ }
+
+ private void getDrawable(Element shape, Transform t) {
+ String geoURL = shape.getAttribute("url");
+ //DrawableGroup group = new DrawableGroup();
+ //group.setName(geoURL.substring(1));
+ //mScene.appendDrawable(group);
+ NodeList nl = shape.getElementsByTagName("instance_material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element materialRef = (Element)nl.item(i);
+ String meshIndexName = materialRef.getAttribute("symbol");
+ String materialName = materialRef.getAttribute("target");
+
+ Drawable d = new Drawable();
+ d.setMesh(geoURL.substring(1), meshIndexName);
+ d.setMaterialName(materialName);
+ d.setName(geoURL.substring(1));
+
+ //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
+
+ // Append transform and material data here
+ TransformParam modelP = new TransformParam("model");
+ modelP.setTransform(t);
+ d.appendSourceParams(modelP);
+ d.setTransform(t);
+ //Log.v(TAG, "Set source param " + t.getName());
+
+ // Now find all the parameters that exist on the material
+ ArrayList<ShaderParam> materialParams;
+ materialParams = mEffectsParams.get(materialName.substring(1));
+ for (int pI = 0; pI < materialParams.size(); pI ++) {
+ d.appendSourceParams(materialParams.get(pI));
+ //Log.v(TAG, "Set source param i: " + pI + " name " + materialParams.get(pI).getParamName());
+ }
+ mScene.appendDrawable(d);
+ //group.appendChildren(d);
+ }
+ }
+ }
+
+ private void updateLight(Element shape, Transform t) {
+ String lightURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ LightBase light = mLights.get(lightURL.substring(1));
+ if (light != null) {
+ light.setTransform(t);
+ //Log.v(TAG, "Set Light " + light.getName() + " " + t.getName());
+ }
+ }
+
+ private void updateCamera(Element shape, Transform t) {
+ String camURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ Camera cam = mCameras.get(camURL.substring(1));
+ if (cam != null) {
+ cam.setTransform(t);
+ //Log.v(TAG, "Set Camera " + cam.getName() + " " + t.getName());
+ }
+ }
+
+ private void getNode(Element node, Transform parent, String indent) {
+ String name = node.getAttribute("name");
+ String id = node.getAttribute("id");
+ CompoundTransform current = new CompoundTransform();
+ current.setName(name);
+ if (parent != null) {
+ parent.appendChild(current);
+ } else {
+ mScene.appendTransform(current);
+ }
+
+ mScene.addToTransformMap(current);
+
+ //Log.v(TAG, indent + "|");
+ //Log.v(TAG, indent + "[" + name + "]");
+
+ Node childNode = node.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element field = (Element)childNode;
+ String fieldName = field.getTagName();
+ String description = field.getAttribute("sid");
+ if (fieldName.equals("translate")) {
+ Float3 value = getFloat3(field);
+ current.addComponent(new TranslateComponent(description, value));
+ //Log.v(TAG, indent + " translate " + description + toString(value));
+ } else if (fieldName.equals("rotate")) {
+ Float4 value = getFloat4(field);
+ //Log.v(TAG, indent + " rotate " + description + toString(value));
+ Float3 axis = new Float3(value.x, value.y, value.z);
+ current.addComponent(new RotateComponent(description, axis, value.w));
+ } else if (fieldName.equals("scale")) {
+ Float3 value = getFloat3(field);
+ //Log.v(TAG, indent + " scale " + description + toString(value));
+ current.addComponent(new ScaleComponent(description, value));
+ } else if (fieldName.equals("instance_geometry")) {
+ getDrawable(field, current);
+ } else if (fieldName.equals("instance_light")) {
+ updateLight(field, current);
+ } else if (fieldName.equals("instance_camera")) {
+ updateCamera(field, current);
+ } else if (fieldName.equals("node")) {
+ getNode(field, current, indent + " ");
+ }
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ Texture2D getTexture(String samplerName) {
+ Element sampler = mDom.getElementById(samplerName);
+ if (sampler == null) {
+ return null;
+ }
+
+ NodeList nl = sampler.getElementsByTagName("source");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String surfaceName = getString(ref);
+ if (surfaceName == null) {
+ return null;
+ }
+
+ Element surface = mDom.getElementById(surfaceName);
+ if (surface == null) {
+ return null;
+ }
+ nl = surface.getElementsByTagName("init_from");
+ if (nl != null && nl.getLength() == 1) {
+ ref = (Element)nl.item(0);
+ String texName = getString(ref);
+ //Log.v(TAG, "Extracted texture name " + texName);
+ return mImages.get(texName);
+ }
+ }
+ return null;
+ }
+
+ void extractParams(Element fx, ArrayList<ShaderParam> params) {
+ Node paramNode = fx.getFirstChild();
+ while (paramNode != null) {
+ if (paramNode.getNodeType() == Node.ELEMENT_NODE) {
+ String name = paramNode.getNodeName();
+ // Now find what type it is
+ Node typeNode = paramNode.getFirstChild();
+ while (typeNode != null && typeNode.getNodeType() != Node.ELEMENT_NODE) {
+ typeNode = typeNode.getNextSibling();
+ }
+ String paramType = typeNode.getNodeName();
+ Element typeElem = (Element)typeNode;
+ ShaderParam sceneParam = null;
+ if (paramType.equals("color")) {
+ Float4Param f4p = new Float4Param(name);
+ Float4 value = getFloat4(typeElem);
+ f4p.setValue(value);
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + toString(value));
+ } else if (paramType.equals("float")) {
+ Float4Param f4p = new Float4Param(name);
+ float value = getFloat(typeElem);
+ f4p.setValue(new Float4(value, value, value, value));
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + value);
+ } else if (paramType.equals("texture")) {
+ String samplerName = typeElem.getAttribute("texture");
+ Texture2D tex = getTexture(samplerName);
+ TextureParam texP = new TextureParam(name);
+ texP.setTexture(tex);
+ sceneParam = texP;
+ //Log.v(TAG, "Extracted texture " + tex);
+ }
+ if (sceneParam != null) {
+ params.add(sceneParam);
+ }
+ }
+ paramNode = paramNode.getNextSibling();
+ }
+ }
+
+ private void convertMaterials(Element mat) {
+ String id = mat.getAttribute("id");
+ NodeList nl = mat.getElementsByTagName("instance_effect");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String url = ref.getAttribute("url");
+ ArrayList<ShaderParam> params = mEffectsParams.get(url.substring(1));
+ mEffectsParams.put(id, params);
+ }
+ }
+
+ private void convertEffects(Element fx) {
+ String id = fx.getAttribute("id");
+ ArrayList<ShaderParam> params = new ArrayList<ShaderParam>();
+
+ NodeList nl = fx.getElementsByTagName("newparam");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ field.setIdAttribute("sid", true);
+ }
+ }
+
+ nl = fx.getElementsByTagName("blinn");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "blinn");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("lambert");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "lambert");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("phong");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "phong");
+ extractParams(field, params);
+ }
+ }
+ mEffectsParams.put(id, params);
+ }
+
+ private void convertLight(Element light) {
+ String name = light.getAttribute("name");
+ String id = light.getAttribute("id");
+
+ // Determine type
+ String[] knownTypes = { "point", "spot", "directional" };
+ final int POINT_LIGHT = 0;
+ final int SPOT_LIGHT = 1;
+ final int DIR_LIGHT = 2;
+ int type = -1;
+ for (int i = 0; i < knownTypes.length; i ++) {
+ NodeList nl = light.getElementsByTagName(knownTypes[i]);
+ if (nl != null && nl.getLength() != 0) {
+ type = i;
+ break;
+ }
+ }
+
+ //Log.v(TAG, "Found Light Type " + type);
+
+ LightBase sceneLight = null;
+ switch (type) {
+ case POINT_LIGHT:
+ sceneLight = new PointLight();
+ break;
+ case SPOT_LIGHT: // TODO: finish light types
+ break;
+ case DIR_LIGHT: // TODO: finish light types
+ break;
+ }
+
+ if (sceneLight == null) {
+ return;
+ }
+
+ Float3 color = getFloat3(light, "color");
+ sceneLight.setColor(color);
+ sceneLight.setName(name);
+ mScene.appendLight(sceneLight);
+ mLights.put(id, sceneLight);
+
+ //Log.v(TAG, "Light " + name + " color " + toString(color));
+ }
+
+ private void convertCamera(Element camera) {
+ String name = camera.getAttribute("name");
+ String id = camera.getAttribute("id");
+ float fov = getFloat(camera, "yfov");
+ float near = getFloat(camera, "znear");
+ float far = getFloat(camera, "zfar");
+
+ Camera sceneCamera = new Camera();
+ sceneCamera.setFOV(fov);
+ sceneCamera.setNear(near);
+ sceneCamera.setFar(far);
+ sceneCamera.setName(name);
+ mScene.appendCamera(sceneCamera);
+ mCameras.put(id, sceneCamera);
+ }
+
+ private void convertImage(Element img) {
+ String name = img.getAttribute("name");
+ String id = img.getAttribute("id");
+ String file = getString(img, "init_from");
+
+ Texture2D tex = new Texture2D();
+ tex.setFileName(file);
+ mScene.appendTextures(tex);
+ mImages.put(id, tex);
+ }
+
+ private void getScene(Element scene) {
+ String name = scene.getAttribute("name");
+ String id = scene.getAttribute("id");
+
+ Node childNode = scene.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ String indent = "";
+ getNode((Element)childNode, null, indent);
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ private String getString(Element elem, String name) {
+ String text = null;
+ NodeList nl = elem.getElementsByTagName(name);
+ if (nl != null) {
+ text = ((Element)nl.item(0)).getFirstChild().getNodeValue();
+ }
+ return text;
+ }
+
+ private String getString(Element elem) {
+ String text = null;
+ text = elem.getFirstChild().getNodeValue();
+ return text;
+ }
+
+ private int getInt(Element elem, String name) {
+ return Integer.parseInt(getString(elem, name));
+ }
+
+ private float getFloat(Element elem, String name) {
+ return Float.parseFloat(getString(elem, name));
+ }
+
+ private float getFloat(Element elem) {
+ return Float.parseFloat(getString(elem));
+ }
+
+ private Float3 parseFloat3(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ return new Float3(x, y, z);
+ }
+
+ private Float4 parseFloat4(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ float w = Float.parseFloat(st.nextToken());
+ return new Float4(x, y, z, w);
+ }
+
+ private Float3 getFloat3(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat4(valueString);
+ }
+
+ private Float3 getFloat3(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat4(valueString);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java
new file mode 100644
index 0000000..9394b66
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java
@@ -0,0 +1,145 @@
+/*
+ * 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.scenegraph;
+
+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.SceneManager.SceneLoadedCallback;
+
+
+public class ColladaScene {
+
+ private String modelName;
+ private static String TAG = "ColladaScene";
+ private final int STATE_LAST_FOCUS = 1;
+ private final boolean mLoadFromSD = true;
+ private static String mSDCardPath = "sdcard/scenegraph/";
+
+ SceneGraphRS mRenderer;
+ SceneLoadedCallback mCallback;
+
+ public ColladaScene(String name, SceneGraphRS renderer) {
+ modelName = name;
+ mRenderer = renderer;
+ }
+
+ public ColladaScene(String name, SceneLoadedCallback cb) {
+ modelName = name;
+ mCallback = cb;
+ }
+
+ public void init(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+
+ new ColladaLoaderTask().execute(modelName + ".dae");
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ Scene mActiveScene;
+
+ private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> {
+ ColladaParser sceneSource;
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ sceneSource = new ColladaParser();
+ InputStream is = null;
+ try {
+ if (!mLoadFromSD) {
+ is = mRes.getAssets().open(names[0]);
+ } else {
+ File f = new File(mSDCardPath + names[0]);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Could not open collada file");
+ return new Boolean(false);
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Stream load time: " + (end - start));
+
+ start = System.currentTimeMillis();
+ sceneSource.init(is);
+ end = System.currentTimeMillis();
+ Log.v("TIMER", "Collada parse time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mActiveScene = sceneSource.getScene();
+ if (mRenderer != null) {
+ mRenderer.prepareToRender(mActiveScene);
+ }
+ if (mCallback != null) {
+ mCallback.mLoadedScene = mActiveScene;
+ mCallback.run();
+ }
+
+ new A3DLoaderTask().execute(modelName + ".a3d");
+ }
+ }
+
+ private class A3DLoaderTask extends AsyncTask<String, Void, Boolean> {
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ FileA3D model;
+ if (!mLoadFromSD) {
+ model = FileA3D.createFromAsset(mRS, mRes.getAssets(), names[0]);
+ } else {
+ model = FileA3D.createFromFile(mRS, mSDCardPath + names[0]);
+ }
+ int numModels = model.getIndexEntryCount();
+ for (int i = 0; i < numModels; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ mActiveScene.meshLoaded(entry.getMesh());
+ }
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "A3D load time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ }
+ }
+
+}
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java
new file mode 100644
index 0000000..0de6ba2
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java
@@ -0,0 +1,118 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.*;
+import android.renderscript.Float3;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class CompoundTransform extends Transform {
+
+ public static class Component {
+ String mName;
+ int mRsId;
+ public Float4 mValue;
+
+ public String getName() {
+ return mName;
+ }
+ }
+
+ public static class TranslateComponent extends Component {
+ public TranslateComponent(String name, Float3 translate) {
+ mRsId = RS_ID_TRANSLATE;
+ mName = name;
+ mValue = new Float4(translate.x, translate.y, translate.z, 0);
+ }
+ }
+
+ public static class RotateComponent extends Component {
+ public RotateComponent(String name, Float3 axis, float angle) {
+ mRsId = RS_ID_ROTATE;
+ mName = name;
+ mValue = new Float4(axis.x, axis.y, axis.z, angle);
+ }
+ }
+
+ public static class ScaleComponent extends Component {
+ public ScaleComponent(String name, Float3 scale) {
+ mRsId = RS_ID_SCALE;
+ mName = name;
+ mValue = new Float4(scale.x, scale.y, scale.z, 0);
+ }
+ }
+
+ public ArrayList<Component> mTransformComponents;
+
+ Matrix4f mLocalMatrix;
+ Matrix4f mGlobalMatrix;
+
+ public CompoundTransform() {
+ mTransformComponents = new ArrayList<Component>();
+ }
+
+ public void addComponent(Component c) {
+ mTransformComponents.add(c);
+ }
+
+ public void setComponent(int index, Component c) {
+ mTransformComponents.set(index, c);
+ }
+
+ void initLocalData() {
+ mTransformData = new ScriptField_SgTransform.Item();
+ int numElements = mTransformComponents.size();
+ for (int i = 0; i < numElements; i ++) {
+ Component ith = mTransformComponents.get(i);
+ mTransformData.transforms[i] = ith.mValue;
+ mTransformData.transformTypes[i] = ith.mRsId;
+ mTransformData.transformNames[i] = getStringAsAllocation(mRS, ith.mName);
+ }
+ // "null" terminate the array
+ mTransformData.transformTypes[numElements] = RS_ID_NONE;
+
+ mTransformData.isDirty = 1;
+ mTransformData.children = null;
+ mTransformData.name = getStringAsAllocation(mRS, getName());
+ }
+
+ public void updateRSData() {
+ int numElements = mTransformComponents.size();
+ for (int i = 0; i < numElements; i ++) {
+ Component ith = mTransformComponents.get(i);
+ mTransformData.transforms[i] = ith.mValue;
+ mTransformData.transformTypes[i] = ith.mRsId;
+ mTransformData.transformNames[i] = getStringAsAllocation(mRS, ith.mName);
+ }
+ // "null" terminate the array
+ mTransformData.transformTypes[numElements] = RS_ID_NONE;
+ mTransformData.isDirty = 1;
+ mField.set(mTransformData, 0, true);
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Drawable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Drawable.java
new file mode 100644
index 0000000..2eaca13
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Drawable.java
@@ -0,0 +1,178 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.renderscript.Allocation;
+import android.renderscript.Matrix4f;
+import android.renderscript.Mesh;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+import android.content.res.Resources;
+
+/**
+ * @hide
+ */
+public class Drawable extends DrawableBase {
+ Allocation mVertexParams;
+ Allocation mFragmentParams;
+ ArrayList<Allocation> mFragmentTextures;
+ ArrayList<ShaderParam> mVertexParam;
+ ArrayList<ShaderParam> mFragmentParam;
+ ArrayList<ShaderParam> mSourceParams;
+ Mesh mMesh;
+ int mMeshIndex;
+
+ int mCullType;
+
+ RenderState mRenderState;
+
+ Transform mTransform;
+
+ String mMeshName;
+ String mMeshIndexName;
+
+ public String mMaterialName;
+
+ // quick hack to prototype
+ int sceneIndex;
+
+ ScriptField_Drawable_s mRsField;
+ ScriptField_Drawable_s.Item mRsFieldItem;
+
+ public Drawable() {
+ mSourceParams = new ArrayList<ShaderParam>();
+ }
+
+ public void setCullType(int cull) {
+ mCullType = cull;
+ }
+
+ public void setRenderState(RenderState renderState) {
+ mRenderState = renderState;
+ }
+
+ public void setMesh(Mesh mesh) {
+ mMesh = mesh;
+ }
+
+ public void setMesh(String mesh, String indexName) {
+ mMeshName = mesh;
+ mMeshIndexName = indexName;
+ }
+
+ public void setMaterialName(String name) {
+ mMaterialName = name;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ }
+
+ public void appendSourceParams(ShaderParam p) {
+ mSourceParams.add(p);
+ }
+
+ public void resolveMeshData(Mesh mMesh) {
+ mMesh = mMesh;
+ if (mMesh == null) {
+ Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName);
+ return;
+ }
+ int subIndexCount = mMesh.getPrimitiveCount();
+ if (subIndexCount == 1 || mMeshIndexName == null) {
+ mMeshIndex = 0;
+ } else {
+ for (int i = 0; i < subIndexCount; i ++) {
+ if (mMesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) {
+ mMeshIndex = i;
+ break;
+ }
+ }
+ }
+
+ mRsFieldItem.mesh = mMesh;
+ mRsFieldItem.meshIndex = mMeshIndex;
+
+ mRsField.set(mRsFieldItem, 0, true);
+ }
+
+ void updateTextures(RenderScriptGL rs, Resources res) {
+ for (int i = 0; i < mSourceParams.size(); i ++) {
+ ShaderParam sp = mSourceParams.get(i);
+ if (sp instanceof TextureParam) {
+ TextureParam p = (TextureParam)sp;
+ mRsFieldItem.pf_textures[0] = p.getTexture().getRsData(rs, res);
+ break;
+ }
+ }
+ mRsField.set(mRsFieldItem, 0, true);
+ }
+
+ void updateTextures(RenderScriptGL rs, Allocation a, int slot) {
+ getRsFieldItem(rs, null);
+ mRsFieldItem.pf_textures[slot] = a;
+ }
+
+ void setVisible(RenderScriptGL rs, boolean vis) {
+ getRsField(rs, null);
+ mRsFieldItem.cullType = vis ? 0 : 2;
+ mRsField.set(mRsFieldItem, 0, true);
+ }
+
+ ScriptField_Drawable_s getRsField(RenderScriptGL rs, Resources res) {
+ if (mRsField != null) {
+ return mRsField;
+ }
+ getRsFieldItem(rs, res);
+
+ mRsField = new ScriptField_Drawable_s(rs, 1);
+ mRsField.set(mRsFieldItem, 0, true);
+
+ return mRsField;
+ }
+
+ void getRsFieldItem(RenderScriptGL rs, Resources res) {
+ if (mRsFieldItem != null) {
+ return;
+ }
+
+ mRsFieldItem = new ScriptField_Drawable_s.Item();
+ mRsFieldItem.mesh = mMesh;
+ mRsFieldItem.meshIndex = mMeshIndex;
+ mRsFieldItem.pv_const = mVertexParams;
+ mRsFieldItem.pf_const = mFragmentParams;
+ if (mTransform != null) {
+ mRsFieldItem.transformMatrix = mTransform.getRSData(rs).getAllocation();
+ }
+ mRsFieldItem.name = getStringAsAllocation(rs, getName());
+ mRsFieldItem.render_state = mRenderState.getRSData(rs).getAllocation();
+ mRsFieldItem.bVolInitialized = 0;
+ mRsFieldItem.cullType = mCullType;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableBase.java
new file mode 100644
index 0000000..113ccd4
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableBase.java
@@ -0,0 +1,39 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class DrawableBase extends SceneGraphBase {
+ public DrawableBase() {
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableGroup.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableGroup.java
new file mode 100644
index 0000000..ac44f0b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/DrawableGroup.java
@@ -0,0 +1,47 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class DrawableGroup extends DrawableBase {
+
+ ArrayList<DrawableBase> mChildren;
+
+ public DrawableGroup() {
+ mChildren = new ArrayList<DrawableBase>();
+ }
+
+ public void appendChildren(DrawableBase d) {
+ mChildren.add(d);
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FileSelector.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FileSelector.java
new file mode 100644
index 0000000..691b433
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/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.scenegraph;
+
+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/scenegraph/Float4Param.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java
new file mode 100644
index 0000000..b40db64
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java
@@ -0,0 +1,70 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.graphics.Camera;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Float4Param extends ShaderParam {
+
+ public static final int VALUE = 0;
+ public static final int CAMERA_POSITION = 1;
+ public static final int CAMERA_DIRECTION = 2;
+ public static final int LIGHT_POSITION = 3;
+ public static final int LIGHT_COLOR = 4;
+ public static final int LIGHT_DIRECTION = 5;
+ Float4 mValue;
+ Camera mCamera;
+ LightBase mLight;
+
+ public Float4Param(String name) {
+ super(name);
+ }
+
+ public void setValue(Float4 v) {
+ mValue = v;
+ }
+
+ public Float4 getValue() {
+ return mValue;
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ }
+
+ public void setLight(LightBase l) {
+ mLight = l;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
new file mode 100644
index 0000000..7aad1f8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
@@ -0,0 +1,57 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Float3;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class LightBase extends SceneGraphBase {
+ Transform mTransform;
+ Float3 mColor;
+ float mIntensity;
+ public LightBase() {
+ mColor = new Float3(0.0f, 0.0f, 0.0f);
+ mIntensity = 1.0f;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ }
+
+ public void setColor(Float3 c) {
+ mColor = c;
+ }
+
+ public void setIntensity(float i) {
+ mIntensity = i;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java
new file mode 100644
index 0000000..61f8ccc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java
@@ -0,0 +1,60 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class MatrixTransform extends Transform {
+
+ Matrix4f mLocalMatrix;
+ public MatrixTransform() {
+ mLocalMatrix = new Matrix4f();
+ }
+
+ public void setMatrix(Matrix4f matrix) {
+ mLocalMatrix = matrix;
+ }
+
+ void initLocalData() {
+ mTransformData = new ScriptField_SgTransform.Item();
+ // "null" terminate the array
+ mTransformData.transformTypes[0] = RS_ID_NONE;
+ mTransformData.localMat = mLocalMatrix;
+
+ mTransformData.isDirty = 1;
+ mTransformData.children = null;
+ mTransformData.name = getStringAsAllocation(mRS, getName());
+ }
+
+ public void updateRSData() {
+ mTransformData.localMat = mLocalMatrix;
+ mTransformData.isDirty = 1;
+ mField.set(mTransformData, 0, true);
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
new file mode 100644
index 0000000..41a54c6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
@@ -0,0 +1,39 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class PointLight extends LightBase {
+ public PointLight() {
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java
new file mode 100644
index 0000000..0012b10
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java
@@ -0,0 +1,116 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.util.Log;
+
+import android.renderscript.*;
+import android.content.res.Resources;
+
+/**
+ * @hide
+ */
+public class RenderPass extends SceneGraphBase {
+
+ Allocation mColorTarget;
+ Float4 mClearColor;
+ boolean mShouldClearColor;
+
+ Allocation mDepthTarget;
+ float mClearDepth;
+ boolean mShouldClearDepth;
+
+ ArrayList<DrawableBase> mObjectsToDraw;
+
+ Camera mCamera;
+
+ ScriptField_RenderPass_s.Item mRsField;
+
+ public RenderPass() {
+ mObjectsToDraw = new ArrayList<DrawableBase>();
+ mClearColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
+ mShouldClearColor = true;
+ mClearDepth = 1.0f;
+ mShouldClearDepth = true;
+ }
+
+ public void appendDrawable(Drawable d) {
+ mObjectsToDraw.add(d);
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ }
+
+ public void setColorTarget(Allocation colorTarget) {
+ mColorTarget = colorTarget;
+ }
+ public void setClearColor(Float4 clearColor) {
+ mClearColor = clearColor;
+ }
+ public void setShouldClearColor(boolean shouldClearColor) {
+ mShouldClearColor = shouldClearColor;
+ }
+
+ public void setDepthTarget(Allocation depthTarget) {
+ mDepthTarget = depthTarget;
+ }
+ public void setClearDepth(float clearDepth) {
+ mClearDepth = clearDepth;
+ }
+ public void setShouldClearDepth(boolean shouldClearDepth) {
+ mShouldClearDepth = shouldClearDepth;
+ }
+
+ ScriptField_RenderPass_s.Item getRsField(RenderScriptGL rs, Resources res) {
+ if (mRsField != null) {
+ return mRsField;
+ }
+
+ mRsField = new ScriptField_RenderPass_s.Item();
+ mRsField.color_target = mColorTarget;
+ mRsField.depth_target = mDepthTarget;
+ mRsField.camera = mCamera != null ? mCamera.getRSData(rs).getAllocation() : null;
+
+ if (mObjectsToDraw.size() != 0) {
+ Allocation drawableData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mObjectsToDraw.size());
+ Allocation[] drawableAllocs = new Allocation[mObjectsToDraw.size()];
+ for (int i = 0; i < mObjectsToDraw.size(); i ++) {
+ Drawable dI = (Drawable)mObjectsToDraw.get(i);
+ drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
+ }
+ drawableData.copyFrom(drawableAllocs);
+ mRsField.objects = drawableData;
+ }
+
+ mRsField.clear_color = mClearColor;
+ mRsField.clear_depth = mClearDepth;
+ mRsField.should_clear_color = mShouldClearColor;
+ mRsField.should_clear_depth = mShouldClearDepth;
+ return mRsField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java
new file mode 100644
index 0000000..e8aec95
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java
@@ -0,0 +1,93 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramRaster;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class RenderState extends SceneGraphBase {
+ ProgramVertex mVertex;
+ ProgramFragment mFragment;
+ ProgramStore mStore;
+ ProgramRaster mRaster;
+
+ ScriptField_RenderState_s mField;
+
+ public RenderState(ProgramVertex pv,
+ ProgramFragment pf,
+ ProgramStore ps,
+ ProgramRaster pr) {
+ mVertex = pv;
+ mFragment = pf;
+ mStore = ps;
+ mRaster = pr;
+ }
+
+ public RenderState(RenderState r) {
+ mVertex = r.mVertex;
+ mFragment = r.mFragment;
+ mStore = r.mStore;
+ mRaster = r.mRaster;
+ }
+
+ public void setProgramVertex(ProgramVertex pv) {
+ mVertex = pv;
+ }
+
+ public void setProgramFragment(ProgramFragment pf) {
+ mFragment = pf;
+ }
+
+ public void setProgramStore(ProgramStore ps) {
+ mStore = ps;
+ }
+
+ public void setProgramRaster(ProgramRaster pr) {
+ mRaster = pr;
+ }
+
+ public ScriptField_RenderState_s getRSData(RenderScriptGL rs) {
+ if (mField != null) {
+ return mField;
+ }
+
+ ScriptField_RenderState_s.Item item = new ScriptField_RenderState_s.Item();
+ item.pv = mVertex;
+ item.pf = mFragment;
+ item.ps = mStore;
+ item.pr = mRaster;
+
+ mField = new ScriptField_RenderState_s(rs, 1);
+ mField.set(item, 0, true);
+ return mField;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
new file mode 100644
index 0000000..b1ae365
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
@@ -0,0 +1,260 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Mesh;
+import android.renderscript.*;
+import android.content.res.Resources;
+import android.util.Log;
+import android.os.AsyncTask;
+
+/**
+ * @hide
+ */
+public class Scene extends SceneGraphBase {
+ private static String TIMER_TAG = "TIMER";
+
+ private class ImageLoaderTask extends AsyncTask<String, Void, Boolean> {
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < mDrawables.size(); i ++) {
+ Drawable dI = (Drawable)mDrawables.get(i);
+ dI.updateTextures(mRS, mRes);
+ }
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Texture init time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ }
+ }
+
+ CompoundTransform mRootTransforms;
+ HashMap<String, Transform> mTransformMap;
+ ArrayList<RenderPass> mRenderPasses;
+ ArrayList<LightBase> mLights;
+ ArrayList<Camera> mCameras;
+ ArrayList<DrawableBase> mDrawables;
+ HashMap<String, DrawableBase> mDrawableMap;
+ ArrayList<Texture2D> mTextures;
+
+ HashMap<String, ArrayList<Drawable> > mDrawableMeshMap;
+
+ // RS Specific stuff
+ ScriptField_SgTransform mTransformRSData;
+
+ RenderScriptGL mRS;
+ Resources mRes;
+
+ ScriptField_RenderPass_s mRenderPassAlloc;
+
+ public Scene() {
+ mRenderPasses = new ArrayList<RenderPass>();
+ mLights = new ArrayList<LightBase>();
+ mCameras = new ArrayList<Camera>();
+ mDrawables = new ArrayList<DrawableBase>();
+ mDrawableMap = new HashMap<String, DrawableBase>();
+ mDrawableMeshMap = new HashMap<String, ArrayList<Drawable> >();
+ mTextures = new ArrayList<Texture2D>();
+ mRootTransforms = new CompoundTransform();
+ mRootTransforms.setName("_scene_root_");
+ mTransformMap = new HashMap<String, Transform>();
+ }
+
+ public void appendTransform(Transform t) {
+ mRootTransforms.appendChild(t);
+ }
+
+ // temporary
+ public void addToTransformMap(Transform t) {
+ mTransformMap.put(t.getName(), t);
+ }
+
+ public Transform getTransformByName(String name) {
+ return mTransformMap.get(name);
+ }
+
+ public void appendRenderPass(RenderPass p) {
+ mRenderPasses.add(p);
+ }
+
+ public void clearRenderPasses() {
+ mRenderPasses.clear();
+ }
+
+ public void appendLight(LightBase l) {
+ mLights.add(l);
+ }
+
+ public void appendCamera(Camera c) {
+ mCameras.add(c);
+ }
+
+ public ArrayList<Camera> getCameras() {
+ return mCameras;
+ }
+
+ public void appendDrawable(DrawableBase d) {
+ mDrawables.add(d);
+ mDrawableMap.put(d.getName(), d);
+ }
+
+ public ArrayList<DrawableBase> getDrawables() {
+ return mDrawables;
+ }
+
+ public DrawableBase getDrawableByName(String name) {
+ return mDrawableMap.get(name);
+ }
+
+ public void appendTextures(Texture2D tex) {
+ mTextures.add(tex);
+ }
+
+ public void assignRenderStateToMaterial(RenderState renderState, String regex) {
+ Pattern pattern = Pattern.compile(regex);
+ int numDrawables = mDrawables.size();
+ for (int i = 0; i < numDrawables; i ++) {
+ Drawable shape = (Drawable)mDrawables.get(i);
+ Matcher m = pattern.matcher(shape.mMaterialName);
+ if (m.find()) {
+ shape.setRenderState(renderState);
+ }
+ }
+ }
+
+ public void assignRenderState(RenderState renderState) {
+ int numDrawables = mDrawables.size();
+ for (int i = 0; i < numDrawables; i ++) {
+ Drawable shape = (Drawable)mDrawables.get(i);
+ shape.setRenderState(renderState);
+ }
+ }
+
+ public void meshLoaded(Mesh m) {
+ ArrayList<Drawable> entries = mDrawableMeshMap.get(m.getName());
+ int numEntries = entries.size();
+ for (int i = 0; i < numEntries; i++) {
+ Drawable d = entries.get(i);
+ d.resolveMeshData(m);
+ //mDrawablesField.set(d.getRsField(mRS, mRes), d.sceneIndex, true);
+ }
+ }
+
+ void addToMeshMap(Drawable d) {
+ ArrayList<Drawable> entries = mDrawableMeshMap.get(d.mMeshName);
+ if (entries == null) {
+ entries = new ArrayList<Drawable>();
+ mDrawableMeshMap.put(d.mMeshName, entries);
+ }
+ entries.add(d);
+ }
+
+ public void destroyRS(SceneManager sceneManager) {
+ mTransformRSData = null;
+ sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
+ sceneManager.mRenderLoop.set_gDrawableObjects(null);
+ mRenderPassAlloc = null;
+ sceneManager.mRenderLoop.set_gRenderPasses(null);
+ sceneManager.mRenderLoop.bind_gFrontToBack(null);
+ sceneManager.mRenderLoop.bind_gBackToFront(null);
+ sceneManager.mRenderLoop.set_gCameras(null);
+
+ mTransformMap = null;
+ mRenderPasses = null;
+ mLights = null;
+ mCameras = null;
+ mDrawables = null;
+ mDrawableMap = null;
+ mTextures = null;
+ mDrawableMeshMap = null;
+ mRootTransforms = null;
+ }
+
+ public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) {
+ if (mRenderPasses.size() != 0) {
+ mRenderPassAlloc = new ScriptField_RenderPass_s(mRS, mRenderPasses.size());
+ for (int i = 0; i < mRenderPasses.size(); i ++) {
+ mRenderPassAlloc.set(mRenderPasses.get(i).getRsField(mRS, mRes), i, false);
+ }
+ mRenderPassAlloc.copyAll();
+ sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation());
+ }
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ mRS = rs;
+ long start = System.currentTimeMillis();
+ mTransformRSData = mRootTransforms.getRSData(rs);
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Transform init time: " + (end - start));
+
+ start = System.currentTimeMillis();
+
+ sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
+ end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Script init time: " + (end - start));
+
+ start = System.currentTimeMillis();
+ Allocation drawableData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mDrawables.size());
+ Allocation[] drawableAllocs = new Allocation[mDrawables.size()];
+ for (int i = 0; i < mDrawables.size(); i ++) {
+ Drawable dI = (Drawable)mDrawables.get(i);
+ dI.sceneIndex = i;
+ addToMeshMap(dI);
+ drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
+ }
+ drawableData.copyFrom(drawableAllocs);
+ sceneManager.mRenderLoop.set_gDrawableObjects(drawableData);
+
+ initRenderPassRS(rs, sceneManager);
+
+ new ImageLoaderTask().execute();
+
+ end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Drawable init time: " + (end - start));
+
+ Allocation opaqueBuffer = Allocation.createSized(rs, Element.U32(rs), mDrawables.size());
+ Allocation transparentBuffer = Allocation.createSized(rs,
+ Element.U32(rs), mDrawables.size());
+
+ sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer);
+ sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer);
+
+ Allocation cameraData = Allocation.createSized(rs, Element.ALLOCATION(rs), mCameras.size());
+ Allocation[] cameraAllocs = new Allocation[mCameras.size()];
+ for (int i = 0; i < mCameras.size(); i ++) {
+ cameraAllocs[i] = mCameras.get(i).getRSData(rs).getAllocation();
+ }
+ cameraData.copyFrom(cameraAllocs);
+ sceneManager.mRenderLoop.set_gCameras(cameraData);
+ }
+}
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraph.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraph.java
new file mode 100644
index 0000000..cfb91f4
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraph.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.scenegraph;
+
+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 SceneGraph extends Activity {
+
+ private SceneGraphView 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 SceneGraphView(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/scenegraph/SceneGraphBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java
new file mode 100644
index 0000000..f5fe7c8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java
@@ -0,0 +1,74 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScript;
+import android.renderscript.RSRuntimeException;
+
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class SceneGraphBase {
+ String mName;
+ public void setName(String n) {
+ mName = n;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ Allocation getStringAsAllocation(RenderScript rs, String str) {
+ if (str == null) {
+ return null;
+ }
+ if (str.length() == 0) {
+ return null;
+ }
+ byte[] allocArray = null;
+ byte[] nullChar = new byte[1];
+ nullChar[0] = 0;
+ try {
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
+ allocArray.length + 1,
+ Allocation.USAGE_SCRIPT);
+ alloc.copy1DRangeFrom(0, allocArray.length, allocArray);
+ alloc.copy1DRangeFrom(allocArray.length, 1, nullChar);
+ return alloc;
+ }
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
new file mode 100644
index 0000000..04b4cd8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
@@ -0,0 +1,629 @@
+/*
+ * 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.scenegraph;
+
+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.SceneManager.SceneLoadedCallback;
+
+public class SceneGraphRS {
+
+ private static String modelName = "orientation_test";
+ private static String TAG = "SceneGraphRS";
+ private final int STATE_LAST_FOCUS = 1;
+ private final boolean mLoadFromSD = true;
+ private static String mSDCardPath = "sdcard/scenegraph/";
+
+ int mWidth;
+ int mHeight;
+ int mRotation;
+
+ boolean mUseBlur;
+
+ SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() {
+ public void run() {
+ prepareToRender(mLoadedScene);
+ }
+ };
+
+ SceneManager mSceneManager;
+
+ TouchHandler mTouchHandler;
+
+ public SceneGraphRS() {
+ mUseBlur = false;
+ }
+
+ void toggleBlur() {
+ mUseBlur = !mUseBlur;
+
+ mActiveScene.clearRenderPasses();
+ initRenderPasses();
+ mActiveScene.initRenderPassRS(mRS, mSceneManager);
+ Drawable plane = (Drawable)mActiveScene.getDrawableByName("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;
+ mRotation = 0;
+
+ mTouchHandler = new TouchHandler();
+
+ mSceneManager = new SceneManager();
+ mSceneManager.initRS(mRS, mRes, mWidth, mHeight);
+
+ renderLoading();
+
+ new LoadingScreenLoaderTask().execute();
+
+ initRS();
+
+ mSceneManager.loadModel(modelName, mLoadedCallback);
+ }
+
+ void loadModel(String path) {
+ String shortName = path.substring(path.lastIndexOf('/') + 1);
+ shortName = shortName.substring(0, shortName.lastIndexOf('.'));
+ mScript.set_gInitialized(false);
+ mActiveScene.destroyRS(mSceneManager);
+ mSceneManager.loadModel(shortName, mLoadedCallback);
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ private Sampler mSampler;
+ private ProgramStore mPSBackground;
+ private ProgramFragment mPFBackground;
+ private ProgramVertex mPVBackground;
+ private ProgramVertexFixedFunction.Constants mPVA;
+
+ private ProgramFragment mPF_Paint;
+ private ProgramFragment mPF_Aluminum;
+ private ProgramFragment mPF_Plastic;
+ private ProgramFragment mPF_Diffuse;
+ private ProgramFragment mPF_BlurH;
+ private ProgramFragment mPF_BlurV;
+ private ProgramFragment mPF_SelectColor;
+ private ProgramFragment mPF_Texture;
+ ScriptField_FShaderParams_s mFsConst;
+ ScriptField_FBlurOffsets_s mFsBlurHConst;
+ ScriptField_FBlurOffsets_s mFsBlurVConst;
+ private ProgramVertex mPV_Paint;
+ ScriptField_VShaderParams_s mVsConst;
+ private ProgramVertex mPV_Blur;
+
+ private Allocation mDefaultCube;
+ private Allocation mAllocPV;
+ private Allocation mEnvCube;
+ private Allocation mDiffCube;
+
+ private Allocation mRenderTargetBlur0Color;
+ private Allocation mRenderTargetBlur0Depth;
+ private Allocation mRenderTargetBlur1Color;
+ private Allocation mRenderTargetBlur1Depth;
+ private Allocation mRenderTargetBlur2Color;
+ private Allocation mRenderTargetBlur2Depth;
+
+ Scene mActiveScene;
+
+ private ScriptC_scenegraph mScript;
+
+ 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();
+ }
+
+ initPFS();
+ initPF();
+ initPV();
+
+ 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);
+ }
+ }
+
+
+ private class ImageLoaderTask extends AsyncTask<String, Void, Boolean> {
+ Allocation tempEnv;
+ Allocation tempDiff;
+
+ InputStream openStream(String name) {
+ InputStream is = null;
+ try {
+ if (!mLoadFromSD) {
+ is = mRes.getAssets().open(name);
+ } else {
+ File f = new File(mSDCardPath + name);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e("PAINTSHADERS", " Message: " + e.getMessage());
+ }
+ return is;
+ }
+
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ InputStream is = openStream("cube_env.png");
+ if (is == null) {
+ return new Boolean(false);
+ }
+
+ Bitmap b = BitmapFactory.decodeStream(is);
+ tempEnv = Allocation.createCubemapFromBitmap(mRS,
+ b,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+
+ is = openStream("cube_spec.png");
+ if (is == null) {
+ return new Boolean(false);
+ }
+
+ b = BitmapFactory.decodeStream(is);
+ tempDiff = Allocation.createCubemapFromBitmap(mRS,
+ b,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Image load time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mEnvCube = tempEnv;
+ mDiffCube = tempDiff;
+
+ mPF_Paint.bindTexture(mEnvCube, 1);
+ mPF_Aluminum.bindTexture(mDiffCube, 1);
+ }
+ }
+
+ 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);
+ }
+
+ private void initPaintShaders() {
+ ProgramVertex.Builder vb = new ProgramVertex.Builder(mRS);
+ mVsConst = new ScriptField_VShaderParams_s(mRS, 1);
+ vb.addConstant(mVsConst.getAllocation().getType());
+ vb.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+ vb.setShader(mRes, R.raw.shader2v);
+ mPV_Paint = vb.create();
+ mPV_Paint.bindConstants(mVsConst.getAllocation(), 0);
+
+ vb = new ProgramVertex.Builder(mRS);
+ vb.addConstant(mVsConst.getAllocation().getType());
+ vb.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+ vb.setShader(mRes, R.raw.blur_vertex);
+ mPV_Blur = vb.create();
+ mPV_Blur.bindConstants(mVsConst.getAllocation(), 0);
+
+ ProgramFragment.Builder fb = new ProgramFragment.Builder(mRS);
+ mFsConst = new ScriptField_FShaderParams_s(mRS, 1);
+ fb.addConstant(mFsConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.paintf);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ fb.addTexture(TextureType.TEXTURE_CUBE);
+ mPF_Paint = fb.create();
+
+ mPF_Paint.bindConstants(mFsConst.getAllocation(), 0);
+ mPF_Paint.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+ mPF_Paint.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.metal);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ fb.addTexture(TextureType.TEXTURE_CUBE);
+ mPF_Aluminum = fb.create();
+
+ mPF_Aluminum.bindConstants(mFsConst.getAllocation(), 0);
+ mPF_Aluminum.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+ mPF_Aluminum.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.plastic);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_Plastic = fb.create();
+ mPF_Plastic.bindConstants(mFsConst.getAllocation(), 0);
+ mPF_Plastic.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.diffuse);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_Diffuse = fb.create();
+ mPF_Diffuse.bindConstants(mFsConst.getAllocation(), 0);
+ mPF_Diffuse.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.texture);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_Texture = fb.create();
+ mPF_Texture.bindConstants(mFsConst.getAllocation(), 0);
+ mPF_Texture.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+
+ mFsBlurHConst = new ScriptField_FBlurOffsets_s(mRS, 1);
+ float xAdvance = 1.0f / (float)mRenderTargetBlur0Color.getType().getX();
+ ScriptField_FBlurOffsets_s.Item item = new ScriptField_FBlurOffsets_s.Item();
+ item.blurOffset0 = - xAdvance * 2.5f;
+ item.blurOffset1 = - xAdvance * 0.5f;
+ item.blurOffset2 = xAdvance * 1.5f;
+ item.blurOffset3 = xAdvance * 3.5f;
+ mFsBlurHConst.set(item, 0, true);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsBlurHConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.blur_h);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_BlurH = fb.create();
+ mPF_BlurH.bindConstants(mFsBlurHConst.getAllocation(), 0);
+ mPF_BlurH.bindTexture(mRenderTargetBlur0Color, 0);
+ mPF_BlurH.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+
+ mFsBlurVConst = new ScriptField_FBlurOffsets_s(mRS, 1);
+ float yAdvance = 1.0f / (float)mRenderTargetBlur0Color.getType().getY();
+ item.blurOffset0 = - yAdvance * 2.5f;
+ item.blurOffset1 = - yAdvance * 0.5f;
+ item.blurOffset2 = yAdvance * 1.5f;
+ item.blurOffset3 = yAdvance * 3.5f;
+ mFsBlurVConst.set(item, 0, true);
+
+ fb = new ProgramFragment.Builder(mRS);
+ fb.addConstant(mFsBlurVConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.blur_v);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_BlurV = fb.create();
+ mPF_BlurV.bindConstants(mFsBlurVConst.getAllocation(), 0);
+ mPF_BlurV.bindTexture(mRenderTargetBlur1Color, 0);
+ mPF_BlurV.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+
+ fb = new ProgramFragment.Builder(mRS);
+ //fb.addConstant(mFsBlurVConst.getAllocation().getType());
+ fb.setShader(mRes, R.raw.select_color);
+ fb.addTexture(TextureType.TEXTURE_2D);
+ mPF_SelectColor = fb.create();
+ //mPF_SelectColor.bindConstants(mFsBlurVConst.getAllocation(), 0);
+ //mPF_SelectColor.bindTexture(mRenderTargetBlur1Color, 0);
+ mPF_SelectColor.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+ }
+
+ private void initPFS() {
+ ProgramStore.Builder b = new ProgramStore.Builder(mRS);
+
+ b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ b.setDitherEnabled(false);
+ b.setDepthMaskEnabled(true);
+ mPSBackground = b.create();
+
+ mScript.set_gPFSBackground(mPSBackground);
+ }
+
+ private void initPF() {
+ Sampler.Builder bs = new Sampler.Builder(mRS);
+ bs.setMinification(Sampler.Value.LINEAR);
+ bs.setMagnification(Sampler.Value.LINEAR);
+ bs.setWrapS(Sampler.Value.CLAMP);
+ bs.setWrapT(Sampler.Value.CLAMP);
+ mSampler = bs.create();
+
+ ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+ b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+ ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+ mPFBackground = b.create();
+ mPFBackground.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+
+ mScript.set_gPFBackground(mPFBackground);
+ }
+
+ private void initPV() {
+ ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+ mPVBackground = pvb.create();
+
+ mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+ ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
+
+ mScript.set_gPVBackground(mPVBackground);
+ }
+
+ void renderLoading() {
+ mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph);
+ mRS.bindRootScript(mScript);
+ }
+
+ void initSceneRS() {
+
+ }
+
+ void createRenderTargets() {
+ Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
+ b.setX(mWidth/8).setY(mHeight/8);
+ Type renderType = b.create();
+ mRenderTargetBlur0Color = Allocation.createTyped(mRS, renderType,
+ Allocation.USAGE_GRAPHICS_TEXTURE |
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ mRenderTargetBlur1Color = Allocation.createTyped(mRS, renderType,
+ Allocation.USAGE_GRAPHICS_TEXTURE |
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ mRenderTargetBlur2Color = Allocation.createTyped(mRS, renderType,
+ Allocation.USAGE_GRAPHICS_TEXTURE |
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+
+ b = new Type.Builder(mRS,
+ Element.createPixel(mRS, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ b.setX(mWidth/8).setY(mHeight/8);
+ mRenderTargetBlur0Depth = Allocation.createTyped(mRS,
+ b.create(),
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+
+ mRenderTargetBlur1Depth = Allocation.createTyped(mRS,
+ b.create(),
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ mRenderTargetBlur2Depth = Allocation.createTyped(mRS,
+ b.create(),
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ }
+
+ ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
+ builder.setDitherEnabled(false);
+ builder.setDepthMaskEnabled(false);
+ return builder.create();
+ }
+
+ Drawable getDrawableQuad(String name, RenderState state) {
+ Drawable quad = new Drawable();
+ quad.setTransform(new MatrixTransform());
+ quad.setMesh(mSceneManager.getScreenAlignedQuad());
+ quad.setName(name);
+ quad.setRenderState(state);
+ quad.setCullType(1);
+ return quad;
+ }
+
+ void addBlurPasses() {
+ ArrayList<DrawableBase> allDraw = mActiveScene.getDrawables();
+ int numDraw = allDraw.size();
+
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ BLEND_ADD_DEPTH_NONE(mRS),
+ ProgramRaster.CULL_NONE(mRS));
+
+ RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor,
+ ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
+ ProgramRaster.CULL_NONE(mRS));
+
+ RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH,
+ ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
+ ProgramRaster.CULL_NONE(mRS));
+
+ RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV,
+ ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
+ ProgramRaster.CULL_NONE(mRS));
+
+ RenderPass blurSourcePass = new RenderPass();
+ blurSourcePass.setColorTarget(mRenderTargetBlur0Color);
+ blurSourcePass.setDepthTarget(mRenderTargetBlur0Depth);
+ blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ blurSourcePass.setShouldClearColor(true);
+ blurSourcePass.setClearDepth(1.0f);
+ blurSourcePass.setShouldClearDepth(true);
+ blurSourcePass.setCamera(mActiveScene.getCameras().get(1));
+ for (int i = 0; i < numDraw; i ++) {
+ blurSourcePass.appendDrawable((Drawable)allDraw.get(i));
+ }
+ mActiveScene.appendRenderPass(blurSourcePass);
+
+ RenderPass selectColorPass = new RenderPass();
+ selectColorPass.setColorTarget(mRenderTargetBlur2Color);
+ selectColorPass.setDepthTarget(mRenderTargetBlur2Depth);
+ selectColorPass.setShouldClearColor(false);
+ selectColorPass.setShouldClearDepth(false);
+ selectColorPass.setCamera(mActiveScene.getCameras().get(1));
+ // Make blur shape
+ Drawable quad = getDrawableQuad("ScreenAlignedQuadS", selectCol);
+ quad.updateTextures(mRS, mRenderTargetBlur0Color, 0);
+ selectColorPass.appendDrawable(quad);
+ mActiveScene.appendRenderPass(selectColorPass);
+
+ RenderPass horizontalBlurPass = new RenderPass();
+ horizontalBlurPass.setColorTarget(mRenderTargetBlur1Color);
+ horizontalBlurPass.setDepthTarget(mRenderTargetBlur1Depth);
+ horizontalBlurPass.setShouldClearColor(false);
+ horizontalBlurPass.setShouldClearDepth(false);
+ horizontalBlurPass.setCamera(mActiveScene.getCameras().get(1));
+ // Make blur shape
+ quad = getDrawableQuad("ScreenAlignedQuadH", hBlur);
+ quad.updateTextures(mRS, mRenderTargetBlur2Color, 0);
+ horizontalBlurPass.appendDrawable(quad);
+ mActiveScene.appendRenderPass(horizontalBlurPass);
+
+ RenderPass verticalBlurPass = new RenderPass();
+ verticalBlurPass.setColorTarget(mRenderTargetBlur2Color);
+ verticalBlurPass.setDepthTarget(mRenderTargetBlur2Depth);
+ verticalBlurPass.setShouldClearColor(false);
+ verticalBlurPass.setShouldClearDepth(false);
+ verticalBlurPass.setCamera(mActiveScene.getCameras().get(1));
+ // Make blur shape
+ quad = getDrawableQuad("ScreenAlignedQuadV", vBlur);
+ quad.updateTextures(mRS, mRenderTargetBlur1Color, 0);
+ verticalBlurPass.appendDrawable(quad);
+ mActiveScene.appendRenderPass(verticalBlurPass);
+
+ }
+
+ void initRenderPasses() {
+ ArrayList<DrawableBase> allDraw = mActiveScene.getDrawables();
+ int numDraw = allDraw.size();
+
+ if (mUseBlur) {
+ addBlurPasses();
+ }
+
+ 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.appendDrawable((Drawable)allDraw.get(i));
+ }
+ mActiveScene.appendRenderPass(mainPass);
+
+ if (mUseBlur) {
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ BLEND_ADD_DEPTH_NONE(mRS),
+ ProgramRaster.CULL_NONE(mRS));
+
+ RenderPass compositePass = new RenderPass();
+ compositePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 0.0f));
+ compositePass.setShouldClearColor(false);
+ compositePass.setClearDepth(1.0f);
+ compositePass.setShouldClearDepth(false);
+ compositePass.setCamera(mActiveScene.getCameras().get(1));
+ Drawable quad = getDrawableQuad("ScreenAlignedQuad", drawTex);
+ quad.updateTextures(mRS, mRenderTargetBlur2Color, 0);
+ compositePass.appendDrawable(quad);
+
+ mActiveScene.appendRenderPass(compositePass);
+ }
+ }
+
+ public void prepareToRender(Scene s) {
+ mActiveScene = s;
+ RenderState plastic = new RenderState(mPV_Paint, mPF_Plastic, null, null);
+ RenderState diffuse = new RenderState(mPV_Paint, mPF_Diffuse, null, null);
+ RenderState paint = new RenderState(mPV_Paint, mPF_Paint, null, null);
+ RenderState aluminum = new RenderState(mPV_Paint, mPF_Aluminum, null, null);
+ RenderState glassTransp = new RenderState(mPV_Paint,
+ mPF_Paint,
+ 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");
+
+ Drawable plane = (Drawable)mActiveScene.getDrawableByName("pPlaneShape1");
+ if (plane != null) {
+ RenderState texState = new RenderState(mPV_Paint, mPF_Texture, 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));
+
+ mScript.set_gInitialized(true);
+ }
+
+ private void initRS() {
+
+ createRenderTargets();
+ initPaintShaders();
+ new ImageLoaderTask().execute();
+
+ Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.defaultcube);
+ mDefaultCube = Allocation.createCubemapFromBitmap(mRS, b);
+ mPF_Paint.bindTexture(mDefaultCube, 1);
+ mPF_Aluminum.bindTexture(mDefaultCube, 1);
+
+ ScriptC_render renderLoop = mSceneManager.getRenderLoop();
+ renderLoop.bind_vConst(mVsConst);
+ renderLoop.bind_fConst(mFsConst);
+
+ 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/scenegraph/SceneGraphView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
new file mode 100644
index 0000000..0f28501
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphView.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.scenegraph;
+
+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 SceneGraphView extends RSSurfaceView {
+
+ public SceneGraphView(Context context) {
+ super(context);
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ }
+
+ private RenderScriptGL mRS;
+ SceneGraphRS 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 SceneGraphRS();
+ 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/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
new file mode 100644
index 0000000..3bb49f3
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
@@ -0,0 +1,127 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Mesh;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.content.res.Resources;
+import android.view.SurfaceHolder;
+import android.util.Log;
+import android.os.AsyncTask;
+
+/**
+ * @hide
+ */
+public class SceneManager extends SceneGraphBase {
+
+ ScriptC_render mRenderLoop;
+ ScriptC_camera mCameraScript;
+ ScriptC_transform mTransformScript;
+
+ RenderScriptGL mRS;
+ Resources mRes;
+ Mesh mQuad;
+ int mWidth;
+ int mHeight;
+
+ public static class SceneLoadedCallback implements Runnable {
+ Scene mLoadedScene;
+ String mName;
+ public void run() {
+ }
+ }
+
+ private void initPFS() {
+ ProgramStore.Builder b = new ProgramStore.Builder(mRS);
+
+ b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ b.setDitherEnabled(false);
+ b.setDepthMaskEnabled(true);
+
+ mRenderLoop.set_gPFSBackground(b.create());
+ }
+
+ public SceneManager() {
+ }
+
+ public void loadModel(String name, SceneLoadedCallback cb) {
+ ColladaScene scene = new ColladaScene(name, cb);
+ scene.init(mRS, mRes);
+ }
+
+ public Mesh getScreenAlignedQuad() {
+ if (mQuad != null) {
+ return mQuad;
+ }
+
+ Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
+ 3, Mesh.TriangleMeshBuilder.TEXTURE_0);
+
+ tmb.setTexture(0.0f, 1.0f);
+ tmb.addVertex(-1.0f, 1.0f, 1.0f);
+
+ tmb.setTexture(0.0f, 0.0f);
+ tmb.addVertex(-1.0f, -1.0f, 1.0f);
+
+ tmb.setTexture(1.0f, 0.0f);
+ tmb.addVertex(1.0f, -1.0f, 1.0f);
+
+ tmb.setTexture(1.0f, 1.0f);
+ tmb.addVertex(1.0f, 1.0f, 1.0f);
+
+ tmb.addTriangle(0, 1, 2);
+ tmb.addTriangle(2, 3, 0);
+
+ mQuad = tmb.create(true);
+ return mQuad;
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
+ mRS = rs;
+ mRes = res;
+ mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
+ mTransformScript.set_gTransformScript(mTransformScript);
+
+ mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
+
+ mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
+ mRenderLoop.set_gTransformScript(mTransformScript);
+ mRenderLoop.set_gCameraScript(mCameraScript);
+
+ Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ mRenderLoop.set_gTGrid(checker);
+ initPFS();
+ }
+
+ public ScriptC_render getRenderLoop() {
+ return mRenderLoop;
+ }
+}
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java
new file mode 100644
index 0000000..22cd1ce
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java
@@ -0,0 +1,47 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class ShaderParam extends SceneGraphBase {
+ String mParamName;
+
+ public ShaderParam(String name) {
+ mParamName = name;
+ }
+
+ public String getParamName() {
+ return mParamName;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
new file mode 100644
index 0000000..fdab999
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
@@ -0,0 +1,89 @@
+/*
+ * 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.scenegraph;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.lang.Math;
+import java.net.URL;
+import java.util.ArrayList;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Matrix4f;
+import android.renderscript.Type.Builder;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Texture2D extends SceneGraphBase {
+ private static String mSDCardPath = "sdcard/scenegraph/";
+ private final boolean mLoadFromSD = true;
+
+ String mFileName;
+ Allocation mRsTexture;
+
+ public Texture2D() {
+ }
+
+ public void setFileName(String file) {
+ mFileName = file;
+ }
+
+ public String getFileName() {
+ return mFileName;
+ }
+
+ Allocation getRsData(RenderScriptGL rs, Resources res) {
+ if (mRsTexture != null) {
+ return mRsTexture;
+ }
+
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ InputStream is = null;
+ try {
+ if (!mLoadFromSD) {
+ is = res.getAssets().open(shortName);
+ } else {
+ File f = new File(mSDCardPath + shortName);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e("Texture2D",
+ "Could not open image file " + shortName + " Message: " + e.getMessage());
+ return null;
+ }
+
+ Bitmap b = BitmapFactory.decodeStream(is);
+ mRsTexture = Allocation.createFromBitmap(rs, b,
+ Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ return mRsTexture;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java
new file mode 100644
index 0000000..0959d12
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java
@@ -0,0 +1,54 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.graphics.Camera;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TextureParam extends ShaderParam {
+
+ Texture2D mTexture;
+
+ public TextureParam(String name) {
+ super(name);
+ }
+
+ public void setTexture(Texture2D t) {
+ mTexture = t;
+ }
+
+ public Texture2D getTexture() {
+ return mTexture;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TouchHandler.java
new file mode 100644
index 0000000..eacc3d0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/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.scenegraph;
+
+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.SceneManager.SceneLoadedCallback;
+
+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/scenegraph/Transform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java
new file mode 100644
index 0000000..04793bc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java
@@ -0,0 +1,88 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.*;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class Transform extends SceneGraphBase {
+
+ RenderScriptGL mRS;
+ Transform mParent;
+ ArrayList<Transform> mChildren;
+
+ static final int RS_ID_NONE = 0;
+ static final int RS_ID_TRANSLATE = 1;
+ static final int RS_ID_ROTATE = 2;
+ static final int RS_ID_SCALE = 3;
+
+ ScriptField_SgTransform mField;
+ ScriptField_SgTransform.Item mTransformData;
+
+ public Transform() {
+ mChildren = new ArrayList<Transform>();
+ mParent = null;
+ }
+
+ public void appendChild(Transform t) {
+ mChildren.add(t);
+ t.mParent = this;
+ }
+
+ abstract void initLocalData();
+ public abstract void updateRSData();
+
+ public ScriptField_SgTransform getRSData(RenderScriptGL rs) {
+ if (mField != null) {
+ return mField;
+ }
+
+ mRS = rs;
+ initLocalData();
+
+ if (mChildren.size() != 0) {
+ Allocation childRSData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mChildren.size());
+ mTransformData.children = childRSData;
+
+ Allocation[] childrenAllocs = new Allocation[mChildren.size()];
+ for (int i = 0; i < mChildren.size(); i ++) {
+ Transform child = mChildren.get(i);
+ childrenAllocs[i] = child.getRSData(rs).getAllocation();
+ }
+ childRSData.copyFrom(childrenAllocs);
+ }
+
+ mField = new ScriptField_SgTransform(rs, 1);
+ mField.set(mTransformData, 0, true);
+
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java
new file mode 100644
index 0000000..fec7639
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java
@@ -0,0 +1,57 @@
+/*
+ * 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.graphics.Camera;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TransformParam extends ShaderParam {
+
+ public static final int TRANSFORM = 0;
+ public static final int TRANSFORM_VIEW = 1;
+ public static final int TRANSFORM_VIEW_PROJ = 2;
+ Transform mTransform;
+ Camera mCamera;
+
+ public TransformParam(String name) {
+ super(name);
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs
new file mode 100644
index 0000000..0b7b00c
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs
@@ -0,0 +1,44 @@
+// 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.scenegraph)
+
+//#define DEBUG_CAMERA
+#include "transform_def.rsh"
+
+void root(const rs_allocation *v_in, rs_allocation *v_out, const float *usrData) {
+
+ SgCamera *cam = (SgCamera *)rsGetElementAt(*v_in, 0);
+ float aspect = *usrData;
+ cam->aspect = aspect;
+ const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
+
+ rsMatrixLoadPerspective(&cam->proj, cam->horizontalFOV, cam->aspect, cam->near, cam->far);
+
+ rs_matrix4x4 camPosMatrix;
+ rsMatrixLoad(&camPosMatrix, &camTransform->globalMat);
+ float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
+ cam->position = rsMatrixMultiply(&camPosMatrix, zero);
+
+ rsMatrixInverse(&camPosMatrix);
+ rsMatrixLoad(&cam->view, &camPosMatrix);
+
+ rsMatrixLoad(&cam->viewProj, &cam->proj);
+ rsMatrixMultiply(&cam->viewProj, &cam->view);
+#ifdef DEBUG_CAMERA
+ printCameraInfo(cam);
+#endif //DEBUG_CAMERA
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
new file mode 100644
index 0000000..1dfe633
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
@@ -0,0 +1,28 @@
+// 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.scenegraph)
+
+// The sole purpose of this script is to have various structs exposed
+// so that java reflected classes are generated
+#include "transform_def.rsh"
+SgTransform *exportPtr;
+SgRenderState *sExport;
+SgDrawable *drExport;
+SgRenderPass *pExport;
+SgCamera *exportPtrCam;
+FBlurOffsets *blurExport;
+VertexShaderInputs *iExport; \ No newline at end of file
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
new file mode 100644
index 0000000..2891657
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -0,0 +1,296 @@
+// 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.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "transform_def.rsh"
+
+rs_script gTransformScript;
+rs_script gCameraScript;
+
+SgTransform *gRootNode;
+rs_allocation gCameras;
+rs_allocation gDrawableObjects;
+
+rs_allocation gRenderPasses;
+
+// Temporary shaders
+rs_allocation gTGrid;
+rs_program_store gPFSBackground;
+
+VShaderParams *vConst;
+FShaderParams *fConst;
+
+uint32_t *gFrontToBack;
+static uint32_t gFrontToBackCount = 0;
+uint32_t *gBackToFront;
+static uint32_t gBackToFrontCount = 0;
+
+static SgCamera *gActiveCamera = NULL;
+static float4 gFrustumPlanes[6];
+
+static rs_allocation nullAlloc;
+
+//#define DEBUG_RENDERABLES
+static void draw(SgDrawable *obj) {
+
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
+#ifdef DEBUG_RENDERABLES
+ rsDebug("**** Drawing object with transform", obj);
+ printName(objTransform->name);
+ rsDebug("Model matrix: ", &objTransform->globalMat);
+ printName(obj->name);
+#endif //DEBUG_RENDERABLES
+
+ SgCamera *cam = gActiveCamera;
+
+ rsMatrixLoad(&vConst->model, &objTransform->globalMat);
+ rsMatrixLoad(&vConst->viewProj, &cam->viewProj);
+ rsgAllocationSyncAll(rsGetAllocation(vConst));
+ fConst->cameraPos = cam->position;
+ rsgAllocationSyncAll(rsGetAllocation(fConst));
+
+ if (rsIsObject(renderState->ps)) {
+ rsgBindProgramStore(renderState->ps);
+ } else {
+ rsgBindProgramStore(gPFSBackground);
+ }
+
+ if (rsIsObject(renderState->pr)) {
+ rsgBindProgramRaster(renderState->pr);
+ } else {
+ rs_program_raster pr;
+ rsgBindProgramRaster(pr);
+ }
+
+ rsgBindProgramFragment(renderState->pf);
+ rsgBindProgramVertex(renderState->pv);
+
+ if (rsIsObject(obj->pf_textures[0])) {
+ rsgBindTexture(renderState->pf, 0, obj->pf_textures[0]);
+ } else {
+ rsgBindTexture(renderState->pf, 0, gTGrid);
+ }
+
+ rsgDrawMesh(obj->mesh, obj->meshIndex);
+}
+
+static void getTransformedSphere(SgDrawable *obj) {
+ obj->worldBoundingSphere = obj->boundingSphere;
+ obj->worldBoundingSphere.w = 1.0f;
+ const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
+ obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere);
+
+ const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f};
+ float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec);
+ scaledVec.w = 0.0f;
+ obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec);
+}
+
+static bool frustumCulled(SgDrawable *obj) {
+ if (!obj->bVolInitialized) {
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ rsgMeshComputeBoundingBox(obj->mesh,
+ &minX, &minY, &minZ,
+ &maxX, &maxY, &maxZ);
+ //rsDebug("min", minX, minY, minZ);
+ //rsDebug("max", maxX, maxY, maxZ);
+ float4 sphere;
+ sphere.x = (maxX + minX) * 0.5f;
+ sphere.y = (maxY + minY) * 0.5f;
+ sphere.z = (maxZ + minZ) * 0.5f;
+ float3 radius;
+ radius.x = (maxX - sphere.x);
+ radius.y = (maxY - sphere.y);
+ radius.z = (maxZ - sphere.z);
+
+ sphere.w = length(radius);
+ obj->boundingSphere = sphere;
+ obj->bVolInitialized = 1;
+ //rsDebug("Sphere", sphere);
+ }
+
+ getTransformedSphere(obj);
+
+ return !rsIsSphereInFrustum(&obj->worldBoundingSphere,
+ &gFrustumPlanes[0], &gFrustumPlanes[1],
+ &gFrustumPlanes[2], &gFrustumPlanes[3],
+ &gFrustumPlanes[3], &gFrustumPlanes[4]);
+}
+
+static void sortToBucket(SgDrawable *obj) {
+ // Not loaded yet
+ if (!rsIsObject(obj->mesh) || obj->cullType == 2) {
+ return;
+ }
+
+ // check to see if we are culling this object and if it's
+ // outside the frustum
+ if (obj->cullType == 0 && frustumCulled(obj)) {
+#ifdef DEBUG_RENDERABLES
+ rsDebug("Culled", obj);
+ printName(obj->name);
+#endif //DEBUG_RENDERABLES
+ return;
+ }
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ if (rsIsObject(renderState->ps)) {
+ gBackToFront[gBackToFrontCount++] = (uint32_t)obj;
+ } else {
+ gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
+ }
+}
+
+static void updateActiveCamera(rs_allocation cam) {
+ gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0);
+
+ rsExtractFrustumPlanes(&gActiveCamera->viewProj,
+ &gFrustumPlanes[0], &gFrustumPlanes[1],
+ &gFrustumPlanes[2], &gFrustumPlanes[3],
+ &gFrustumPlanes[3], &gFrustumPlanes[4]);
+}
+
+static void prepareCameras() {
+ // now compute all the camera matrices
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect));
+}
+
+static void drawSorted() {
+ for (int i = 0; i < gFrontToBackCount; i ++) {
+ SgDrawable *current = (SgDrawable*)gFrontToBack[i];
+ draw(current);
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgDrawable *current = (SgDrawable*)gBackToFront[i];
+ draw(current);
+ }
+}
+
+static void drawAllObjects(rs_allocation allObj) {
+ if (!rsIsObject(allObj)) {
+ return;
+ }
+ int numDrawables = rsAllocationGetDimX(allObj);
+ for (int i = 0; i < numDrawables; i ++) {
+ rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i);
+ SgDrawable *current = (SgDrawable*)rsGetElementAt(*drawAlloc, 0);
+ sortToBucket(current);
+ }
+ drawSorted();
+}
+
+void root(const void *v_in, void *v_out) {
+
+ //rsDebug("=============================================================================", 0);
+ // first step is to update the transform hierachy
+ rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0);
+
+ prepareCameras();
+
+ rsgClearDepth(1.0f);
+
+ int numDrawables = rsAllocationGetDimX(gDrawableObjects);
+ if (rsIsObject(gRenderPasses)) {
+ int numPasses = rsAllocationGetDimX(gRenderPasses);
+ for (uint i = 0; i < numPasses; i ++) {
+ gFrontToBackCount = 0;
+ gBackToFrontCount = 0;
+ SgRenderPass *pass = (SgRenderPass*)rsGetElementAt(gRenderPasses, i);
+ if (rsIsObject(pass->color_target)) {
+ rsgBindColorTarget(pass->color_target, 0);
+ }
+ if (rsIsObject(pass->depth_target)) {
+ rsgBindDepthTarget(pass->depth_target);
+ }
+ if (!rsIsObject(pass->color_target) &&
+ !rsIsObject(pass->depth_target)) {
+ rsgClearAllRenderTargets();
+ }
+ updateActiveCamera(pass->camera);
+ if (pass->should_clear_color) {
+ rsgClearColor(pass->clear_color.x, pass->clear_color.y,
+ pass->clear_color.z, pass->clear_color.w);
+ }
+ if (pass->should_clear_depth) {
+ rsgClearDepth(pass->clear_depth);
+ }
+ drawAllObjects(pass->objects);
+ }
+ } else {
+ gFrontToBackCount = 0;
+ gBackToFrontCount = 0;
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+ rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 1);
+ updateActiveCamera(*camAlloc);
+ drawAllObjects(gDrawableObjects);
+ }
+}
+
+static bool intersect(const SgDrawable *obj, float3 pnt, float3 vec) {
+ // Solving for t^2 + Bt + C = 0
+ float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz;
+ float B = dot(originMinusCenter, vec) * 2.0f;
+ float C = dot(originMinusCenter, originMinusCenter) -
+ obj->worldBoundingSphere.w * obj->worldBoundingSphere.w;
+
+ float discriminant = B * B - 4.0f * C;
+ if (discriminant < 0.0f) {
+ return false;
+ }
+ discriminant = sqrt(discriminant);
+
+ float t0 = (-B - discriminant) * 0.5f;
+ float t1 = (-B + discriminant) * 0.5f;
+
+ if (t0 > t1) {
+ float temp = t0;
+ t0 = t1;
+ t1 = temp;
+ }
+
+ // The sphere is behind us
+ if (t1 < 0.0f) {
+ return false;
+ }
+ return true;
+}
+
+// Search through sorted and culled objects
+void pick(int screenX, int screenY) {
+ float3 pnt, vec;
+ getCameraRay(gActiveCamera, screenX, screenY, &pnt, &vec);
+
+ for (int i = 0; i < gFrontToBackCount; i ++) {
+ SgDrawable *current = (SgDrawable*)gFrontToBack[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = 2;
+ }
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgDrawable *current = (SgDrawable*)gBackToFront[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = 2;
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph.rs
new file mode 100644
index 0000000..421105b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph.rs
@@ -0,0 +1,90 @@
+// 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.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "transform_def.rsh"
+
+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/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
new file mode 100644
index 0000000..6bc5317
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -0,0 +1,111 @@
+// 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.modelviewer)
+
+//#define DEBUG_TRANSFORMS
+
+#include "transform_def.rsh"
+
+rs_script gTransformScript;
+
+typedef struct {
+ int changed;
+ rs_matrix4x4 *mat;
+} ParentData;
+
+static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
+ rs_matrix4x4 temp;
+
+ switch (type) {
+ case TRANSFORM_TRANSLATE:
+ rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
+ break;
+ case TRANSFORM_ROTATE:
+ rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
+ break;
+ case TRANSFORM_SCALE:
+ rsMatrixLoadScale(&temp, data.x, data.y, data.z);
+ break;
+ }
+ rsMatrixMultiply(mat, &temp);
+}
+
+void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) {
+
+ SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0);
+ const ParentData *parent = (const ParentData *)usrData;
+
+#ifdef DEBUG_TRANSFORMS
+ rsDebug("**** Transform data", (int)data);
+ rsDebug("Transform is dirty", data->isDirty);
+ rsDebug("Transform parent", (int)parent);
+ rsDebug("Transform child ", (int)data->children.p);
+ printName(data->name);
+#endif //DEBUG_TRANSFORMS
+
+ rs_matrix4x4 *localMat = &data->localMat;
+ rs_matrix4x4 *globalMat = &data->globalMat;
+
+ ParentData toChild;
+ toChild.changed = 0;
+ toChild.mat = globalMat;
+
+ // Refresh matrices if dirty
+ if (data->isDirty) {
+ toChild.changed = 1;
+
+ bool resetLocal = false;
+ for (int i = 0; i < 16; i ++) {
+ if (data->transformTypes[i] == TRANSFORM_NONE) {
+ break;
+ }
+ if (!resetLocal) {
+ // Reset our local matrix only for component transforms
+ rsMatrixLoadIdentity(localMat);
+ resetLocal = true;
+ }
+#ifdef DEBUG_TRANSFORMS
+ if (rsIsObject(data->transformNames[i])) {
+ rsDebug((const char*)rsGetElementAt(data->transformNames[i], 0),
+ data->transforms[i]);
+ } else {
+ rsDebug("Transform adding transformation type", data->transformTypes[i]);
+ rsDebug("Transform adding transformation", data->transforms[i]);
+ }
+#endif //DEBUG_TRANSFORMS
+ appendTransformation(data->transformTypes[i], data->transforms[i], localMat);
+ }
+ }
+
+ if (parent) {
+ if (parent->changed || data->isDirty) {
+ toChild.changed = 1;
+
+ rsMatrixLoad(globalMat, parent->mat);
+ rsMatrixMultiply(globalMat, localMat);
+ }
+ } else if (data->isDirty) {
+ rsMatrixLoad(globalMat, localMat);
+ }
+
+ if (rsIsObject(data->children)) {
+ rs_allocation nullAlloc;
+ rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
+ }
+
+ data->isDirty = 0;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh
new file mode 100644
index 0000000..e093bf9
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh
@@ -0,0 +1,179 @@
+// Copyright (C) 2009 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.scenegraph)
+
+#include "rs_graphics.rsh"
+
+#define TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+static void printName(rs_allocation name) {
+ rsDebug("Object Name: ", 0);
+ if (!rsIsObject(name)) {
+ rsDebug("no name", 0);
+ return;
+ }
+
+ rsDebug((const char*)rsGetElementAt(name, 0), 0);
+}
+
+typedef struct __attribute__((packed, aligned(4))) SgTransform {
+ rs_matrix4x4 globalMat;
+ rs_matrix4x4 localMat;
+
+ float4 transforms[16];
+ int transformTypes[16];
+ rs_allocation transformNames[16];
+
+ int isDirty;
+
+ rs_allocation children;
+
+ rs_allocation name;
+} SgTransform;
+
+typedef struct RenderState_s {
+ rs_program_vertex pv;
+ rs_program_fragment pf;
+ rs_program_store ps;
+ rs_program_raster pr;
+} SgRenderState;
+
+typedef struct Drawable_s {
+ rs_allocation render_state;
+ rs_allocation pv_const;
+ rs_allocation pf_const;
+ rs_allocation pf_textures[8];
+ int pf_num_textures;
+ rs_mesh mesh;
+ int meshIndex;
+ rs_allocation transformMatrix;
+ rs_allocation name;
+ float4 boundingSphere;
+ float4 worldBoundingSphere;
+ int bVolInitialized;
+ int cullType; // specifies whether to frustum cull
+} SgDrawable;
+
+typedef struct RenderPass_s {
+ rs_allocation color_target;
+ rs_allocation depth_target;
+ rs_allocation camera;
+ rs_allocation objects;
+
+ float4 clear_color;
+ float clear_depth;
+ bool should_clear_color;
+ bool should_clear_depth;
+} SgRenderPass;
+
+typedef struct __attribute__((packed, aligned(4))) Camera_s {
+ rs_matrix4x4 proj;
+ rs_matrix4x4 view;
+ rs_matrix4x4 viewProj;
+ float4 position;
+ float near;
+ float far;
+ float horizontalFOV;
+ float aspect;
+ rs_allocation name;
+ rs_allocation transformMatrix;
+} SgCamera;
+
+typedef struct VShaderParams_s {
+ rs_matrix4x4 model;
+ rs_matrix4x4 viewProj;
+} VShaderParams;
+
+typedef struct FShaderParams_s {
+ float4 cameraPos;
+} FShaderParams;
+
+typedef struct FBlurOffsets_s {
+ float blurOffset0;
+ float blurOffset1;
+ float blurOffset2;
+ float blurOffset3;
+} FBlurOffsets;
+
+typedef struct VertexShaderInputs_s {
+ float4 position;
+ float3 normal;
+ float2 texture0;
+} VertexShaderInputs;
+
+static void printCameraInfo(SgCamera *cam) {
+ rsDebug("***** Camera information. ptr:", cam);
+ printName(cam->name);
+ const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
+ rsDebug("Transform name:", camTransform);
+ printName(camTransform->name);
+
+ rsDebug("Aspect: ", cam->aspect);
+ rsDebug("Near: ", cam->near);
+ rsDebug("Far: ", cam->far);
+ rsDebug("Fov: ", cam->horizontalFOV);
+ rsDebug("Position: ", cam->position);
+ rsDebug("Proj: ", &cam->proj);
+ rsDebug("View: ", &cam->view);
+}
+
+static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
+ rsDebug("=================================", screenX);
+ rsDebug("Point X", screenX);
+ rsDebug("Point Y", screenY);
+
+ rs_matrix4x4 mvpInv;
+ rsMatrixLoad(&mvpInv, &cam->viewProj);
+ rsMatrixInverse(&mvpInv);
+
+ float width = (float)rsgGetWidth();
+ float height = (float)rsgGetHeight();
+
+ float4 pos = {(float)screenX, height - (float)screenY, 0.0f, 1.0f};
+
+ pos.x /= width;
+ pos.y /= height;
+
+ rsDebug("Pre Norm X", pos.x);
+ rsDebug("Pre Norm Y", pos.y);
+
+ pos.xy = pos.xy * 2.0f - 1.0f;
+
+ rsDebug("Norm X", pos.x);
+ rsDebug("Norm Y", pos.y);
+
+ pos = rsMatrixMultiply(&mvpInv, pos);
+ float oneOverW = 1.0f / pos.w;
+ pos.xyz *= oneOverW;
+
+ rsDebug("World X", pos.x);
+ rsDebug("World Y", pos.y);
+ rsDebug("World Z", pos.z);
+
+ rsDebug("Cam X", cam->position.x);
+ rsDebug("Cam Y", cam->position.y);
+ rsDebug("Cam Z", cam->position.z);
+
+ *vec = normalize(pos.xyz - cam->position.xyz);
+ rsDebug("Vec X", vec->x);
+ rsDebug("Vec Y", vec->y);
+ rsDebug("Vec Z", vec->z);
+ *pnt = cam->position.xyz;
+}