176d6ea97b0d3e64787398a179e015443dde9c024Winson Chungpackage com.android.noisefield;
276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
376d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.content.res.Resources;
476d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.graphics.Bitmap;
576d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.graphics.BitmapFactory;
676d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.Allocation;
733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hongimport android.renderscript.Float3;
833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hongimport android.renderscript.Float4;
976d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.Matrix4f;
1076d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.Mesh;
1176d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.Program;
1276d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramFragment;
1376d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramFragmentFixedFunction;
1476d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramRaster;
1576d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramStore;
1676d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramVertex;
1776d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramVertexFixedFunction;
1876d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.RenderScriptGL;
1976d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.Sampler;
2033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hongimport android.renderscript.Mesh.Primitive;
2176d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramStore.BlendDstFunc;
2276d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.renderscript.ProgramStore.BlendSrcFunc;
234f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport android.os.Bundle;
244f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport android.app.WallpaperManager;
2576d6ea97b0d3e64787398a179e015443dde9c024Winson Chungimport android.util.Log;
264f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport android.view.MotionEvent;
274f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport java.io.InputStreamReader;
284f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport java.io.InputStream;
294f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport java.io.BufferedReader;
304f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport java.io.IOException;
314f6e266df7b4384c43deeac4643a79dcf1063636Leon Hongimport java.util.ArrayList;
3276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
3376d6ea97b0d3e64787398a179e015443dde9c024Winson Chungpublic class NoiseFieldRS {
344f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    public static String LOG_TAG = "NoiseField";
3576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
3676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private Resources mRes;
3776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private RenderScriptGL mRS;
3876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private ScriptC_noisefield mScript;
394f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    private int mHeight;
404f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    private int mWidth;
414f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    private boolean mTouchDown;
4276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
4376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
4476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private ScriptField_VpConsts mPvConsts;
4533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private Allocation mDotAllocation;
4633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private ScriptField_VertexColor_s mVertexColors;
4733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private ScriptField_Particle mDotParticles;
4833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private Mesh mDotMesh;
4933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private int mDensityDPI;
5076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
5133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    public void init(int dpi, RenderScriptGL rs,
5233113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong                     Resources res, int width, int height) {
5333113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mDensityDPI = dpi;
5433113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mRS = rs;
5533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mRes = res;
5676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
5733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mWidth = width;
5833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mHeight = height;
5976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
6033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mOptionsARGB.inScaled = false;
6133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
6276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
6333113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
6476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
654f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        mDotParticles = new ScriptField_Particle(mRS, 83);
6633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        smb2.addVertexAllocation(mDotParticles.getAllocation());
6776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
6833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        smb2.addIndexSetType(Mesh.Primitive.POINT);
6933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript = new ScriptC_noisefield(mRS, mRes, R.raw.noisefield);
7076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
7133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mDotMesh = smb2.create();
7233113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_dotMesh(mDotMesh);
7333113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.bind_dotParticles(mDotParticles);
7476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
7533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mPvConsts = new ScriptField_VpConsts(mRS, 1);
7676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
7733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        createProgramVertex();
7833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        createProgramRaster();
7933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        createProgramFragmentStore();
8033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        createProgramFragment();
8133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        createBackgroundMesh();
8233113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        loadTextures();
8376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
8433113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_densityDPI(mDensityDPI);
8533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.invoke_positionParticles();
8676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
8776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
8876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private Matrix4f getProjectionNormalized(int w, int h) {
8976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        // range -1,1 in the narrow axis at z = 0.
9076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        Matrix4f m1 = new Matrix4f();
9176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        Matrix4f m2 = new Matrix4f();
9276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
9376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        if (w > h) {
9476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung            float aspect = ((float) w) / h;
9576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung            m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100);
9676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        } else {
9776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung            float aspect = ((float) h) / w;
982215802fd84dfb4dfe5b11c05aacd6f1d1eb890fLeon Hong            m1.loadFrustum(-0.5f, 1, -aspect, aspect, 1, 100);
9976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        }
10076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
10176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m2.loadRotate(180, 0, 1, 0);
10276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m1.loadMultiply(m1, m2);
10376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
10476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m2.loadScale(-1, 1, 1);
10576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m1.loadMultiply(m1, m2);
10676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
10776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m2.loadTranslate(0, 0, 1);
10876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        m1.loadMultiply(m1, m2);
10976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        return m1;
11076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
11176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
11276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void updateProjectionMatrices() {
11376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
11476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
11576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        i.MVP = projNorm;
11633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        i.scaleSize = mDensityDPI/240.0f;
11776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mPvConsts.set(i, 0, true);
11876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
11976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
12033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    private void createBackgroundMesh() {
12133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        // The composition and colors of the background mesh were plotted on paper and photoshop
1224f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        // first then translated to the csv file in raw. Points and colors are not random.
1234f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        ArrayList<String> meshData = new ArrayList<String>();
1244f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        InputStream inputStream = mRes.openRawResource(R.raw.bgmesh);
1254f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
1264f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        try {
1274f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            String line;
1284f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            while ((line = reader.readLine()) != null) {
1294f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                meshData.add(line);
1304f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            }
1314f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        } catch (IOException e) {
1324f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            Log.e(LOG_TAG, "Unable to load background mesh from csv file.");
1334f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        } finally {
1344f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            try {
1354f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                inputStream.close();
1364f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            } catch (IOException e) {
1374f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                Log.e(LOG_TAG, "Unable to close background mesh csv file.");
1384f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            }
1394f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        }
14033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
1414f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        int meshDataSize = meshData.size();
1424f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        mVertexColors = new ScriptField_VertexColor_s(mRS, meshDataSize);
1434f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        for (int i=0; i<meshDataSize; i++) {
1444f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            String line = (String) meshData.get(i);
1454f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            String[] values = line.split(",");
1464f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            float xPos = Float.parseFloat(values[0]);
1474f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            float yPos = Float.parseFloat(values[1]);
1484f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            float red = Float.parseFloat(values[2]);
1494f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            float green = Float.parseFloat(values[3]);
1504f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            float blue = Float.parseFloat(values[4]);
1514f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            mVertexColors.set_position(i, new Float3(xPos, yPos, 0.0f), false);
1524f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            mVertexColors.set_color(i, new Float4(red, green, blue, 1.0f), false);
1534f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        }
15433113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mVertexColors.copyAll();
15533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
15633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        Mesh.AllocationBuilder backgroundBuilder = new Mesh.AllocationBuilder(mRS);
15733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        backgroundBuilder.addIndexSetType(Primitive.TRIANGLE);
15833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        backgroundBuilder.addVertexAllocation(mVertexColors.getAllocation());
15933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_gBackgroundMesh(backgroundBuilder.create());
16033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.bind_vertexColors(mVertexColors);
16133113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong    }
16233113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
16376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private Allocation loadTexture(int id) {
16476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id);
16576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        return allocation;
16676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
16776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
16876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void loadTextures() {
16933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mDotAllocation = loadTexture(R.drawable.dot);
17033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_textureDot(mDotAllocation);
17176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
17276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
17376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void createProgramVertex() {
17433113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        ProgramVertex.Builder backgroundBuilder = new ProgramVertex.Builder(mRS);
17533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        backgroundBuilder.setShader(mRes, R.raw.bg_vs);
17633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        backgroundBuilder.addInput(ScriptField_VertexColor_s.createElement(mRS));
17733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        ProgramVertex programVertexBackground = backgroundBuilder.create();
17833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_vertBg(programVertexBackground);
17933113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
18076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        updateProjectionMatrices();
18176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
18276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
18376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        builder = new ProgramVertex.Builder(mRS);
18476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        builder.setShader(mRes, R.raw.noisefield_vs);
18576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        builder.addConstant(mPvConsts.getType());
18633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        builder.addInput(mDotMesh.getVertexAllocation(0).getType().getElement());
18733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
18876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramVertex pvs = builder.create();
18976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        pvs.bindConstants(mPvConsts.getAllocation(), 0);
19076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mRS.bindProgramVertex(pvs);
19176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mScript.set_vertDots(pvs);
19276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
19376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
19476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void createProgramFragment() {
19533113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        ProgramFragment.Builder backgroundBuilder = new ProgramFragment.Builder(mRS);
19633113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        backgroundBuilder.setShader(mRes, R.raw.bg_fs);
19733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        ProgramFragment programFragmentBackground = backgroundBuilder.create();
19833113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        mScript.set_fragBg(programFragmentBackground);
19976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
20076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
20176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        builder.setShader(mRes, R.raw.noisefield_fs);
20233113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        builder.addTexture(Program.TextureType.TEXTURE_2D);
20376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramFragment pf = builder.create();
20476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
20576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mScript.set_fragDots(pf);
20676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
20776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
20876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void createProgramRaster() {
20976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
21076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        builder.setPointSpriteEnabled(true);
21176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramRaster pr = builder.create();
21276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mRS.bindProgramRaster(pr);
21376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
21476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
21576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    private void createProgramFragmentStore() {
21676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
21733113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE );
21876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mRS.bindProgramStore(builder.create());
21976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
22076d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
22176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    public void start() {
22276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mRS.bindRootScript(mScript);
22376d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
22476d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
22576d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    public void stop() {
22676d6ea97b0d3e64787398a179e015443dde9c024Winson Chung        mRS.bindRootScript(null);
22776d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
22876d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
22976d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    public void resize(int w, int h) {
23033113fcccefc422f984b6fbb89293c23d7d33a27Leon Hong
23176d6ea97b0d3e64787398a179e015443dde9c024Winson Chung    }
23276d6ea97b0d3e64787398a179e015443dde9c024Winson Chung
2334f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    public void onTouchEvent(MotionEvent ev) {
2344f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        int act = ev.getActionMasked();
2354f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        if (act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP) {
2364f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            if(mTouchDown){
2374f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                mTouchDown = false;
2384f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                mScript.set_touchDown(mTouchDown);
2394f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            }
2404f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            return;
2414f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        } else if(   act == MotionEvent.ACTION_DOWN
2424f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                  || act == MotionEvent.ACTION_MOVE
2434f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                  || act == MotionEvent.ACTION_POINTER_DOWN) {
2444f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            int pcount = ev.getPointerCount();
2454f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong
2464f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            if(!mTouchDown){
2474f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                mTouchDown = true;
2484f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                mScript.set_touchDown(mTouchDown);
2494f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            }
2504f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            if(pcount > 0){
2514f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                // just send first pointer position
2524f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong                mScript.invoke_touch(ev.getX(0), ev.getY(0));
2534f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong            }
2544f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong        }
2554f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong    }
2564f6e266df7b4384c43deeac4643a79dcf1063636Leon Hong}