Home | History | Annotate | Download | only in scenegraph
      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