Sample scene graph
Change-Id: I65b210b770121ac02c5857b48d2ec0d053133dd6
This commit is contained in:
26
tests/RenderScriptTests/SceneGraph/Android.mk
Normal file
26
tests/RenderScriptTests/SceneGraph/Android.mk
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := SceneGraphTest
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
22
tests/RenderScriptTests/SceneGraph/AndroidManifest.xml
Normal file
22
tests/RenderScriptTests/SceneGraph/AndroidManifest.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.scenegraph">
|
||||
<uses-permission
|
||||
android:name="android.permission.INTERNET" />
|
||||
<application android:label="SceneGraphTest">
|
||||
<activity android:name="SceneGraph"
|
||||
android:label="SceneGraphTest">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="FileSelector"
|
||||
android:label="FileSelector"
|
||||
android:hardwareAccelerated="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
BIN
tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
Normal file
BIN
tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
25
tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml
Normal file
25
tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/load_model"
|
||||
android:title="@string/load_model" />
|
||||
<item android:id="@+id/use_blur"
|
||||
android:title="@string/use_blur" />
|
||||
</menu>
|
||||
15
tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
Normal file
15
tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
Normal file
@@ -0,0 +1,15 @@
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
vec2 blurCoord = varTex0;
|
||||
blurCoord.x = varTex0.x + UNI_blurOffset0;
|
||||
vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.x = varTex0.x + UNI_blurOffset1;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.x = varTex0.x + UNI_blurOffset2;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.x = varTex0.x + UNI_blurOffset3;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
|
||||
gl_FragColor = vec4(col * 0.25, 0.0); //texture2D(UNI_Tex0, varTex0);
|
||||
}
|
||||
17
tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
Normal file
17
tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
Normal file
@@ -0,0 +1,17 @@
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
vec2 blurCoord = varTex0;
|
||||
blurCoord.y = varTex0.y + UNI_blurOffset0;
|
||||
vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.y = varTex0.y + UNI_blurOffset1;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.y = varTex0.y + UNI_blurOffset2;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
blurCoord.y = varTex0.y + UNI_blurOffset3;
|
||||
col += texture2D(UNI_Tex0, blurCoord).rgb;
|
||||
|
||||
col = col * 0.25;
|
||||
|
||||
gl_FragColor = vec4(col, 0.0); //texture2D(UNI_Tex0, varTex0);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
gl_Position = ATTRIB_position;
|
||||
varTex0 = ATTRIB_texture0;
|
||||
}
|
||||
|
||||
19
tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
Normal file
19
tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
Normal file
@@ -0,0 +1,19 @@
|
||||
varying vec3 varWorldPos;
|
||||
varying vec3 varWorldNormal;
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
|
||||
vec3 worldNorm = (varWorldNormal);
|
||||
|
||||
vec3 light0Vec = V;
|
||||
vec3 light0R = reflect(light0Vec, worldNorm);
|
||||
float light0_Diffuse = dot(worldNorm, light0Vec);
|
||||
|
||||
vec2 t0 = varTex0.xy;
|
||||
lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
|
||||
col.xyz = col.xyz * light0_Diffuse * 1.2;
|
||||
gl_FragColor = col; //vec4(0.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
23
tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
Normal file
23
tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
Normal file
@@ -0,0 +1,23 @@
|
||||
varying vec3 varWorldPos;
|
||||
varying vec3 varWorldNormal;
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
|
||||
vec3 worldNorm = normalize(varWorldNormal);
|
||||
|
||||
vec3 light0Vec = V;
|
||||
vec3 light0R = reflect(light0Vec, worldNorm);
|
||||
float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0);
|
||||
float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
|
||||
float light0_Specular = pow(light0Spec, 15.0) * 0.5;
|
||||
|
||||
vec2 t0 = varTex0.xy;
|
||||
lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
|
||||
col.xyz = col.xyz * (textureCube(UNI_Tex1, worldNorm).rgb * 0.5 + vec3(light0_Diffuse));
|
||||
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
26
tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
Normal file
26
tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
Normal file
@@ -0,0 +1,26 @@
|
||||
varying vec3 varWorldPos;
|
||||
varying vec3 varWorldNormal;
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
|
||||
vec3 worldNorm = normalize(varWorldNormal);
|
||||
|
||||
vec3 light0Vec = V;
|
||||
vec3 light0R = reflect(light0Vec, worldNorm);
|
||||
float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.01, 0.99);
|
||||
float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
|
||||
float light0_Specular = pow(light0Spec, 150.0) * 0.5;
|
||||
|
||||
vec2 t0 = varTex0.xy;
|
||||
lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
|
||||
col.xyz = col.xyz * light0_Diffuse * 1.1;
|
||||
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
|
||||
|
||||
float fresnel = mix(pow(1.0 - light0_Diffuse, 15.0), 1.0, 0.1);
|
||||
col.xyz = mix(col.xyz, textureCube(UNI_Tex1, -light0R).rgb * 2.4, fresnel);
|
||||
col.w = 0.8;
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
22
tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
Normal file
22
tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
Normal file
@@ -0,0 +1,22 @@
|
||||
varying vec3 varWorldPos;
|
||||
varying vec3 varWorldNormal;
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
|
||||
vec3 worldNorm = normalize(varWorldNormal);
|
||||
|
||||
vec3 light0Vec = V;
|
||||
vec3 light0R = reflect(light0Vec, worldNorm);
|
||||
float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0);
|
||||
float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
|
||||
float light0_Specular = pow(light0Spec, 10.0) * 0.5;
|
||||
|
||||
vec2 t0 = varTex0.xy;
|
||||
lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
|
||||
col.xyz = col.xyz * light0_Diffuse * 1.2;
|
||||
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
BIN
tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d
Normal file
BIN
tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d
Normal file
Binary file not shown.
13
tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
Normal file
13
tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
vec3 col = texture2D(UNI_Tex0, varTex0).rgb;
|
||||
|
||||
vec3 desat = vec3(0.299, 0.587, 0.114);
|
||||
float lum = dot(desat, col);
|
||||
float stepVal = step(lum, 0.8);
|
||||
col = mix(col, vec3(0.0), stepVal)*0.8;
|
||||
|
||||
gl_FragColor = vec4(col, 0.0);
|
||||
}
|
||||
|
||||
17
tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl
Normal file
17
tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl
Normal file
@@ -0,0 +1,17 @@
|
||||
varying vec3 varWorldPos;
|
||||
varying vec3 varWorldNormal;
|
||||
varying vec2 varTex0;
|
||||
|
||||
// This is where actual shader code begins
|
||||
void main() {
|
||||
vec4 objPos = ATTRIB_position;
|
||||
vec4 worldPos = UNI_model * objPos;
|
||||
gl_Position = UNI_viewProj * worldPos;
|
||||
|
||||
mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
|
||||
vec3 worldNorm = model3 * ATTRIB_normal;
|
||||
|
||||
varWorldPos = worldPos.xyz;
|
||||
varWorldNormal = worldNorm;
|
||||
varTex0 = ATTRIB_texture0;
|
||||
}
|
||||
7
tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
Normal file
7
tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
Normal file
@@ -0,0 +1,7 @@
|
||||
varying vec2 varTex0;
|
||||
|
||||
void main() {
|
||||
lowp vec4 col = texture2D(UNI_Tex0, varTex0).rgba;
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
24
tests/RenderScriptTests/SceneGraph/res/values/strings.xml
Normal file
24
tests/RenderScriptTests/SceneGraph/res/values/strings.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<skip />
|
||||
<string name="load_model">Load Model</string>
|
||||
<string name="use_blur">Use Blur</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.renderscript.*;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Camera extends SceneGraphBase {
|
||||
|
||||
Transform mTransform;
|
||||
float mFOV;
|
||||
float mNear;
|
||||
float mFar;
|
||||
|
||||
ScriptField_Camera_s mField;
|
||||
|
||||
public Camera() {
|
||||
mFOV = 60.0f;
|
||||
mNear = 0.1f;
|
||||
mFar = 100.0f;
|
||||
}
|
||||
|
||||
public void setTransform(Transform t) {
|
||||
mTransform = t;
|
||||
}
|
||||
public void setFOV(float fov) {
|
||||
mFOV = fov;
|
||||
}
|
||||
|
||||
public void setNear(float n) {
|
||||
mNear = n;
|
||||
}
|
||||
|
||||
public void setFar(float f) {
|
||||
mFar = f;
|
||||
}
|
||||
|
||||
ScriptField_Camera_s getRSData(RenderScriptGL rs) {
|
||||
if (mField != null) {
|
||||
return mField;
|
||||
}
|
||||
|
||||
mField = new ScriptField_Camera_s(rs, 1);
|
||||
ScriptField_Camera_s.Item cam = new ScriptField_Camera_s.Item();
|
||||
cam.horizontalFOV = mFOV;
|
||||
cam.near = mNear;
|
||||
cam.far = mFar;
|
||||
cam.transformMatrix = mTransform.getRSData(rs).getAllocation();
|
||||
cam.name = getStringAsAllocation(rs, getName());
|
||||
mField.set(cam, 0, true);
|
||||
|
||||
return mField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
import com.android.scenegraph.CompoundTransform.TranslateComponent;
|
||||
import com.android.scenegraph.CompoundTransform.RotateComponent;
|
||||
import com.android.scenegraph.CompoundTransform.ScaleComponent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.util.Log;
|
||||
|
||||
public class ColladaParser {
|
||||
static final String TAG = "ColladaParser";
|
||||
Document mDom;
|
||||
|
||||
HashMap<String, LightBase> mLights;
|
||||
HashMap<String, Camera> mCameras;
|
||||
HashMap<String, ArrayList<ShaderParam> > mEffectsParams;
|
||||
HashMap<String, Texture2D> mImages;
|
||||
HashMap<String, Texture2D> mSamplerImageMap;
|
||||
Scene mScene;
|
||||
|
||||
String toString(Float3 v) {
|
||||
String valueStr = v.x + " " + v.y + " " + v.z;
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
String toString(Float4 v) {
|
||||
String valueStr = v.x + " " + v.y + " " + v.z + " " + v.w;
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
public ColladaParser(){
|
||||
mLights = new HashMap<String, LightBase>();
|
||||
mCameras = new HashMap<String, Camera>();
|
||||
mEffectsParams = new HashMap<String, ArrayList<ShaderParam> >();
|
||||
mImages = new HashMap<String, Texture2D>();
|
||||
}
|
||||
|
||||
public void init(InputStream is) {
|
||||
mLights.clear();
|
||||
mCameras.clear();
|
||||
mEffectsParams.clear();
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
mDom = db.parse(is);
|
||||
} catch(ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
} catch(SAXException e) {
|
||||
e.printStackTrace();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", " Parse time: " + (end - start));
|
||||
exportSceneData();
|
||||
}
|
||||
|
||||
Scene getScene() {
|
||||
return mScene;
|
||||
}
|
||||
|
||||
private void exportSceneData(){
|
||||
mScene = new Scene();
|
||||
|
||||
Element docEle = mDom.getDocumentElement();
|
||||
NodeList nl = docEle.getElementsByTagName("light");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element l = (Element)nl.item(i);
|
||||
convertLight(l);
|
||||
}
|
||||
}
|
||||
|
||||
nl = docEle.getElementsByTagName("camera");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element c = (Element)nl.item(i);
|
||||
convertCamera(c);
|
||||
}
|
||||
}
|
||||
|
||||
nl = docEle.getElementsByTagName("image");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element img = (Element)nl.item(i);
|
||||
convertImage(img);
|
||||
}
|
||||
}
|
||||
|
||||
nl = docEle.getElementsByTagName("effect");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element e = (Element)nl.item(i);
|
||||
convertEffects(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Material is just a link to the effect
|
||||
nl = docEle.getElementsByTagName("material");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element m = (Element)nl.item(i);
|
||||
convertMaterials(m);
|
||||
}
|
||||
}
|
||||
|
||||
nl = docEle.getElementsByTagName("visual_scene");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element s = (Element)nl.item(i);
|
||||
getScene(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getDrawable(Element shape, Transform t) {
|
||||
String geoURL = shape.getAttribute("url");
|
||||
//DrawableGroup group = new DrawableGroup();
|
||||
//group.setName(geoURL.substring(1));
|
||||
//mScene.appendDrawable(group);
|
||||
NodeList nl = shape.getElementsByTagName("instance_material");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element materialRef = (Element)nl.item(i);
|
||||
String meshIndexName = materialRef.getAttribute("symbol");
|
||||
String materialName = materialRef.getAttribute("target");
|
||||
|
||||
Drawable d = new Drawable();
|
||||
d.setMesh(geoURL.substring(1), meshIndexName);
|
||||
d.setMaterialName(materialName);
|
||||
d.setName(geoURL.substring(1));
|
||||
|
||||
//Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
|
||||
|
||||
// Append transform and material data here
|
||||
TransformParam modelP = new TransformParam("model");
|
||||
modelP.setTransform(t);
|
||||
d.appendSourceParams(modelP);
|
||||
d.setTransform(t);
|
||||
//Log.v(TAG, "Set source param " + t.getName());
|
||||
|
||||
// Now find all the parameters that exist on the material
|
||||
ArrayList<ShaderParam> materialParams;
|
||||
materialParams = mEffectsParams.get(materialName.substring(1));
|
||||
for (int pI = 0; pI < materialParams.size(); pI ++) {
|
||||
d.appendSourceParams(materialParams.get(pI));
|
||||
//Log.v(TAG, "Set source param i: " + pI + " name " + materialParams.get(pI).getParamName());
|
||||
}
|
||||
mScene.appendDrawable(d);
|
||||
//group.appendChildren(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLight(Element shape, Transform t) {
|
||||
String lightURL = shape.getAttribute("url");
|
||||
// collada uses a uri structure to link things,
|
||||
// but we ignore it for now and do a simple search
|
||||
LightBase light = mLights.get(lightURL.substring(1));
|
||||
if (light != null) {
|
||||
light.setTransform(t);
|
||||
//Log.v(TAG, "Set Light " + light.getName() + " " + t.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCamera(Element shape, Transform t) {
|
||||
String camURL = shape.getAttribute("url");
|
||||
// collada uses a uri structure to link things,
|
||||
// but we ignore it for now and do a simple search
|
||||
Camera cam = mCameras.get(camURL.substring(1));
|
||||
if (cam != null) {
|
||||
cam.setTransform(t);
|
||||
//Log.v(TAG, "Set Camera " + cam.getName() + " " + t.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void getNode(Element node, Transform parent, String indent) {
|
||||
String name = node.getAttribute("name");
|
||||
String id = node.getAttribute("id");
|
||||
CompoundTransform current = new CompoundTransform();
|
||||
current.setName(name);
|
||||
if (parent != null) {
|
||||
parent.appendChild(current);
|
||||
} else {
|
||||
mScene.appendTransform(current);
|
||||
}
|
||||
|
||||
mScene.addToTransformMap(current);
|
||||
|
||||
//Log.v(TAG, indent + "|");
|
||||
//Log.v(TAG, indent + "[" + name + "]");
|
||||
|
||||
Node childNode = node.getFirstChild();
|
||||
while (childNode != null) {
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element field = (Element)childNode;
|
||||
String fieldName = field.getTagName();
|
||||
String description = field.getAttribute("sid");
|
||||
if (fieldName.equals("translate")) {
|
||||
Float3 value = getFloat3(field);
|
||||
current.addComponent(new TranslateComponent(description, value));
|
||||
//Log.v(TAG, indent + " translate " + description + toString(value));
|
||||
} else if (fieldName.equals("rotate")) {
|
||||
Float4 value = getFloat4(field);
|
||||
//Log.v(TAG, indent + " rotate " + description + toString(value));
|
||||
Float3 axis = new Float3(value.x, value.y, value.z);
|
||||
current.addComponent(new RotateComponent(description, axis, value.w));
|
||||
} else if (fieldName.equals("scale")) {
|
||||
Float3 value = getFloat3(field);
|
||||
//Log.v(TAG, indent + " scale " + description + toString(value));
|
||||
current.addComponent(new ScaleComponent(description, value));
|
||||
} else if (fieldName.equals("instance_geometry")) {
|
||||
getDrawable(field, current);
|
||||
} else if (fieldName.equals("instance_light")) {
|
||||
updateLight(field, current);
|
||||
} else if (fieldName.equals("instance_camera")) {
|
||||
updateCamera(field, current);
|
||||
} else if (fieldName.equals("node")) {
|
||||
getNode(field, current, indent + " ");
|
||||
}
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
Texture2D getTexture(String samplerName) {
|
||||
Element sampler = mDom.getElementById(samplerName);
|
||||
if (sampler == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NodeList nl = sampler.getElementsByTagName("source");
|
||||
if (nl != null && nl.getLength() == 1) {
|
||||
Element ref = (Element)nl.item(0);
|
||||
String surfaceName = getString(ref);
|
||||
if (surfaceName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Element surface = mDom.getElementById(surfaceName);
|
||||
if (surface == null) {
|
||||
return null;
|
||||
}
|
||||
nl = surface.getElementsByTagName("init_from");
|
||||
if (nl != null && nl.getLength() == 1) {
|
||||
ref = (Element)nl.item(0);
|
||||
String texName = getString(ref);
|
||||
//Log.v(TAG, "Extracted texture name " + texName);
|
||||
return mImages.get(texName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void extractParams(Element fx, ArrayList<ShaderParam> params) {
|
||||
Node paramNode = fx.getFirstChild();
|
||||
while (paramNode != null) {
|
||||
if (paramNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String name = paramNode.getNodeName();
|
||||
// Now find what type it is
|
||||
Node typeNode = paramNode.getFirstChild();
|
||||
while (typeNode != null && typeNode.getNodeType() != Node.ELEMENT_NODE) {
|
||||
typeNode = typeNode.getNextSibling();
|
||||
}
|
||||
String paramType = typeNode.getNodeName();
|
||||
Element typeElem = (Element)typeNode;
|
||||
ShaderParam sceneParam = null;
|
||||
if (paramType.equals("color")) {
|
||||
Float4Param f4p = new Float4Param(name);
|
||||
Float4 value = getFloat4(typeElem);
|
||||
f4p.setValue(value);
|
||||
sceneParam = f4p;
|
||||
//Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + toString(value));
|
||||
} else if (paramType.equals("float")) {
|
||||
Float4Param f4p = new Float4Param(name);
|
||||
float value = getFloat(typeElem);
|
||||
f4p.setValue(new Float4(value, value, value, value));
|
||||
sceneParam = f4p;
|
||||
//Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + value);
|
||||
} else if (paramType.equals("texture")) {
|
||||
String samplerName = typeElem.getAttribute("texture");
|
||||
Texture2D tex = getTexture(samplerName);
|
||||
TextureParam texP = new TextureParam(name);
|
||||
texP.setTexture(tex);
|
||||
sceneParam = texP;
|
||||
//Log.v(TAG, "Extracted texture " + tex);
|
||||
}
|
||||
if (sceneParam != null) {
|
||||
params.add(sceneParam);
|
||||
}
|
||||
}
|
||||
paramNode = paramNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
private void convertMaterials(Element mat) {
|
||||
String id = mat.getAttribute("id");
|
||||
NodeList nl = mat.getElementsByTagName("instance_effect");
|
||||
if (nl != null && nl.getLength() == 1) {
|
||||
Element ref = (Element)nl.item(0);
|
||||
String url = ref.getAttribute("url");
|
||||
ArrayList<ShaderParam> params = mEffectsParams.get(url.substring(1));
|
||||
mEffectsParams.put(id, params);
|
||||
}
|
||||
}
|
||||
|
||||
private void convertEffects(Element fx) {
|
||||
String id = fx.getAttribute("id");
|
||||
ArrayList<ShaderParam> params = new ArrayList<ShaderParam>();
|
||||
|
||||
NodeList nl = fx.getElementsByTagName("newparam");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element field = (Element)nl.item(i);
|
||||
field.setIdAttribute("sid", true);
|
||||
}
|
||||
}
|
||||
|
||||
nl = fx.getElementsByTagName("blinn");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element field = (Element)nl.item(i);
|
||||
//Log.v(TAG, "blinn");
|
||||
extractParams(field, params);
|
||||
}
|
||||
}
|
||||
nl = fx.getElementsByTagName("lambert");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element field = (Element)nl.item(i);
|
||||
//Log.v(TAG, "lambert");
|
||||
extractParams(field, params);
|
||||
}
|
||||
}
|
||||
nl = fx.getElementsByTagName("phong");
|
||||
if (nl != null) {
|
||||
for(int i = 0; i < nl.getLength(); i++) {
|
||||
Element field = (Element)nl.item(i);
|
||||
//Log.v(TAG, "phong");
|
||||
extractParams(field, params);
|
||||
}
|
||||
}
|
||||
mEffectsParams.put(id, params);
|
||||
}
|
||||
|
||||
private void convertLight(Element light) {
|
||||
String name = light.getAttribute("name");
|
||||
String id = light.getAttribute("id");
|
||||
|
||||
// Determine type
|
||||
String[] knownTypes = { "point", "spot", "directional" };
|
||||
final int POINT_LIGHT = 0;
|
||||
final int SPOT_LIGHT = 1;
|
||||
final int DIR_LIGHT = 2;
|
||||
int type = -1;
|
||||
for (int i = 0; i < knownTypes.length; i ++) {
|
||||
NodeList nl = light.getElementsByTagName(knownTypes[i]);
|
||||
if (nl != null && nl.getLength() != 0) {
|
||||
type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Log.v(TAG, "Found Light Type " + type);
|
||||
|
||||
LightBase sceneLight = null;
|
||||
switch (type) {
|
||||
case POINT_LIGHT:
|
||||
sceneLight = new PointLight();
|
||||
break;
|
||||
case SPOT_LIGHT: // TODO: finish light types
|
||||
break;
|
||||
case DIR_LIGHT: // TODO: finish light types
|
||||
break;
|
||||
}
|
||||
|
||||
if (sceneLight == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Float3 color = getFloat3(light, "color");
|
||||
sceneLight.setColor(color);
|
||||
sceneLight.setName(name);
|
||||
mScene.appendLight(sceneLight);
|
||||
mLights.put(id, sceneLight);
|
||||
|
||||
//Log.v(TAG, "Light " + name + " color " + toString(color));
|
||||
}
|
||||
|
||||
private void convertCamera(Element camera) {
|
||||
String name = camera.getAttribute("name");
|
||||
String id = camera.getAttribute("id");
|
||||
float fov = getFloat(camera, "yfov");
|
||||
float near = getFloat(camera, "znear");
|
||||
float far = getFloat(camera, "zfar");
|
||||
|
||||
Camera sceneCamera = new Camera();
|
||||
sceneCamera.setFOV(fov);
|
||||
sceneCamera.setNear(near);
|
||||
sceneCamera.setFar(far);
|
||||
sceneCamera.setName(name);
|
||||
mScene.appendCamera(sceneCamera);
|
||||
mCameras.put(id, sceneCamera);
|
||||
}
|
||||
|
||||
private void convertImage(Element img) {
|
||||
String name = img.getAttribute("name");
|
||||
String id = img.getAttribute("id");
|
||||
String file = getString(img, "init_from");
|
||||
|
||||
Texture2D tex = new Texture2D();
|
||||
tex.setFileName(file);
|
||||
mScene.appendTextures(tex);
|
||||
mImages.put(id, tex);
|
||||
}
|
||||
|
||||
private void getScene(Element scene) {
|
||||
String name = scene.getAttribute("name");
|
||||
String id = scene.getAttribute("id");
|
||||
|
||||
Node childNode = scene.getFirstChild();
|
||||
while (childNode != null) {
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String indent = "";
|
||||
getNode((Element)childNode, null, indent);
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(Element elem, String name) {
|
||||
String text = null;
|
||||
NodeList nl = elem.getElementsByTagName(name);
|
||||
if (nl != null) {
|
||||
text = ((Element)nl.item(0)).getFirstChild().getNodeValue();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private String getString(Element elem) {
|
||||
String text = null;
|
||||
text = elem.getFirstChild().getNodeValue();
|
||||
return text;
|
||||
}
|
||||
|
||||
private int getInt(Element elem, String name) {
|
||||
return Integer.parseInt(getString(elem, name));
|
||||
}
|
||||
|
||||
private float getFloat(Element elem, String name) {
|
||||
return Float.parseFloat(getString(elem, name));
|
||||
}
|
||||
|
||||
private float getFloat(Element elem) {
|
||||
return Float.parseFloat(getString(elem));
|
||||
}
|
||||
|
||||
private Float3 parseFloat3(String valueString) {
|
||||
StringTokenizer st = new StringTokenizer(valueString);
|
||||
float x = Float.parseFloat(st.nextToken());
|
||||
float y = Float.parseFloat(st.nextToken());
|
||||
float z = Float.parseFloat(st.nextToken());
|
||||
return new Float3(x, y, z);
|
||||
}
|
||||
|
||||
private Float4 parseFloat4(String valueString) {
|
||||
StringTokenizer st = new StringTokenizer(valueString);
|
||||
float x = Float.parseFloat(st.nextToken());
|
||||
float y = Float.parseFloat(st.nextToken());
|
||||
float z = Float.parseFloat(st.nextToken());
|
||||
float w = Float.parseFloat(st.nextToken());
|
||||
return new Float4(x, y, z, w);
|
||||
}
|
||||
|
||||
private Float3 getFloat3(Element elem, String name) {
|
||||
String valueString = getString(elem, name);
|
||||
return parseFloat3(valueString);
|
||||
}
|
||||
|
||||
private Float4 getFloat4(Element elem, String name) {
|
||||
String valueString = getString(elem, name);
|
||||
return parseFloat4(valueString);
|
||||
}
|
||||
|
||||
private Float3 getFloat3(Element elem) {
|
||||
String valueString = getString(elem);
|
||||
return parseFloat3(valueString);
|
||||
}
|
||||
|
||||
private Float4 getFloat4(Element elem) {
|
||||
String valueString = getString(elem);
|
||||
return parseFloat4(valueString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.renderscript.Element.Builder;
|
||||
import android.renderscript.Font.Style;
|
||||
import android.renderscript.Program.TextureType;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
import android.util.Log;
|
||||
import com.android.scenegraph.SceneManager.SceneLoadedCallback;
|
||||
|
||||
|
||||
public class ColladaScene {
|
||||
|
||||
private String modelName;
|
||||
private static String TAG = "ColladaScene";
|
||||
private final int STATE_LAST_FOCUS = 1;
|
||||
private final boolean mLoadFromSD = true;
|
||||
private static String mSDCardPath = "sdcard/scenegraph/";
|
||||
|
||||
SceneGraphRS mRenderer;
|
||||
SceneLoadedCallback mCallback;
|
||||
|
||||
public ColladaScene(String name, SceneGraphRS renderer) {
|
||||
modelName = name;
|
||||
mRenderer = renderer;
|
||||
}
|
||||
|
||||
public ColladaScene(String name, SceneLoadedCallback cb) {
|
||||
modelName = name;
|
||||
mCallback = cb;
|
||||
}
|
||||
|
||||
public void init(RenderScriptGL rs, Resources res) {
|
||||
mRS = rs;
|
||||
mRes = res;
|
||||
|
||||
new ColladaLoaderTask().execute(modelName + ".dae");
|
||||
}
|
||||
|
||||
private Resources mRes;
|
||||
private RenderScriptGL mRS;
|
||||
Scene mActiveScene;
|
||||
|
||||
private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> {
|
||||
ColladaParser sceneSource;
|
||||
protected Boolean doInBackground(String... names) {
|
||||
long start = System.currentTimeMillis();
|
||||
sceneSource = new ColladaParser();
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (!mLoadFromSD) {
|
||||
is = mRes.getAssets().open(names[0]);
|
||||
} else {
|
||||
File f = new File(mSDCardPath + names[0]);
|
||||
is = new BufferedInputStream(new FileInputStream(f));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not open collada file");
|
||||
return new Boolean(false);
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "Stream load time: " + (end - start));
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
sceneSource.init(is);
|
||||
end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "Collada parse time: " + (end - start));
|
||||
return new Boolean(true);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
mActiveScene = sceneSource.getScene();
|
||||
if (mRenderer != null) {
|
||||
mRenderer.prepareToRender(mActiveScene);
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.mLoadedScene = mActiveScene;
|
||||
mCallback.run();
|
||||
}
|
||||
|
||||
new A3DLoaderTask().execute(modelName + ".a3d");
|
||||
}
|
||||
}
|
||||
|
||||
private class A3DLoaderTask extends AsyncTask<String, Void, Boolean> {
|
||||
protected Boolean doInBackground(String... names) {
|
||||
long start = System.currentTimeMillis();
|
||||
FileA3D model;
|
||||
if (!mLoadFromSD) {
|
||||
model = FileA3D.createFromAsset(mRS, mRes.getAssets(), names[0]);
|
||||
} else {
|
||||
model = FileA3D.createFromFile(mRS, mSDCardPath + names[0]);
|
||||
}
|
||||
int numModels = model.getIndexEntryCount();
|
||||
for (int i = 0; i < numModels; i ++) {
|
||||
FileA3D.IndexEntry entry = model.getIndexEntry(i);
|
||||
if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
|
||||
mActiveScene.meshLoaded(entry.getMesh());
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "A3D load time: " + (end - start));
|
||||
return new Boolean(true);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Float3;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class CompoundTransform extends Transform {
|
||||
|
||||
public static class Component {
|
||||
String mName;
|
||||
int mRsId;
|
||||
public Float4 mValue;
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TranslateComponent extends Component {
|
||||
public TranslateComponent(String name, Float3 translate) {
|
||||
mRsId = RS_ID_TRANSLATE;
|
||||
mName = name;
|
||||
mValue = new Float4(translate.x, translate.y, translate.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RotateComponent extends Component {
|
||||
public RotateComponent(String name, Float3 axis, float angle) {
|
||||
mRsId = RS_ID_ROTATE;
|
||||
mName = name;
|
||||
mValue = new Float4(axis.x, axis.y, axis.z, angle);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScaleComponent extends Component {
|
||||
public ScaleComponent(String name, Float3 scale) {
|
||||
mRsId = RS_ID_SCALE;
|
||||
mName = name;
|
||||
mValue = new Float4(scale.x, scale.y, scale.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Component> mTransformComponents;
|
||||
|
||||
Matrix4f mLocalMatrix;
|
||||
Matrix4f mGlobalMatrix;
|
||||
|
||||
public CompoundTransform() {
|
||||
mTransformComponents = new ArrayList<Component>();
|
||||
}
|
||||
|
||||
public void addComponent(Component c) {
|
||||
mTransformComponents.add(c);
|
||||
}
|
||||
|
||||
public void setComponent(int index, Component c) {
|
||||
mTransformComponents.set(index, c);
|
||||
}
|
||||
|
||||
void initLocalData() {
|
||||
mTransformData = new ScriptField_SgTransform.Item();
|
||||
int numElements = mTransformComponents.size();
|
||||
for (int i = 0; i < numElements; i ++) {
|
||||
Component ith = mTransformComponents.get(i);
|
||||
mTransformData.transforms[i] = ith.mValue;
|
||||
mTransformData.transformTypes[i] = ith.mRsId;
|
||||
mTransformData.transformNames[i] = getStringAsAllocation(mRS, ith.mName);
|
||||
}
|
||||
// "null" terminate the array
|
||||
mTransformData.transformTypes[numElements] = RS_ID_NONE;
|
||||
|
||||
mTransformData.isDirty = 1;
|
||||
mTransformData.children = null;
|
||||
mTransformData.name = getStringAsAllocation(mRS, getName());
|
||||
}
|
||||
|
||||
public void updateRSData() {
|
||||
int numElements = mTransformComponents.size();
|
||||
for (int i = 0; i < numElements; i ++) {
|
||||
Component ith = mTransformComponents.get(i);
|
||||
mTransformData.transforms[i] = ith.mValue;
|
||||
mTransformData.transformTypes[i] = ith.mRsId;
|
||||
mTransformData.transformNames[i] = getStringAsAllocation(mRS, ith.mName);
|
||||
}
|
||||
// "null" terminate the array
|
||||
mTransformData.transformTypes[numElements] = RS_ID_NONE;
|
||||
mTransformData.isDirty = 1;
|
||||
mField.set(mTransformData, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import android.renderscript.Allocation;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.Mesh;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.util.Log;
|
||||
import android.content.res.Resources;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Drawable extends DrawableBase {
|
||||
Allocation mVertexParams;
|
||||
Allocation mFragmentParams;
|
||||
ArrayList<Allocation> mFragmentTextures;
|
||||
ArrayList<ShaderParam> mVertexParam;
|
||||
ArrayList<ShaderParam> mFragmentParam;
|
||||
ArrayList<ShaderParam> mSourceParams;
|
||||
Mesh mMesh;
|
||||
int mMeshIndex;
|
||||
|
||||
int mCullType;
|
||||
|
||||
RenderState mRenderState;
|
||||
|
||||
Transform mTransform;
|
||||
|
||||
String mMeshName;
|
||||
String mMeshIndexName;
|
||||
|
||||
public String mMaterialName;
|
||||
|
||||
// quick hack to prototype
|
||||
int sceneIndex;
|
||||
|
||||
ScriptField_Drawable_s mRsField;
|
||||
ScriptField_Drawable_s.Item mRsFieldItem;
|
||||
|
||||
public Drawable() {
|
||||
mSourceParams = new ArrayList<ShaderParam>();
|
||||
}
|
||||
|
||||
public void setCullType(int cull) {
|
||||
mCullType = cull;
|
||||
}
|
||||
|
||||
public void setRenderState(RenderState renderState) {
|
||||
mRenderState = renderState;
|
||||
}
|
||||
|
||||
public void setMesh(Mesh mesh) {
|
||||
mMesh = mesh;
|
||||
}
|
||||
|
||||
public void setMesh(String mesh, String indexName) {
|
||||
mMeshName = mesh;
|
||||
mMeshIndexName = indexName;
|
||||
}
|
||||
|
||||
public void setMaterialName(String name) {
|
||||
mMaterialName = name;
|
||||
}
|
||||
|
||||
public void setTransform(Transform t) {
|
||||
mTransform = t;
|
||||
}
|
||||
|
||||
public void appendSourceParams(ShaderParam p) {
|
||||
mSourceParams.add(p);
|
||||
}
|
||||
|
||||
public void resolveMeshData(Mesh mMesh) {
|
||||
mMesh = mMesh;
|
||||
if (mMesh == null) {
|
||||
Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName);
|
||||
return;
|
||||
}
|
||||
int subIndexCount = mMesh.getPrimitiveCount();
|
||||
if (subIndexCount == 1 || mMeshIndexName == null) {
|
||||
mMeshIndex = 0;
|
||||
} else {
|
||||
for (int i = 0; i < subIndexCount; i ++) {
|
||||
if (mMesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) {
|
||||
mMeshIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mRsFieldItem.mesh = mMesh;
|
||||
mRsFieldItem.meshIndex = mMeshIndex;
|
||||
|
||||
mRsField.set(mRsFieldItem, 0, true);
|
||||
}
|
||||
|
||||
void updateTextures(RenderScriptGL rs, Resources res) {
|
||||
for (int i = 0; i < mSourceParams.size(); i ++) {
|
||||
ShaderParam sp = mSourceParams.get(i);
|
||||
if (sp instanceof TextureParam) {
|
||||
TextureParam p = (TextureParam)sp;
|
||||
mRsFieldItem.pf_textures[0] = p.getTexture().getRsData(rs, res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mRsField.set(mRsFieldItem, 0, true);
|
||||
}
|
||||
|
||||
void updateTextures(RenderScriptGL rs, Allocation a, int slot) {
|
||||
getRsFieldItem(rs, null);
|
||||
mRsFieldItem.pf_textures[slot] = a;
|
||||
}
|
||||
|
||||
void setVisible(RenderScriptGL rs, boolean vis) {
|
||||
getRsField(rs, null);
|
||||
mRsFieldItem.cullType = vis ? 0 : 2;
|
||||
mRsField.set(mRsFieldItem, 0, true);
|
||||
}
|
||||
|
||||
ScriptField_Drawable_s getRsField(RenderScriptGL rs, Resources res) {
|
||||
if (mRsField != null) {
|
||||
return mRsField;
|
||||
}
|
||||
getRsFieldItem(rs, res);
|
||||
|
||||
mRsField = new ScriptField_Drawable_s(rs, 1);
|
||||
mRsField.set(mRsFieldItem, 0, true);
|
||||
|
||||
return mRsField;
|
||||
}
|
||||
|
||||
void getRsFieldItem(RenderScriptGL rs, Resources res) {
|
||||
if (mRsFieldItem != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRsFieldItem = new ScriptField_Drawable_s.Item();
|
||||
mRsFieldItem.mesh = mMesh;
|
||||
mRsFieldItem.meshIndex = mMeshIndex;
|
||||
mRsFieldItem.pv_const = mVertexParams;
|
||||
mRsFieldItem.pf_const = mFragmentParams;
|
||||
if (mTransform != null) {
|
||||
mRsFieldItem.transformMatrix = mTransform.getRSData(rs).getAllocation();
|
||||
}
|
||||
mRsFieldItem.name = getStringAsAllocation(rs, getName());
|
||||
mRsFieldItem.render_state = mRenderState.getRSData(rs).getAllocation();
|
||||
mRsFieldItem.bVolInitialized = 0;
|
||||
mRsFieldItem.cullType = mCullType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class DrawableBase extends SceneGraphBase {
|
||||
public DrawableBase() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class DrawableGroup extends DrawableBase {
|
||||
|
||||
ArrayList<DrawableBase> mChildren;
|
||||
|
||||
public DrawableGroup() {
|
||||
mChildren = new ArrayList<DrawableBase>();
|
||||
}
|
||||
|
||||
public void appendChildren(DrawableBase d) {
|
||||
mChildren.add(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* A list view where the last item the user clicked is placed in
|
||||
* the "activated" state, causing its background to highlight.
|
||||
*/
|
||||
public class FileSelector extends ListActivity {
|
||||
|
||||
File[] mCurrentSubList;
|
||||
File mCurrentFile;
|
||||
|
||||
class DAEFilter implements FileFilter {
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
return file.getName().endsWith(".dae");
|
||||
}
|
||||
}
|
||||
|
||||
private void populateList(File file) {
|
||||
|
||||
mCurrentFile = file;
|
||||
setTitle(mCurrentFile.getAbsolutePath() + "/*.dae");
|
||||
List<String> names = new ArrayList<String>();
|
||||
names.add("..");
|
||||
|
||||
mCurrentSubList = mCurrentFile.listFiles(new DAEFilter());
|
||||
|
||||
if (mCurrentSubList != null) {
|
||||
for (int i = 0; i < mCurrentSubList.length; i ++) {
|
||||
String fileName = mCurrentSubList[i].getName();
|
||||
if (mCurrentSubList[i].isDirectory()) {
|
||||
fileName = "/" + fileName;
|
||||
}
|
||||
names.add(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
// Use the built-in layout for showing a list item with a single
|
||||
// line of text whose background is changes when activated.
|
||||
setListAdapter(new ArrayAdapter<String>(this,
|
||||
android.R.layout.simple_list_item_activated_1, names));
|
||||
getListView().setTextFilterEnabled(true);
|
||||
|
||||
// Tell the list view to show one checked/activated item at a time.
|
||||
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
populateList(new File("/sdcard/"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (position == 0) {
|
||||
File parent = mCurrentFile.getParentFile();
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
populateList(parent);
|
||||
return;
|
||||
}
|
||||
|
||||
// the first thing in list is parent directory
|
||||
File selectedFile = mCurrentSubList[position - 1];
|
||||
if (selectedFile.isDirectory()) {
|
||||
populateList(selectedFile);
|
||||
return;
|
||||
}
|
||||
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.setData(Uri.fromFile(selectedFile));
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.graphics.Camera;
|
||||
import android.renderscript.Float4;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.Element;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Float4Param extends ShaderParam {
|
||||
|
||||
public static final int VALUE = 0;
|
||||
public static final int CAMERA_POSITION = 1;
|
||||
public static final int CAMERA_DIRECTION = 2;
|
||||
public static final int LIGHT_POSITION = 3;
|
||||
public static final int LIGHT_COLOR = 4;
|
||||
public static final int LIGHT_DIRECTION = 5;
|
||||
Float4 mValue;
|
||||
Camera mCamera;
|
||||
LightBase mLight;
|
||||
|
||||
public Float4Param(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void setValue(Float4 v) {
|
||||
mValue = v;
|
||||
}
|
||||
|
||||
public Float4 getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public void setCamera(Camera c) {
|
||||
mCamera = c;
|
||||
}
|
||||
|
||||
public void setLight(LightBase l) {
|
||||
mLight = l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Float3;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class LightBase extends SceneGraphBase {
|
||||
Transform mTransform;
|
||||
Float3 mColor;
|
||||
float mIntensity;
|
||||
public LightBase() {
|
||||
mColor = new Float3(0.0f, 0.0f, 0.0f);
|
||||
mIntensity = 1.0f;
|
||||
}
|
||||
|
||||
public void setTransform(Transform t) {
|
||||
mTransform = t;
|
||||
}
|
||||
|
||||
public void setColor(Float3 c) {
|
||||
mColor = c;
|
||||
}
|
||||
|
||||
public void setIntensity(float i) {
|
||||
mIntensity = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class MatrixTransform extends Transform {
|
||||
|
||||
Matrix4f mLocalMatrix;
|
||||
public MatrixTransform() {
|
||||
mLocalMatrix = new Matrix4f();
|
||||
}
|
||||
|
||||
public void setMatrix(Matrix4f matrix) {
|
||||
mLocalMatrix = matrix;
|
||||
}
|
||||
|
||||
void initLocalData() {
|
||||
mTransformData = new ScriptField_SgTransform.Item();
|
||||
// "null" terminate the array
|
||||
mTransformData.transformTypes[0] = RS_ID_NONE;
|
||||
mTransformData.localMat = mLocalMatrix;
|
||||
|
||||
mTransformData.isDirty = 1;
|
||||
mTransformData.children = null;
|
||||
mTransformData.name = getStringAsAllocation(mRS, getName());
|
||||
}
|
||||
|
||||
public void updateRSData() {
|
||||
mTransformData.localMat = mLocalMatrix;
|
||||
mTransformData.isDirty = 1;
|
||||
mField.set(mTransformData, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class PointLight extends LightBase {
|
||||
public PointLight() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class RenderPass extends SceneGraphBase {
|
||||
|
||||
Allocation mColorTarget;
|
||||
Float4 mClearColor;
|
||||
boolean mShouldClearColor;
|
||||
|
||||
Allocation mDepthTarget;
|
||||
float mClearDepth;
|
||||
boolean mShouldClearDepth;
|
||||
|
||||
ArrayList<DrawableBase> mObjectsToDraw;
|
||||
|
||||
Camera mCamera;
|
||||
|
||||
ScriptField_RenderPass_s.Item mRsField;
|
||||
|
||||
public RenderPass() {
|
||||
mObjectsToDraw = new ArrayList<DrawableBase>();
|
||||
mClearColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
mShouldClearColor = true;
|
||||
mClearDepth = 1.0f;
|
||||
mShouldClearDepth = true;
|
||||
}
|
||||
|
||||
public void appendDrawable(Drawable d) {
|
||||
mObjectsToDraw.add(d);
|
||||
}
|
||||
|
||||
public void setCamera(Camera c) {
|
||||
mCamera = c;
|
||||
}
|
||||
|
||||
public void setColorTarget(Allocation colorTarget) {
|
||||
mColorTarget = colorTarget;
|
||||
}
|
||||
public void setClearColor(Float4 clearColor) {
|
||||
mClearColor = clearColor;
|
||||
}
|
||||
public void setShouldClearColor(boolean shouldClearColor) {
|
||||
mShouldClearColor = shouldClearColor;
|
||||
}
|
||||
|
||||
public void setDepthTarget(Allocation depthTarget) {
|
||||
mDepthTarget = depthTarget;
|
||||
}
|
||||
public void setClearDepth(float clearDepth) {
|
||||
mClearDepth = clearDepth;
|
||||
}
|
||||
public void setShouldClearDepth(boolean shouldClearDepth) {
|
||||
mShouldClearDepth = shouldClearDepth;
|
||||
}
|
||||
|
||||
ScriptField_RenderPass_s.Item getRsField(RenderScriptGL rs, Resources res) {
|
||||
if (mRsField != null) {
|
||||
return mRsField;
|
||||
}
|
||||
|
||||
mRsField = new ScriptField_RenderPass_s.Item();
|
||||
mRsField.color_target = mColorTarget;
|
||||
mRsField.depth_target = mDepthTarget;
|
||||
mRsField.camera = mCamera != null ? mCamera.getRSData(rs).getAllocation() : null;
|
||||
|
||||
if (mObjectsToDraw.size() != 0) {
|
||||
Allocation drawableData = Allocation.createSized(rs,
|
||||
Element.ALLOCATION(rs),
|
||||
mObjectsToDraw.size());
|
||||
Allocation[] drawableAllocs = new Allocation[mObjectsToDraw.size()];
|
||||
for (int i = 0; i < mObjectsToDraw.size(); i ++) {
|
||||
Drawable dI = (Drawable)mObjectsToDraw.get(i);
|
||||
drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
|
||||
}
|
||||
drawableData.copyFrom(drawableAllocs);
|
||||
mRsField.objects = drawableData;
|
||||
}
|
||||
|
||||
mRsField.clear_color = mClearColor;
|
||||
mRsField.clear_depth = mClearDepth;
|
||||
mRsField.should_clear_color = mShouldClearColor;
|
||||
mRsField.should_clear_depth = mShouldClearDepth;
|
||||
return mRsField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Allocation;
|
||||
import android.renderscript.Element;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramRaster;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.RSRuntimeException;
|
||||
import android.renderscript.RenderScript;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class RenderState extends SceneGraphBase {
|
||||
ProgramVertex mVertex;
|
||||
ProgramFragment mFragment;
|
||||
ProgramStore mStore;
|
||||
ProgramRaster mRaster;
|
||||
|
||||
ScriptField_RenderState_s mField;
|
||||
|
||||
public RenderState(ProgramVertex pv,
|
||||
ProgramFragment pf,
|
||||
ProgramStore ps,
|
||||
ProgramRaster pr) {
|
||||
mVertex = pv;
|
||||
mFragment = pf;
|
||||
mStore = ps;
|
||||
mRaster = pr;
|
||||
}
|
||||
|
||||
public RenderState(RenderState r) {
|
||||
mVertex = r.mVertex;
|
||||
mFragment = r.mFragment;
|
||||
mStore = r.mStore;
|
||||
mRaster = r.mRaster;
|
||||
}
|
||||
|
||||
public void setProgramVertex(ProgramVertex pv) {
|
||||
mVertex = pv;
|
||||
}
|
||||
|
||||
public void setProgramFragment(ProgramFragment pf) {
|
||||
mFragment = pf;
|
||||
}
|
||||
|
||||
public void setProgramStore(ProgramStore ps) {
|
||||
mStore = ps;
|
||||
}
|
||||
|
||||
public void setProgramRaster(ProgramRaster pr) {
|
||||
mRaster = pr;
|
||||
}
|
||||
|
||||
public ScriptField_RenderState_s getRSData(RenderScriptGL rs) {
|
||||
if (mField != null) {
|
||||
return mField;
|
||||
}
|
||||
|
||||
ScriptField_RenderState_s.Item item = new ScriptField_RenderState_s.Item();
|
||||
item.pv = mVertex;
|
||||
item.pf = mFragment;
|
||||
item.ps = mStore;
|
||||
item.pr = mRaster;
|
||||
|
||||
mField = new ScriptField_RenderState_s(rs, 1);
|
||||
mField.set(item, 0, true);
|
||||
return mField;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.renderscript.Mesh;
|
||||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Scene extends SceneGraphBase {
|
||||
private static String TIMER_TAG = "TIMER";
|
||||
|
||||
private class ImageLoaderTask extends AsyncTask<String, Void, Boolean> {
|
||||
protected Boolean doInBackground(String... names) {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < mDrawables.size(); i ++) {
|
||||
Drawable dI = (Drawable)mDrawables.get(i);
|
||||
dI.updateTextures(mRS, mRes);
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v(TIMER_TAG, "Texture init time: " + (end - start));
|
||||
return new Boolean(true);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
}
|
||||
}
|
||||
|
||||
CompoundTransform mRootTransforms;
|
||||
HashMap<String, Transform> mTransformMap;
|
||||
ArrayList<RenderPass> mRenderPasses;
|
||||
ArrayList<LightBase> mLights;
|
||||
ArrayList<Camera> mCameras;
|
||||
ArrayList<DrawableBase> mDrawables;
|
||||
HashMap<String, DrawableBase> mDrawableMap;
|
||||
ArrayList<Texture2D> mTextures;
|
||||
|
||||
HashMap<String, ArrayList<Drawable> > mDrawableMeshMap;
|
||||
|
||||
// RS Specific stuff
|
||||
ScriptField_SgTransform mTransformRSData;
|
||||
|
||||
RenderScriptGL mRS;
|
||||
Resources mRes;
|
||||
|
||||
ScriptField_RenderPass_s mRenderPassAlloc;
|
||||
|
||||
public Scene() {
|
||||
mRenderPasses = new ArrayList<RenderPass>();
|
||||
mLights = new ArrayList<LightBase>();
|
||||
mCameras = new ArrayList<Camera>();
|
||||
mDrawables = new ArrayList<DrawableBase>();
|
||||
mDrawableMap = new HashMap<String, DrawableBase>();
|
||||
mDrawableMeshMap = new HashMap<String, ArrayList<Drawable> >();
|
||||
mTextures = new ArrayList<Texture2D>();
|
||||
mRootTransforms = new CompoundTransform();
|
||||
mRootTransforms.setName("_scene_root_");
|
||||
mTransformMap = new HashMap<String, Transform>();
|
||||
}
|
||||
|
||||
public void appendTransform(Transform t) {
|
||||
mRootTransforms.appendChild(t);
|
||||
}
|
||||
|
||||
// temporary
|
||||
public void addToTransformMap(Transform t) {
|
||||
mTransformMap.put(t.getName(), t);
|
||||
}
|
||||
|
||||
public Transform getTransformByName(String name) {
|
||||
return mTransformMap.get(name);
|
||||
}
|
||||
|
||||
public void appendRenderPass(RenderPass p) {
|
||||
mRenderPasses.add(p);
|
||||
}
|
||||
|
||||
public void clearRenderPasses() {
|
||||
mRenderPasses.clear();
|
||||
}
|
||||
|
||||
public void appendLight(LightBase l) {
|
||||
mLights.add(l);
|
||||
}
|
||||
|
||||
public void appendCamera(Camera c) {
|
||||
mCameras.add(c);
|
||||
}
|
||||
|
||||
public ArrayList<Camera> getCameras() {
|
||||
return mCameras;
|
||||
}
|
||||
|
||||
public void appendDrawable(DrawableBase d) {
|
||||
mDrawables.add(d);
|
||||
mDrawableMap.put(d.getName(), d);
|
||||
}
|
||||
|
||||
public ArrayList<DrawableBase> getDrawables() {
|
||||
return mDrawables;
|
||||
}
|
||||
|
||||
public DrawableBase getDrawableByName(String name) {
|
||||
return mDrawableMap.get(name);
|
||||
}
|
||||
|
||||
public void appendTextures(Texture2D tex) {
|
||||
mTextures.add(tex);
|
||||
}
|
||||
|
||||
public void assignRenderStateToMaterial(RenderState renderState, String regex) {
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
int numDrawables = mDrawables.size();
|
||||
for (int i = 0; i < numDrawables; i ++) {
|
||||
Drawable shape = (Drawable)mDrawables.get(i);
|
||||
Matcher m = pattern.matcher(shape.mMaterialName);
|
||||
if (m.find()) {
|
||||
shape.setRenderState(renderState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void assignRenderState(RenderState renderState) {
|
||||
int numDrawables = mDrawables.size();
|
||||
for (int i = 0; i < numDrawables; i ++) {
|
||||
Drawable shape = (Drawable)mDrawables.get(i);
|
||||
shape.setRenderState(renderState);
|
||||
}
|
||||
}
|
||||
|
||||
public void meshLoaded(Mesh m) {
|
||||
ArrayList<Drawable> entries = mDrawableMeshMap.get(m.getName());
|
||||
int numEntries = entries.size();
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
Drawable d = entries.get(i);
|
||||
d.resolveMeshData(m);
|
||||
//mDrawablesField.set(d.getRsField(mRS, mRes), d.sceneIndex, true);
|
||||
}
|
||||
}
|
||||
|
||||
void addToMeshMap(Drawable d) {
|
||||
ArrayList<Drawable> entries = mDrawableMeshMap.get(d.mMeshName);
|
||||
if (entries == null) {
|
||||
entries = new ArrayList<Drawable>();
|
||||
mDrawableMeshMap.put(d.mMeshName, entries);
|
||||
}
|
||||
entries.add(d);
|
||||
}
|
||||
|
||||
public void destroyRS(SceneManager sceneManager) {
|
||||
mTransformRSData = null;
|
||||
sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
|
||||
sceneManager.mRenderLoop.set_gDrawableObjects(null);
|
||||
mRenderPassAlloc = null;
|
||||
sceneManager.mRenderLoop.set_gRenderPasses(null);
|
||||
sceneManager.mRenderLoop.bind_gFrontToBack(null);
|
||||
sceneManager.mRenderLoop.bind_gBackToFront(null);
|
||||
sceneManager.mRenderLoop.set_gCameras(null);
|
||||
|
||||
mTransformMap = null;
|
||||
mRenderPasses = null;
|
||||
mLights = null;
|
||||
mCameras = null;
|
||||
mDrawables = null;
|
||||
mDrawableMap = null;
|
||||
mTextures = null;
|
||||
mDrawableMeshMap = null;
|
||||
mRootTransforms = null;
|
||||
}
|
||||
|
||||
public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) {
|
||||
if (mRenderPasses.size() != 0) {
|
||||
mRenderPassAlloc = new ScriptField_RenderPass_s(mRS, mRenderPasses.size());
|
||||
for (int i = 0; i < mRenderPasses.size(); i ++) {
|
||||
mRenderPassAlloc.set(mRenderPasses.get(i).getRsField(mRS, mRes), i, false);
|
||||
}
|
||||
mRenderPassAlloc.copyAll();
|
||||
sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation());
|
||||
}
|
||||
}
|
||||
|
||||
public void initRS(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
|
||||
mRS = rs;
|
||||
long start = System.currentTimeMillis();
|
||||
mTransformRSData = mRootTransforms.getRSData(rs);
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v(TIMER_TAG, "Transform init time: " + (end - start));
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
|
||||
sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
|
||||
end = System.currentTimeMillis();
|
||||
Log.v(TIMER_TAG, "Script init time: " + (end - start));
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
Allocation drawableData = Allocation.createSized(rs,
|
||||
Element.ALLOCATION(rs),
|
||||
mDrawables.size());
|
||||
Allocation[] drawableAllocs = new Allocation[mDrawables.size()];
|
||||
for (int i = 0; i < mDrawables.size(); i ++) {
|
||||
Drawable dI = (Drawable)mDrawables.get(i);
|
||||
dI.sceneIndex = i;
|
||||
addToMeshMap(dI);
|
||||
drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
|
||||
}
|
||||
drawableData.copyFrom(drawableAllocs);
|
||||
sceneManager.mRenderLoop.set_gDrawableObjects(drawableData);
|
||||
|
||||
initRenderPassRS(rs, sceneManager);
|
||||
|
||||
new ImageLoaderTask().execute();
|
||||
|
||||
end = System.currentTimeMillis();
|
||||
Log.v(TIMER_TAG, "Drawable init time: " + (end - start));
|
||||
|
||||
Allocation opaqueBuffer = Allocation.createSized(rs, Element.U32(rs), mDrawables.size());
|
||||
Allocation transparentBuffer = Allocation.createSized(rs,
|
||||
Element.U32(rs), mDrawables.size());
|
||||
|
||||
sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer);
|
||||
sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer);
|
||||
|
||||
Allocation cameraData = Allocation.createSized(rs, Element.ALLOCATION(rs), mCameras.size());
|
||||
Allocation[] cameraAllocs = new Allocation[mCameras.size()];
|
||||
for (int i = 0; i < mCameras.size(); i ++) {
|
||||
cameraAllocs[i] = mCameras.get(i).getRSData(rs).getAllocation();
|
||||
}
|
||||
cameraData.copyFrom(cameraAllocs);
|
||||
sceneManager.mRenderLoop.set_gCameras(cameraData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import android.renderscript.RSSurfaceView;
|
||||
import android.renderscript.RenderScript;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.provider.Settings.System;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.Window;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.lang.Runtime;
|
||||
|
||||
public class SceneGraph extends Activity {
|
||||
|
||||
private SceneGraphView mView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
// Create our Preview view and set it as the content of our
|
||||
// Activity
|
||||
mView = new SceneGraphView(this);
|
||||
setContentView(mView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mView.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mView.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.loader_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle item selection
|
||||
switch (item.getItemId()) {
|
||||
case R.id.load_model:
|
||||
loadModel();
|
||||
return true;
|
||||
case R.id.use_blur:
|
||||
mView.mRender.toggleBlur();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int FIND_DAE_MODEL = 10;
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (requestCode == FIND_DAE_MODEL) {
|
||||
Uri selectedImageUri = data.getData();
|
||||
Log.e("Selected Path: ", selectedImageUri.getPath());
|
||||
mView.mRender.loadModel(selectedImageUri.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadModel() {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_PICK);
|
||||
intent.setClassName("com.android.scenegraph",
|
||||
"com.android.scenegraph.FileSelector");
|
||||
startActivityForResult(intent, FIND_DAE_MODEL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Allocation;
|
||||
import android.renderscript.Element;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.RenderScript;
|
||||
import android.renderscript.RSRuntimeException;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public abstract class SceneGraphBase {
|
||||
String mName;
|
||||
public void setName(String n) {
|
||||
mName = n;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
Allocation getStringAsAllocation(RenderScript rs, String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
if (str.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
byte[] allocArray = null;
|
||||
byte[] nullChar = new byte[1];
|
||||
nullChar[0] = 0;
|
||||
try {
|
||||
allocArray = str.getBytes("UTF-8");
|
||||
Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
|
||||
allocArray.length + 1,
|
||||
Allocation.USAGE_SCRIPT);
|
||||
alloc.copy1DRangeFrom(0, allocArray.length, allocArray);
|
||||
alloc.copy1DRangeFrom(allocArray.length, 1, nullChar);
|
||||
return alloc;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RSRuntimeException("Could not convert string to utf-8.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.renderscript.Element.Builder;
|
||||
import android.renderscript.Font.Style;
|
||||
import android.renderscript.Program.TextureType;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.scenegraph.SceneManager.SceneLoadedCallback;
|
||||
|
||||
public class SceneGraphRS {
|
||||
|
||||
private static String modelName = "orientation_test";
|
||||
private static String TAG = "SceneGraphRS";
|
||||
private final int STATE_LAST_FOCUS = 1;
|
||||
private final boolean mLoadFromSD = true;
|
||||
private static String mSDCardPath = "sdcard/scenegraph/";
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
int mRotation;
|
||||
|
||||
boolean mUseBlur;
|
||||
|
||||
SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() {
|
||||
public void run() {
|
||||
prepareToRender(mLoadedScene);
|
||||
}
|
||||
};
|
||||
|
||||
SceneManager mSceneManager;
|
||||
|
||||
TouchHandler mTouchHandler;
|
||||
|
||||
public SceneGraphRS() {
|
||||
mUseBlur = false;
|
||||
}
|
||||
|
||||
void toggleBlur() {
|
||||
mUseBlur = !mUseBlur;
|
||||
|
||||
mActiveScene.clearRenderPasses();
|
||||
initRenderPasses();
|
||||
mActiveScene.initRenderPassRS(mRS, mSceneManager);
|
||||
Drawable plane = (Drawable)mActiveScene.getDrawableByName("pPlaneShape1");
|
||||
if (plane != null) {
|
||||
plane.setVisible(mRS, !mUseBlur);
|
||||
}
|
||||
}
|
||||
|
||||
public void init(RenderScriptGL rs, Resources res, int width, int height) {
|
||||
mRS = rs;
|
||||
mRes = res;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mRotation = 0;
|
||||
|
||||
mTouchHandler = new TouchHandler();
|
||||
|
||||
mSceneManager = new SceneManager();
|
||||
mSceneManager.initRS(mRS, mRes, mWidth, mHeight);
|
||||
|
||||
renderLoading();
|
||||
|
||||
new LoadingScreenLoaderTask().execute();
|
||||
|
||||
initRS();
|
||||
|
||||
mSceneManager.loadModel(modelName, mLoadedCallback);
|
||||
}
|
||||
|
||||
void loadModel(String path) {
|
||||
String shortName = path.substring(path.lastIndexOf('/') + 1);
|
||||
shortName = shortName.substring(0, shortName.lastIndexOf('.'));
|
||||
mScript.set_gInitialized(false);
|
||||
mActiveScene.destroyRS(mSceneManager);
|
||||
mSceneManager.loadModel(shortName, mLoadedCallback);
|
||||
}
|
||||
|
||||
private Resources mRes;
|
||||
private RenderScriptGL mRS;
|
||||
private Sampler mSampler;
|
||||
private ProgramStore mPSBackground;
|
||||
private ProgramFragment mPFBackground;
|
||||
private ProgramVertex mPVBackground;
|
||||
private ProgramVertexFixedFunction.Constants mPVA;
|
||||
|
||||
private ProgramFragment mPF_Paint;
|
||||
private ProgramFragment mPF_Aluminum;
|
||||
private ProgramFragment mPF_Plastic;
|
||||
private ProgramFragment mPF_Diffuse;
|
||||
private ProgramFragment mPF_BlurH;
|
||||
private ProgramFragment mPF_BlurV;
|
||||
private ProgramFragment mPF_SelectColor;
|
||||
private ProgramFragment mPF_Texture;
|
||||
ScriptField_FShaderParams_s mFsConst;
|
||||
ScriptField_FBlurOffsets_s mFsBlurHConst;
|
||||
ScriptField_FBlurOffsets_s mFsBlurVConst;
|
||||
private ProgramVertex mPV_Paint;
|
||||
ScriptField_VShaderParams_s mVsConst;
|
||||
private ProgramVertex mPV_Blur;
|
||||
|
||||
private Allocation mDefaultCube;
|
||||
private Allocation mAllocPV;
|
||||
private Allocation mEnvCube;
|
||||
private Allocation mDiffCube;
|
||||
|
||||
private Allocation mRenderTargetBlur0Color;
|
||||
private Allocation mRenderTargetBlur0Depth;
|
||||
private Allocation mRenderTargetBlur1Color;
|
||||
private Allocation mRenderTargetBlur1Depth;
|
||||
private Allocation mRenderTargetBlur2Color;
|
||||
private Allocation mRenderTargetBlur2Depth;
|
||||
|
||||
Scene mActiveScene;
|
||||
|
||||
private ScriptC_scenegraph mScript;
|
||||
|
||||
private class LoadingScreenLoaderTask extends AsyncTask<String, Void, Boolean> {
|
||||
Allocation robotTex;
|
||||
Mesh robotMesh;
|
||||
protected Boolean doInBackground(String... names) {
|
||||
long start = System.currentTimeMillis();
|
||||
robotTex = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
|
||||
MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
|
||||
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
|
||||
FileA3D.IndexEntry entry = model.getIndexEntry(0);
|
||||
if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
|
||||
robotMesh = entry.getMesh();
|
||||
}
|
||||
|
||||
initPFS();
|
||||
initPF();
|
||||
initPV();
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "Loading load time: " + (end - start));
|
||||
return new Boolean(true);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
mScript.set_gRobotTex(robotTex);
|
||||
mScript.set_gRobotMesh(robotMesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ImageLoaderTask extends AsyncTask<String, Void, Boolean> {
|
||||
Allocation tempEnv;
|
||||
Allocation tempDiff;
|
||||
|
||||
InputStream openStream(String name) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (!mLoadFromSD) {
|
||||
is = mRes.getAssets().open(name);
|
||||
} else {
|
||||
File f = new File(mSDCardPath + name);
|
||||
is = new BufferedInputStream(new FileInputStream(f));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e("PAINTSHADERS", " Message: " + e.getMessage());
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(String... names) {
|
||||
long start = System.currentTimeMillis();
|
||||
InputStream is = openStream("cube_env.png");
|
||||
if (is == null) {
|
||||
return new Boolean(false);
|
||||
}
|
||||
|
||||
Bitmap b = BitmapFactory.decodeStream(is);
|
||||
tempEnv = Allocation.createCubemapFromBitmap(mRS,
|
||||
b,
|
||||
MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
|
||||
is = openStream("cube_spec.png");
|
||||
if (is == null) {
|
||||
return new Boolean(false);
|
||||
}
|
||||
|
||||
b = BitmapFactory.decodeStream(is);
|
||||
tempDiff = Allocation.createCubemapFromBitmap(mRS,
|
||||
b,
|
||||
MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "Image load time: " + (end - start));
|
||||
return new Boolean(true);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
mEnvCube = tempEnv;
|
||||
mDiffCube = tempDiff;
|
||||
|
||||
mPF_Paint.bindTexture(mEnvCube, 1);
|
||||
mPF_Aluminum.bindTexture(mDiffCube, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void onActionDown(float x, float y) {
|
||||
mTouchHandler.onActionDown(x, y);
|
||||
|
||||
//mSceneManager.getRenderLoop().invoke_pick((int)x, (int)y);
|
||||
}
|
||||
|
||||
public void onActionScale(float scale) {
|
||||
mTouchHandler.onActionScale(scale);
|
||||
}
|
||||
|
||||
public void onActionMove(float x, float y) {
|
||||
mTouchHandler.onActionMove(x, y);
|
||||
}
|
||||
|
||||
private void initPaintShaders() {
|
||||
ProgramVertex.Builder vb = new ProgramVertex.Builder(mRS);
|
||||
mVsConst = new ScriptField_VShaderParams_s(mRS, 1);
|
||||
vb.addConstant(mVsConst.getAllocation().getType());
|
||||
vb.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
|
||||
vb.setShader(mRes, R.raw.shader2v);
|
||||
mPV_Paint = vb.create();
|
||||
mPV_Paint.bindConstants(mVsConst.getAllocation(), 0);
|
||||
|
||||
vb = new ProgramVertex.Builder(mRS);
|
||||
vb.addConstant(mVsConst.getAllocation().getType());
|
||||
vb.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
|
||||
vb.setShader(mRes, R.raw.blur_vertex);
|
||||
mPV_Blur = vb.create();
|
||||
mPV_Blur.bindConstants(mVsConst.getAllocation(), 0);
|
||||
|
||||
ProgramFragment.Builder fb = new ProgramFragment.Builder(mRS);
|
||||
mFsConst = new ScriptField_FShaderParams_s(mRS, 1);
|
||||
fb.addConstant(mFsConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.paintf);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
fb.addTexture(TextureType.TEXTURE_CUBE);
|
||||
mPF_Paint = fb.create();
|
||||
|
||||
mPF_Paint.bindConstants(mFsConst.getAllocation(), 0);
|
||||
mPF_Paint.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
|
||||
mPF_Paint.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.metal);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
fb.addTexture(TextureType.TEXTURE_CUBE);
|
||||
mPF_Aluminum = fb.create();
|
||||
|
||||
mPF_Aluminum.bindConstants(mFsConst.getAllocation(), 0);
|
||||
mPF_Aluminum.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
|
||||
mPF_Aluminum.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.plastic);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_Plastic = fb.create();
|
||||
mPF_Plastic.bindConstants(mFsConst.getAllocation(), 0);
|
||||
mPF_Plastic.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.diffuse);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_Diffuse = fb.create();
|
||||
mPF_Diffuse.bindConstants(mFsConst.getAllocation(), 0);
|
||||
mPF_Diffuse.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.texture);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_Texture = fb.create();
|
||||
mPF_Texture.bindConstants(mFsConst.getAllocation(), 0);
|
||||
mPF_Texture.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
|
||||
|
||||
mFsBlurHConst = new ScriptField_FBlurOffsets_s(mRS, 1);
|
||||
float xAdvance = 1.0f / (float)mRenderTargetBlur0Color.getType().getX();
|
||||
ScriptField_FBlurOffsets_s.Item item = new ScriptField_FBlurOffsets_s.Item();
|
||||
item.blurOffset0 = - xAdvance * 2.5f;
|
||||
item.blurOffset1 = - xAdvance * 0.5f;
|
||||
item.blurOffset2 = xAdvance * 1.5f;
|
||||
item.blurOffset3 = xAdvance * 3.5f;
|
||||
mFsBlurHConst.set(item, 0, true);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsBlurHConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.blur_h);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_BlurH = fb.create();
|
||||
mPF_BlurH.bindConstants(mFsBlurHConst.getAllocation(), 0);
|
||||
mPF_BlurH.bindTexture(mRenderTargetBlur0Color, 0);
|
||||
mPF_BlurH.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
|
||||
|
||||
mFsBlurVConst = new ScriptField_FBlurOffsets_s(mRS, 1);
|
||||
float yAdvance = 1.0f / (float)mRenderTargetBlur0Color.getType().getY();
|
||||
item.blurOffset0 = - yAdvance * 2.5f;
|
||||
item.blurOffset1 = - yAdvance * 0.5f;
|
||||
item.blurOffset2 = yAdvance * 1.5f;
|
||||
item.blurOffset3 = yAdvance * 3.5f;
|
||||
mFsBlurVConst.set(item, 0, true);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
fb.addConstant(mFsBlurVConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.blur_v);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_BlurV = fb.create();
|
||||
mPF_BlurV.bindConstants(mFsBlurVConst.getAllocation(), 0);
|
||||
mPF_BlurV.bindTexture(mRenderTargetBlur1Color, 0);
|
||||
mPF_BlurV.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
|
||||
|
||||
fb = new ProgramFragment.Builder(mRS);
|
||||
//fb.addConstant(mFsBlurVConst.getAllocation().getType());
|
||||
fb.setShader(mRes, R.raw.select_color);
|
||||
fb.addTexture(TextureType.TEXTURE_2D);
|
||||
mPF_SelectColor = fb.create();
|
||||
//mPF_SelectColor.bindConstants(mFsBlurVConst.getAllocation(), 0);
|
||||
//mPF_SelectColor.bindTexture(mRenderTargetBlur1Color, 0);
|
||||
mPF_SelectColor.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
|
||||
}
|
||||
|
||||
private void initPFS() {
|
||||
ProgramStore.Builder b = new ProgramStore.Builder(mRS);
|
||||
|
||||
b.setDepthFunc(ProgramStore.DepthFunc.LESS);
|
||||
b.setDitherEnabled(false);
|
||||
b.setDepthMaskEnabled(true);
|
||||
mPSBackground = b.create();
|
||||
|
||||
mScript.set_gPFSBackground(mPSBackground);
|
||||
}
|
||||
|
||||
private void initPF() {
|
||||
Sampler.Builder bs = new Sampler.Builder(mRS);
|
||||
bs.setMinification(Sampler.Value.LINEAR);
|
||||
bs.setMagnification(Sampler.Value.LINEAR);
|
||||
bs.setWrapS(Sampler.Value.CLAMP);
|
||||
bs.setWrapT(Sampler.Value.CLAMP);
|
||||
mSampler = bs.create();
|
||||
|
||||
ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
|
||||
b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
|
||||
ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
|
||||
mPFBackground = b.create();
|
||||
mPFBackground.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
|
||||
|
||||
mScript.set_gPFBackground(mPFBackground);
|
||||
}
|
||||
|
||||
private void initPV() {
|
||||
ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
|
||||
mPVBackground = pvb.create();
|
||||
|
||||
mPVA = new ProgramVertexFixedFunction.Constants(mRS);
|
||||
((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
|
||||
|
||||
mScript.set_gPVBackground(mPVBackground);
|
||||
}
|
||||
|
||||
void renderLoading() {
|
||||
mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph);
|
||||
mRS.bindRootScript(mScript);
|
||||
}
|
||||
|
||||
void initSceneRS() {
|
||||
|
||||
}
|
||||
|
||||
void createRenderTargets() {
|
||||
Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
|
||||
b.setX(mWidth/8).setY(mHeight/8);
|
||||
Type renderType = b.create();
|
||||
mRenderTargetBlur0Color = Allocation.createTyped(mRS, renderType,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE |
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mRenderTargetBlur1Color = Allocation.createTyped(mRS, renderType,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE |
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mRenderTargetBlur2Color = Allocation.createTyped(mRS, renderType,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE |
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
|
||||
b = new Type.Builder(mRS,
|
||||
Element.createPixel(mRS, Element.DataType.UNSIGNED_16,
|
||||
Element.DataKind.PIXEL_DEPTH));
|
||||
b.setX(mWidth/8).setY(mHeight/8);
|
||||
mRenderTargetBlur0Depth = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
|
||||
mRenderTargetBlur1Depth = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mRenderTargetBlur2Depth = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
}
|
||||
|
||||
ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
|
||||
ProgramStore.Builder builder = new ProgramStore.Builder(rs);
|
||||
builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
|
||||
builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
|
||||
builder.setDitherEnabled(false);
|
||||
builder.setDepthMaskEnabled(false);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
Drawable getDrawableQuad(String name, RenderState state) {
|
||||
Drawable quad = new Drawable();
|
||||
quad.setTransform(new MatrixTransform());
|
||||
quad.setMesh(mSceneManager.getScreenAlignedQuad());
|
||||
quad.setName(name);
|
||||
quad.setRenderState(state);
|
||||
quad.setCullType(1);
|
||||
return quad;
|
||||
}
|
||||
|
||||
void addBlurPasses() {
|
||||
ArrayList<DrawableBase> allDraw = mActiveScene.getDrawables();
|
||||
int numDraw = allDraw.size();
|
||||
|
||||
RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
|
||||
BLEND_ADD_DEPTH_NONE(mRS),
|
||||
ProgramRaster.CULL_NONE(mRS));
|
||||
|
||||
RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor,
|
||||
ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
|
||||
ProgramRaster.CULL_NONE(mRS));
|
||||
|
||||
RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH,
|
||||
ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
|
||||
ProgramRaster.CULL_NONE(mRS));
|
||||
|
||||
RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV,
|
||||
ProgramStore.BLEND_NONE_DEPTH_NONE(mRS),
|
||||
ProgramRaster.CULL_NONE(mRS));
|
||||
|
||||
RenderPass blurSourcePass = new RenderPass();
|
||||
blurSourcePass.setColorTarget(mRenderTargetBlur0Color);
|
||||
blurSourcePass.setDepthTarget(mRenderTargetBlur0Depth);
|
||||
blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
blurSourcePass.setShouldClearColor(true);
|
||||
blurSourcePass.setClearDepth(1.0f);
|
||||
blurSourcePass.setShouldClearDepth(true);
|
||||
blurSourcePass.setCamera(mActiveScene.getCameras().get(1));
|
||||
for (int i = 0; i < numDraw; i ++) {
|
||||
blurSourcePass.appendDrawable((Drawable)allDraw.get(i));
|
||||
}
|
||||
mActiveScene.appendRenderPass(blurSourcePass);
|
||||
|
||||
RenderPass selectColorPass = new RenderPass();
|
||||
selectColorPass.setColorTarget(mRenderTargetBlur2Color);
|
||||
selectColorPass.setDepthTarget(mRenderTargetBlur2Depth);
|
||||
selectColorPass.setShouldClearColor(false);
|
||||
selectColorPass.setShouldClearDepth(false);
|
||||
selectColorPass.setCamera(mActiveScene.getCameras().get(1));
|
||||
// Make blur shape
|
||||
Drawable quad = getDrawableQuad("ScreenAlignedQuadS", selectCol);
|
||||
quad.updateTextures(mRS, mRenderTargetBlur0Color, 0);
|
||||
selectColorPass.appendDrawable(quad);
|
||||
mActiveScene.appendRenderPass(selectColorPass);
|
||||
|
||||
RenderPass horizontalBlurPass = new RenderPass();
|
||||
horizontalBlurPass.setColorTarget(mRenderTargetBlur1Color);
|
||||
horizontalBlurPass.setDepthTarget(mRenderTargetBlur1Depth);
|
||||
horizontalBlurPass.setShouldClearColor(false);
|
||||
horizontalBlurPass.setShouldClearDepth(false);
|
||||
horizontalBlurPass.setCamera(mActiveScene.getCameras().get(1));
|
||||
// Make blur shape
|
||||
quad = getDrawableQuad("ScreenAlignedQuadH", hBlur);
|
||||
quad.updateTextures(mRS, mRenderTargetBlur2Color, 0);
|
||||
horizontalBlurPass.appendDrawable(quad);
|
||||
mActiveScene.appendRenderPass(horizontalBlurPass);
|
||||
|
||||
RenderPass verticalBlurPass = new RenderPass();
|
||||
verticalBlurPass.setColorTarget(mRenderTargetBlur2Color);
|
||||
verticalBlurPass.setDepthTarget(mRenderTargetBlur2Depth);
|
||||
verticalBlurPass.setShouldClearColor(false);
|
||||
verticalBlurPass.setShouldClearDepth(false);
|
||||
verticalBlurPass.setCamera(mActiveScene.getCameras().get(1));
|
||||
// Make blur shape
|
||||
quad = getDrawableQuad("ScreenAlignedQuadV", vBlur);
|
||||
quad.updateTextures(mRS, mRenderTargetBlur1Color, 0);
|
||||
verticalBlurPass.appendDrawable(quad);
|
||||
mActiveScene.appendRenderPass(verticalBlurPass);
|
||||
|
||||
}
|
||||
|
||||
void initRenderPasses() {
|
||||
ArrayList<DrawableBase> allDraw = mActiveScene.getDrawables();
|
||||
int numDraw = allDraw.size();
|
||||
|
||||
if (mUseBlur) {
|
||||
addBlurPasses();
|
||||
}
|
||||
|
||||
RenderPass mainPass = new RenderPass();
|
||||
mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
mainPass.setShouldClearColor(true);
|
||||
mainPass.setClearDepth(1.0f);
|
||||
mainPass.setShouldClearDepth(true);
|
||||
mainPass.setCamera(mActiveScene.getCameras().get(1));
|
||||
for (int i = 0; i < numDraw; i ++) {
|
||||
mainPass.appendDrawable((Drawable)allDraw.get(i));
|
||||
}
|
||||
mActiveScene.appendRenderPass(mainPass);
|
||||
|
||||
if (mUseBlur) {
|
||||
RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
|
||||
BLEND_ADD_DEPTH_NONE(mRS),
|
||||
ProgramRaster.CULL_NONE(mRS));
|
||||
|
||||
RenderPass compositePass = new RenderPass();
|
||||
compositePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 0.0f));
|
||||
compositePass.setShouldClearColor(false);
|
||||
compositePass.setClearDepth(1.0f);
|
||||
compositePass.setShouldClearDepth(false);
|
||||
compositePass.setCamera(mActiveScene.getCameras().get(1));
|
||||
Drawable quad = getDrawableQuad("ScreenAlignedQuad", drawTex);
|
||||
quad.updateTextures(mRS, mRenderTargetBlur2Color, 0);
|
||||
compositePass.appendDrawable(quad);
|
||||
|
||||
mActiveScene.appendRenderPass(compositePass);
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareToRender(Scene s) {
|
||||
mActiveScene = s;
|
||||
RenderState plastic = new RenderState(mPV_Paint, mPF_Plastic, null, null);
|
||||
RenderState diffuse = new RenderState(mPV_Paint, mPF_Diffuse, null, null);
|
||||
RenderState paint = new RenderState(mPV_Paint, mPF_Paint, null, null);
|
||||
RenderState aluminum = new RenderState(mPV_Paint, mPF_Aluminum, null, null);
|
||||
RenderState glassTransp = new RenderState(mPV_Paint,
|
||||
mPF_Paint,
|
||||
ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS),
|
||||
null);
|
||||
|
||||
initRenderPasses();
|
||||
|
||||
mActiveScene.assignRenderState(plastic);
|
||||
|
||||
mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$");
|
||||
|
||||
mActiveScene.assignRenderStateToMaterial(paint, "^#Paint");
|
||||
mActiveScene.assignRenderStateToMaterial(paint, "^#Carbon");
|
||||
mActiveScene.assignRenderStateToMaterial(paint, "^#Glass");
|
||||
mActiveScene.assignRenderStateToMaterial(paint, "^#MainGlass");
|
||||
|
||||
mActiveScene.assignRenderStateToMaterial(aluminum, "^#Metal");
|
||||
mActiveScene.assignRenderStateToMaterial(aluminum, "^#Brake");
|
||||
|
||||
mActiveScene.assignRenderStateToMaterial(glassTransp, "^#GlassLight");
|
||||
|
||||
Drawable plane = (Drawable)mActiveScene.getDrawableByName("pPlaneShape1");
|
||||
if (plane != null) {
|
||||
RenderState texState = new RenderState(mPV_Paint, mPF_Texture, null, null);
|
||||
plane.setRenderState(texState);
|
||||
plane.setVisible(mRS, !mUseBlur);
|
||||
}
|
||||
|
||||
mTouchHandler.init(mActiveScene);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
mActiveScene.initRS(mRS, mRes, mSceneManager);
|
||||
long end = System.currentTimeMillis();
|
||||
Log.v("TIMER", "Scene init time: " + (end - start));
|
||||
|
||||
mScript.set_gInitialized(true);
|
||||
}
|
||||
|
||||
private void initRS() {
|
||||
|
||||
createRenderTargets();
|
||||
initPaintShaders();
|
||||
new ImageLoaderTask().execute();
|
||||
|
||||
Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.defaultcube);
|
||||
mDefaultCube = Allocation.createCubemapFromBitmap(mRS, b);
|
||||
mPF_Paint.bindTexture(mDefaultCube, 1);
|
||||
mPF_Aluminum.bindTexture(mDefaultCube, 1);
|
||||
|
||||
ScriptC_render renderLoop = mSceneManager.getRenderLoop();
|
||||
renderLoop.bind_vConst(mVsConst);
|
||||
renderLoop.bind_fConst(mFsConst);
|
||||
|
||||
mScript.set_gRenderLoop(renderLoop);
|
||||
Allocation dummyAlloc = Allocation.createSized(mRS, Element.I32(mRS), 1);
|
||||
mScript.set_gDummyAlloc(dummyAlloc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import android.renderscript.RSSurfaceView;
|
||||
import android.renderscript.RenderScript;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
|
||||
public class SceneGraphView extends RSSurfaceView {
|
||||
|
||||
public SceneGraphView(Context context) {
|
||||
super(context);
|
||||
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
|
||||
}
|
||||
|
||||
private RenderScriptGL mRS;
|
||||
SceneGraphRS mRender;
|
||||
|
||||
private ScaleGestureDetector mScaleDetector;
|
||||
private static final int INVALID_POINTER_ID = -1;
|
||||
private int mActivePointerId = INVALID_POINTER_ID;
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
super.surfaceChanged(holder, format, w, h);
|
||||
if (mRS == null) {
|
||||
RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
|
||||
sc.setDepth(16, 24);
|
||||
mRS = createRenderScriptGL(sc);
|
||||
mRS.setSurface(holder, w, h);
|
||||
mRender = new SceneGraphRS();
|
||||
mRender.init(mRS, getResources(), w, h);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
if (mRS != null) {
|
||||
mRender = null;
|
||||
mRS = null;
|
||||
destroyRenderScriptGL();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
// break point at here
|
||||
// this method doesn't work when 'extends View' include 'extends ScrollView'.
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
mScaleDetector.onTouchEvent(ev);
|
||||
|
||||
boolean ret = false;
|
||||
float x = ev.getX();
|
||||
float y = ev.getY();
|
||||
|
||||
final int action = ev.getAction();
|
||||
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mRender.onActionDown(x, y);
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (!mScaleDetector.isInProgress()) {
|
||||
mRender.onActionMove(x, y);
|
||||
}
|
||||
mRender.onActionDown(x, y);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP: {
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
final int pointerId = ev.getPointerId(pointerIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
// This was our active pointer going up. Choose a new
|
||||
// active pointer and adjust accordingly.
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
|
||||
x = ev.getX(newPointerIndex);
|
||||
y = ev.getY(newPointerIndex);
|
||||
mRender.onActionDown(x, y);
|
||||
mActivePointerId = ev.getPointerId(newPointerIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
mRender.onActionScale(detector.getScaleFactor());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.renderscript.Mesh;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.content.res.Resources;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.util.Log;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class SceneManager extends SceneGraphBase {
|
||||
|
||||
ScriptC_render mRenderLoop;
|
||||
ScriptC_camera mCameraScript;
|
||||
ScriptC_transform mTransformScript;
|
||||
|
||||
RenderScriptGL mRS;
|
||||
Resources mRes;
|
||||
Mesh mQuad;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
|
||||
public static class SceneLoadedCallback implements Runnable {
|
||||
Scene mLoadedScene;
|
||||
String mName;
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
private void initPFS() {
|
||||
ProgramStore.Builder b = new ProgramStore.Builder(mRS);
|
||||
|
||||
b.setDepthFunc(ProgramStore.DepthFunc.LESS);
|
||||
b.setDitherEnabled(false);
|
||||
b.setDepthMaskEnabled(true);
|
||||
|
||||
mRenderLoop.set_gPFSBackground(b.create());
|
||||
}
|
||||
|
||||
public SceneManager() {
|
||||
}
|
||||
|
||||
public void loadModel(String name, SceneLoadedCallback cb) {
|
||||
ColladaScene scene = new ColladaScene(name, cb);
|
||||
scene.init(mRS, mRes);
|
||||
}
|
||||
|
||||
public Mesh getScreenAlignedQuad() {
|
||||
if (mQuad != null) {
|
||||
return mQuad;
|
||||
}
|
||||
|
||||
Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
|
||||
3, Mesh.TriangleMeshBuilder.TEXTURE_0);
|
||||
|
||||
tmb.setTexture(0.0f, 1.0f);
|
||||
tmb.addVertex(-1.0f, 1.0f, 1.0f);
|
||||
|
||||
tmb.setTexture(0.0f, 0.0f);
|
||||
tmb.addVertex(-1.0f, -1.0f, 1.0f);
|
||||
|
||||
tmb.setTexture(1.0f, 0.0f);
|
||||
tmb.addVertex(1.0f, -1.0f, 1.0f);
|
||||
|
||||
tmb.setTexture(1.0f, 1.0f);
|
||||
tmb.addVertex(1.0f, 1.0f, 1.0f);
|
||||
|
||||
tmb.addTriangle(0, 1, 2);
|
||||
tmb.addTriangle(2, 3, 0);
|
||||
|
||||
mQuad = tmb.create(true);
|
||||
return mQuad;
|
||||
}
|
||||
|
||||
public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
|
||||
mRS = rs;
|
||||
mRes = res;
|
||||
mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
|
||||
mTransformScript.set_gTransformScript(mTransformScript);
|
||||
|
||||
mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
|
||||
|
||||
mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
|
||||
mRenderLoop.set_gTransformScript(mTransformScript);
|
||||
mRenderLoop.set_gCameraScript(mCameraScript);
|
||||
|
||||
Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
|
||||
MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
mRenderLoop.set_gTGrid(checker);
|
||||
initPFS();
|
||||
}
|
||||
|
||||
public ScriptC_render getRenderLoop() {
|
||||
return mRenderLoop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.Element;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class ShaderParam extends SceneGraphBase {
|
||||
String mParamName;
|
||||
|
||||
public ShaderParam(String name) {
|
||||
mParamName = name;
|
||||
}
|
||||
|
||||
public String getParamName() {
|
||||
return mParamName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.lang.Math;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.Type.Builder;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Texture2D extends SceneGraphBase {
|
||||
private static String mSDCardPath = "sdcard/scenegraph/";
|
||||
private final boolean mLoadFromSD = true;
|
||||
|
||||
String mFileName;
|
||||
Allocation mRsTexture;
|
||||
|
||||
public Texture2D() {
|
||||
}
|
||||
|
||||
public void setFileName(String file) {
|
||||
mFileName = file;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return mFileName;
|
||||
}
|
||||
|
||||
Allocation getRsData(RenderScriptGL rs, Resources res) {
|
||||
if (mRsTexture != null) {
|
||||
return mRsTexture;
|
||||
}
|
||||
|
||||
String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (!mLoadFromSD) {
|
||||
is = res.getAssets().open(shortName);
|
||||
} else {
|
||||
File f = new File(mSDCardPath + shortName);
|
||||
is = new BufferedInputStream(new FileInputStream(f));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e("Texture2D",
|
||||
"Could not open image file " + shortName + " Message: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
Bitmap b = BitmapFactory.decodeStream(is);
|
||||
mRsTexture = Allocation.createFromBitmap(rs, b,
|
||||
Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
return mRsTexture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.graphics.Camera;
|
||||
import android.renderscript.Float4;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.Element;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class TextureParam extends ShaderParam {
|
||||
|
||||
Texture2D mTexture;
|
||||
|
||||
public TextureParam(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void setTexture(Texture2D t) {
|
||||
mTexture = t;
|
||||
}
|
||||
|
||||
public Texture2D getTexture() {
|
||||
return mTexture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.renderscript.Element.Builder;
|
||||
import android.renderscript.Font.Style;
|
||||
import android.renderscript.Program.TextureType;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.scenegraph.SceneManager.SceneLoadedCallback;
|
||||
|
||||
public class TouchHandler {
|
||||
|
||||
private static String TAG = "TouchHandler";
|
||||
|
||||
public TouchHandler() {
|
||||
}
|
||||
|
||||
public void init(Scene scene) {
|
||||
mCameraRotate = (CompoundTransform)scene.getTransformByName("CameraAim");
|
||||
mCameraDist = (CompoundTransform)scene.getTransformByName("CameraDist");
|
||||
|
||||
if (mCameraRotate != null && mCameraDist != null) {
|
||||
mRotateX = mCameraRotate.mTransformComponents.get(2);
|
||||
mRotateY = mCameraRotate.mTransformComponents.get(1);
|
||||
mDist = mCameraDist.mTransformComponents.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Resources mRes;
|
||||
private RenderScriptGL mRS;
|
||||
|
||||
float mLastX;
|
||||
float mLastY;
|
||||
|
||||
CompoundTransform mCameraRotate;
|
||||
CompoundTransform mCameraDist;
|
||||
|
||||
CompoundTransform.Component mRotateX;
|
||||
CompoundTransform.Component mRotateY;
|
||||
CompoundTransform.Component mDist;
|
||||
|
||||
public void onActionDown(float x, float y) {
|
||||
mLastX = x;
|
||||
mLastY = y;
|
||||
}
|
||||
|
||||
public void onActionScale(float scale) {
|
||||
if (mCameraDist == null) {
|
||||
return;
|
||||
}
|
||||
mDist.mValue.z *= 1.0f / scale;
|
||||
mDist.mValue.z = Math.max(20.0f, Math.min(mDist.mValue.z, 100.0f));
|
||||
mCameraDist.updateRSData();
|
||||
}
|
||||
|
||||
public void onActionMove(float x, float y) {
|
||||
if (mCameraRotate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
float dx = mLastX - x;
|
||||
float dy = mLastY - y;
|
||||
|
||||
if (Math.abs(dy) <= 2.0f) {
|
||||
dy = 0.0f;
|
||||
}
|
||||
if (Math.abs(dx) <= 2.0f) {
|
||||
dx = 0.0f;
|
||||
}
|
||||
|
||||
mRotateY.mValue.w += dx*0.25;
|
||||
if (mRotateY.mValue.w > 360) {
|
||||
mRotateY.mValue.w -= 360;
|
||||
}
|
||||
if (mRotateY.mValue.w < 0) {
|
||||
mRotateY.mValue.w += 360;
|
||||
}
|
||||
|
||||
mRotateX.mValue.w += dy*0.25;
|
||||
mRotateX.mValue.w = Math.max(mRotateX.mValue.w, -80.0f);
|
||||
mRotateX.mValue.w = Math.min(mRotateX.mValue.w, 0.0f);
|
||||
|
||||
mLastX = x;
|
||||
mLastY = y;
|
||||
|
||||
mCameraRotate.updateRSData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public abstract class Transform extends SceneGraphBase {
|
||||
|
||||
RenderScriptGL mRS;
|
||||
Transform mParent;
|
||||
ArrayList<Transform> mChildren;
|
||||
|
||||
static final int RS_ID_NONE = 0;
|
||||
static final int RS_ID_TRANSLATE = 1;
|
||||
static final int RS_ID_ROTATE = 2;
|
||||
static final int RS_ID_SCALE = 3;
|
||||
|
||||
ScriptField_SgTransform mField;
|
||||
ScriptField_SgTransform.Item mTransformData;
|
||||
|
||||
public Transform() {
|
||||
mChildren = new ArrayList<Transform>();
|
||||
mParent = null;
|
||||
}
|
||||
|
||||
public void appendChild(Transform t) {
|
||||
mChildren.add(t);
|
||||
t.mParent = this;
|
||||
}
|
||||
|
||||
abstract void initLocalData();
|
||||
public abstract void updateRSData();
|
||||
|
||||
public ScriptField_SgTransform getRSData(RenderScriptGL rs) {
|
||||
if (mField != null) {
|
||||
return mField;
|
||||
}
|
||||
|
||||
mRS = rs;
|
||||
initLocalData();
|
||||
|
||||
if (mChildren.size() != 0) {
|
||||
Allocation childRSData = Allocation.createSized(rs,
|
||||
Element.ALLOCATION(rs),
|
||||
mChildren.size());
|
||||
mTransformData.children = childRSData;
|
||||
|
||||
Allocation[] childrenAllocs = new Allocation[mChildren.size()];
|
||||
for (int i = 0; i < mChildren.size(); i ++) {
|
||||
Transform child = mChildren.get(i);
|
||||
childrenAllocs[i] = child.getRSData(rs).getAllocation();
|
||||
}
|
||||
childRSData.copyFrom(childrenAllocs);
|
||||
}
|
||||
|
||||
mField = new ScriptField_SgTransform(rs, 1);
|
||||
mField.set(mTransformData, 0, true);
|
||||
|
||||
return mField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.scenegraph;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.graphics.Camera;
|
||||
import android.renderscript.Matrix4f;
|
||||
import android.renderscript.ProgramFragment;
|
||||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.Element;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class TransformParam extends ShaderParam {
|
||||
|
||||
public static final int TRANSFORM = 0;
|
||||
public static final int TRANSFORM_VIEW = 1;
|
||||
public static final int TRANSFORM_VIEW_PROJ = 2;
|
||||
Transform mTransform;
|
||||
Camera mCamera;
|
||||
|
||||
public TransformParam(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void setTransform(Transform t) {
|
||||
mTransform = t;
|
||||
}
|
||||
|
||||
public void setCamera(Camera c) {
|
||||
mCamera = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.scenegraph)
|
||||
|
||||
//#define DEBUG_CAMERA
|
||||
#include "transform_def.rsh"
|
||||
|
||||
void root(const rs_allocation *v_in, rs_allocation *v_out, const float *usrData) {
|
||||
|
||||
SgCamera *cam = (SgCamera *)rsGetElementAt(*v_in, 0);
|
||||
float aspect = *usrData;
|
||||
cam->aspect = aspect;
|
||||
const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
|
||||
|
||||
rsMatrixLoadPerspective(&cam->proj, cam->horizontalFOV, cam->aspect, cam->near, cam->far);
|
||||
|
||||
rs_matrix4x4 camPosMatrix;
|
||||
rsMatrixLoad(&camPosMatrix, &camTransform->globalMat);
|
||||
float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
cam->position = rsMatrixMultiply(&camPosMatrix, zero);
|
||||
|
||||
rsMatrixInverse(&camPosMatrix);
|
||||
rsMatrixLoad(&cam->view, &camPosMatrix);
|
||||
|
||||
rsMatrixLoad(&cam->viewProj, &cam->proj);
|
||||
rsMatrixMultiply(&cam->viewProj, &cam->view);
|
||||
#ifdef DEBUG_CAMERA
|
||||
printCameraInfo(cam);
|
||||
#endif //DEBUG_CAMERA
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.scenegraph)
|
||||
|
||||
// The sole purpose of this script is to have various structs exposed
|
||||
// so that java reflected classes are generated
|
||||
#include "transform_def.rsh"
|
||||
SgTransform *exportPtr;
|
||||
SgRenderState *sExport;
|
||||
SgDrawable *drExport;
|
||||
SgRenderPass *pExport;
|
||||
SgCamera *exportPtrCam;
|
||||
FBlurOffsets *blurExport;
|
||||
VertexShaderInputs *iExport;
|
||||
@@ -0,0 +1,296 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.scenegraph)
|
||||
|
||||
#include "rs_graphics.rsh"
|
||||
#include "transform_def.rsh"
|
||||
|
||||
rs_script gTransformScript;
|
||||
rs_script gCameraScript;
|
||||
|
||||
SgTransform *gRootNode;
|
||||
rs_allocation gCameras;
|
||||
rs_allocation gDrawableObjects;
|
||||
|
||||
rs_allocation gRenderPasses;
|
||||
|
||||
// Temporary shaders
|
||||
rs_allocation gTGrid;
|
||||
rs_program_store gPFSBackground;
|
||||
|
||||
VShaderParams *vConst;
|
||||
FShaderParams *fConst;
|
||||
|
||||
uint32_t *gFrontToBack;
|
||||
static uint32_t gFrontToBackCount = 0;
|
||||
uint32_t *gBackToFront;
|
||||
static uint32_t gBackToFrontCount = 0;
|
||||
|
||||
static SgCamera *gActiveCamera = NULL;
|
||||
static float4 gFrustumPlanes[6];
|
||||
|
||||
static rs_allocation nullAlloc;
|
||||
|
||||
//#define DEBUG_RENDERABLES
|
||||
static void draw(SgDrawable *obj) {
|
||||
|
||||
const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
|
||||
const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
|
||||
#ifdef DEBUG_RENDERABLES
|
||||
rsDebug("**** Drawing object with transform", obj);
|
||||
printName(objTransform->name);
|
||||
rsDebug("Model matrix: ", &objTransform->globalMat);
|
||||
printName(obj->name);
|
||||
#endif //DEBUG_RENDERABLES
|
||||
|
||||
SgCamera *cam = gActiveCamera;
|
||||
|
||||
rsMatrixLoad(&vConst->model, &objTransform->globalMat);
|
||||
rsMatrixLoad(&vConst->viewProj, &cam->viewProj);
|
||||
rsgAllocationSyncAll(rsGetAllocation(vConst));
|
||||
fConst->cameraPos = cam->position;
|
||||
rsgAllocationSyncAll(rsGetAllocation(fConst));
|
||||
|
||||
if (rsIsObject(renderState->ps)) {
|
||||
rsgBindProgramStore(renderState->ps);
|
||||
} else {
|
||||
rsgBindProgramStore(gPFSBackground);
|
||||
}
|
||||
|
||||
if (rsIsObject(renderState->pr)) {
|
||||
rsgBindProgramRaster(renderState->pr);
|
||||
} else {
|
||||
rs_program_raster pr;
|
||||
rsgBindProgramRaster(pr);
|
||||
}
|
||||
|
||||
rsgBindProgramFragment(renderState->pf);
|
||||
rsgBindProgramVertex(renderState->pv);
|
||||
|
||||
if (rsIsObject(obj->pf_textures[0])) {
|
||||
rsgBindTexture(renderState->pf, 0, obj->pf_textures[0]);
|
||||
} else {
|
||||
rsgBindTexture(renderState->pf, 0, gTGrid);
|
||||
}
|
||||
|
||||
rsgDrawMesh(obj->mesh, obj->meshIndex);
|
||||
}
|
||||
|
||||
static void getTransformedSphere(SgDrawable *obj) {
|
||||
obj->worldBoundingSphere = obj->boundingSphere;
|
||||
obj->worldBoundingSphere.w = 1.0f;
|
||||
const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
|
||||
obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere);
|
||||
|
||||
const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f};
|
||||
float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec);
|
||||
scaledVec.w = 0.0f;
|
||||
obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec);
|
||||
}
|
||||
|
||||
static bool frustumCulled(SgDrawable *obj) {
|
||||
if (!obj->bVolInitialized) {
|
||||
float minX, minY, minZ, maxX, maxY, maxZ;
|
||||
rsgMeshComputeBoundingBox(obj->mesh,
|
||||
&minX, &minY, &minZ,
|
||||
&maxX, &maxY, &maxZ);
|
||||
//rsDebug("min", minX, minY, minZ);
|
||||
//rsDebug("max", maxX, maxY, maxZ);
|
||||
float4 sphere;
|
||||
sphere.x = (maxX + minX) * 0.5f;
|
||||
sphere.y = (maxY + minY) * 0.5f;
|
||||
sphere.z = (maxZ + minZ) * 0.5f;
|
||||
float3 radius;
|
||||
radius.x = (maxX - sphere.x);
|
||||
radius.y = (maxY - sphere.y);
|
||||
radius.z = (maxZ - sphere.z);
|
||||
|
||||
sphere.w = length(radius);
|
||||
obj->boundingSphere = sphere;
|
||||
obj->bVolInitialized = 1;
|
||||
//rsDebug("Sphere", sphere);
|
||||
}
|
||||
|
||||
getTransformedSphere(obj);
|
||||
|
||||
return !rsIsSphereInFrustum(&obj->worldBoundingSphere,
|
||||
&gFrustumPlanes[0], &gFrustumPlanes[1],
|
||||
&gFrustumPlanes[2], &gFrustumPlanes[3],
|
||||
&gFrustumPlanes[3], &gFrustumPlanes[4]);
|
||||
}
|
||||
|
||||
static void sortToBucket(SgDrawable *obj) {
|
||||
// Not loaded yet
|
||||
if (!rsIsObject(obj->mesh) || obj->cullType == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check to see if we are culling this object and if it's
|
||||
// outside the frustum
|
||||
if (obj->cullType == 0 && frustumCulled(obj)) {
|
||||
#ifdef DEBUG_RENDERABLES
|
||||
rsDebug("Culled", obj);
|
||||
printName(obj->name);
|
||||
#endif //DEBUG_RENDERABLES
|
||||
return;
|
||||
}
|
||||
const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
|
||||
if (rsIsObject(renderState->ps)) {
|
||||
gBackToFront[gBackToFrontCount++] = (uint32_t)obj;
|
||||
} else {
|
||||
gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
|
||||
}
|
||||
}
|
||||
|
||||
static void updateActiveCamera(rs_allocation cam) {
|
||||
gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0);
|
||||
|
||||
rsExtractFrustumPlanes(&gActiveCamera->viewProj,
|
||||
&gFrustumPlanes[0], &gFrustumPlanes[1],
|
||||
&gFrustumPlanes[2], &gFrustumPlanes[3],
|
||||
&gFrustumPlanes[3], &gFrustumPlanes[4]);
|
||||
}
|
||||
|
||||
static void prepareCameras() {
|
||||
// now compute all the camera matrices
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect));
|
||||
}
|
||||
|
||||
static void drawSorted() {
|
||||
for (int i = 0; i < gFrontToBackCount; i ++) {
|
||||
SgDrawable *current = (SgDrawable*)gFrontToBack[i];
|
||||
draw(current);
|
||||
}
|
||||
|
||||
for (int i = 0; i < gBackToFrontCount; i ++) {
|
||||
SgDrawable *current = (SgDrawable*)gBackToFront[i];
|
||||
draw(current);
|
||||
}
|
||||
}
|
||||
|
||||
static void drawAllObjects(rs_allocation allObj) {
|
||||
if (!rsIsObject(allObj)) {
|
||||
return;
|
||||
}
|
||||
int numDrawables = rsAllocationGetDimX(allObj);
|
||||
for (int i = 0; i < numDrawables; i ++) {
|
||||
rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i);
|
||||
SgDrawable *current = (SgDrawable*)rsGetElementAt(*drawAlloc, 0);
|
||||
sortToBucket(current);
|
||||
}
|
||||
drawSorted();
|
||||
}
|
||||
|
||||
void root(const void *v_in, void *v_out) {
|
||||
|
||||
//rsDebug("=============================================================================", 0);
|
||||
// first step is to update the transform hierachy
|
||||
rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0);
|
||||
|
||||
prepareCameras();
|
||||
|
||||
rsgClearDepth(1.0f);
|
||||
|
||||
int numDrawables = rsAllocationGetDimX(gDrawableObjects);
|
||||
if (rsIsObject(gRenderPasses)) {
|
||||
int numPasses = rsAllocationGetDimX(gRenderPasses);
|
||||
for (uint i = 0; i < numPasses; i ++) {
|
||||
gFrontToBackCount = 0;
|
||||
gBackToFrontCount = 0;
|
||||
SgRenderPass *pass = (SgRenderPass*)rsGetElementAt(gRenderPasses, i);
|
||||
if (rsIsObject(pass->color_target)) {
|
||||
rsgBindColorTarget(pass->color_target, 0);
|
||||
}
|
||||
if (rsIsObject(pass->depth_target)) {
|
||||
rsgBindDepthTarget(pass->depth_target);
|
||||
}
|
||||
if (!rsIsObject(pass->color_target) &&
|
||||
!rsIsObject(pass->depth_target)) {
|
||||
rsgClearAllRenderTargets();
|
||||
}
|
||||
updateActiveCamera(pass->camera);
|
||||
if (pass->should_clear_color) {
|
||||
rsgClearColor(pass->clear_color.x, pass->clear_color.y,
|
||||
pass->clear_color.z, pass->clear_color.w);
|
||||
}
|
||||
if (pass->should_clear_depth) {
|
||||
rsgClearDepth(pass->clear_depth);
|
||||
}
|
||||
drawAllObjects(pass->objects);
|
||||
}
|
||||
} else {
|
||||
gFrontToBackCount = 0;
|
||||
gBackToFrontCount = 0;
|
||||
rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 1);
|
||||
updateActiveCamera(*camAlloc);
|
||||
drawAllObjects(gDrawableObjects);
|
||||
}
|
||||
}
|
||||
|
||||
static bool intersect(const SgDrawable *obj, float3 pnt, float3 vec) {
|
||||
// Solving for t^2 + Bt + C = 0
|
||||
float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz;
|
||||
float B = dot(originMinusCenter, vec) * 2.0f;
|
||||
float C = dot(originMinusCenter, originMinusCenter) -
|
||||
obj->worldBoundingSphere.w * obj->worldBoundingSphere.w;
|
||||
|
||||
float discriminant = B * B - 4.0f * C;
|
||||
if (discriminant < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
discriminant = sqrt(discriminant);
|
||||
|
||||
float t0 = (-B - discriminant) * 0.5f;
|
||||
float t1 = (-B + discriminant) * 0.5f;
|
||||
|
||||
if (t0 > t1) {
|
||||
float temp = t0;
|
||||
t0 = t1;
|
||||
t1 = temp;
|
||||
}
|
||||
|
||||
// The sphere is behind us
|
||||
if (t1 < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search through sorted and culled objects
|
||||
void pick(int screenX, int screenY) {
|
||||
float3 pnt, vec;
|
||||
getCameraRay(gActiveCamera, screenX, screenY, &pnt, &vec);
|
||||
|
||||
for (int i = 0; i < gFrontToBackCount; i ++) {
|
||||
SgDrawable *current = (SgDrawable*)gFrontToBack[i];
|
||||
bool isPicked = intersect(current, pnt, vec);
|
||||
if (isPicked) {
|
||||
current->cullType = 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < gBackToFrontCount; i ++) {
|
||||
SgDrawable *current = (SgDrawable*)gBackToFront[i];
|
||||
bool isPicked = intersect(current, pnt, vec);
|
||||
if (isPicked) {
|
||||
current->cullType = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.scenegraph)
|
||||
|
||||
#include "rs_graphics.rsh"
|
||||
#include "transform_def.rsh"
|
||||
|
||||
rs_program_vertex gPVBackground;
|
||||
rs_program_fragment gPFBackground;
|
||||
|
||||
rs_allocation gRobotTex;
|
||||
rs_mesh gRobotMesh;
|
||||
|
||||
rs_program_store gPFSBackground;
|
||||
|
||||
rs_allocation gDummyAlloc;
|
||||
rs_script gRenderLoop;
|
||||
|
||||
bool gInitialized = false;
|
||||
|
||||
float gRotate;
|
||||
|
||||
void init() {
|
||||
gRotate = 0.0f;
|
||||
}
|
||||
|
||||
static int pos = 50;
|
||||
static float gRotateY = 120.0f;
|
||||
static float3 gLookAt = 0;
|
||||
static float gZoom = 50.0f;
|
||||
static void displayLoading() {
|
||||
if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) {
|
||||
rsgBindProgramVertex(gPVBackground);
|
||||
rs_matrix4x4 proj;
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
|
||||
rsgBindProgramFragment(gPFBackground);
|
||||
rsgBindProgramStore(gPFSBackground);
|
||||
rsgBindTexture(gPFBackground, 0, gRobotTex);
|
||||
|
||||
rs_matrix4x4 matrix;
|
||||
rsMatrixLoadIdentity(&matrix);
|
||||
// Position our models on the screen
|
||||
gRotateY += rsGetDt()*100;
|
||||
rsMatrixTranslate(&matrix, 0, 0, -gZoom);
|
||||
rsMatrixRotate(&matrix, 20.0f, 1.0f, 0.0f, 0.0f);
|
||||
rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
|
||||
rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
rsgDrawMesh(gRobotMesh);
|
||||
}
|
||||
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
const char* text = "Initializing...";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
int centeredPos = width / 2 - (right - left) / 2;
|
||||
rsgDrawText(text, centeredPos, height / 2 + height / 10);
|
||||
}
|
||||
|
||||
int root(void) {
|
||||
rs_allocation nullAlloc;
|
||||
if (!gInitialized) {
|
||||
rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
displayLoading();
|
||||
return 30;
|
||||
}
|
||||
|
||||
rsForEach(gRenderLoop, gDummyAlloc, nullAlloc);
|
||||
|
||||
return 10;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.modelviewer)
|
||||
|
||||
//#define DEBUG_TRANSFORMS
|
||||
|
||||
#include "transform_def.rsh"
|
||||
|
||||
rs_script gTransformScript;
|
||||
|
||||
typedef struct {
|
||||
int changed;
|
||||
rs_matrix4x4 *mat;
|
||||
} ParentData;
|
||||
|
||||
static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
|
||||
rs_matrix4x4 temp;
|
||||
|
||||
switch (type) {
|
||||
case TRANSFORM_TRANSLATE:
|
||||
rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
|
||||
break;
|
||||
case TRANSFORM_ROTATE:
|
||||
rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
|
||||
break;
|
||||
case TRANSFORM_SCALE:
|
||||
rsMatrixLoadScale(&temp, data.x, data.y, data.z);
|
||||
break;
|
||||
}
|
||||
rsMatrixMultiply(mat, &temp);
|
||||
}
|
||||
|
||||
void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) {
|
||||
|
||||
SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0);
|
||||
const ParentData *parent = (const ParentData *)usrData;
|
||||
|
||||
#ifdef DEBUG_TRANSFORMS
|
||||
rsDebug("**** Transform data", (int)data);
|
||||
rsDebug("Transform is dirty", data->isDirty);
|
||||
rsDebug("Transform parent", (int)parent);
|
||||
rsDebug("Transform child ", (int)data->children.p);
|
||||
printName(data->name);
|
||||
#endif //DEBUG_TRANSFORMS
|
||||
|
||||
rs_matrix4x4 *localMat = &data->localMat;
|
||||
rs_matrix4x4 *globalMat = &data->globalMat;
|
||||
|
||||
ParentData toChild;
|
||||
toChild.changed = 0;
|
||||
toChild.mat = globalMat;
|
||||
|
||||
// Refresh matrices if dirty
|
||||
if (data->isDirty) {
|
||||
toChild.changed = 1;
|
||||
|
||||
bool resetLocal = false;
|
||||
for (int i = 0; i < 16; i ++) {
|
||||
if (data->transformTypes[i] == TRANSFORM_NONE) {
|
||||
break;
|
||||
}
|
||||
if (!resetLocal) {
|
||||
// Reset our local matrix only for component transforms
|
||||
rsMatrixLoadIdentity(localMat);
|
||||
resetLocal = true;
|
||||
}
|
||||
#ifdef DEBUG_TRANSFORMS
|
||||
if (rsIsObject(data->transformNames[i])) {
|
||||
rsDebug((const char*)rsGetElementAt(data->transformNames[i], 0),
|
||||
data->transforms[i]);
|
||||
} else {
|
||||
rsDebug("Transform adding transformation type", data->transformTypes[i]);
|
||||
rsDebug("Transform adding transformation", data->transforms[i]);
|
||||
}
|
||||
#endif //DEBUG_TRANSFORMS
|
||||
appendTransformation(data->transformTypes[i], data->transforms[i], localMat);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
if (parent->changed || data->isDirty) {
|
||||
toChild.changed = 1;
|
||||
|
||||
rsMatrixLoad(globalMat, parent->mat);
|
||||
rsMatrixMultiply(globalMat, localMat);
|
||||
}
|
||||
} else if (data->isDirty) {
|
||||
rsMatrixLoad(globalMat, localMat);
|
||||
}
|
||||
|
||||
if (rsIsObject(data->children)) {
|
||||
rs_allocation nullAlloc;
|
||||
rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
|
||||
}
|
||||
|
||||
data->isDirty = 0;
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright (C) 2009 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.scenegraph)
|
||||
|
||||
#include "rs_graphics.rsh"
|
||||
|
||||
#define TRANSFORM_NONE 0
|
||||
#define TRANSFORM_TRANSLATE 1
|
||||
#define TRANSFORM_ROTATE 2
|
||||
#define TRANSFORM_SCALE 3
|
||||
|
||||
static void printName(rs_allocation name) {
|
||||
rsDebug("Object Name: ", 0);
|
||||
if (!rsIsObject(name)) {
|
||||
rsDebug("no name", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
rsDebug((const char*)rsGetElementAt(name, 0), 0);
|
||||
}
|
||||
|
||||
typedef struct __attribute__((packed, aligned(4))) SgTransform {
|
||||
rs_matrix4x4 globalMat;
|
||||
rs_matrix4x4 localMat;
|
||||
|
||||
float4 transforms[16];
|
||||
int transformTypes[16];
|
||||
rs_allocation transformNames[16];
|
||||
|
||||
int isDirty;
|
||||
|
||||
rs_allocation children;
|
||||
|
||||
rs_allocation name;
|
||||
} SgTransform;
|
||||
|
||||
typedef struct RenderState_s {
|
||||
rs_program_vertex pv;
|
||||
rs_program_fragment pf;
|
||||
rs_program_store ps;
|
||||
rs_program_raster pr;
|
||||
} SgRenderState;
|
||||
|
||||
typedef struct Drawable_s {
|
||||
rs_allocation render_state;
|
||||
rs_allocation pv_const;
|
||||
rs_allocation pf_const;
|
||||
rs_allocation pf_textures[8];
|
||||
int pf_num_textures;
|
||||
rs_mesh mesh;
|
||||
int meshIndex;
|
||||
rs_allocation transformMatrix;
|
||||
rs_allocation name;
|
||||
float4 boundingSphere;
|
||||
float4 worldBoundingSphere;
|
||||
int bVolInitialized;
|
||||
int cullType; // specifies whether to frustum cull
|
||||
} SgDrawable;
|
||||
|
||||
typedef struct RenderPass_s {
|
||||
rs_allocation color_target;
|
||||
rs_allocation depth_target;
|
||||
rs_allocation camera;
|
||||
rs_allocation objects;
|
||||
|
||||
float4 clear_color;
|
||||
float clear_depth;
|
||||
bool should_clear_color;
|
||||
bool should_clear_depth;
|
||||
} SgRenderPass;
|
||||
|
||||
typedef struct __attribute__((packed, aligned(4))) Camera_s {
|
||||
rs_matrix4x4 proj;
|
||||
rs_matrix4x4 view;
|
||||
rs_matrix4x4 viewProj;
|
||||
float4 position;
|
||||
float near;
|
||||
float far;
|
||||
float horizontalFOV;
|
||||
float aspect;
|
||||
rs_allocation name;
|
||||
rs_allocation transformMatrix;
|
||||
} SgCamera;
|
||||
|
||||
typedef struct VShaderParams_s {
|
||||
rs_matrix4x4 model;
|
||||
rs_matrix4x4 viewProj;
|
||||
} VShaderParams;
|
||||
|
||||
typedef struct FShaderParams_s {
|
||||
float4 cameraPos;
|
||||
} FShaderParams;
|
||||
|
||||
typedef struct FBlurOffsets_s {
|
||||
float blurOffset0;
|
||||
float blurOffset1;
|
||||
float blurOffset2;
|
||||
float blurOffset3;
|
||||
} FBlurOffsets;
|
||||
|
||||
typedef struct VertexShaderInputs_s {
|
||||
float4 position;
|
||||
float3 normal;
|
||||
float2 texture0;
|
||||
} VertexShaderInputs;
|
||||
|
||||
static void printCameraInfo(SgCamera *cam) {
|
||||
rsDebug("***** Camera information. ptr:", cam);
|
||||
printName(cam->name);
|
||||
const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
|
||||
rsDebug("Transform name:", camTransform);
|
||||
printName(camTransform->name);
|
||||
|
||||
rsDebug("Aspect: ", cam->aspect);
|
||||
rsDebug("Near: ", cam->near);
|
||||
rsDebug("Far: ", cam->far);
|
||||
rsDebug("Fov: ", cam->horizontalFOV);
|
||||
rsDebug("Position: ", cam->position);
|
||||
rsDebug("Proj: ", &cam->proj);
|
||||
rsDebug("View: ", &cam->view);
|
||||
}
|
||||
|
||||
static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
|
||||
rsDebug("=================================", screenX);
|
||||
rsDebug("Point X", screenX);
|
||||
rsDebug("Point Y", screenY);
|
||||
|
||||
rs_matrix4x4 mvpInv;
|
||||
rsMatrixLoad(&mvpInv, &cam->viewProj);
|
||||
rsMatrixInverse(&mvpInv);
|
||||
|
||||
float width = (float)rsgGetWidth();
|
||||
float height = (float)rsgGetHeight();
|
||||
|
||||
float4 pos = {(float)screenX, height - (float)screenY, 0.0f, 1.0f};
|
||||
|
||||
pos.x /= width;
|
||||
pos.y /= height;
|
||||
|
||||
rsDebug("Pre Norm X", pos.x);
|
||||
rsDebug("Pre Norm Y", pos.y);
|
||||
|
||||
pos.xy = pos.xy * 2.0f - 1.0f;
|
||||
|
||||
rsDebug("Norm X", pos.x);
|
||||
rsDebug("Norm Y", pos.y);
|
||||
|
||||
pos = rsMatrixMultiply(&mvpInv, pos);
|
||||
float oneOverW = 1.0f / pos.w;
|
||||
pos.xyz *= oneOverW;
|
||||
|
||||
rsDebug("World X", pos.x);
|
||||
rsDebug("World Y", pos.y);
|
||||
rsDebug("World Z", pos.z);
|
||||
|
||||
rsDebug("Cam X", cam->position.x);
|
||||
rsDebug("Cam Y", cam->position.y);
|
||||
rsDebug("Cam Z", cam->position.z);
|
||||
|
||||
*vec = normalize(pos.xyz - cam->position.xyz);
|
||||
rsDebug("Vec X", vec->x);
|
||||
rsDebug("Vec Y", vec->y);
|
||||
rsDebug("Vec Z", vec->z);
|
||||
*pnt = cam->position.xyz;
|
||||
}
|
||||
Reference in New Issue
Block a user