1 /* 2 * Copyright (C) 2011 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.scenegraph; 18 19 import java.lang.Math; 20 import java.util.ArrayList; 21 import java.util.HashMap; 22 import java.util.Iterator; 23 24 import com.android.scenegraph.Float4Param; 25 import com.android.scenegraph.MatrixTransform; 26 import com.android.scenegraph.SceneManager; 27 import com.android.scenegraph.ShaderParam; 28 import com.android.scenegraph.TransformParam; 29 30 import android.content.res.Resources; 31 import android.renderscript.Allocation; 32 import android.renderscript.Element; 33 import android.renderscript.Element.DataType; 34 import android.renderscript.Matrix4f; 35 import android.renderscript.Mesh; 36 import android.renderscript.ProgramFragment; 37 import android.renderscript.ProgramStore; 38 import android.renderscript.ProgramVertex; 39 import android.renderscript.RenderScriptGL; 40 import android.util.Log; 41 42 /** 43 * @hide 44 */ 45 public class Renderable extends RenderableBase { 46 HashMap<String, ShaderParam> mSourceParams; 47 48 RenderState mRenderState; 49 Transform mTransform; 50 51 String mMeshName; 52 String mMeshIndexName; 53 54 public String mMaterialName; 55 56 ScriptField_Renderable_s mField; 57 ScriptField_Renderable_s.Item mData; 58 59 public Renderable() { 60 mSourceParams = new HashMap<String, ShaderParam>(); 61 mData = new ScriptField_Renderable_s.Item(); 62 } 63 64 public void setCullType(int cull) { 65 mData.cullType = cull; 66 } 67 68 public void setRenderState(RenderState renderState) { 69 mRenderState = renderState; 70 if (mField != null) { 71 RenderScriptGL rs = SceneManager.getRS(); 72 updateFieldItem(rs); 73 mField.set(mData, 0, true); 74 } 75 } 76 77 public void setMesh(Mesh mesh) { 78 mData.mesh = mesh; 79 if (mField != null) { 80 mField.set_mesh(0, mData.mesh, true); 81 } 82 } 83 84 public void setMesh(String mesh, String indexName) { 85 mMeshName = mesh; 86 mMeshIndexName = indexName; 87 } 88 89 public void setMaterialName(String name) { 90 mMaterialName = name; 91 } 92 93 public Transform getTransform() { 94 return mTransform; 95 } 96 97 public void setTransform(Transform t) { 98 mTransform = t; 99 if (mField != null) { 100 RenderScriptGL rs = SceneManager.getRS(); 101 updateFieldItem(rs); 102 mField.set(mData, 0, true); 103 } 104 } 105 106 public void appendSourceParams(ShaderParam p) { 107 mSourceParams.put(p.getParamName(), p); 108 // Possibly lift this restriction later 109 if (mField != null) { 110 throw new RuntimeException("Can't add source params to objects that are rendering"); 111 } 112 } 113 114 public void resolveMeshData(Mesh mesh) { 115 mData.mesh = mesh; 116 if (mData.mesh == null) { 117 Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName); 118 return; 119 } 120 int subIndexCount = mData.mesh.getPrimitiveCount(); 121 if (subIndexCount == 1 || mMeshIndexName == null) { 122 mData.meshIndex = 0; 123 } else { 124 for (int i = 0; i < subIndexCount; i ++) { 125 if (mData.mesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) { 126 mData.meshIndex = i; 127 break; 128 } 129 } 130 } 131 if (mField != null) { 132 mField.set(mData, 0, true); 133 } 134 } 135 136 void updateTextures(RenderScriptGL rs) { 137 Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator(); 138 int paramIndex = 0; 139 while (allParamsIter.hasNext()) { 140 ShaderParam sp = allParamsIter.next(); 141 if (sp instanceof TextureParam) { 142 TextureParam p = (TextureParam)sp; 143 TextureBase tex = p.getTexture(); 144 if (tex != null) { 145 mData.pf_textures[paramIndex++] = tex.getRsData(false).getAllocation(); 146 } 147 } 148 } 149 ProgramFragment pf = mRenderState.mFragment.mProgram; 150 mData.pf_num_textures = pf != null ? Math.min(pf.getTextureCount(), paramIndex) : 0; 151 if (mField != null) { 152 mField.set_pf_textures(0, mData.pf_textures, true); 153 mField.set_pf_num_textures(0, mData.pf_num_textures, true); 154 } 155 } 156 157 public void setVisible(boolean vis) { 158 mData.cullType = vis ? 0 : 2; 159 if (mField != null) { 160 mField.set_cullType(0, mData.cullType, true); 161 } 162 } 163 164 ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) { 165 if (mField != null) { 166 return mField; 167 } 168 updateFieldItem(rs); 169 updateTextures(rs); 170 171 mField = new ScriptField_Renderable_s(rs, 1); 172 mField.set(mData, 0, true); 173 174 return mField; 175 } 176 177 void updateVertexConstants(RenderScriptGL rs) { 178 Allocation pvParams = null, vertexConstants = null; 179 VertexShader pv = mRenderState.mVertex; 180 if (pv != null && pv.getObjectConstants() != null) { 181 vertexConstants = Allocation.createTyped(rs, pv.getObjectConstants()); 182 Element vertexConst = vertexConstants.getType().getElement(); 183 pvParams = ShaderParam.fillInParams(vertexConst, mSourceParams, 184 mTransform).getAllocation(); 185 } 186 mData.pv_const = vertexConstants; 187 mData.pv_constParams = pvParams; 188 } 189 190 void updateFragmentConstants(RenderScriptGL rs) { 191 Allocation pfParams = null, fragmentConstants = null; 192 FragmentShader pf = mRenderState.mFragment; 193 if (pf != null && pf.getObjectConstants() != null) { 194 fragmentConstants = Allocation.createTyped(rs, pf.getObjectConstants()); 195 Element fragmentConst = fragmentConstants.getType().getElement(); 196 pfParams = ShaderParam.fillInParams(fragmentConst, mSourceParams, 197 mTransform).getAllocation(); 198 } 199 mData.pf_const = fragmentConstants; 200 mData.pf_constParams = pfParams; 201 } 202 203 void updateFieldItem(RenderScriptGL rs) { 204 if (mRenderState == null) { 205 mRenderState = SceneManager.getDefaultState(); 206 } 207 if (mTransform == null) { 208 mTransform = SceneManager.getDefaultTransform(); 209 } 210 updateVertexConstants(rs); 211 updateFragmentConstants(rs); 212 213 mData.transformMatrix = mTransform.getRSData().getAllocation(); 214 215 mData.name = getNameAlloc(rs); 216 mData.render_state = mRenderState.getRSData().getAllocation(); 217 mData.bVolInitialized = 0; 218 } 219 } 220 221 222 223 224 225