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 
Renderable()59     public Renderable() {
60         mSourceParams = new HashMap<String, ShaderParam>();
61         mData = new ScriptField_Renderable_s.Item();
62     }
63 
setCullType(int cull)64     public void setCullType(int cull) {
65         mData.cullType = cull;
66     }
67 
setRenderState(RenderState renderState)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 
setMesh(Mesh mesh)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 
setMesh(String mesh, String indexName)84     public void setMesh(String mesh, String indexName) {
85         mMeshName = mesh;
86         mMeshIndexName = indexName;
87     }
88 
setMaterialName(String name)89     public void setMaterialName(String name) {
90         mMaterialName = name;
91     }
92 
getTransform()93     public Transform getTransform() {
94         return mTransform;
95     }
96 
setTransform(Transform t)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 
appendSourceParams(ShaderParam p)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 
resolveMeshData(Mesh mesh)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 
updateTextures(RenderScriptGL rs)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 
setVisible(boolean vis)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 
getRsField(RenderScriptGL rs, Resources res)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 
updateVertexConstants(RenderScriptGL rs)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 
updateFragmentConstants(RenderScriptGL rs)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 
updateFieldItem(RenderScriptGL rs)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