Home | History | Annotate | Download | only in phasebeam
      1 package com.android.phasebeam;
      2 
      3 import static android.renderscript.Sampler.Value.NEAREST;
      4 import static android.renderscript.Sampler.Value.WRAP;
      5 
      6 import android.content.res.Resources;
      7 import android.renderscript.Allocation;
      8 import android.renderscript.Matrix4f;
      9 import android.renderscript.Mesh;
     10 import android.renderscript.Program;
     11 import android.renderscript.ProgramFragment;
     12 import android.renderscript.ProgramFragmentFixedFunction;
     13 import android.renderscript.ProgramRaster;
     14 import android.renderscript.ProgramStore;
     15 import android.renderscript.ProgramVertex;
     16 import android.renderscript.ProgramVertexFixedFunction;
     17 import android.renderscript.RenderScriptGL;
     18 import android.renderscript.Sampler;
     19 import android.renderscript.ProgramStore.BlendDstFunc;
     20 import android.renderscript.ProgramStore.BlendSrcFunc;
     21 import android.renderscript.Mesh.Primitive;
     22 import android.graphics.Color;
     23 import android.renderscript.Float3;
     24 import android.renderscript.Float4;
     25 import java.io.InputStreamReader;
     26 import java.io.InputStream;
     27 import java.io.BufferedReader;
     28 import java.io.IOException;
     29 import java.util.ArrayList;
     30 import android.util.Log;
     31 
     32 public class PhaseBeamRS {
     33     public static String LOG_TAG = "PhaseBeam";
     34     public static final int DOT_COUNT = 28;
     35     private Resources mRes;
     36     private RenderScriptGL mRS;
     37     private ScriptC_phasebeam mScript;
     38     int mHeight;
     39     int mWidth;
     40 
     41     private ScriptField_VpConsts mPvConsts;
     42     private Allocation mDotAllocation;
     43     private Allocation mBeamAllocation;
     44 
     45     private ScriptField_Particle mDotParticles;
     46     private Mesh mDotMesh;
     47 
     48     private ScriptField_Particle mBeamParticles;
     49     private Mesh mBeamMesh;
     50 
     51     private ScriptField_VertexColor_s mVertexColors;
     52 
     53     private int mDensityDPI;
     54 
     55     boolean mInited = false;
     56 
     57     public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) {
     58         if (!mInited) {
     59             mDensityDPI = dpi;
     60 
     61             mRS = rs;
     62             mRes = res;
     63 
     64             mWidth = width;
     65             mHeight = height;
     66 
     67             mDotParticles = new ScriptField_Particle(mRS, DOT_COUNT);
     68             Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
     69             smb2.addVertexAllocation(mDotParticles.getAllocation());
     70             smb2.addIndexSetType(Mesh.Primitive.POINT);
     71             mDotMesh = smb2.create();
     72 
     73             mBeamParticles = new ScriptField_Particle(mRS, DOT_COUNT);
     74             Mesh.AllocationBuilder smb3 = new Mesh.AllocationBuilder(mRS);
     75             smb3.addVertexAllocation(mBeamParticles.getAllocation());
     76             smb3.addIndexSetType(Mesh.Primitive.POINT);
     77             mBeamMesh = smb3.create();
     78 
     79             mScript = new ScriptC_phasebeam(mRS, mRes, R.raw.phasebeam);
     80             mScript.set_dotMesh(mDotMesh);
     81             mScript.set_beamMesh(mBeamMesh);
     82             mScript.bind_dotParticles(mDotParticles);
     83             mScript.bind_beamParticles(mBeamParticles);
     84 
     85             mPvConsts = new ScriptField_VpConsts(mRS, 1);
     86 
     87             createProgramVertex();
     88             createProgramRaster();
     89             createProgramFragmentStore();
     90             createProgramFragment();
     91             createBackgroundMesh();
     92             loadTextures();
     93 
     94             mScript.set_densityDPI(mDensityDPI);
     95 
     96             mRS.bindRootScript(mScript);
     97 
     98             mScript.invoke_positionParticles();
     99             mInited = true;
    100         }
    101     }
    102 
    103     private Matrix4f getProjectionNormalized(int w, int h) {
    104         // range -1,1 in the narrow axis at z = 0.
    105         Matrix4f m1 = new Matrix4f();
    106         Matrix4f m2 = new Matrix4f();
    107 
    108         if (w > h) {
    109             float aspect = ((float) w) / h;
    110             m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100);
    111         } else {
    112             float aspect = ((float) h) / w;
    113             m1.loadFrustum(-1, 1, -aspect, aspect, 1, 100);
    114         }
    115 
    116         m2.loadRotate(180, 0, 1, 0);
    117         m1.loadMultiply(m1, m2);
    118 
    119         m2.loadScale(-1, 1, 1);
    120         m1.loadMultiply(m1, m2);
    121 
    122         m2.loadTranslate(0, 0, 1);
    123         m1.loadMultiply(m1, m2);
    124         return m1;
    125     }
    126 
    127     private void updateProjectionMatrices() {
    128         Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
    129         ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
    130         i.MVP = projNorm;
    131         i.scaleSize = mDensityDPI / 240.0f;
    132         mPvConsts.set(i, 0, true);
    133     }
    134 
    135     private void createBackgroundMesh() {
    136         // The composition and colors of the background mesh were plotted on paper and photoshop
    137         // first then translated to the csv file in raw. Points and colors are not random.
    138         ArrayList meshData = new ArrayList();
    139         InputStream inputStream = mRes.openRawResource(R.raw.bgmesh);
    140         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    141         try {
    142             String line;
    143             while ((line = reader.readLine()) != null) {
    144                 meshData.add(line);
    145             }
    146         } catch (IOException e) {
    147             Log.e(LOG_TAG, "Unable to load background mesh from csv file.");
    148         } finally {
    149             try {
    150                 inputStream.close();
    151             } catch (IOException e) {
    152                 Log.e(LOG_TAG, "Unable to close background mesh csv file.");
    153             }
    154         }
    155 
    156         int meshDataSize = meshData.size();
    157         mVertexColors = new ScriptField_VertexColor_s(mRS, meshDataSize);
    158         for(int i=0; i<meshDataSize; i++) {
    159             String line = (String) meshData.get(i);
    160             String[] values = line.split(",");
    161             float xPos = new Float(values[0]);
    162             float yPos = new Float(values[1]);
    163             float red = new Float(values[2]);
    164             float green = new Float(values[3]);
    165             float blue = new Float(values[4]);
    166             mVertexColors.set_position(i, new Float3(xPos, yPos, 0.0f), false);
    167             mVertexColors.set_color(i, new Float4(red, green, blue, 1.0f), false);
    168         }
    169         mVertexColors.copyAll();
    170 
    171         Mesh.AllocationBuilder backgroundBuilder = new Mesh.AllocationBuilder(mRS);
    172         backgroundBuilder.addIndexSetType(Primitive.TRIANGLE);
    173         backgroundBuilder.addVertexAllocation(mVertexColors.getAllocation());
    174         mScript.set_gBackgroundMesh(backgroundBuilder.create());
    175         mScript.bind_vertexColors(mVertexColors);
    176     }
    177 
    178     private Allocation loadTexture(int id) {
    179         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id);
    180         return allocation;
    181     }
    182 
    183     private void loadTextures() {
    184         mDotAllocation = loadTexture(R.drawable.dot);
    185         mBeamAllocation = loadTexture(R.drawable.beam);
    186         mScript.set_textureDot(mDotAllocation);
    187         mScript.set_textureBeam(mBeamAllocation);
    188     }
    189 
    190     private void createProgramVertex() {
    191         ProgramVertex.Builder backgroundBuilder = new ProgramVertex.Builder(mRS);
    192         backgroundBuilder.setShader(mRes, R.raw.bg_vs);
    193         backgroundBuilder.addInput(ScriptField_VertexColor_s.createElement(mRS));
    194         ProgramVertex programVertexBackground = backgroundBuilder.create();
    195         mScript.set_vertBg(programVertexBackground);
    196 
    197         updateProjectionMatrices();
    198 
    199         ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
    200         builder.setShader(mRes, R.raw.dot_vs);
    201         builder.addConstant(mPvConsts.getType());
    202         builder.addInput(mDotMesh.getVertexAllocation(0).getType().getElement());
    203         ProgramVertex pvs = builder.create();
    204         pvs.bindConstants(mPvConsts.getAllocation(), 0);
    205         mRS.bindProgramVertex(pvs);
    206         mScript.set_vertDots(pvs);
    207 
    208     }
    209 
    210     private void createProgramFragment() {
    211         ProgramFragment.Builder backgroundBuilder = new ProgramFragment.Builder(mRS);
    212         backgroundBuilder.setShader(mRes, R.raw.bg_fs);
    213         ProgramFragment programFragmentBackground = backgroundBuilder.create();
    214         mScript.set_fragBg(programFragmentBackground);
    215 
    216         ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
    217         builder.setShader(mRes, R.raw.dot_fs);
    218         builder.addTexture(Program.TextureType.TEXTURE_2D);
    219         ProgramFragment pf = builder.create();
    220         pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
    221         mScript.set_fragDots(pf);
    222 
    223     }
    224 
    225     private void createProgramRaster() {
    226         ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
    227         builder.setPointSpriteEnabled(true);
    228         ProgramRaster pr = builder.create();
    229         mRS.bindProgramRaster(pr);
    230     }
    231 
    232     private void createProgramFragmentStore() {
    233         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
    234         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
    235         mRS.bindProgramStore(builder.create());
    236     }
    237 
    238     public void start() {
    239         mRS.bindRootScript(mScript);
    240     }
    241 
    242     public void stop() {
    243         mRS.bindRootScript(null);
    244     }
    245 
    246     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
    247         mScript.set_xOffset(xOffset);
    248     }
    249 
    250     public void resize(int w, int h) {
    251 
    252     }
    253 
    254 }
    255