summaryrefslogtreecommitdiffstats
path: root/tests/RenderScriptTests/SceneGraph/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/RenderScriptTests/SceneGraph/src')
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java118
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java563
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java139
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java208
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java153
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java145
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java111
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java60
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java43
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java120
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java111
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java220
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java39
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java47
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java336
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java61
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java296
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java76
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java151
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java78
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java38
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java84
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java63
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java98
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java81
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java108
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs66
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs86
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs56
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs29
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs33
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs36
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh157
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs237
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh317
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs127
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs29
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java110
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java187
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java115
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java113
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java267
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java152
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java94
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs98
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh52
46 files changed, 5908 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..b07cd08
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.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 com.android.scenegraph.SceneManager;
+
+import android.renderscript.*;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Camera extends SceneGraphBase {
+
+ Transform mTransform;
+
+ ScriptField_Camera_s.Item mData;
+ ScriptField_Camera_s mField;
+
+ public Camera() {
+ mData = new ScriptField_Camera_s.Item();
+ mData.near = 0.1f;
+ mData.far = 100.0f;
+ mData.horizontalFOV = 60.0f;
+ mData.aspect = 0;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ if (mField != null) {
+ mField.set_transformMatrix(0, mTransform.getRSData().getAllocation(), false);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+ public void setFOV(float fov) {
+ mData.horizontalFOV = fov;
+ if (mField != null) {
+ mField.set_horizontalFOV(0, fov, false);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setNear(float n) {
+ mData.near = n;
+ if (mField != null) {
+ mField.set_near(0, n, false);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setFar(float f) {
+ mData.far = f;
+ if (mField != null) {
+ mField.set_far(0, f, false);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setName(String n) {
+ super.setName(n);
+ if (mField != null) {
+ RenderScriptGL rs = SceneManager.getRS();
+ mData.name = getNameAlloc(rs);
+ mField.set_name(0, mData.name, false);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ ScriptField_Camera_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+
+ if (mTransform == null) {
+ throw new RuntimeException("Cameras without transforms are invalid");
+ }
+
+ mField = new ScriptField_Camera_s(rs, 1);
+
+ mData.transformMatrix = mTransform.getRSData().getAllocation();
+ mData.transformTimestamp = 1;
+ mData.timestamp = 1;
+ mData.isDirty = 1;
+ mData.name = getNameAlloc(rs);
+ mField.set(mData, 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..d954313
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
@@ -0,0 +1,563 @@
+/*
+ * 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;
+ HashMap<String, String> mMeshIdNameMap;
+ Scene mScene;
+
+ String mRootDir;
+
+ 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>();
+ mMeshIdNameMap = new HashMap<String, String>();
+ }
+
+ public void init(InputStream is, String rootDir) {
+ mLights.clear();
+ mCameras.clear();
+ mEffectsParams.clear();
+
+ mRootDir = rootDir;
+
+ 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);
+ }
+ }
+
+ // Look through the geometry list and build up a correlation between id's and names
+ nl = docEle.getElementsByTagName("geometry");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertGeometries(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 getRenderable(Element shape, Transform t) {
+ String geoURL = shape.getAttribute("url").substring(1);
+ String geoName = mMeshIdNameMap.get(geoURL);
+ if (geoName != null) {
+ geoURL = geoName;
+ }
+ //RenderableGroup group = new RenderableGroup();
+ //group.setName(geoURL.substring(1));
+ //mScene.appendRenderable(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");
+
+ Renderable d = new Renderable();
+ d.setMesh(geoURL, meshIndexName);
+ d.setMaterialName(materialName.substring(1));
+ d.setName(geoURL);
+
+ //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
+
+ 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.appendRenderable(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")) {
+ getRenderable(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();
+ }
+ }
+
+ // This will find the actual texture node, which is sometimes hidden behind a sampler
+ // and sometimes referenced directly
+ Texture2D getTexture(String samplerName) {
+ String texName = samplerName;
+
+ // Check to see if the image file is hidden by a sampler surface link combo
+ Element sampler = mDom.getElementById(samplerName);
+ if (sampler != 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);
+ texName = getString(ref);
+ }
+ }
+ }
+
+ //Log.v(TAG, "Extracted texture name " + texName);
+ return mImages.get(texName);
+ }
+
+ 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 convertGeometries(Element geo) {
+ String id = geo.getAttribute("id");
+ String name = geo.getAttribute("name");
+ if (!id.equals(name)) {
+ mMeshIdNameMap.put(id, name);
+ }
+ }
+
+ 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.x, color.y, color.z);
+ 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 = 30.0f;
+ if (getString(camera, "yfov") != null) {
+ fov = getFloat(camera, "yfov");
+ } else if(getString(camera, "xfov") != null) {
+ float aspect = getFloat(camera, "aspect_ratio");
+ fov = getFloat(camera, "xfov") / aspect;
+ }
+
+ 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);
+ tex.setFileDir(mRootDir);
+ 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 && nl.getLength() != 0) {
+ 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..301075e
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java
@@ -0,0 +1,139 @@
+/*
+ * 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;
+ boolean mLoadFromSD = false;
+
+ SceneLoadedCallback mCallback;
+
+ public ColladaScene(String name, SceneLoadedCallback cb) {
+ modelName = name;
+ mCallback = cb;
+ }
+
+ public void init(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+
+ mLoadFromSD = SceneManager.isSDCardPath(modelName);
+
+ new ColladaLoaderTask().execute(modelName);
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ Scene mActiveScene;
+
+ private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> {
+ ColladaParser sceneSource;
+ protected Boolean doInBackground(String... names) {
+ String rootDir = names[0].substring(0, names[0].lastIndexOf('/') + 1);
+ long start = System.currentTimeMillis();
+ sceneSource = new ColladaParser();
+ InputStream is = null;
+ try {
+ if (!mLoadFromSD) {
+ is = mRes.getAssets().open(names[0]);
+ } else {
+ File f = new File(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, rootDir);
+ end = System.currentTimeMillis();
+ Log.v("TIMER", "Collada parse time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mActiveScene = sceneSource.getScene();
+ if (mCallback != null) {
+ mCallback.mLoadedScene = mActiveScene;
+ mCallback.run();
+ }
+
+ String shortName = modelName.substring(0, modelName.lastIndexOf('.'));
+ new A3DLoaderTask().execute(shortName + ".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, 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..99dc41c
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java
@@ -0,0 +1,208 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+
+import android.renderscript.*;
+import android.renderscript.Float3;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class CompoundTransform extends Transform {
+
+ public static abstract class Component {
+ String mName;
+ CompoundTransform mParent;
+ int mParentIndex;
+ protected ScriptField_TransformComponent_s.Item mData;
+
+ Component(String name) {
+ mData = new ScriptField_TransformComponent_s.Item();
+ mName = name;
+ }
+
+ void setNameAlloc() {
+ RenderScriptGL rs = SceneManager.getRS();
+ if (mData.name != null) {
+ return;
+ }
+ mData.name = SceneManager.getCachedAlloc(getName());
+ if (mData.name == null) {
+ mData.name = SceneManager.getStringAsAllocation(rs, getName());
+ SceneManager.cacheAlloc(getName(), mData.name);
+ }
+ }
+
+ abstract ScriptField_TransformComponent_s.Item getRSData();
+
+ protected void update() {
+ if (mParent != null) {
+ mParent.updateRSComponent(this);
+ }
+ }
+
+ public String getName() {
+ return mName;
+ }
+ }
+
+ public static class TranslateComponent extends Component {
+ public TranslateComponent(String name, Float3 translate) {
+ super(name);
+ setValue(translate);
+ }
+ public Float3 getValue() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public void setValue(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ ScriptField_TransformComponent_s.Item getRSData() {
+ setNameAlloc();
+ mData.type = SceneManager.getConst().get_transform_TRANSLATE();
+ return mData;
+ }
+ }
+
+ public static class RotateComponent extends Component {
+ public RotateComponent(String name, Float3 axis, float angle) {
+ super(name);
+ setAxis(axis);
+ setAngle(angle);
+ }
+ public Float3 getAxis() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public float getAngle() {
+ return mData.value.w;
+ }
+ public void setAxis(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ public void setAngle(float val) {
+ mData.value.w = val;
+ update();
+ }
+ ScriptField_TransformComponent_s.Item getRSData() {
+ setNameAlloc();
+ mData.type = SceneManager.getConst().get_transform_ROTATE();
+ return mData;
+ }
+ }
+
+ public static class ScaleComponent extends Component {
+ public ScaleComponent(String name, Float3 scale) {
+ super(name);
+ setValue(scale);
+ }
+ public Float3 getValue() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public void setValue(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ ScriptField_TransformComponent_s.Item getRSData() {
+ setNameAlloc();
+ mData.type = SceneManager.getConst().get_transform_SCALE();
+ return mData;
+ }
+ }
+
+ ScriptField_TransformComponent_s mComponentField;
+ public ArrayList<Component> mTransformComponents;
+
+ public CompoundTransform() {
+ mTransformComponents = new ArrayList<Component>();
+ }
+
+ public void addComponent(Component c) {
+ if (c.mParent != null) {
+ throw new IllegalArgumentException("Transform components may not be shared");
+ }
+ c.mParent = this;
+ c.mParentIndex = mTransformComponents.size();
+ mTransformComponents.add(c);
+ updateRSComponentAllocation();
+ }
+
+ public void setComponent(int index, Component c) {
+ if (c.mParent != null) {
+ throw new IllegalArgumentException("Transform components may not be shared");
+ }
+ if (index >= mTransformComponents.size()) {
+ throw new IllegalArgumentException("Invalid component index");
+ }
+ c.mParent = this;
+ c.mParentIndex = index;
+ mTransformComponents.set(index, c);
+ updateRSComponent(c);
+ }
+
+ void updateRSComponent(Component c) {
+ if (mField == null || mComponentField == null) {
+ return;
+ }
+ mComponentField.set(c.getRSData(), c.mParentIndex, true);
+ mField.set_isDirty(0, 1, true);
+ }
+
+ void updateRSComponentAllocation() {
+ if (mField == null) {
+ return;
+ }
+ initLocalData();
+
+ mField.set_components(0, mTransformData.components, false);
+ mField.set_isDirty(0, 1, true);
+ }
+
+ void initLocalData() {
+ RenderScriptGL rs = SceneManager.getRS();
+ int numComponenets = mTransformComponents.size();
+ if (numComponenets > 0) {
+ mComponentField = new ScriptField_TransformComponent_s(rs, numComponenets);
+ for (int i = 0; i < numComponenets; i ++) {
+ Component ith = mTransformComponents.get(i);
+ mComponentField.set(ith.getRSData(), i, false);
+ }
+ mComponentField.copyAll();
+
+ mTransformData.components = mComponentField.getAllocation();
+ }
+ }
+}
+
+
+
+
+
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..4098129
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java
@@ -0,0 +1,153 @@
+/*
+ * 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 com.android.scenegraph.Scene;
+import com.android.scenegraph.SceneManager;
+
+import android.renderscript.Element;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Float4Param extends ShaderParam {
+ private static String TAG = "Float4Param";
+
+ LightBase mLight;
+
+ public Float4Param(String name) {
+ super(name);
+ }
+
+ public Float4Param(String name, float x) {
+ super(name);
+ set(x, 0, 0, 0, 1);
+ }
+
+ public Float4Param(String name, float x, float y) {
+ super(name);
+ set(x, y, 0, 0, 2);
+ }
+
+ public Float4Param(String name, float x, float y, float z) {
+ super(name);
+ set(x, y, z, 0, 3);
+ }
+
+ public Float4Param(String name, float x, float y, float z, float w) {
+ super(name);
+ set(x, y, z, w, 4);
+ }
+
+ void set(float x, float y, float z, float w, int vecSize) {
+ mData.float_value.x = x;
+ mData.float_value.y = y;
+ mData.float_value.z = z;
+ mData.float_value.w = w;
+ mData.float_vecSize = vecSize;
+ if (mField != null) {
+ mField.set_float_value(0, mData.float_value, false);
+ mField.set_float_vecSize(0, mData.float_vecSize, true);
+ }
+ }
+
+ public void setValue(Float4 v) {
+ set(v.x, v.y, v.z, v.w, mData.float_vecSize);
+ }
+
+ public Float4 getValue() {
+ return mData.float_value;
+ }
+
+ public void setVecSize(int vecSize) {
+ mData.float_vecSize = vecSize;
+ if (mField != null) {
+ mField.set_float_vecSize(0, mData.float_vecSize, true);
+ }
+ }
+
+ public void setLight(LightBase l) {
+ mLight = l;
+ if (mField != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ mField.set_light(0, mData.light, true);
+ }
+ }
+
+ boolean findLight(String property) {
+ String indexStr = mParamName.substring(property.length() + 1);
+ if (indexStr == null) {
+ Log.e(TAG, "Invalid light index.");
+ return false;
+ }
+ int index = Integer.parseInt(indexStr);
+ if (index == -1) {
+ return false;
+ }
+ Scene parentScene = SceneManager.getInstance().getActiveScene();
+ ArrayList<LightBase> allLights = parentScene.getLights();
+ if (index >= allLights.size()) {
+ return false;
+ }
+ mLight = allLights.get(index);
+ if (mLight == null) {
+ return false;
+ }
+ return true;
+ }
+
+ int getTypeFromName() {
+ int paramType = SceneManager.getConst().get_shaderParam_FLOAT4_DATA();
+ if (mParamName.equalsIgnoreCase(cameraPos)) {
+ paramType = SceneManager.getConst().get_shaderParam_FLOAT4_CAMERA_POS();
+ } else if(mParamName.equalsIgnoreCase(cameraDir)) {
+ paramType = SceneManager.getConst().get_shaderParam_FLOAT4_CAMERA_DIR();
+ } else if(mParamName.startsWith(lightColor) && findLight(lightColor)) {
+ paramType = SceneManager.getConst().get_shaderParam_FLOAT4_LIGHT_COLOR();
+ } else if(mParamName.startsWith(lightPos) && findLight(lightPos)) {
+ paramType = SceneManager.getConst().get_shaderParam_FLOAT4_LIGHT_POS();
+ } else if(mParamName.startsWith(lightDir) && findLight(lightDir)) {
+ paramType = SceneManager.getConst().get_shaderParam_FLOAT4_LIGHT_DIR();
+ }
+ return paramType;
+ }
+
+ void initLocalData() {
+ mData.type = getTypeFromName();
+ if (mCamera != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ }
+ if (mLight != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
new file mode 100644
index 0000000..ff6bbba
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.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.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.TextureBase;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramFragment.Builder;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class FragmentShader extends Shader {
+ ProgramFragment mProgram;
+ ScriptField_FragmentShader_s mField;
+
+ public static class Builder {
+
+ FragmentShader mShader;
+ ProgramFragment.Builder mBuilder;
+
+ public Builder(RenderScriptGL rs) {
+ mShader = new FragmentShader();
+ mBuilder = new ProgramFragment.Builder(rs);
+ }
+
+ public Builder setShader(Resources resources, int resourceID) {
+ mBuilder.setShader(resources, resourceID);
+ return this;
+ }
+
+ public Builder setObjectConst(Type type) {
+ mShader.mPerObjConstants = type;
+ return this;
+ }
+
+ public Builder setShaderConst(Type type) {
+ mShader.mPerShaderConstants = type;
+ return this;
+ }
+
+ public Builder addShaderTexture(Program.TextureType texType, String name) {
+ mShader.mShaderTextureNames.add(name);
+ mShader.mShaderTextureTypes.add(texType);
+ return this;
+ }
+
+ public Builder addTexture(Program.TextureType texType, String name) {
+ mShader.mTextureNames.add(name);
+ mShader.mTextureTypes.add(texType);
+ return this;
+ }
+
+ public FragmentShader create() {
+ if (mShader.mPerShaderConstants != null) {
+ mBuilder.addConstant(mShader.mPerShaderConstants);
+ }
+ if (mShader.mPerObjConstants != null) {
+ mBuilder.addConstant(mShader.mPerObjConstants);
+ }
+ for (int i = 0; i < mShader.mTextureTypes.size(); i ++) {
+ mBuilder.addTexture(mShader.mTextureTypes.get(i));
+ }
+ for (int i = 0; i < mShader.mShaderTextureTypes.size(); i ++) {
+ mBuilder.addTexture(mShader.mShaderTextureTypes.get(i));
+ }
+
+ mShader.mProgram = mBuilder.create();
+ return mShader;
+ }
+ }
+
+ public ProgramFragment getProgram() {
+ return mProgram;
+ }
+
+ public void updateTextures() {
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return;
+ }
+ int shaderTextureStart = mTextureTypes.size();
+ for (int i = 0; i < mShaderTextureNames.size(); i ++) {
+ ShaderParam sp = mSourceParams.get(mShaderTextureNames.get(i));
+ if (sp != null && sp instanceof TextureParam) {
+ TextureParam p = (TextureParam)sp;
+ TextureBase tex = p.getTexture();
+ if (tex != null) {
+ mProgram.bindTexture(tex.getRsData(), shaderTextureStart + i);
+ }
+ }
+ }
+ }
+
+ ScriptField_FragmentShader_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ ScriptField_FragmentShader_s.Item item = new ScriptField_FragmentShader_s.Item();
+ item.program = mProgram;
+
+ linkConstants(rs);
+ if (mPerShaderConstants != null) {
+ item.shaderConst = mConstantBuffer;
+ item.shaderConstParams = mConstantBufferParams.getAllocation();
+ mProgram.bindConstants(item.shaderConst, 0);
+ }
+
+ item.objectConstIndex = -1;
+ if (mPerObjConstants != null) {
+ item.objectConstIndex = mPerShaderConstants != null ? 1 : 0;
+ }
+
+ mField = new ScriptField_FragmentShader_s(rs, 1);
+ mField.set(item, 0, true);
+ return mField;
+ }
+}
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..8f5e2e7
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
@@ -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.
+ */
+
+package com.android.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class LightBase extends SceneGraphBase {
+ static final int RS_LIGHT_POINT = 0;
+ static final int RS_LIGHT_DIRECTIONAL = 1;
+
+ ScriptField_Light_s mField;
+ ScriptField_Light_s.Item mFieldData;
+ Transform mTransform;
+ Float4 mColor;
+ float mIntensity;
+ public LightBase() {
+ mColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
+ mIntensity = 1.0f;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ updateRSData();
+ }
+
+ public void setColor(float r, float g, float b) {
+ mColor.x = r;
+ mColor.y = g;
+ mColor.z = b;
+ updateRSData();
+ }
+
+ public void setColor(Float3 c) {
+ setColor(c.x, c.y, c.z);
+ }
+
+ public void setIntensity(float i) {
+ mIntensity = i;
+ updateRSData();
+ }
+
+ public void setName(String n) {
+ super.setName(n);
+ updateRSData();
+ }
+
+ protected void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ RenderScriptGL rs = SceneManager.getRS();
+ mFieldData.transformMatrix = mTransform.getRSData().getAllocation();
+ mFieldData.name = getNameAlloc(rs);
+ mFieldData.color = mColor;
+ mFieldData.intensity = mIntensity;
+
+ initLocalData();
+
+ mField.set(mFieldData, 0, true);
+ }
+
+ abstract void initLocalData();
+
+ ScriptField_Light_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+ if (mField == null) {
+ mField = new ScriptField_Light_s(rs, 1);
+ mFieldData = new ScriptField_Light_s.Item();
+ }
+
+ updateRSData();
+
+ return mField;
+ }
+}
+
+
+
+
+
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..6d70bc9
--- /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;
+ updateRSData();
+ }
+
+ public Matrix4f getMatrix() {
+ return new Matrix4f(mLocalMatrix.getArray());
+ }
+
+ void initLocalData() {
+ mTransformData.localMat = mLocalMatrix;
+ }
+
+ void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ mField.set_localMat(0, mLocalMatrix, false);
+ mField.set_isDirty(0, 1, 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..574bafc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
@@ -0,0 +1,43 @@
+/*
+ * 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() {
+ }
+
+ void initLocalData() {
+ mFieldData.type = RS_LIGHT_POINT;
+ }
+}
+
+
+
+
+
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..3cd70f5
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java
@@ -0,0 +1,120 @@
+/*
+ * 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<RenderableBase> mObjectsToDraw;
+
+ Camera mCamera;
+
+ ScriptField_RenderPass_s.Item mRsField;
+
+ public RenderPass() {
+ mObjectsToDraw = new ArrayList<RenderableBase>();
+ mClearColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
+ mShouldClearColor = true;
+ mClearDepth = 1.0f;
+ mShouldClearDepth = true;
+ }
+
+ public void appendRenderable(Renderable 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;
+ }
+
+ public ArrayList<RenderableBase> getRenderables() {
+ return mObjectsToDraw;
+ }
+
+ 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().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 ++) {
+ Renderable dI = (Renderable)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..c08a722
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java
@@ -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.
+ */
+
+package com.android.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import android.content.res.Resources;
+
+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 {
+ VertexShader mVertex;
+ FragmentShader mFragment;
+ ProgramStore mStore;
+ ProgramRaster mRaster;
+
+ ScriptField_RenderState_s mField;
+
+ public RenderState(VertexShader pv,
+ FragmentShader 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(VertexShader pv) {
+ mVertex = pv;
+ updateRSData();
+ }
+
+ public void setProgramFragment(FragmentShader pf) {
+ mFragment = pf;
+ updateRSData();
+ }
+
+ public void setProgramStore(ProgramStore ps) {
+ mStore = ps;
+ updateRSData();
+ }
+
+ public void setProgramRaster(ProgramRaster pr) {
+ mRaster = pr;
+ updateRSData();
+ }
+
+ void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ ScriptField_RenderState_s.Item item = new ScriptField_RenderState_s.Item();
+ item.pv = mVertex.getRSData().getAllocation();
+ item.pf = mFragment.getRSData().getAllocation();
+ item.ps = mStore;
+ item.pr = mRaster;
+
+ mField.set(item, 0, true);
+ }
+
+ public ScriptField_RenderState_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+
+ mField = new ScriptField_RenderState_s(rs, 1);
+ updateRSData();
+
+ return mField;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
new file mode 100644
index 0000000..2b6c1b9
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
@@ -0,0 +1,220 @@
+/*
+ * 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.Iterator;
+
+import com.android.scenegraph.Float4Param;
+import com.android.scenegraph.ShaderParam;
+import com.android.scenegraph.TransformParam;
+
+import android.content.res.Resources;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Element.DataType;
+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;
+
+/**
+ * @hide
+ */
+public class Renderable extends RenderableBase {
+ Allocation mVertexConstants;
+ Allocation mVertexParams;
+ Allocation mFragmentConstants;
+ Allocation mFragmentParams;
+ ArrayList<Allocation> mFragmentTextures;
+
+ HashMap<String, 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_Renderable_s mRsField;
+ ScriptField_Renderable_s.Item mRsFieldItem;
+
+ public Renderable() {
+ mSourceParams = new HashMap<String, 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.put(p.getParamName(), 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) {
+ Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator();
+ int paramIndex = 0;
+ while (allParamsIter.hasNext()) {
+ ShaderParam sp = allParamsIter.next();
+ if (sp instanceof TextureParam) {
+ TextureParam p = (TextureParam)sp;
+ TextureBase tex = p.getTexture();
+ if (tex != null) {
+ mRsFieldItem.pf_textures[paramIndex++] = tex.getRsData();
+ }
+ }
+ }
+ ProgramFragment pf = mRenderState.mFragment.mProgram;
+ mRsFieldItem.pf_num_textures = pf != null ? Math.min(pf.getTextureCount(), paramIndex) : 0;
+ mRsField.set(mRsFieldItem, 0, true);
+ }
+
+ void updateTextures(RenderScriptGL rs, Allocation a, int slot) {
+ getRsFieldItem(rs, null);
+ mRsFieldItem.pf_textures[slot] = a;
+ }
+
+ public void setVisible(RenderScriptGL rs, boolean vis) {
+ getRsField(rs, null);
+ mRsFieldItem.cullType = vis ? 0 : 2;
+ mRsField.set(mRsFieldItem, 0, true);
+ }
+
+ ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) {
+ if (mRsField != null) {
+ return mRsField;
+ }
+ getRsFieldItem(rs, res);
+
+ mRsField = new ScriptField_Renderable_s(rs, 1);
+ mRsField.set(mRsFieldItem, 0, true);
+
+ return mRsField;
+ }
+
+ void getRsFieldItem(RenderScriptGL rs, Resources res) {
+ if (mRsFieldItem != null) {
+ return;
+ }
+
+ VertexShader pv = mRenderState.mVertex;
+ if (pv != null && pv.getObjectConstants() != null) {
+ mVertexConstants = Allocation.createTyped(rs, pv.getObjectConstants());
+ }
+ FragmentShader pf = mRenderState.mFragment;
+ if (pf != null && pf.getObjectConstants() != null) {
+ mFragmentConstants = Allocation.createTyped(rs, pf.getObjectConstants());
+ }
+
+ // Very important step that links available inputs and the constants vertex and
+ // fragment shader request
+ ScriptField_ShaderParam_s pvParams = null;
+ // Assign all the vertex params
+ if (mVertexConstants != null) {
+ Element vertexConst = mVertexConstants.getType().getElement();
+ pvParams = ShaderParam.fillInParams(vertexConst, mSourceParams, mTransform);
+ }
+
+ ScriptField_ShaderParam_s pfParams = null;
+ // Assign all the fragment params
+ if (mFragmentConstants != null) {
+ Element fragmentConst = mFragmentConstants.getType().getElement();
+ pfParams = ShaderParam.fillInParams(fragmentConst, mSourceParams, mTransform);
+ }
+
+ mRsFieldItem = new ScriptField_Renderable_s.Item();
+ mRsFieldItem.mesh = mMesh;
+ mRsFieldItem.meshIndex = mMeshIndex;
+ mRsFieldItem.pv_const = mVertexConstants;
+ mRsFieldItem.pv_constParams = pvParams != null ? pvParams.getAllocation() : null;
+ mRsFieldItem.pf_const = mFragmentConstants;
+ mRsFieldItem.pf_constParams = pfParams != null ? pfParams.getAllocation() : null;
+ if (mTransform != null) {
+ mRsFieldItem.transformMatrix = mTransform.getRSData().getAllocation();
+ }
+ mRsFieldItem.name = SceneManager.getStringAsAllocation(rs, getName());
+ mRsFieldItem.render_state = mRenderState.getRSData().getAllocation();
+ mRsFieldItem.bVolInitialized = 0;
+ mRsFieldItem.cullType = mCullType;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java
new file mode 100644
index 0000000..74535dd
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.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 RenderableBase extends SceneGraphBase {
+ public RenderableBase() {
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java
new file mode 100644
index 0000000..590bbab
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.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 RenderableGroup extends RenderableBase {
+
+ ArrayList<RenderableBase> mChildren;
+
+ public RenderableGroup() {
+ mChildren = new ArrayList<RenderableBase>();
+ }
+
+ public void appendChildren(RenderableBase d) {
+ mChildren.add(d);
+ }
+}
+
+
+
+
+
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..e325204
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
@@ -0,0 +1,336 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Mesh;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Scene extends SceneGraphBase {
+ private static String TIMER_TAG = "TIMER";
+
+ private class ImageLoaderTask extends AsyncTask<ArrayList<RenderableBase>, Void, Boolean> {
+ protected Boolean doInBackground(ArrayList<RenderableBase>... objects) {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < objects[0].size(); i ++) {
+ Renderable dI = (Renderable)objects[0].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) {
+ }
+ }
+
+ private class ShaderImageLoader extends AsyncTask<ArrayList<FragmentShader>, Void, Boolean> {
+ protected Boolean doInBackground(ArrayList<FragmentShader>... objects) {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < objects[0].size(); i ++) {
+ FragmentShader sI = objects[0].get(i);
+ sI.updateTextures();
+ }
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Shader 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<FragmentShader> mFragmentShaders;
+ ArrayList<VertexShader> mVertexShaders;
+ ArrayList<RenderableBase> mRenderables;
+ HashMap<String, RenderableBase> mRenderableMap;
+ ArrayList<Texture2D> mTextures;
+
+ HashMap<String, ArrayList<Renderable> > mRenderableMeshMap;
+
+ // 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>();
+ mFragmentShaders = new ArrayList<FragmentShader>();
+ mVertexShaders = new ArrayList<VertexShader>();
+ mRenderables = new ArrayList<RenderableBase>();
+ mRenderableMap = new HashMap<String, RenderableBase>();
+ mRenderableMeshMap = new HashMap<String, ArrayList<Renderable> >();
+ 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 void appendShader(FragmentShader f) {
+ mFragmentShaders.add(f);
+ }
+
+ public void appendShader(VertexShader v) {
+ mVertexShaders.add(v);
+ }
+
+ public ArrayList<Camera> getCameras() {
+ return mCameras;
+ }
+
+ public ArrayList<LightBase> getLights() {
+ return mLights;
+ }
+
+ public void appendRenderable(RenderableBase d) {
+ mRenderables.add(d);
+ mRenderableMap.put(d.getName(), d);
+ }
+
+ public ArrayList<RenderableBase> getRenderables() {
+ return mRenderables;
+ }
+
+ public RenderableBase getRenderableByName(String name) {
+ return mRenderableMap.get(name);
+ }
+
+ public void appendTextures(Texture2D tex) {
+ mTextures.add(tex);
+ }
+
+ public void assignRenderStateToMaterial(RenderState renderState, String regex) {
+ Pattern pattern = Pattern.compile(regex);
+ int numRenderables = mRenderables.size();
+ for (int i = 0; i < numRenderables; i ++) {
+ Renderable shape = (Renderable)mRenderables.get(i);
+ Matcher m = pattern.matcher(shape.mMaterialName);
+ if (m.find()) {
+ shape.setRenderState(renderState);
+ }
+ }
+ }
+
+ public void assignRenderState(RenderState renderState) {
+ int numRenderables = mRenderables.size();
+ for (int i = 0; i < numRenderables; i ++) {
+ Renderable shape = (Renderable)mRenderables.get(i);
+ shape.setRenderState(renderState);
+ }
+ }
+
+ public void meshLoaded(Mesh m) {
+ ArrayList<Renderable> entries = mRenderableMeshMap.get(m.getName());
+ int numEntries = entries.size();
+ for (int i = 0; i < numEntries; i++) {
+ Renderable d = entries.get(i);
+ d.resolveMeshData(m);
+ //mRenderablesField.set(d.getRsField(mRS, mRes), d.sceneIndex, true);
+ }
+ }
+
+ void addToMeshMap(Renderable d) {
+ ArrayList<Renderable> entries = mRenderableMeshMap.get(d.mMeshName);
+ if (entries == null) {
+ entries = new ArrayList<Renderable>();
+ mRenderableMeshMap.put(d.mMeshName, entries);
+ }
+ entries.add(d);
+ }
+
+ public void destroyRS() {
+ SceneManager sceneManager = SceneManager.getInstance();
+ mTransformRSData = null;
+ sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
+ sceneManager.mRenderLoop.set_gRenderableObjects(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;
+ mRenderables = null;
+ mRenderableMap = null;
+ mTextures = null;
+ mRenderableMeshMap = null;
+ mRootTransforms = null;
+ }
+
+ public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) {
+ new ShaderImageLoader().execute(mFragmentShaders);
+ 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);
+ new ImageLoaderTask().execute(mRenderPasses.get(i).getRenderables());
+ }
+ mRenderPassAlloc.copyAll();
+ sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation());
+ } else {
+ new ImageLoaderTask().execute(mRenderables);
+ }
+ }
+
+ private void addDrawables(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ Allocation drawableData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mRenderables.size());
+ Allocation[] drawableAllocs = new Allocation[mRenderables.size()];
+ for (int i = 0; i < mRenderables.size(); i ++) {
+ Renderable dI = (Renderable)mRenderables.get(i);
+ dI.sceneIndex = i;
+ addToMeshMap(dI);
+ drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
+ }
+ drawableData.copyFrom(drawableAllocs);
+ sceneManager.mRenderLoop.set_gRenderableObjects(drawableData);
+
+ initRenderPassRS(rs, sceneManager);
+ }
+
+ private void addShaders(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ Allocation shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs),
+ mVertexShaders.size());
+ Allocation[] shaderAllocs = new Allocation[mVertexShaders.size()];
+ for (int i = 0; i < mVertexShaders.size(); i ++) {
+ VertexShader sI = mVertexShaders.get(i);
+ shaderAllocs[i] = sI.getRSData().getAllocation();
+ }
+ shaderData.copyFrom(shaderAllocs);
+ sceneManager.mRenderLoop.set_gVertexShaders(shaderData);
+
+ shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs), mFragmentShaders.size());
+ shaderAllocs = new Allocation[mFragmentShaders.size()];
+ for (int i = 0; i < mFragmentShaders.size(); i ++) {
+ FragmentShader sI = mFragmentShaders.get(i);
+ shaderAllocs[i] = sI.getRSData().getAllocation();
+ }
+ shaderData.copyFrom(shaderAllocs);
+ sceneManager.mRenderLoop.set_gFragmentShaders(shaderData);
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ mRS = rs;
+ mRes = res;
+ long start = System.currentTimeMillis();
+ mTransformRSData = mRootTransforms.getRSData();
+ 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();
+ addDrawables(rs, res, sceneManager);
+ end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Renderable init time: " + (end - start));
+
+ addShaders(rs, res, sceneManager);
+
+ Allocation opaqueBuffer = Allocation.createSized(rs, Element.U32(rs), mRenderables.size());
+ Allocation transparentBuffer = Allocation.createSized(rs,
+ Element.U32(rs), mRenderables.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().getAllocation();
+ }
+ cameraData.copyFrom(cameraAllocs);
+ sceneManager.mRenderLoop.set_gCameras(cameraData);
+
+ if (mLights.size() != 0) {
+ Allocation lightData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mCameras.size());
+ Allocation[] lightAllocs = new Allocation[mLights.size()];
+ for (int i = 0; i < mLights.size(); i ++) {
+ lightAllocs[i] = mLights.get(i).getRSData().getAllocation();
+ }
+ lightData.copyFrom(lightAllocs);
+ sceneManager.mRenderLoop.set_gLights(lightData);
+ }
+ }
+}
+
+
+
+
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..412ffbf
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+
+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.RSRuntimeException;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class SceneGraphBase {
+ String mName;
+ Allocation mNameAlloc;
+ public void setName(String n) {
+ mName = n;
+ mNameAlloc = null;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ Allocation getNameAlloc(RenderScriptGL rs) {
+ if (mNameAlloc == null) {
+ mNameAlloc = SceneManager.getStringAsAllocation(rs, getName());
+ }
+ return mNameAlloc;
+ }
+}
+
+
+
+
+
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..930b569
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
@@ -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.
+ */
+
+package com.android.scenegraph;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.android.scenegraph.Scene;
+
+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.Mesh;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.android.testapp.R;
+
+/**
+ * @hide
+ */
+public class SceneManager extends SceneGraphBase {
+
+ HashMap<String, Allocation> mAllocationMap;
+
+ ScriptC_render mRenderLoop;
+ ScriptC mCameraScript;
+ ScriptC mLightScript;
+ ScriptC mObjectParamsScript;
+ ScriptC mFragmentParamsScript;
+ ScriptC mVertexParamsScript;
+ ScriptC mCullScript;
+ ScriptC_transform mTransformScript;
+ ScriptC_export mExportScript;
+
+ RenderScriptGL mRS;
+ Resources mRes;
+ Mesh mQuad;
+ int mWidth;
+ int mHeight;
+
+ Scene mActiveScene;
+ private static SceneManager sSceneManager;
+
+ public static boolean isSDCardPath(String path) {
+ int sdCardIndex = path.indexOf("sdcard/");
+ // We are looking for /sdcard/ or sdcard/
+ if (sdCardIndex == 0 || sdCardIndex == 1) {
+ return true;
+ }
+ sdCardIndex = path.indexOf("mnt/sdcard/");
+ if (sdCardIndex == 0 || sdCardIndex == 1) {
+ return true;
+ }
+ return false;
+ }
+
+ static Bitmap loadBitmap(String name, Resources res) {
+ InputStream is = null;
+ boolean loadFromSD = isSDCardPath(name);
+ try {
+ if (!loadFromSD) {
+ is = res.getAssets().open(name);
+ } else {
+ File f = new File(name);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e("ImageLoaderTask", " Message: " + e.getMessage());
+ return null;
+ }
+
+ Bitmap b = BitmapFactory.decodeStream(is);
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log.e("ImageLoaderTask", " Message: " + e.getMessage());
+ }
+ return b;
+ }
+
+ public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
+ Bitmap b = loadBitmap(name, res);
+ return Allocation.createCubemapFromBitmap(rs, b,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ }
+
+ public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) {
+ Bitmap b = loadBitmap(name, res);
+ return Allocation.createFromBitmap(rs, b,
+ Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ }
+
+ public static 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();
+ }
+
+ static 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.");
+ }
+ }
+
+ static Allocation getCachedAlloc(String str) {
+ if (sSceneManager == null) {
+ throw new RuntimeException("Scene manager not initialized");
+ }
+ return sSceneManager.mAllocationMap.get(str);
+ }
+
+ static void cacheAlloc(String str, Allocation alloc) {
+ if (sSceneManager == null) {
+ throw new RuntimeException("Scene manager not initialized");
+ }
+ sSceneManager.mAllocationMap.put(str, alloc);
+ }
+
+ public static class SceneLoadedCallback implements Runnable {
+ public Scene mLoadedScene;
+ public String mName;
+ public void run() {
+ }
+ }
+
+ public Scene getActiveScene() {
+ return mActiveScene;
+ }
+
+ public void setActiveScene(Scene s) {
+ mActiveScene = s;
+ }
+
+ static RenderScriptGL getRS() {
+ if (sSceneManager == null) {
+ return null;
+ }
+ return sSceneManager.mRS;
+ }
+
+ static Resources getRes() {
+ if (sSceneManager == null) {
+ return null;
+ }
+ return sSceneManager.mRes;
+ }
+
+ // Constants exported from native to java
+ static ScriptC_export getConst() {
+ return sSceneManager.mExportScript;
+ }
+
+ public static SceneManager getInstance() {
+ if (sSceneManager == null) {
+ sSceneManager = new SceneManager();
+ }
+ return sSceneManager;
+ }
+
+ protected 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 Renderable getRenderableQuad(String name, RenderState state) {
+ Renderable quad = new Renderable();
+ quad.setTransform(new MatrixTransform());
+ quad.setMesh(getScreenAlignedQuad());
+ quad.setName(name);
+ quad.setRenderState(state);
+ quad.setCullType(1);
+ return quad;
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
+ mRS = rs;
+ mRes = res;
+ mAllocationMap = new HashMap<String, Allocation>();
+
+ mExportScript = new ScriptC_export(rs, res, R.raw.export);
+
+ mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
+ mTransformScript.set_gTransformScript(mTransformScript);
+
+ mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
+ mLightScript = new ScriptC_light(rs, res, R.raw.light);
+ mObjectParamsScript = new ScriptC_object_params(rs, res, R.raw.object_params);
+ mFragmentParamsScript = new ScriptC_object_params(rs, res, R.raw.fragment_params);
+ mVertexParamsScript = new ScriptC_object_params(rs, res, R.raw.vertex_params);
+ mCullScript = new ScriptC_cull(rs, res, R.raw.cull);
+
+ mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
+ mRenderLoop.set_gTransformScript(mTransformScript);
+ mRenderLoop.set_gCameraScript(mCameraScript);
+ mRenderLoop.set_gLightScript(mLightScript);
+ mRenderLoop.set_gObjectParamsScript(mObjectParamsScript);
+ mRenderLoop.set_gFragmentParamsScript(mFragmentParamsScript);
+ mRenderLoop.set_gVertexParamsScript(mVertexParamsScript);
+ mRenderLoop.set_gCullScript(mCullScript);
+
+ Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ mRenderLoop.set_gTGrid(checker);
+ mRenderLoop.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
+ }
+
+ public ScriptC getRenderLoop() {
+ return mRenderLoop;
+ }
+}
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java
new file mode 100644
index 0000000..4975114
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java
@@ -0,0 +1,76 @@
+/*
+ * 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 com.android.scenegraph.SceneGraphBase;
+import com.android.scenegraph.ShaderParam;
+
+import android.renderscript.*;
+import android.renderscript.ProgramFragment.Builder;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class Shader extends SceneGraphBase {
+ protected Type mPerObjConstants;
+ protected Type mPerShaderConstants;
+
+ protected HashMap<String, ShaderParam> mSourceParams;
+ protected ArrayList<String> mShaderTextureNames;
+ protected ArrayList<Program.TextureType > mShaderTextureTypes;
+ protected ArrayList<String> mTextureNames;
+ protected ArrayList<Program.TextureType > mTextureTypes;
+
+ protected Allocation mConstantBuffer;
+ protected ScriptField_ShaderParam_s mConstantBufferParams;
+
+ public Shader() {
+ mSourceParams = new HashMap<String, ShaderParam>();
+ mShaderTextureNames = new ArrayList<String>();
+ mShaderTextureTypes = new ArrayList<Program.TextureType>();
+ mTextureNames = new ArrayList<String>();
+ mTextureTypes = new ArrayList<Program.TextureType>();
+ }
+
+ public void appendSourceParams(ShaderParam p) {
+ mSourceParams.put(p.getParamName(), p);
+ }
+
+ public Type getObjectConstants() {
+ return mPerObjConstants;
+ }
+
+ public Type getShaderConstants() {
+ return mPerObjConstants;
+ }
+
+ void linkConstants(RenderScriptGL rs) {
+ if (mPerShaderConstants == null) {
+ return;
+ }
+
+ Element constElem = mPerShaderConstants.getElement();
+ mConstantBufferParams = ShaderParam.fillInParams(constElem, mSourceParams, null);
+
+ mConstantBuffer = Allocation.createTyped(rs, mPerShaderConstants);
+ }
+}
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..b1071d3
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java
@@ -0,0 +1,151 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+import com.android.scenegraph.Transform;
+
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class ShaderParam extends SceneGraphBase {
+
+ static final String cameraPos = "cameraPos";
+ static final String cameraDir = "cameraDir";
+
+ static final String lightColor = "lightColor";
+ static final String lightPos = "lightPos";
+ static final String lightDir = "lightDir";
+
+ static final String view = "view";
+ static final String proj = "proj";
+ static final String viewProj = "viewProj";
+ static final String model = "model";
+ static final String modelView = "modelView";
+ static final String modelViewProj = "modelViewProj";
+
+ ScriptField_ShaderParamData_s.Item mData;
+ ScriptField_ShaderParamData_s mField;
+
+ String mParamName;
+ Camera mCamera;
+
+ static ScriptField_ShaderParam_s fillInParams(Element constantElem,
+ HashMap<String, ShaderParam> sourceParams,
+ Transform transform) {
+ RenderScriptGL rs = SceneManager.getRS();
+ ArrayList<ScriptField_ShaderParam_s.Item> paramList;
+ paramList = new ArrayList<ScriptField_ShaderParam_s.Item>();
+
+ int subElemCount = constantElem.getSubElementCount();
+ for (int i = 0; i < subElemCount; i ++) {
+ String inputName = constantElem.getSubElementName(i);
+ int offset = constantElem.getSubElementOffsetBytes(i);
+
+ ShaderParam matchingParam = sourceParams.get(inputName);
+ Element subElem = constantElem.getSubElement(i);
+ // Make one if it's not there
+ if (matchingParam == null) {
+ if (subElem.getDataType() == Element.DataType.FLOAT_32) {
+ matchingParam = new Float4Param(inputName);
+ } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) {
+ TransformParam trParam = new TransformParam(inputName);
+ trParam.setTransform(transform);
+ matchingParam = trParam;
+ }
+ }
+ if (subElem.getDataType() == Element.DataType.FLOAT_32) {
+ Float4Param fParam = (Float4Param)matchingParam;
+ fParam.setVecSize(subElem.getVectorSize());
+ }
+ ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item();
+ paramRS.bufferOffset = offset;
+ paramRS.transformTimestamp = 0;
+ paramRS.data = matchingParam.getRSData().getAllocation();
+
+ paramList.add(paramRS);
+ }
+
+ ScriptField_ShaderParam_s rsParams = null;
+ int paramCount = paramList.size();
+ if (paramCount != 0) {
+ rsParams = new ScriptField_ShaderParam_s(rs, paramCount);
+ for (int i = 0; i < paramCount; i++) {
+ rsParams.set(paramList.get(i), i, false);
+ }
+ rsParams.copyAll();
+ }
+ return rsParams;
+ }
+
+ public ShaderParam(String name) {
+ mParamName = name;
+ mData = new ScriptField_ShaderParamData_s.Item();
+ }
+
+ public String getParamName() {
+ return mParamName;
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ if (mField != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ mField.set_camera(0, mData.camera, true);
+ }
+ }
+
+ abstract void initLocalData();
+
+ public ScriptField_ShaderParamData_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ mField = new ScriptField_ShaderParamData_s(rs, 1);
+
+ if (mParamName != null) {
+ mData.paramName = SceneManager.getCachedAlloc(mParamName);
+ if (mData.paramName == null) {
+ mData.paramName = SceneManager.getStringAsAllocation(rs, mParamName);
+ SceneManager.cacheAlloc(mParamName, mData.paramName);
+ }
+ }
+ initLocalData();
+
+ mField.set(mData, 0, true);
+ return mField;
+ }
+}
+
+
+
+
+
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..2f04858
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Texture2D extends TextureBase {
+ String mFileName;
+ String mFileDir;
+
+ public Texture2D() {
+ }
+
+ public Texture2D(Allocation tex) {
+ setTexture(tex);
+ }
+
+ public void setFileDir(String dir) {
+ mFileDir = dir;
+ }
+
+ public void setFileName(String file) {
+ mFileName = file;
+ }
+
+ public String getFileName() {
+ return mFileName;
+ }
+
+ public void setTexture(Allocation tex) {
+ mRsTexture = tex;
+ }
+
+ Allocation getRsData() {
+ if (mRsTexture != null) {
+ return mRsTexture;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ mRsTexture = SceneManager.loadTexture2D(mFileDir + shortName, rs, res);
+
+ return mRsTexture;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java
new file mode 100644
index 0000000..425c6d6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.scenegraph;
+
+import java.lang.Math;
+
+import com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class TextureBase extends SceneGraphBase {
+ protected Allocation mRsTexture;
+ abstract Allocation getRsData();
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
new file mode 100644
index 0000000..ba42494
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.android.scenegraph.SceneManager;
+import com.android.scenegraph.TextureBase;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TextureCube extends TextureBase {
+ String mFileName;
+ String mFileDir;
+
+ public TextureCube() {
+ }
+
+ public TextureCube(Allocation tex) {
+ setTexture(tex);
+ }
+
+ public TextureCube(String dir, String file) {
+ setFileDir(dir);
+ setFileName(file);
+ }
+
+ public void setFileDir(String dir) {
+ mFileDir = dir;
+ }
+
+ public void setFileName(String file) {
+ mFileName = file;
+ }
+
+ public String getFileName() {
+ return mFileName;
+ }
+
+ public void setTexture(Allocation tex) {
+ mRsTexture = tex;
+ }
+
+ Allocation getRsData() {
+ if (mRsTexture != null) {
+ return mRsTexture;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ mRsTexture = SceneManager.loadCubemap(mFileDir + shortName, rs, res);
+
+ 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..dd6b8f2
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java
@@ -0,0 +1,63 @@
+/*
+ * 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.RenderScriptGL;
+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 {
+
+ TextureBase mTexture;
+
+ public TextureParam(String name) {
+ super(name);
+ }
+
+ public TextureParam(String name, TextureBase t) {
+ super(name);
+ setTexture(t);
+ }
+
+ public void setTexture(TextureBase t) {
+ mTexture = t;
+ }
+
+ public TextureBase getTexture() {
+ return mTexture;
+ }
+
+ void initLocalData() {
+ }
+}
+
+
+
+
+
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..8180bd0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java
@@ -0,0 +1,98 @@
+/*
+ * 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 {
+ Transform mParent;
+ ArrayList<Transform> mChildren;
+
+ 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;
+ updateRSChildData(true);
+ }
+
+ abstract void initLocalData();
+
+ void updateRSChildData(boolean copyData) {
+ if (mField == null) {
+ return;
+ }
+ RenderScriptGL rs = SceneManager.getRS();
+ 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().getAllocation();
+ }
+ childRSData.copyFrom(childrenAllocs);
+ }
+ if (copyData) {
+ mField.set(mTransformData, 0, true);
+ }
+ }
+
+ ScriptField_SgTransform getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+ mField = new ScriptField_SgTransform(rs, 1);
+
+ mTransformData = new ScriptField_SgTransform.Item();
+ mTransformData.name = getNameAlloc(rs);
+ mTransformData.isDirty = 1;
+ mTransformData.timestamp = 1;
+
+ initLocalData();
+ updateRSChildData(false);
+
+ 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..0950983
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.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.RenderScriptGL;
+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 {
+
+ Transform mTransform;
+ LightBase mLight;
+
+ public TransformParam(String name) {
+ super(name);
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ }
+
+ int getTypeFromName() {
+ int paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_DATA();
+ if (mParamName.equalsIgnoreCase(view)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_VIEW();
+ } else if(mParamName.equalsIgnoreCase(proj)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_PROJ();
+ } else if(mParamName.equalsIgnoreCase(viewProj)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_VIEW_PROJ();
+ } else if(mParamName.equalsIgnoreCase(model)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_MODEL();
+ } else if(mParamName.equalsIgnoreCase(modelView)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_MODEL_VIEW();
+ } else if(mParamName.equalsIgnoreCase(modelViewProj)) {
+ paramType = SceneManager.getConst().get_shaderParam_TRANSFORM_MODEL_VIEW_PROJ();
+ }
+ return paramType;
+ }
+
+ void initLocalData() {
+ mData.type = getTypeFromName();
+ if (mTransform != null) {
+ mData.transform = mTransform.getRSData().getAllocation();
+ }
+ if (mCamera != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ }
+ if (mLight != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java
new file mode 100644
index 0000000..f7d0e6d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java
@@ -0,0 +1,108 @@
+/*
+ * 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.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class VertexShader extends Shader {
+ ProgramVertex mProgram;
+ ScriptField_VertexShader_s mField;
+
+ public static class Builder {
+ VertexShader mShader;
+ ProgramVertex.Builder mBuilder;
+
+ public Builder(RenderScriptGL rs) {
+ mShader = new VertexShader();
+ mBuilder = new ProgramVertex.Builder(rs);
+ }
+
+ public Builder setShader(Resources resources, int resourceID) {
+ mBuilder.setShader(resources, resourceID);
+ return this;
+ }
+
+ public Builder setObjectConst(Type type) {
+ mShader.mPerObjConstants = type;
+ return this;
+ }
+
+ public Builder setShaderConst(Type type) {
+ mShader.mPerShaderConstants = type;
+ return this;
+ }
+
+ public Builder addInput(Element e) {
+ mBuilder.addInput(e);
+ return this;
+ }
+
+ public VertexShader create() {
+ if (mShader.mPerShaderConstants != null) {
+ mBuilder.addConstant(mShader.mPerShaderConstants);
+ }
+ if (mShader.mPerObjConstants != null) {
+ mBuilder.addConstant(mShader.mPerObjConstants);
+ }
+ mShader.mProgram = mBuilder.create();
+ return mShader;
+ }
+ }
+
+ public ProgramVertex getProgram() {
+ return mProgram;
+ }
+
+ ScriptField_VertexShader_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ ScriptField_VertexShader_s.Item item = new ScriptField_VertexShader_s.Item();
+ item.program = mProgram;
+
+ linkConstants(rs);
+ if (mPerShaderConstants != null) {
+ item.shaderConst = mConstantBuffer;
+ item.shaderConstParams = mConstantBufferParams.getAllocation();
+ mProgram.bindConstants(item.shaderConst, 0);
+ }
+
+ item.objectConstIndex = -1;
+ if (mPerObjConstants != null) {
+ item.objectConstIndex = mPerShaderConstants != null ? 1 : 0;
+ }
+
+ mField = new ScriptField_VertexShader_s(rs, 1);
+ mField.set(item, 0, true);
+ return mField;
+ }
+}
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..dc0a885
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs
@@ -0,0 +1,66 @@
+// 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 "scenegraph_objects.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;
+ if (cam->aspect != aspect) {
+ cam->isDirty = 1;
+ cam->aspect = aspect;
+ }
+ if (cam->isDirty) {
+ rsMatrixLoadPerspective(&cam->proj, cam->horizontalFOV, cam->aspect, cam->near, cam->far);
+ }
+
+ const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
+ //rsDebug("Camera stamp", cam->transformTimestamp);
+ //rsDebug("Transform stamp", camTransform->timestamp);
+ if (camTransform->timestamp != cam->transformTimestamp || cam->isDirty) {
+ cam->isDirty = 1;
+ 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);
+
+ rsExtractFrustumPlanes(&cam->viewProj,
+ &cam->frustumPlanes[0], &cam->frustumPlanes[1],
+ &cam->frustumPlanes[2], &cam->frustumPlanes[3],
+ &cam->frustumPlanes[3], &cam->frustumPlanes[4]);
+ }
+
+ if (cam->isDirty) {
+ cam->timestamp ++;
+ }
+
+ cam->isDirty = 0;
+ cam->transformTimestamp = camTransform->timestamp;
+
+#ifdef DEBUG_CAMERA
+ printCameraInfo(cam);
+#endif //DEBUG_CAMERA
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs
new file mode 100644
index 0000000..024e026
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs
@@ -0,0 +1,86 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+static void getTransformedSphere(SgRenderable *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(SgRenderable *obj, SgCamera *cam) {
+ 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,
+ &cam->frustumPlanes[0], &cam->frustumPlanes[1],
+ &cam->frustumPlanes[2], &cam->frustumPlanes[3],
+ &cam->frustumPlanes[4], &cam->frustumPlanes[5]);
+}
+
+
+void root(rs_allocation *v_out, const void *usrData) {
+
+ SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+
+ drawable->isVisible = 0;
+ // Not loaded yet
+ if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) {
+ return;
+ }
+
+ // check to see if we are culling this object and if it's
+ // outside the frustum
+ if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) {
+#ifdef DEBUG_RENDERABLES
+ rsDebug("Culled", drawable);
+ printName(drawable->name);
+#endif // DEBUG_RENDERABLES
+ return;
+ }
+ drawable->isVisible = 1;
+}
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..6201496
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
@@ -0,0 +1,56 @@
+// 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 "scenegraph_objects.rsh"
+
+// Export our native constants to java so that we don't have parallel definitions
+const int shaderParam_FLOAT4_DATA = SHADER_PARAM_FLOAT4_DATA;
+const int shaderParam_TRANSFORM_DATA = SHADER_PARAM_TRANSFORM_DATA;
+const int shaderParam_TRANSFORM_MODEL = SHADER_PARAM_TRANSFORM_MODEL;
+
+const int shaderParam_FLOAT4_CAMERA_POS = SHADER_PARAM_FLOAT4_CAMERA_POS;
+const int shaderParam_FLOAT4_CAMERA_DIR = SHADER_PARAM_FLOAT4_CAMERA_DIR;
+const int shaderParam_TRANSFORM_VIEW = SHADER_PARAM_TRANSFORM_VIEW;
+const int shaderParam_TRANSFORM_PROJ = SHADER_PARAM_TRANSFORM_PROJ;
+const int shaderParam_TRANSFORM_VIEW_PROJ = SHADER_PARAM_TRANSFORM_VIEW_PROJ;
+const int shaderParam_TRANSFORM_MODEL_VIEW = SHADER_PARAM_TRANSFORM_MODEL_VIEW;
+const int shaderParam_TRANSFORM_MODEL_VIEW_PROJ = SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ;
+
+const int shaderParam_FLOAT4_LIGHT_COLOR = SHADER_PARAM_FLOAT4_LIGHT_COLOR;
+const int shaderParam_FLOAT4_LIGHT_POS = SHADER_PARAM_FLOAT4_LIGHT_POS;
+const int shaderParam_FLOAT4_LIGHT_DIR = SHADER_PARAM_FLOAT4_LIGHT_DIR;
+
+const int shaderParam_TEXTURE = SHADER_PARAM_TEXTURE;
+
+const int transform_TRANSLATE = TRANSFORM_TRANSLATE;
+const int transform_ROTATE = TRANSFORM_ROTATE;
+const int transform_SCALE = TRANSFORM_SCALE;
+
+SgTransform *exportPtr;
+SgTransformComponent *componentPtr;
+SgRenderState *sExport;
+SgRenderable *drExport;
+SgRenderPass *pExport;
+SgCamera *exportPtrCam;
+SgLight *exportPtrLight;
+SgShaderParam *spExport;
+SgShaderParamData *spDataExport;
+SgVertexShader *pvExport;
+SgFragmentShader *pfExport;
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs
new file mode 100644
index 0000000..f5816ed
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+ SgFragmentShader *shader = (SgFragmentShader *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(shader->shaderConst, shader->shaderConstParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
new file mode 100644
index 0000000..e11979f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
@@ -0,0 +1,33 @@
+// 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_LIGHT
+#include "scenegraph_objects.rsh"
+
+void root(const rs_allocation *v_in, rs_allocation *v_out) {
+
+ SgLight *light = (SgLight *)rsGetElementAt(*v_in, 0);
+ const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+
+ float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
+ light->position = rsMatrixMultiply(&lTransform->globalMat, zero);
+
+#ifdef DEBUG_LIGHT
+ printLightInfo(light);
+#endif //DEBUG_LIGHT
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs
new file mode 100644
index 0000000..0d524a6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs
@@ -0,0 +1,36 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+
+ SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
+ // Visibility flag was set earlier in the cull stage
+ if (!drawable->isVisible) {
+ return;
+ }
+
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(drawable->pf_const, drawable->pf_constParams, camera);
+ processAllParams(drawable->pv_const, drawable->pv_constParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
new file mode 100644
index 0000000..2169de3
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
@@ -0,0 +1,157 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+static void debugParam(SgShaderParam *p, SgShaderParamData *pData,
+ uint8_t *constantBuffer, const SgCamera *currentCam) {
+ rsDebug("____________ Param bufferOffset", p->bufferOffset);
+ rsDebug("Param Type ", pData->type);
+ if (rsIsObject(pData->paramName)) {
+ printName(pData->paramName);
+ }
+
+ uint8_t *dataPtr = constantBuffer + p->bufferOffset;
+ const SgTransform *pTransform = NULL;
+ if (rsIsObject(pData->transform)) {
+ pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0);
+
+ rsDebug("Param transform", pTransform);
+ printName(pTransform->name);
+ }
+
+ const SgLight *pLight = NULL;
+ if (rsIsObject(pData->light)) {
+ pLight = (const SgLight *)rsGetElementAt(pData->light, 0);
+ printLightInfo(pLight);
+ }
+}
+
+
+static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
+#ifdef DEBUG_PARAMS
+ rsDebug("Writing value ", *input);
+ rsDebug("Writing vec size ", vecSize);
+#endif // DEBUG_PARAMS
+
+ switch (vecSize) {
+ case 1:
+ *ptr = input->x;
+ break;
+ case 2:
+ *((float2*)ptr) = (*input).xy;
+ break;
+ case 3:
+ *((float3*)ptr) = (*input).xyz;
+ break;
+ case 4:
+ *((float4*)ptr) = *input;
+ break;
+ }
+}
+
+static bool processParam(SgShaderParam *p, SgShaderParamData *pData,
+ uint8_t *constantBuffer, const SgCamera *currentCam) {
+ const SgTransform *pTransform = NULL;
+ if (rsIsObject(pData->transform)) {
+ pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0);
+ // If we are a transform param and our transform is unchanged, nothing to do
+ bool isTransformOnly = (pData->type > SHADER_PARAM_DATA_ONLY);
+ if (p->transformTimestamp == pTransform->timestamp && isTransformOnly) {
+ return false;
+ }
+ p->transformTimestamp = pTransform->timestamp;
+ }
+
+ const SgLight *pLight = NULL;
+ if (rsIsObject(pData->light)) {
+ pLight = (const SgLight *)rsGetElementAt(pData->light, 0);
+ }
+
+ uint8_t *dataPtr = constantBuffer + p->bufferOffset;
+
+ switch(pData->type) {
+ case SHADER_PARAM_FLOAT4_DATA:
+ writeFloatData((float*)dataPtr, &pData->float_value, pData->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_CAMERA_POS:
+ writeFloatData((float*)dataPtr, &currentCam->position, pData->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_CAMERA_DIR: break;
+ case SHADER_PARAM_FLOAT4_LIGHT_COLOR:
+ writeFloatData((float*)dataPtr, &pLight->color, pData->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_LIGHT_POS:
+ writeFloatData((float*)dataPtr, &pLight->position, pData->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_LIGHT_DIR: break;
+
+ case SHADER_PARAM_TRANSFORM_DATA:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_VIEW:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->view);
+ break;
+ case SHADER_PARAM_TRANSFORM_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->proj);
+ break;
+ case SHADER_PARAM_TRANSFORM_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->viewProj);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->view);
+ rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr,
+ (rs_matrix4x4*)dataPtr,
+ &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->viewProj);
+ rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr,
+ (rs_matrix4x4*)dataPtr,
+ &pTransform->globalMat);
+ break;
+ }
+ return true;
+}
+
+static void processAllParams(rs_allocation shaderConst,
+ rs_allocation allParams,
+ const SgCamera *camera) {
+ if (rsIsObject(shaderConst)) {
+ uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(shaderConst, 0);
+
+ int numParams = 0;
+ if (rsIsObject(allParams)) {
+ numParams = rsAllocationGetDimX(allParams);
+ }
+ bool updated = false;
+ for (int i = 0; i < numParams; i ++) {
+ SgShaderParam *current = (SgShaderParam*)rsGetElementAt(allParams, i);
+ SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0);
+#ifdef DEBUG_PARAMS
+ debugParam(current, currentData, constantBuffer, camera);
+#endif // DEBUG_PARAMS
+ updated = processParam(current, currentData, constantBuffer, camera) || updated;
+ }
+ }
+}
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..ecfec08
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -0,0 +1,237 @@
+// Copyright (C) 2011-2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "scenegraph_objects.rsh"
+
+rs_script gTransformScript;
+rs_script gCameraScript;
+rs_script gLightScript;
+rs_script gObjectParamsScript;
+rs_script gFragmentParamsScript;
+rs_script gVertexParamsScript;
+rs_script gCullScript;
+
+SgTransform *gRootNode;
+rs_allocation gCameras;
+rs_allocation gLights;
+rs_allocation gFragmentShaders;
+rs_allocation gVertexShaders;
+rs_allocation gRenderableObjects;
+
+rs_allocation gRenderPasses;
+
+// Temporary shaders
+rs_allocation gTGrid;
+rs_program_store gPFSBackground;
+
+uint32_t *gFrontToBack;
+static uint32_t gFrontToBackCount = 0;
+uint32_t *gBackToFront;
+static uint32_t gBackToFrontCount = 0;
+
+static SgCamera *gActiveCamera = NULL;
+
+static rs_allocation nullAlloc;
+
+//#define DEBUG_RENDERABLES
+static void draw(SgRenderable *obj) {
+#ifdef DEBUG_RENDERABLES
+ const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
+ rsDebug("**** Drawing object with transform", obj);
+ printName(objTransform->name);
+ rsDebug("Model matrix: ", &objTransform->globalMat);
+ printName(obj->name);
+#endif //DEBUG_RENDERABLES
+
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ const SgVertexShader *pv = (const SgVertexShader *)rsGetElementAt(renderState->pv, 0);
+ const SgFragmentShader *pf = (const SgFragmentShader *)rsGetElementAt(renderState->pf, 0);
+
+ if (pv->objectConstIndex != -1) {
+ rsgBindConstant(pv->program, pv->objectConstIndex, obj->pv_const);
+ }
+ if (pf->objectConstIndex != -1) {
+ rsgBindConstant(pf->program, pf->objectConstIndex, obj->pf_const);
+ }
+
+ if (rsIsObject(renderState->ps)) {
+ rsgBindProgramStore(renderState->ps);
+ } else {
+ rsgBindProgramStore(gPFSBackground);
+ }
+
+ if (rsIsObject(renderState->pr)) {
+ rsgBindProgramRaster(renderState->pr);
+ } else {
+ rs_program_raster pr;
+ rsgBindProgramRaster(pr);
+ }
+
+ rsgBindProgramVertex(pv->program);
+ rsgBindProgramFragment(pf->program);
+
+ for (uint32_t i = 0; i < obj->pf_num_textures; i ++) {
+ if (rsIsObject(obj->pf_textures[i])) {
+ rsgBindTexture(pf->program, i, obj->pf_textures[i]);
+ } else {
+ rsgBindTexture(pf->program, i, gTGrid);
+ }
+ }
+
+ rsgDrawMesh(obj->mesh, obj->meshIndex);
+}
+
+static void sortToBucket(SgRenderable *obj) {
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ if (rsIsObject(renderState->ps)) {
+ bool isOpaque = false;
+ if (isOpaque) {
+ gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
+ } else {
+ gBackToFront[gBackToFrontCount++] = (uint32_t)obj;
+ }
+ } else {
+ gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
+ }
+}
+
+static void updateActiveCamera(rs_allocation cam) {
+ gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0);
+}
+
+static void prepareCameras() {
+ // now compute all the camera matrices
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect));
+}
+
+static void prepareLights() {
+ if (rsIsObject(gLights)) {
+ rsForEach(gLightScript, gLights, nullAlloc);
+ }
+}
+
+static void drawSorted() {
+ for (int i = 0; i < gFrontToBackCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gFrontToBack[i];
+ draw(current);
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gBackToFront[i];
+ draw(current);
+ }
+}
+
+static void drawAllObjects(rs_allocation allObj) {
+ if (!rsIsObject(allObj)) {
+ return;
+ }
+
+ rsForEach(gVertexParamsScript, nullAlloc, gVertexShaders,
+ gActiveCamera, sizeof(gActiveCamera));
+ rsForEach(gFragmentParamsScript, nullAlloc, gFragmentShaders,
+ gActiveCamera, sizeof(gActiveCamera));
+
+ // Run the params and cull script
+ rsForEach(gCullScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera));
+ rsForEach(gObjectParamsScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera));
+
+ int numRenderables = rsAllocationGetDimX(allObj);
+ for (int i = 0; i < numRenderables; i ++) {
+ rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i);
+ SgRenderable *current = (SgRenderable*)rsGetElementAt(*drawAlloc, 0);
+ if (current->isVisible) {
+ sortToBucket(current);
+ }
+ }
+ drawSorted();
+}
+
+void root(const void *v_in, void *v_out) {
+#ifdef DEBUG_RENDERABLES
+ rsDebug("=============================================================================", 0);
+#endif // DEBUG_RENDERABLES
+ // first step is to update the transform hierachy
+ rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0);
+
+ prepareCameras();
+ prepareLights();
+
+ rsgClearDepth(1.0f);
+
+ int numRenderables = rsAllocationGetDimX(gRenderableObjects);
+ 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(gRenderableObjects);
+ }
+}
+
+// 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 ++) {
+ SgRenderable *current = (SgRenderable*)gFrontToBack[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = CULL_ALWAYS;
+ }
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gBackToFront[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = CULL_ALWAYS;
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
new file mode 100644
index 0000000..af39ecf
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
@@ -0,0 +1,317 @@
+// Copyright (C) 2011-2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#ifndef _TRANSFORM_DEF_
+#define _TRANSFORM_DEF_
+
+#include "rs_graphics.rsh"
+
+#define TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+#define CULL_FRUSTUM 0
+#define CULL_ALWAYS 2
+
+#define LIGHT_POINT 0
+#define LIGHT_DIRECTIONAL 1
+
+// Shader params that involve only data
+#define SHADER_PARAM_DATA_ONLY 10000
+#define SHADER_PARAM_FLOAT4_DATA 10001
+#define SHADER_PARAM_TRANSFORM_DATA 10002
+#define SHADER_PARAM_TRANSFORM_MODEL 10003
+
+// Shader params that involve camera
+#define SHADER_PARAM_CAMERA 1000
+#define SHADER_PARAM_FLOAT4_CAMERA_POS 1001
+#define SHADER_PARAM_FLOAT4_CAMERA_DIR 1002
+#define SHADER_PARAM_TRANSFORM_VIEW 1003
+#define SHADER_PARAM_TRANSFORM_PROJ 1004
+#define SHADER_PARAM_TRANSFORM_VIEW_PROJ 1005
+#define SHADER_PARAM_TRANSFORM_MODEL_VIEW 1006
+#define SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ 1007
+
+// Shader Params that only involve lights
+#define SHADER_PARAM_LIGHT 100
+#define SHADER_PARAM_FLOAT4_LIGHT_COLOR 103
+#define SHADER_PARAM_FLOAT4_LIGHT_POS 104
+#define SHADER_PARAM_FLOAT4_LIGHT_DIR 105
+
+#define SHADER_PARAM_TEXTURE 10
+
+#define TEXTURE_NONE 0
+#define TEXTURE_2D 1
+#define TEXTURE_CUBE 2
+
+typedef struct TransformComponent_s {
+ float4 value;
+ int type;
+ rs_allocation name;
+} SgTransformComponent;
+
+typedef struct __attribute__((packed, aligned(4))) SgTransform {
+ rs_matrix4x4 globalMat;
+ rs_matrix4x4 localMat;
+
+ rs_allocation components;
+ int isDirty;
+
+ rs_allocation children;
+ rs_allocation name;
+
+ // Used to check whether transform params need to be updated
+ uint32_t timestamp;
+} SgTransform;
+
+typedef struct VertexShader_s {
+ rs_program_vertex program;
+ // Buffer with vertex constant data
+ rs_allocation shaderConst;
+ // ShaderParam's that populate data
+ rs_allocation shaderConstParams;
+ // location of the per object constants on the buffer
+ int objectConstIndex;
+} SgVertexShader;
+
+typedef struct FragmentShader_s {
+ rs_program_fragment program;
+ // Buffer with vertex constant data
+ rs_allocation shaderConst;
+ // ShaderParam's that populate data
+ rs_allocation shaderConstParams;
+ // location of the per object constants on the buffer
+ int objectConstIndex;
+} SgFragmentShader;
+
+typedef struct RenderState_s {
+ rs_allocation pv; // VertexShader struct
+ rs_allocation pf; // FragmentShader struct
+ rs_program_store ps;
+ rs_program_raster pr;
+} SgRenderState;
+
+typedef struct Renderable_s {
+ rs_allocation render_state;
+ // Buffer with vertex constant data
+ rs_allocation pv_const;
+ // ShaderParam's that populate data
+ rs_allocation pv_constParams;
+ // Buffer with fragment constant data
+ rs_allocation pf_const;
+ // ShaderParam's that populate data
+ rs_allocation pf_constParams;
+ 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
+ int isVisible;
+} SgRenderable;
+
+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 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;
+ float4 frustumPlanes[6];
+
+ int isDirty;
+ // Timestamp of the camera itself to signal params if anything changes
+ uint32_t timestamp;
+ // Timestamp of our transform
+ uint32_t transformTimestamp;
+} SgCamera;
+
+typedef struct Light_s {
+ float4 position;
+ float4 color;
+ float intensity;
+ int type;
+ rs_allocation name;
+ rs_allocation transformMatrix;
+} SgLight;
+
+// This represents the shader parameter data needed to set a float or transform data
+typedef struct ShaderParamData_s {
+ int type;
+
+ float4 float_value;
+ // Use one param type to handle all vector types for now
+ int float_vecSize;
+ rs_allocation paramName;
+ rs_allocation camera;
+ rs_allocation light;
+ rs_allocation transform;
+ rs_allocation texture;
+} SgShaderParamData;
+
+// This represents a shader parameter that knows how to update itself for a given
+// renderable or shader and contains a timestamp for the last time this buffer was updated
+typedef struct ShaderParam_s {
+ // Used to check whether transform params need to be updated
+ uint32_t transformTimestamp;
+ // Specifies where in the constant buffer data gets written to
+ int bufferOffset;
+ // An instance of SgShaderParamData that could be shared by multiple objects
+ rs_allocation data;
+} SgShaderParam;
+
+// This represents a texture object
+typedef struct Texture_s {
+ uint32_t type;
+ rs_allocation texture;
+} SgTexture;
+
+static void printName(rs_allocation name) {
+ if (!rsIsObject(name)) {
+ rsDebug("no name", 0);
+ return;
+ }
+
+ rsDebug((const char*)rsGetElementAt(name, 0), 0);
+}
+
+static void printCameraInfo(const 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 printLightInfo(const SgLight *light) {
+ rsDebug("***** Light information. ptr:", light);
+ printName(light->name);
+ const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+ rsDebug("Transform name:", lTransform);
+ printName(lTransform->name);
+
+ rsDebug("Position: ", light->position);
+ rsDebug("Color : ", light->color);
+ rsDebug("Intensity: ", light->intensity);
+ rsDebug("Type: ", light->type);
+}
+
+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;
+}
+
+static bool intersect(const SgRenderable *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;
+}
+
+
+#endif // _TRANSFORM_DEF_
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..941b5a8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.modelviewer)
+
+#include "scenegraph_objects.rsh"
+
+rs_script gTransformScript;
+
+typedef struct {
+ int changed;
+ rs_matrix4x4 *mat;
+} ParentData;
+
+//#define DEBUG_TRANSFORMS
+static void debugTransform(SgTransform *data, const ParentData *parent) {
+ rsDebug("****** <Transform> ******", (int)data);
+ printName(data->name);
+ rsDebug("isDirty", data->isDirty);
+ rsDebug("parent", (int)parent);
+ rsDebug("child ", rsIsObject(data->children));
+
+ // Refresh matrices if dirty
+ if (data->isDirty && rsIsObject(data->components)) {
+ uint32_t numComponenets = rsAllocationGetDimX(data->components);
+ for (int i = 0; i < numComponenets; i ++) {
+ const SgTransformComponent *comp = NULL;
+ comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
+
+ if (rsIsObject(comp->name)) {
+ rsDebug((const char*)rsGetElementAt(comp->name, 0), comp->value);
+ rsDebug("Type", comp->type);
+ } else {
+ rsDebug("no name", comp->value);
+ rsDebug("Type", comp->type);
+ }
+ }
+ }
+
+ rsDebug("timestamp", data->timestamp);
+ rsDebug("****** </Transform> ******", (int)data);
+}
+
+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
+ debugTransform(data, parent);
+#endif //DEBUG_TRANSFORMS
+
+ rs_matrix4x4 *localMat = &data->localMat;
+ rs_matrix4x4 *globalMat = &data->globalMat;
+
+ // Refresh matrices if dirty
+ if (data->isDirty && rsIsObject(data->components)) {
+ bool resetLocal = false;
+ uint32_t numComponenets = rsAllocationGetDimX(data->components);
+ for (int i = 0; i < numComponenets; i ++) {
+ if (!resetLocal) {
+ // Reset our local matrix only for component transforms
+ rsMatrixLoadIdentity(localMat);
+ resetLocal = true;
+ }
+ const SgTransformComponent *comp = NULL;
+ comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
+ appendTransformation(comp->type, comp->value, localMat);
+ }
+ }
+
+ if (parent) {
+ data->isDirty = (parent->changed || data->isDirty) ? 1 : 0;
+ if (data->isDirty) {
+ rsMatrixLoad(globalMat, parent->mat);
+ rsMatrixMultiply(globalMat, localMat);
+ }
+ } else if (data->isDirty) {
+ rsMatrixLoad(globalMat, localMat);
+ }
+
+ ParentData toChild;
+ toChild.changed = 0;
+ toChild.mat = globalMat;
+
+ if (data->isDirty) {
+ toChild.changed = 1;
+ data->timestamp ++;
+ }
+
+ 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/vertex_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs
new file mode 100644
index 0000000..88955a8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+ SgVertexShader *shader = (SgVertexShader *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(shader->shaderConst, shader->shaderConstParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java
new file mode 100644
index 0000000..420e133
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * A list view where the last item the user clicked is placed in
+ * the "activated" state, causing its background to highlight.
+ */
+public class FileSelector extends ListActivity {
+
+ File[] mCurrentSubList;
+ File mCurrentFile;
+
+ class DAEFilter implements FileFilter {
+ public boolean accept(File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
+ return file.getName().endsWith(".dae");
+ }
+ }
+
+ private void populateList(File file) {
+
+ mCurrentFile = file;
+ setTitle(mCurrentFile.getAbsolutePath() + "/*.dae");
+ List<String> names = new ArrayList<String>();
+ names.add("..");
+
+ mCurrentSubList = mCurrentFile.listFiles(new DAEFilter());
+
+ if (mCurrentSubList != null) {
+ for (int i = 0; i < mCurrentSubList.length; i ++) {
+ String fileName = mCurrentSubList[i].getName();
+ if (mCurrentSubList[i].isDirectory()) {
+ fileName = "/" + fileName;
+ }
+ names.add(fileName);
+ }
+ }
+
+ // Use the built-in layout for showing a list item with a single
+ // line of text whose background is changes when activated.
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_activated_1, names));
+ getListView().setTextFilterEnabled(true);
+
+ // Tell the list view to show one checked/activated item at a time.
+ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ populateList(new File("/sdcard/"));
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ if (position == 0) {
+ File parent = mCurrentFile.getParentFile();
+ if (parent == null) {
+ return;
+ }
+ populateList(parent);
+ return;
+ }
+
+ // the first thing in list is parent directory
+ File selectedFile = mCurrentSubList[position - 1];
+ if (selectedFile.isDirectory()) {
+ populateList(selectedFile);
+ return;
+ }
+
+ Intent resultIntent = new Intent();
+ resultIntent.setData(Uri.fromFile(selectedFile));
+ setResult(RESULT_OK, resultIntent);
+ finish();
+ }
+
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java
new file mode 100644
index 0000000..2299b72
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.testapp;
+
+import java.util.ArrayList;
+
+import com.android.scenegraph.*;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+class FullscreenBlur {
+
+ static Allocation sRenderTargetBlur0Color;
+ static Allocation sRenderTargetBlur0Depth;
+ static Allocation sRenderTargetBlur1Color;
+ static Allocation sRenderTargetBlur1Depth;
+ static Allocation sRenderTargetBlur2Color;
+ static Allocation sRenderTargetBlur2Depth;
+
+ static FragmentShader mPF_BlurH;
+ static FragmentShader mPF_BlurV;
+ static FragmentShader mPF_SelectColor;
+ static FragmentShader mPF_Texture;
+ static VertexShader mPV_Paint;
+ static VertexShader mPV_Blur;
+
+ // This is only used when full screen blur is enabled
+ // Basically, it's the offscreen render targets
+ static void createRenderTargets(RenderScriptGL rs, int w, int h) {
+ Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
+ Type renderType = b.setX(w/8).setY(h/8).create();
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Color = Allocation.createTyped(rs, renderType, usage);
+
+ b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ renderType = b.setX(w/8).setY(h/8).create();
+ usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Depth = Allocation.createTyped(rs, renderType, usage);
+ }
+
+ static void addOffsets(Renderable quad, float advance) {
+ quad.appendSourceParams(new Float4Param("blurOffset0", - advance * 2.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset1", - advance * 0.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset2", advance * 1.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset3", advance * 3.5f));
+ }
+
+ static RenderPass addPass(Scene scene, Allocation color, Allocation depth) {
+ RenderPass pass = new RenderPass();
+ pass.setColorTarget(color);
+ pass.setDepthTarget(depth);
+ pass.setShouldClearColor(false);
+ pass.setShouldClearDepth(false);
+ pass.setCamera(scene.getCameras().get(1));
+ scene.appendRenderPass(pass);
+ return pass;
+ }
+
+ static void addBlurPasses(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ ArrayList<RenderableBase> allDraw = scene.getRenderables();
+ int numDraw = allDraw.size();
+
+ ProgramRaster cullNone = ProgramRaster.CULL_NONE(rs);
+ ProgramStore blendAdd = SceneManager.BLEND_ADD_DEPTH_NONE(rs);
+ ProgramStore blendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(rs);
+
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture, blendAdd, cullNone);
+ RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor, blendNone, cullNone);
+ RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH, blendNone, cullNone);
+ RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV, blendNone, cullNone);
+
+ // Renders the scene off screen
+ RenderPass blurSourcePass = addPass(scene,
+ sRenderTargetBlur0Color,
+ sRenderTargetBlur0Depth);
+ blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ blurSourcePass.setShouldClearColor(true);
+ blurSourcePass.setClearDepth(1.0f);
+ blurSourcePass.setShouldClearDepth(true);
+ for (int i = 0; i < numDraw; i ++) {
+ blurSourcePass.appendRenderable((Renderable)allDraw.get(i));
+ }
+
+ // Pass for selecting bright colors
+ RenderPass selectColorPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur0Color)));
+ selectColorPass.appendRenderable(quad);
+
+ // Horizontal blur
+ RenderPass horizontalBlurPass = addPass(scene,
+ sRenderTargetBlur1Color,
+ sRenderTargetBlur1Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getX());
+ horizontalBlurPass.appendRenderable(quad);
+
+ // Vertical Blur
+ RenderPass verticalBlurPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur1Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getY());
+ verticalBlurPass.appendRenderable(quad);
+ }
+
+ // Additively renders the blurred colors on top of the scene
+ static void addCompositePass(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ SceneManager.BLEND_ADD_DEPTH_NONE(rs),
+ ProgramRaster.CULL_NONE(rs));
+
+ RenderPass compositePass = addPass(scene, null, null);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuad", drawTex);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ compositePass.appendRenderable(quad);
+ }
+
+ static private FragmentShader getShader(Resources res, RenderScriptGL rs,
+ int resID, Type constants) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(rs);
+ fb.setShader(res, resID);
+ fb.addTexture(TextureType.TEXTURE_2D, "color");
+ if (constants != null) {
+ fb.setObjectConst(constants);
+ }
+ FragmentShader prog = fb.create();
+ prog.getProgram().bindSampler(Sampler.CLAMP_LINEAR(rs), 0);
+ return prog;
+ }
+
+ static void initShaders(Resources res, RenderScriptGL rs) {
+ ScriptField_BlurOffsets blurConst = new ScriptField_BlurOffsets(rs, 1);
+ VertexShader.Builder vb = new VertexShader.Builder(rs);
+ vb.addInput(ScriptField_VertexShaderInputs.createElement(rs));
+ vb.setShader(res, R.raw.blur_vertex);
+ mPV_Blur = vb.create();
+
+ mPF_Texture = getShader(res, rs, R.raw.texture, null);
+ mPF_Texture.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(rs), 0);
+ mPF_BlurH = getShader(res, rs, R.raw.blur_h, blurConst.getAllocation().getType());
+ mPF_BlurV = getShader(res, rs, R.raw.blur_v, blurConst.getAllocation().getType());
+ mPF_SelectColor = getShader(res, rs, R.raw.select_color, null);
+ }
+
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java
new file mode 100644
index 0000000..385a7ab
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+import android.view.MenuInflater;
+import android.view.Window;
+import android.net.Uri;
+
+import java.lang.Runtime;
+
+public class TestApp extends Activity {
+
+ private TestAppView mView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new TestAppView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.resume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.pause();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.loader_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.load_model:
+ loadModel();
+ return true;
+ case R.id.use_blur:
+ mView.mRender.toggleBlur();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static final int FIND_DAE_MODEL = 10;
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_OK) {
+ if (requestCode == FIND_DAE_MODEL) {
+ Uri selectedImageUri = data.getData();
+ Log.e("Selected Path: ", selectedImageUri.getPath());
+ mView.mRender.loadModel(selectedImageUri.getPath());
+ }
+ }
+ }
+
+ public void loadModel() {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_PICK);
+ intent.setClassName("com.android.testapp",
+ "com.android.testapp.FileSelector");
+ startActivityForResult(intent, FIND_DAE_MODEL);
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java
new file mode 100644
index 0000000..60616cc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+// This is where the scenegraph and the rendered objects are initialized and used
+public class TestAppLoadingScreen {
+
+ private static String TAG = "TestAppLoadingScreen";
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ private ScriptC_test_app mScript;
+
+ public TestAppLoadingScreen(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+ // Shows the loading screen with some text
+ renderLoading();
+ // Adds a little 3D bugdroid model to the laoding screen asynchronously.
+ new LoadingScreenLoaderTask().execute();
+ }
+
+ public void showLoadingScreen(boolean show) {
+ mScript.set_gInitialized(!show);
+ }
+
+ // The loading screen has some elements that shouldn't be loaded on the UI thread
+ private class LoadingScreenLoaderTask extends AsyncTask<String, Void, Boolean> {
+ Allocation robotTex;
+ Mesh robotMesh;
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ robotTex = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+
+ FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+ FileA3D.IndexEntry entry = model.getIndexEntry(0);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ robotMesh = entry.getMesh();
+ }
+
+ mScript.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
+
+ ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+ b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+ ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+ ProgramFragment pfDefault = b.create();
+ pfDefault.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+ mScript.set_gPFBackground(pfDefault);
+
+ ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+ ProgramVertexFixedFunction pvDefault = pvb.create();
+ ProgramVertexFixedFunction.Constants va = new ProgramVertexFixedFunction.Constants(mRS);
+ ((ProgramVertexFixedFunction)pvDefault).bindConstants(va);
+ mScript.set_gPVBackground(pvDefault);
+
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Loading load time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mScript.set_gRobotTex(robotTex);
+ mScript.set_gRobotMesh(robotMesh);
+ }
+ }
+
+ // Creates a simple script to show a loding screen until everything is initialized
+ // Could also be used to do some custom renderscript work before handing things over
+ // to the scenegraph
+ void renderLoading() {
+ mScript = new ScriptC_test_app(mRS, mRes, R.raw.test_app);
+ mRS.bindRootScript(mScript);
+ }
+
+ public void setRenderLoop(ScriptC renderLoop) {
+ mScript.set_gRenderLoop(renderLoop);
+ Allocation dummyAlloc = Allocation.createSized(mRS, Element.I32(mRS), 1);
+ mScript.set_gDummyAlloc(dummyAlloc);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java
new file mode 100644
index 0000000..0892fdb
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2011-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import com.android.scenegraph.*;
+import com.android.scenegraph.SceneManager.SceneLoadedCallback;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Program.TextureType;
+import android.util.Log;
+
+// This is where the scenegraph and the rendered objects are initialized and used
+public class TestAppRS {
+
+ private static String modelName = "orientation_test.dae";
+ private static String TAG = "TestAppRS";
+ private static String mFilePath = "";
+
+ int mWidth;
+ int mHeight;
+
+ boolean mUseBlur;
+
+ TestAppLoadingScreen mLoadingScreen;
+
+ // Used to asynchronously load scene elements like meshes and transform hierarchies
+ SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() {
+ public void run() {
+ prepareToRender(mLoadedScene);
+ }
+ };
+
+ // Top level class that initializes all the elements needed to use the scene graph
+ SceneManager mSceneManager;
+
+ // Used to move the camera around in the 3D world
+ TouchHandler mTouchHandler;
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+
+ // Shaders
+ private FragmentShader mPaintF;
+ private FragmentShader mLightsF;
+ private FragmentShader mAluminumF;
+ private FragmentShader mPlasticF;
+ private FragmentShader mDiffuseF;
+ private FragmentShader mTextureF;
+ private VertexShader mGenericV;
+
+ Scene mActiveScene;
+
+ // This is a part of the test app, it's used to tests multiple render passes and is toggled
+ // on and off in the menu, off by default
+ void toggleBlur() {
+ mUseBlur = !mUseBlur;
+
+ mActiveScene.clearRenderPasses();
+ initRenderPasses();
+ mActiveScene.initRenderPassRS(mRS, mSceneManager);
+
+ // This is just a hardcoded object in the scene that gets turned on and off for the demo
+ // to make things look a bit better. This could be deleted in the cleanup
+ Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
+ if (plane != null) {
+ plane.setVisible(mRS, !mUseBlur);
+ }
+ }
+
+ public void init(RenderScriptGL rs, Resources res, int width, int height) {
+ mUseBlur = false;
+ mRS = rs;
+ mRes = res;
+ mWidth = width;
+ mHeight = height;
+
+ mTouchHandler = new TouchHandler();
+
+ mSceneManager = SceneManager.getInstance();
+ // Initializes all the RS specific scenegraph elements
+ mSceneManager.initRS(mRS, mRes, mWidth, mHeight);
+
+ mLoadingScreen = new TestAppLoadingScreen(mRS, mRes);
+
+ // Initi renderscript stuff specific to the app. This will need to be abstracted out later.
+ FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight);
+ initPaintShaders();
+ mLoadingScreen.setRenderLoop(mSceneManager.getRenderLoop());
+
+ // Load a scene to render
+ mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback);
+ }
+
+ // When a new model file is selected from the UI, this function gets called to init everything
+ void loadModel(String path) {
+ mLoadingScreen.showLoadingScreen(true);
+ mActiveScene.destroyRS();
+ mSceneManager.loadModel(path, mLoadedCallback);
+ }
+
+ public void onActionDown(float x, float y) {
+ mTouchHandler.onActionDown(x, y);
+ }
+
+ public void onActionScale(float scale) {
+ mTouchHandler.onActionScale(scale);
+ }
+
+ public void onActionMove(float x, float y) {
+ mTouchHandler.onActionMove(x, y);
+ }
+
+ FragmentShader createFromResource(int id, boolean addCubemap, Type constType) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+ fb.setShaderConst(constType);
+ fb.setShader(mRes, id);
+ fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
+ if (addCubemap) {
+ fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection");
+ }
+ FragmentShader pf = fb.create();
+ pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+ if (addCubemap) {
+ pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
+ }
+ return pf;
+ }
+
+ private void initPaintShaders() {
+ ScriptField_ModelParams objConst = new ScriptField_ModelParams(mRS, 1);
+ ScriptField_ViewProjParams shaderConst = new ScriptField_ViewProjParams(mRS, 1);
+
+ VertexShader.Builder vb = new VertexShader.Builder(mRS);
+ vb.addInput(ScriptField_VertexShaderInputs.createElement(mRS));
+ vb.setShader(mRes, R.raw.shader2v);
+ vb.setObjectConst(objConst.getAllocation().getType());
+ vb.setShaderConst(shaderConst.getAllocation().getType());
+ mGenericV = vb.create();
+
+ ScriptField_CameraParams fsConst = new ScriptField_CameraParams(mRS, 1);
+ ScriptField_LightParams fsConst2 = new ScriptField_LightParams(mRS, 1);
+
+ mPaintF = createFromResource(R.raw.paintf, true, fsConst.getAllocation().getType());
+ // Assign a reflection map
+ TextureCube envCube = new TextureCube("sdcard/scenegraph/", "cube_env.png");
+ mPaintF.appendSourceParams(new TextureParam("reflection", envCube));
+
+ mAluminumF = createFromResource(R.raw.metal, true, fsConst.getAllocation().getType());
+ TextureCube diffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png");
+ mAluminumF.appendSourceParams(new TextureParam("reflection", diffCube));
+
+ mPlasticF = createFromResource(R.raw.plastic, false, fsConst.getAllocation().getType());
+ mDiffuseF = createFromResource(R.raw.diffuse, false, fsConst.getAllocation().getType());
+ mTextureF = createFromResource(R.raw.texture, false, fsConst.getAllocation().getType());
+
+ FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+ fb.setObjectConst(fsConst2.getAllocation().getType());
+ fb.setShader(mRes, R.raw.plastic_lights);
+ mLightsF = fb.create();
+
+ FullscreenBlur.initShaders(mRes, mRS);
+ }
+
+ void initRenderPasses() {
+ ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables();
+ int numDraw = allDraw.size();
+
+ if (mUseBlur) {
+ FullscreenBlur.addBlurPasses(mActiveScene, mRS);
+ }
+
+ RenderPass mainPass = new RenderPass();
+ mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ mainPass.setShouldClearColor(true);
+ mainPass.setClearDepth(1.0f);
+ mainPass.setShouldClearDepth(true);
+ mainPass.setCamera(mActiveScene.getCameras().get(1));
+ for (int i = 0; i < numDraw; i ++) {
+ mainPass.appendRenderable((Renderable)allDraw.get(i));
+ }
+ mActiveScene.appendRenderPass(mainPass);
+
+ if (mUseBlur) {
+ FullscreenBlur.addCompositePass(mActiveScene, mRS);
+ }
+ }
+
+ private void addShadersToScene() {
+ mActiveScene.appendShader(mPaintF);
+ mActiveScene.appendShader(mLightsF);
+ mActiveScene.appendShader(mAluminumF);
+ mActiveScene.appendShader(mPlasticF);
+ mActiveScene.appendShader(mDiffuseF);
+ mActiveScene.appendShader(mTextureF);
+ mActiveScene.appendShader(mGenericV);
+ }
+
+ public void prepareToRender(Scene s) {
+ mSceneManager.setActiveScene(s);
+ mActiveScene = s;
+ addShadersToScene();
+ RenderState plastic = new RenderState(mGenericV, mPlasticF, null, null);
+ RenderState diffuse = new RenderState(mGenericV, mDiffuseF, null, null);
+ RenderState paint = new RenderState(mGenericV, mPaintF, null, null);
+ RenderState aluminum = new RenderState(mGenericV, mAluminumF, null, null);
+ RenderState lights = new RenderState(mGenericV, mLightsF, null, null);
+ RenderState glassTransp = new RenderState(mGenericV, mPaintF,
+ ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null);
+
+ initRenderPasses();
+
+ mActiveScene.assignRenderState(plastic);
+
+ mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$");
+
+ mActiveScene.assignRenderStateToMaterial(paint, "^Paint");
+ mActiveScene.assignRenderStateToMaterial(paint, "^Carbon");
+ mActiveScene.assignRenderStateToMaterial(paint, "^Glass");
+ mActiveScene.assignRenderStateToMaterial(paint, "^MainGlass");
+
+ mActiveScene.assignRenderStateToMaterial(aluminum, "^Metal");
+ mActiveScene.assignRenderStateToMaterial(aluminum, "^Brake");
+
+ mActiveScene.assignRenderStateToMaterial(glassTransp, "^GlassLight");
+
+ mActiveScene.assignRenderStateToMaterial(lights, "^LightBlinn");
+
+ Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
+ if (plane != null) {
+ RenderState texState = new RenderState(mGenericV, mTextureF, null, null);
+ plane.setRenderState(texState);
+ plane.setVisible(mRS, !mUseBlur);
+ }
+
+ mTouchHandler.init(mActiveScene);
+
+ long start = System.currentTimeMillis();
+ mActiveScene.initRS(mRS, mRes, mSceneManager);
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Scene init time: " + (end - start));
+
+ mLoadingScreen.showLoadingScreen(false);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java
new file mode 100644
index 0000000..687f35b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+
+public class TestAppView extends RSSurfaceView {
+
+ public TestAppView(Context context) {
+ super(context);
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ }
+
+ private RenderScriptGL mRS;
+ TestAppRS mRender;
+
+ private ScaleGestureDetector mScaleDetector;
+ private static final int INVALID_POINTER_ID = -1;
+ private int mActivePointerId = INVALID_POINTER_ID;
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ if (mRS == null) {
+ RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+ sc.setDepth(16, 24);
+ mRS = createRenderScriptGL(sc);
+ mRS.setSurface(holder, w, h);
+ mRender = new TestAppRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mRS != null) {
+ mRender = null;
+ mRS = null;
+ destroyRenderScriptGL();
+ }
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ // break point at here
+ // this method doesn't work when 'extends View' include 'extends ScrollView'.
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ mScaleDetector.onTouchEvent(ev);
+
+ boolean ret = false;
+ float x = ev.getX();
+ float y = ev.getY();
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(0);
+ ret = true;
+ break;
+ }
+ case MotionEvent.ACTION_MOVE: {
+ if (!mScaleDetector.isInProgress()) {
+ mRender.onActionMove(x, y);
+ }
+ mRender.onActionDown(x, y);
+ ret = true;
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ x = ev.getX(newPointerIndex);
+ y = ev.getY(newPointerIndex);
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ }
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ mRender.onActionScale(detector.getScaleFactor());
+ return true;
+ }
+ }
+}
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
new file mode 100644
index 0000000..5dcc9f8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testapp;
+
+import android.util.Log;
+import android.renderscript.Float3;
+import com.android.scenegraph.*;
+import com.android.scenegraph.CompoundTransform.RotateComponent;
+import com.android.scenegraph.CompoundTransform.TranslateComponent;
+
+public class TouchHandler {
+ private static String TAG = "TouchHandler";
+
+ float mLastX;
+ float mLastY;
+
+ RotateComponent mRotateX;
+ float mRotateXValue;
+ RotateComponent mRotateY;
+ float mRotateYValue;
+ TranslateComponent mDist;
+ Float3 mDistValue;
+
+ public void init(Scene scene) {
+ CompoundTransform cameraRotate = (CompoundTransform)scene.getTransformByName("CameraAim");
+ CompoundTransform cameraDist = (CompoundTransform)scene.getTransformByName("CameraDist");
+
+ if (cameraRotate != null && cameraDist != null) {
+ mRotateX = (RotateComponent)cameraRotate.mTransformComponents.get(2);
+ mRotateXValue = mRotateX.getAngle();
+ mRotateY = (RotateComponent)cameraRotate.mTransformComponents.get(1);
+ mRotateYValue = mRotateY.getAngle();
+ mDist = (TranslateComponent)cameraDist.mTransformComponents.get(0);
+ mDistValue = mDist.getValue();
+ }
+ }
+
+ public void onActionDown(float x, float y) {
+ mLastX = x;
+ mLastY = y;
+ }
+
+ public void onActionScale(float scale) {
+ if (mDist == null) {
+ return;
+ }
+ mDistValue.z *= 1.0f / scale;
+ mDistValue.z = Math.max(20.0f, Math.min(mDistValue.z, 100.0f));
+ mDist.setValue(mDistValue);
+ }
+
+ public void onActionMove(float x, float y) {
+ if (mRotateX == 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;
+ }
+
+ mRotateYValue += dx * 0.25f;
+ mRotateYValue %= 360.0f;
+
+ mRotateXValue += dy * 0.25f;
+ mRotateXValue = Math.max(mRotateXValue , -80.0f);
+ mRotateXValue = Math.min(mRotateXValue , 0.0f);
+
+ mRotateX.setAngle(mRotateXValue);
+ mRotateY.setAngle(mRotateYValue);
+
+ mLastX = x;
+ mLastY = y;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
new file mode 100644
index 0000000..e4dcc39
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
@@ -0,0 +1,98 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.testapp)
+
+#include "rs_graphics.rsh"
+#include "test_app.rsh"
+
+// Making sure these get reflected
+FBlurOffsets *blurExport;
+VShaderInputs *iExport;
+FShaderParams *fConst;
+FShaderLightParams *fConts2;
+VSParams *vConst2;
+VObjectParams *vConst3;
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gRobotTex;
+rs_mesh gRobotMesh;
+
+rs_program_store gPFSBackground;
+
+rs_allocation gDummyAlloc;
+rs_script gRenderLoop;
+
+bool gInitialized = false;
+
+float gRotate;
+
+void init() {
+ gRotate = 0.0f;
+}
+
+static int pos = 50;
+static float gRotateY = 120.0f;
+static float3 gLookAt = 0;
+static float gZoom = 50.0f;
+static void displayLoading() {
+ if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) {
+ rsgBindProgramVertex(gPVBackground);
+ rs_matrix4x4 proj;
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+
+ rsgBindProgramFragment(gPFBackground);
+ rsgBindProgramStore(gPFSBackground);
+ rsgBindTexture(gPFBackground, 0, gRobotTex);
+
+ rs_matrix4x4 matrix;
+ rsMatrixLoadIdentity(&matrix);
+ // Position our models on the screen
+ gRotateY += rsGetDt()*100;
+ rsMatrixTranslate(&matrix, 0, 0, -gZoom);
+ rsMatrixRotate(&matrix, 20.0f, 1.0f, 0.0f, 0.0f);
+ rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
+ rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+ rsgDrawMesh(gRobotMesh);
+ }
+
+ uint width = rsgGetWidth();
+ uint height = rsgGetHeight();
+ int left = 0, right = 0, top = 0, bottom = 0;
+ const char* text = "Initializing...";
+ rsgMeasureText(text, &left, &right, &top, &bottom);
+ int centeredPos = width / 2 - (right - left) / 2;
+ rsgDrawText(text, centeredPos, height / 2 + height / 10);
+}
+
+int root(void) {
+ rs_allocation nullAlloc;
+ if (!gInitialized) {
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+ displayLoading();
+ return 30;
+ }
+
+ rsForEach(gRenderLoop, gDummyAlloc, nullAlloc);
+
+ return 10;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh
new file mode 100644
index 0000000..5fbcbb2
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh
@@ -0,0 +1,52 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.testapp)
+
+// Helpers
+typedef struct ViewProjParams {
+ rs_matrix4x4 viewProj;
+} VSParams;
+
+typedef struct ModelParams {
+ rs_matrix4x4 model;
+} VObjectParams;
+
+typedef struct CameraParams {
+ float4 cameraPos;
+} FShaderParams;
+
+typedef struct LightParams {
+ float4 lightPos_0;
+ float4 lightColor_0;
+ float4 lightPos_1;
+ float4 lightColor_1;
+ float4 cameraPos;
+ float4 diffuse;
+} FShaderLightParams;
+
+typedef struct BlurOffsets {
+ float blurOffset0;
+ float blurOffset1;
+ float blurOffset2;
+ float blurOffset3;
+} FBlurOffsets;
+
+typedef struct VertexShaderInputs {
+ float4 position;
+ float3 normal;
+ float2 texture0;
+} VShaderInputs;