1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.testapp; 18 19 import java.util.ArrayList; 20 import java.util.HashMap; 21 import java.util.Map; 22 import java.util.Vector; 23 24 import com.android.scenegraph.*; 25 import com.android.scenegraph.SceneManager.SceneLoadedCallback; 26 27 import android.content.res.Resources; 28 import android.graphics.Bitmap; 29 import android.graphics.BitmapFactory; 30 import android.os.AsyncTask; 31 import android.renderscript.*; 32 import android.renderscript.Program.TextureType; 33 import android.util.Log; 34 35 // This is where the scenegraph and the rendered objects are initialized and used 36 public class SimpleAppRS { 37 SceneManager mSceneManager; 38 39 RenderScriptGL mRS; 40 Resources mRes; 41 42 Scene mScene; 43 Mesh mSimpleMesh; 44 Mesh mSphereMesh; 45 Mesh mCubeMesh; 46 47 public void init(RenderScriptGL rs, Resources res, int width, int height) { 48 mRS = rs; 49 mRes = res; 50 mSceneManager = SceneManager.getInstance(); 51 mSceneManager.initRS(mRS, mRes, width, height); 52 53 mScene = new Scene(); 54 55 setupGeometry(); 56 setupColoredQuad(); 57 setupTexturedQuad(); 58 setupShadedGeometry(); 59 setupCamera(); 60 setupRenderPass(); 61 62 mSceneManager.setActiveScene(mScene); 63 64 mScene.initRS(); 65 mRS.bindRootScript(mSceneManager.getRenderLoop()); 66 } 67 68 private void setupGeometry() { 69 Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 3, 70 Mesh.TriangleMeshBuilder.TEXTURE_0); 71 72 // Create four vertices with texture coordinates 73 tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 0.0f); 74 tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 0.0f); 75 tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 0.0f); 76 tmb.setTexture(1.0f, 1.0f).addVertex(1.0f, 1.0f, 0.0f); 77 78 tmb.addTriangle(0, 1, 2); 79 tmb.addTriangle(2, 3, 0); 80 mSimpleMesh = tmb.create(true); 81 82 // Load a file that constains two pieces of geometry, a sphere and a cube 83 FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.unit_obj); 84 for (int i = 0; i < model.getIndexEntryCount(); i ++) { 85 FileA3D.IndexEntry entry = model.getIndexEntry(i); 86 if (entry != null && entry.getName().equals("CubeMesh")) { 87 mCubeMesh = entry.getMesh(); 88 } else if (entry != null && entry.getName().equals("SphereMesh")) { 89 mSphereMesh = entry.getMesh(); 90 } 91 } 92 } 93 94 private void setupColoredQuad() { 95 // Built-in shader that provides position, texcoord and normal 96 VertexShader genericV = SceneManager.getDefaultVS(); 97 // Built-in shader that displays a color 98 FragmentShader colorF = SceneManager.getColorFS(); 99 RenderState colorRS = new RenderState(genericV, colorF, null, null); 100 101 // Draw a simple colored quad 102 Renderable quad = mScene.appendNewRenderable(); 103 quad.setMesh(mSimpleMesh); 104 // Our shader has a constant input called "color" 105 // This tells the scenegraph to assign the following float3 to that input 106 quad.appendSourceParams(new Float4Param("color", 0.2f, 0.3f, 0.4f)); 107 quad.setRenderState(colorRS); 108 } 109 110 private void setupTexturedQuad() { 111 // Built-in shader that provides position, texcoord and normal 112 VertexShader genericV = SceneManager.getDefaultVS(); 113 // Built-in shader that displays a texture 114 FragmentShader textureF = SceneManager.getTextureFS(); 115 // We want to use transparency based on the alpha channel of the texture 116 ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS); 117 RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null); 118 119 // Draw a textured quad 120 Renderable quad = mScene.appendNewRenderable(); 121 quad.setMesh(mSimpleMesh); 122 // Make a transform to position the quad 123 CompoundTransform t = mScene.appendNewCompoundTransform(); 124 t.addTranslate("position", new Float3(2, 2, 0)); 125 quad.setTransform(t); 126 // Our fragment shader has a constant texture input called "color" 127 // This will assign an icon from drawables to that input 128 quad.appendSourceParams(new TextureParam("color", new Texture2D(R.drawable.icon))); 129 quad.setRenderState(texRS); 130 } 131 132 private FragmentShader createLambertShader() { 133 // Describe what constant inputs our shader wants 134 Element.Builder b = new Element.Builder(mRS); 135 b.add(Element.F32_4(mRS), "cameraPos"); 136 137 // Create a shader from a text file in resources 138 FragmentShader.Builder fb = new FragmentShader.Builder(mRS); 139 // Tell the shader what constants we want 140 fb.setShaderConst(new Type.Builder(mRS, b.create()).setX(1).create()); 141 // Shader code location 142 fb.setShader(mRes, R.raw.diffuse); 143 // We want a texture called diffuse on our shader 144 fb.addTexture(TextureType.TEXTURE_2D, "diffuse"); 145 FragmentShader shader = fb.create(); 146 mScene.appendShader(shader); 147 return shader; 148 } 149 150 private void setupShadedGeometry() { 151 // Built-in shader that provides position, texcoord and normal 152 VertexShader genericV = SceneManager.getDefaultVS(); 153 // Custom shader 154 FragmentShader diffuseF = createLambertShader(); 155 RenderState diffuseRS = new RenderState(genericV, diffuseF, null, null); 156 157 // Draw a sphere 158 Renderable sphere = mScene.appendNewRenderable(); 159 // Use the sphere geometry loaded earlier 160 sphere.setMesh(mSphereMesh); 161 // Make a transform to position the sphere 162 CompoundTransform t = mScene.appendNewCompoundTransform(); 163 t.addTranslate("position", new Float3(-1, 2, 3)); 164 t.addScale("scale", new Float3(1.4f, 1.4f, 1.4f)); 165 sphere.setTransform(t); 166 // Tell the renderable which texture to use when we draw 167 // This will mean a texture param in the shader called "diffuse" 168 // will be assigned a texture called red.jpg 169 sphere.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "red.jpg"))); 170 sphere.setRenderState(diffuseRS); 171 172 // Draw a cube 173 Renderable cube = mScene.appendNewRenderable(); 174 cube.setMesh(mCubeMesh); 175 t = mScene.appendNewCompoundTransform(); 176 t.addTranslate("position", new Float3(-2, -2.1f, 0)); 177 t.addRotate("rotateX", new Float3(1, 0, 0), 30); 178 t.addRotate("rotateY", new Float3(0, 1, 0), 30); 179 t.addScale("scale", new Float3(2, 2, 2)); 180 cube.setTransform(t); 181 cube.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "orange.jpg"))); 182 cube.setRenderState(diffuseRS); 183 } 184 185 private void setupCamera() { 186 Camera camera = mScene.appendNewCamera(); 187 camera.setFar(200); 188 camera.setNear(0.1f); 189 camera.setFOV(60); 190 CompoundTransform cameraTransform = mScene.appendNewCompoundTransform(); 191 cameraTransform.addTranslate("camera", new Float3(0, 0, 10)); 192 camera.setTransform(cameraTransform); 193 } 194 195 private void setupRenderPass() { 196 RenderPass mainPass = mScene.appendNewRenderPass(); 197 mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f)); 198 mainPass.setShouldClearColor(true); 199 mainPass.setClearDepth(1.0f); 200 mainPass.setShouldClearDepth(true); 201 mainPass.setCamera(mScene.getCameras().get(0)); 202 ArrayList<RenderableBase> allRender = mScene.getRenderables(); 203 for (RenderableBase renderable : allRender) { 204 mainPass.appendRenderable((Renderable)renderable); 205 } 206 } 207 } 208