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                                                Allocation.MipmapControl.MIPMAP_NONE,
    181                                                Allocation.USAGE_GRAPHICS_TEXTURE);
    182         return allocation;
    183     }
    184 
    185     private void loadTextures() {
    186         mDotAllocation = loadTexture(R.drawable.dot);
    187         mBeamAllocation = loadTexture(R.drawable.beam);
    188         mScript.set_textureDot(mDotAllocation);
    189         mScript.set_textureBeam(mBeamAllocation);
    190     }
    191 
    192     private void createProgramVertex() {
    193         ProgramVertex.Builder backgroundBuilder = new ProgramVertex.Builder(mRS);
    194         backgroundBuilder.setShader(mRes, R.raw.bg_vs);
    195         backgroundBuilder.addInput(ScriptField_VertexColor_s.createElement(mRS));
    196         ProgramVertex programVertexBackground = backgroundBuilder.create();
    197         mScript.set_vertBg(programVertexBackground);
    198 
    199         updateProjectionMatrices();
    200 
    201         ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
    202         builder.setShader(mRes, R.raw.dot_vs);
    203         builder.addConstant(mPvConsts.getType());
    204         builder.addInput(mDotMesh.getVertexAllocation(0).getType().getElement());
    205         ProgramVertex pvs = builder.create();
    206         pvs.bindConstants(mPvConsts.getAllocation(), 0);
    207         mRS.bindProgramVertex(pvs);
    208         mScript.set_vertDots(pvs);
    209 
    210     }
    211 
    212     private void createProgramFragment() {
    213         ProgramFragment.Builder backgroundBuilder = new ProgramFragment.Builder(mRS);
    214         backgroundBuilder.setShader(mRes, R.raw.bg_fs);
    215         ProgramFragment programFragmentBackground = backgroundBuilder.create();
    216         mScript.set_fragBg(programFragmentBackground);
    217 
    218         ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
    219         builder.setShader(mRes, R.raw.dot_fs);
    220         builder.addTexture(Program.TextureType.TEXTURE_2D);
    221         ProgramFragment pf = builder.create();
    222         pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
    223         mScript.set_fragDots(pf);
    224 
    225     }
    226 
    227     private void createProgramRaster() {
    228         ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
    229         builder.setPointSpriteEnabled(true);
    230         ProgramRaster pr = builder.create();
    231         mRS.bindProgramRaster(pr);
    232     }
    233 
    234     private void createProgramFragmentStore() {
    235         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
    236         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
    237         mRS.bindProgramStore(builder.create());
    238     }
    239 
    240     public void start() {
    241         mRS.bindRootScript(mScript);
    242     }
    243 
    244     public void stop() {
    245         mRS.bindRootScript(null);
    246     }
    247 
    248     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
    249         mScript.set_xOffset(xOffset);
    250     }
    251 
    252     public void resize(int w, int h) {
    253 
    254     }
    255 
    256 }
    257