Optimizations and animation update

- Changed background to mesh
- Code formatting fixes

Change-Id: I6520c5e506fd0166230e0b9c3748051cc2954201
diff --git a/res/drawable-nodpi/dot.png b/res/drawable-nodpi/dot.png
index fd8729f..586c3e2 100644
--- a/res/drawable-nodpi/dot.png
+++ b/res/drawable-nodpi/dot.png
Binary files differ
diff --git a/res/drawable-nodpi/wallpaper_thumb.png b/res/drawable-nodpi/wallpaper_thumb.png
index b0f604d..33ab307 100644
--- a/res/drawable-nodpi/wallpaper_thumb.png
+++ b/res/drawable-nodpi/wallpaper_thumb.png
Binary files differ
diff --git a/res/raw/bg_fs.glsl b/res/raw/bg_fs.glsl
new file mode 100644
index 0000000..d20885d
--- /dev/null
+++ b/res/raw/bg_fs.glsl
@@ -0,0 +1,5 @@
+varying lowp vec4 color;
+
+void main() {
+    gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/res/raw/bg_vs.glsl b/res/raw/bg_vs.glsl
new file mode 100644
index 0000000..d604369
--- /dev/null
+++ b/res/raw/bg_vs.glsl
@@ -0,0 +1,6 @@
+varying lowp vec4 color;
+
+void main() {
+    color = ATTRIB_color;
+    gl_Position = vec4(ATTRIB_position.x + ATTRIB_offsetX, ATTRIB_position.y, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/res/raw/noisefield_vs.glsl b/res/raw/noisefield_vs.glsl
index ea38887..94f41f2 100644
--- a/res/raw/noisefield_vs.glsl
+++ b/res/raw/noisefield_vs.glsl
@@ -1,17 +1,10 @@
 varying float pointSize;
 varying float alpha;
-
 void main() {
-    vec4 pos;
-    pos.xyz = ATTRIB_position.xyz;
-    pos.w = 1.0;
-    pos.x = pos.x - ATTRIB_offsetX;
+    vec4 pos = vec4(ATTRIB_position.xyz, 1.0);
     gl_Position = UNI_MVP * pos;
 
-    float pointSize = 1.0 + ATTRIB_speed * ATTRIB_scaleSize * 3000.0;
+    float pointSize = 1.0 + ATTRIB_speed * UNI_scaleSize * 2500.0;
     alpha = ATTRIB_alpha;
     gl_PointSize = pointSize;
-}
-
-
-
+}
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 300b45a..e48c411 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="wallpaper_label">Bubble</string>
+    <string name="wallpaper_label">Bubbles</string>
     <string name="wallpaper_author">Google</string>
-    <string name="wallpaper_description">DESC</string>
+    <string name="wallpaper_description">Watch some bubbles</string>
 </resources>
diff --git a/src/com/android/noisefield/NoiseFieldRS.java b/src/com/android/noisefield/NoiseFieldRS.java
index 0ce7ca1..3962e0a 100644
--- a/src/com/android/noisefield/NoiseFieldRS.java
+++ b/src/com/android/noisefield/NoiseFieldRS.java
@@ -1,12 +1,11 @@
 package com.android.noisefield;
 
-import static android.renderscript.Sampler.Value.NEAREST;
-import static android.renderscript.Sampler.Value.WRAP;
-
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.renderscript.Allocation;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
 import android.renderscript.Matrix4f;
 import android.renderscript.Mesh;
 import android.renderscript.Program;
@@ -18,14 +17,13 @@
 import android.renderscript.ProgramVertexFixedFunction;
 import android.renderscript.RenderScriptGL;
 import android.renderscript.Sampler;
+import android.renderscript.Mesh.Primitive;
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
 import android.util.Log;
 
 public class NoiseFieldRS {
 
-    public static final int DOT_COUNT = 300;
-
     private Resources mRes;
     private RenderScriptGL mRS;
     private ScriptC_noisefield mScript;
@@ -34,55 +32,49 @@
     private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
 
     private ScriptField_VpConsts mPvConsts;
-    private Allocation dotAllocation;
-    private Allocation bgAllocation;
-    private Allocation vignetteAllocation;
+    private Allocation mDotAllocation;
+    private ScriptField_VertexColor_s mVertexColors;
+    private ScriptField_Particle mDotParticles;
+    private Mesh mDotMesh;
+    private int mDensityDPI;
 
-    private ScriptField_Particle dotParticles;
-    private Mesh dotMesh;
+    public void init(int dpi, RenderScriptGL rs,
+                     Resources res, int width, int height) {
+        mDensityDPI = dpi;
 
-    private int densityDPI;
+        mRS = rs;
+        mRes = res;
 
-    boolean inited = false;
+        mWidth = width;
+        mHeight = height;
 
-    public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) {
-        if (!inited) {
-            densityDPI = dpi;
+        mOptionsARGB.inScaled = false;
+        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
 
-            mRS = rs;
-            mRes = res;
+        Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
 
-            mWidth = width;
-            mHeight = height;
+        mDotParticles = new ScriptField_Particle(mRS, 150);
+        smb2.addVertexAllocation(mDotParticles.getAllocation());
 
-            mOptionsARGB.inScaled = false;
-            mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        smb2.addIndexSetType(Mesh.Primitive.POINT);
+        mScript = new ScriptC_noisefield(mRS, mRes, R.raw.noisefield);
 
-            dotParticles = new ScriptField_Particle(mRS, DOT_COUNT);
-            Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
-            smb2.addVertexAllocation(dotParticles.getAllocation());
-            smb2.addIndexSetType(Mesh.Primitive.POINT);
-            dotMesh = smb2.create();
 
-            mScript = new ScriptC_noisefield(mRS, mRes, R.raw.noisefield);
-            mScript.set_dotMesh(dotMesh);
-            mScript.bind_dotParticles(dotParticles);
+        mDotMesh = smb2.create();
+        mScript.set_dotMesh(mDotMesh);
+        mScript.bind_dotParticles(mDotParticles);
 
-            mPvConsts = new ScriptField_VpConsts(mRS, 1);
+        mPvConsts = new ScriptField_VpConsts(mRS, 1);
 
-            createProgramVertex();
-            createProgramRaster();
-            createProgramFragmentStore();
-            createProgramFragment();
-            loadTextures();
+        createProgramVertex();
+        createProgramRaster();
+        createProgramFragmentStore();
+        createProgramFragment();
+        createBackgroundMesh();
+        loadTextures();
 
-            mScript.set_densityDPI(densityDPI);
-
-            mRS.bindRootScript(mScript);
-
-            mScript.invoke_positionParticles();
-            inited = true;
-        }
+        mScript.set_densityDPI(mDensityDPI);
+        mScript.invoke_positionParticles();
     }
 
     private Matrix4f getProjectionNormalized(int w, int h) {
@@ -110,49 +102,154 @@
     }
 
     private void updateProjectionMatrices() {
-        Matrix4f proj = new Matrix4f();
-        proj.loadOrthoWindow(mWidth, mHeight);
-
-        Log.d("------------------- UPDATE PROJECTION MATRICES", mWidth + "  " + mHeight);
-
         Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
         ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
-        // i.Proj = projNorm;
         i.MVP = projNorm;
+        i.scaleSize = mDensityDPI/240.0f;
         mPvConsts.set(i, 0, true);
     }
 
+    private void createBackgroundMesh() {
+        // The composition and colors of the background mesh were plotted on paper and photoshop
+        // first then translated to the code you see below. Points and colors are not random.
+
+        mVertexColors = new ScriptField_VertexColor_s(mRS, 48);
+        Float3 a = new Float3(-1.5f, 1.0f, 0.0f);
+        Float3 b = new Float3(0.0f, 1.0f, 0.0f);
+        Float3 c = new Float3(1.5f, 1.0f, 0.0f);
+        Float3 d = new Float3(-1.05f, 0.3f, 0.0f);
+        Float3 e = new Float3(-0.6f, 0.4f, 0.0f);
+        Float3 f = new Float3(0.3f, 0.4f, 0.0f);
+        Float3 g = new Float3(0.0f, 0.2f, 0.0f);
+        Float3 h = new Float3(-0.6f, 0.1f, 0.0f);
+        Float3 i = new Float3(-1.5f, -0.2f, 0.0f);
+        Float3 j = new Float3(-0.45f, -0.3f, 0.0f);
+        Float3 k = new Float3(-1.5f, -1.0f, 0.0f);
+        Float3 l = new Float3(1.5f, -1.0f, 0.0f);
+        mVertexColors.set_position(0, a, false);
+        mVertexColors.set_color(0, (new Float4(0.08f,0.335f,0.406f, 1.0f)), false);
+        mVertexColors.set_position(1, i, false);
+        mVertexColors.set_color(1, (new Float4(0.137f,0.176f,0.225f, 1.0f)), false);
+        mVertexColors.set_position(2, d, false);
+        mVertexColors.set_color(2, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(3, a, false);
+        mVertexColors.set_color(3, (new Float4(0.08f,0.335f,0.406f, 1.0f)), false);
+        mVertexColors.set_position(4, d, false);
+        mVertexColors.set_color(4, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(5, e, false);
+        mVertexColors.set_color(5, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(6, a, false);
+        mVertexColors.set_color(6, (new Float4(0.08f,0.335f,0.406f, 1.0f)), false);
+        mVertexColors.set_position(7, e, false);
+        mVertexColors.set_color(7, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(8, b, false);
+        mVertexColors.set_color(8, (new Float4(0.133f,0.404f,0.478f, 1.0f)), false);
+        mVertexColors.set_position(9, b, false);
+        mVertexColors.set_color(9, (new Float4(0.133f,0.404f,0.478f, 1.0f)), false);
+        mVertexColors.set_position(10, e, false);
+        mVertexColors.set_color(10, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(11, f, false);
+        mVertexColors.set_color(11, (new Float4(0.0f,0.124f,0.178f, 1.0f)), false);
+        mVertexColors.set_position(12, b, false);
+        mVertexColors.set_color(12, (new Float4(0.133f,0.404f,0.478f, 1.0f)), false);
+        mVertexColors.set_position(13, f, false);
+        mVertexColors.set_color(13, (new Float4(0.0f,0.124f,0.178f, 1.0f)), false);
+        mVertexColors.set_position(14, c, false);
+        mVertexColors.set_color(14, (new Float4(0.002f,0.173f,0.231f, 1.0f)), false);
+        mVertexColors.set_position(15, c, false);
+        mVertexColors.set_color(15, (new Float4(0.002f,0.173f,0.231f, 1.0f)), false);
+        mVertexColors.set_position(16, f, false);
+        mVertexColors.set_color(16, (new Float4(0.0f,0.124f,0.178f, 1.0f)), false);
+        mVertexColors.set_position(17, l, false);
+        mVertexColors.set_color(17, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(18, f, false);
+        mVertexColors.set_color(18, (new Float4(0.0f,0.124f,0.178f, 1.0f)), false);
+        mVertexColors.set_position(19, e, false);
+        mVertexColors.set_color(19, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(20, g, false);
+        mVertexColors.set_color(20, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(21, f, false);
+        mVertexColors.set_color(21, (new Float4(0.0f,0.124f,0.178f, 1.0f)), false);
+        mVertexColors.set_position(22, g, false);
+        mVertexColors.set_color(22, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(23, l, false);
+        mVertexColors.set_color(23, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(24, g, false);
+        mVertexColors.set_color(24, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(25, e, false);
+        mVertexColors.set_color(25, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(26, h, false);
+        mVertexColors.set_color(26, (new Float4(0.002f,0.196f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(27, h, false);
+        mVertexColors.set_color(27, (new Float4(0.002f,0.196f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(28, e, false);
+        mVertexColors.set_color(28, (new Float4(0.0f,0.184f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(29, d, false);
+        mVertexColors.set_color(29, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(30, d, false);
+        mVertexColors.set_color(30, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(31, i, false);
+        mVertexColors.set_color(31, (new Float4(0.137f,0.176f,0.225f, 1.0f)), false);
+        mVertexColors.set_position(32, h, false);
+        mVertexColors.set_color(32, (new Float4(0.002f,0.196f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(33, j, false);
+        mVertexColors.set_color(33, (new Float4(0.002f,0.059f,0.09f, 1.0f)), false);
+        mVertexColors.set_position(34, h, false);
+        mVertexColors.set_color(34, (new Float4(0.002f,0.196f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(35, i, false);
+        mVertexColors.set_color(35, (new Float4(0.137f,0.176f,0.225f, 1.0f)), false);
+        mVertexColors.set_position(36, j, false);
+        mVertexColors.set_color(36, (new Float4(0.002f,0.059f,0.09f, 1.0f)), false);
+        mVertexColors.set_position(37, i, false);
+        mVertexColors.set_color(37, (new Float4(0.137f,0.176f,0.225f, 1.0f)), false);
+        mVertexColors.set_position(38, k, false);
+        mVertexColors.set_color(38, (new Float4(0.204f,0.212f,0.218f, 1.0f)), false);
+        mVertexColors.set_position(39, l, false);
+        mVertexColors.set_color(39, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(40, j, false);
+        mVertexColors.set_color(40, (new Float4(0.002f,0.059f,0.09f, 1.0f)), false);
+        mVertexColors.set_position(41, k, false);
+        mVertexColors.set_color(41, (new Float4(0.204f,0.212f,0.218f, 1.0f)), false);
+        mVertexColors.set_position(42, g, false);
+        mVertexColors.set_color(42, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(43, h, false);
+        mVertexColors.set_color(43, (new Float4(0.002f,0.196f,0.233f, 1.0f)), false);
+        mVertexColors.set_position(44, j, false);
+        mVertexColors.set_color(44, (new Float4(0.002f,0.059f,0.09f, 1.0f)), false);
+        mVertexColors.set_position(45, l, false);
+        mVertexColors.set_color(45, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(46, g, false);
+        mVertexColors.set_color(46, (new Float4(0.0f,0.088f,0.135f, 1.0f)), false);
+        mVertexColors.set_position(47, j, false);
+        mVertexColors.set_color(47, (new Float4(0.002f,0.059f,0.09f, 1.0f)), false);
+
+        mVertexColors.copyAll();
+
+        Mesh.AllocationBuilder backgroundBuilder = new Mesh.AllocationBuilder(mRS);
+        backgroundBuilder.addIndexSetType(Primitive.TRIANGLE);
+        backgroundBuilder.addVertexAllocation(mVertexColors.getAllocation());
+        mScript.set_gBackgroundMesh(backgroundBuilder.create());
+
+        mScript.bind_vertexColors(mVertexColors);
+    }
+
     private Allocation loadTexture(int id) {
         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id);
         return allocation;
     }
 
-    private Allocation loadTextureARGB(int id) {
-        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
-        return Allocation.createFromBitmap(mRS, b,
-                Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                Allocation.USAGE_GRAPHICS_TEXTURE);
-    }
-
     private void loadTextures() {
-        dotAllocation = loadTexture(R.drawable.dot);
-        bgAllocation = loadTexture(R.drawable.bg);
-        vignetteAllocation = loadTextureARGB(R.drawable.vignette);
-        mScript.set_textureDot(dotAllocation);
-        mScript.set_textureBg(bgAllocation);
-        mScript.set_textureVignette(vignetteAllocation);
+        mDotAllocation = loadTexture(R.drawable.dot);
+        mScript.set_textureDot(mDotAllocation);
     }
 
     private void createProgramVertex() {
-        ProgramVertexFixedFunction.Constants mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(
-                mRS);
-        Matrix4f proj = new Matrix4f();
-        proj.loadOrthoWindow(mWidth, mHeight);
-        mPvOrthoAlloc.setProjection(proj);
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        ProgramVertex pv = pvb.create();
-        ((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc);
-        mScript.set_vertBg(pv);
+        ProgramVertex.Builder backgroundBuilder = new ProgramVertex.Builder(mRS);
+        backgroundBuilder.setShader(mRes, R.raw.bg_vs);
+        backgroundBuilder.addInput(ScriptField_VertexColor_s.createElement(mRS));
+        ProgramVertex programVertexBackground = backgroundBuilder.create();
+        mScript.set_vertBg(programVertexBackground);
+
 
         updateProjectionMatrices();
 
@@ -160,36 +257,23 @@
         builder = new ProgramVertex.Builder(mRS);
         builder.setShader(mRes, R.raw.noisefield_vs);
         builder.addConstant(mPvConsts.getType());
-        builder.addInput(dotMesh.getVertexAllocation(0).getType().getElement());
+        builder.addInput(mDotMesh.getVertexAllocation(0).getType().getElement());
+
         ProgramVertex pvs = builder.create();
         pvs.bindConstants(mPvConsts.getAllocation(), 0);
         mRS.bindProgramVertex(pvs);
         mScript.set_vertDots(pvs);
-
     }
 
     private void createProgramFragment() {
-        Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
-        samplerBuilder.setMinification(NEAREST);
-        samplerBuilder.setMagnification(NEAREST);
-        samplerBuilder.setWrapS(WRAP);
-        samplerBuilder.setWrapT(WRAP);
-        Sampler sn = samplerBuilder.create();
-        ProgramFragmentFixedFunction.Builder builderff = new ProgramFragmentFixedFunction.Builder(
-                mRS);
-        builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
-
-        builderff.setVaryingColor(true);
-        ProgramFragment pfff = builderff.create();
-
-        mScript.set_fragBg(pfff);
-        pfff.bindSampler(sn, 0);
+        ProgramFragment.Builder backgroundBuilder = new ProgramFragment.Builder(mRS);
+        backgroundBuilder.setShader(mRes, R.raw.bg_fs);
+        ProgramFragment programFragmentBackground = backgroundBuilder.create();
+        mScript.set_fragBg(programFragmentBackground);
 
         ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
-        builder = new ProgramFragment.Builder(mRS);
-        builder.addTexture(Program.TextureType.TEXTURE_2D);
         builder.setShader(mRes, R.raw.noisefield_fs);
+        builder.addTexture(Program.TextureType.TEXTURE_2D);
         ProgramFragment pf = builder.create();
         pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
         mScript.set_fragDots(pf);
@@ -204,15 +288,8 @@
 
     private void createProgramFragmentStore() {
         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
-        // builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA );
-        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
-        // why alpha no work with additive blending?
-        // builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE );
         mRS.bindProgramStore(builder.create());
-        mScript.set_storeAdd(builder.create());
-
-        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        mScript.set_storeAlpha(builder.create());
     }
 
     public void start() {
@@ -229,17 +306,7 @@
     }
 
     public void resize(int w, int h) {
-        // why do i need to do this again when surface changed for wallpaper, but not when as an app?
-        ProgramVertexFixedFunction.Constants mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(
-                mRS);
-        Matrix4f proj = new Matrix4f();
-        proj.loadOrthoWindow(w, h);
-        mPvOrthoAlloc.setProjection(proj);
 
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        ProgramVertex pv = pvb.create();
-        ((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc);
-        mScript.set_vertBg(pv);
     }
 
 }
diff --git a/src/com/android/noisefield/NoiseFieldWallpaper.java b/src/com/android/noisefield/NoiseFieldWallpaper.java
index 7d26bd9..09661cf 100644
--- a/src/com/android/noisefield/NoiseFieldWallpaper.java
+++ b/src/com/android/noisefield/NoiseFieldWallpaper.java
@@ -28,7 +28,7 @@
             super.onCreate(surfaceHolder);
             setTouchEventsEnabled(true);
             surfaceHolder.setSizeFromLayout();
-            surfaceHolder.setFormat(PixelFormat.RGBA_8888);
+            surfaceHolder.setFormat(PixelFormat.RGB_888);
 
             DisplayMetrics metrics = new DisplayMetrics();
             ((WindowManager) getApplication().getSystemService(Service.WINDOW_SERVICE))
diff --git a/src/com/android/noisefield/noisefield.rs b/src/com/android/noisefield/noisefield.rs
index 1fb2ad9..f6b16d8 100644
--- a/src/com/android/noisefield/noisefield.rs
+++ b/src/com/android/noisefield/noisefield.rs
@@ -8,7 +8,6 @@
 
 
 rs_allocation textureDot;
-rs_allocation textureBg;
 rs_allocation textureVignette;
 
 rs_program_vertex vertBg;
@@ -20,33 +19,37 @@
 rs_program_store storeAlpha;
 rs_program_store storeAdd;
 
-typedef struct __attribute__((packed, aligned(4))) Particle {
-    float3 position;
-    float offsetX;
+typedef struct VpConsts {
+    rs_matrix4x4 MVP;
     float scaleSize;
+} VpConsts_t;
+VpConsts_t *vpConstants;
+
+typedef struct Particle {
+    float3 position;
     float speed;
     float wander;
     float alphaStart;
     float alpha;
-    float life;
-    float death;
+    int life;
+    int death;
 } Particle_t;
+Particle_t *dotParticles;
 
-typedef struct VpConsts {
-    rs_matrix4x4 MVP;
-} VpConsts_t;
-VpConsts_t *vpConstants;
 
-Particle_t *dotParticles; 
+typedef struct VertexColor_s {
+    float3 position;
+    float4 color;
+    float offsetX;
+
+} VertexColor;
+VertexColor* vertexColors;
+
 rs_mesh dotMesh;
-
+rs_mesh gBackgroundMesh;
 
 float densityDPI;
-float xOffset;
-
-
-
-
+float xOffset = 0.0;
 
 #define B 0x100
 #define BM 0xff
@@ -149,151 +152,100 @@
     q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
     b = mix(u, v, sx);
 
-    //return 1.5f * mix(a, b, sy);
-    return 8.0f * mix(a, b, sy);
+    return 1.5f * mix(a, b, sy);
 }
 
-
-
-
-
-
 void positionParticles(){
-    rsDebug("HELLO!!!!!!!!!!", rsUptimeMillis());
-
-    float width = rsgGetWidth();
-    float height = rsgGetHeight();
-
     Particle_t* particle = dotParticles;
     int size = rsAllocationGetDimX(rsGetAllocation(dotParticles));
-    
-    
-    
     for(int i=0; i<size; i++){
-    
-
         particle->position.x = rsRand(-1.0f, 1.0f);
         particle->position.y = rsRand(-1.0f, 1.0f);
-        particle->scaleSize = densityDPI/240.0f;
-        particle->position.z = 0.0;
-        particle->offsetX = xOffset;
         particle->speed = rsRand(0.0002f, 0.02f);
         particle->wander = rsRand(0.50f, 1.5f);
-        particle->death = 0.0;
-        particle->life = rsRand(300.0, 800.0f);
+        particle->death = 0;
+        particle->life = rsRand(300, 800);
         particle->alphaStart = rsRand(0.01f, 1.0f);
         particle->alpha = particle->alphaStart;
         particle++;
-        
-        float dist = sqrt(particle->position.x*particle->position.x + particle->position.y*particle->position.y);
-        if(dist < 0.75){
-            dist = 0;
-        } else {
-            dist = dist-0.75;
-        }
-        if(particle->alpha < 1.0f){
-            particle->alpha+=0.01;
-            particle->alpha *= (1-dist);
-        }
-        
     }
-    
-    
-    
-    
 }
 
-
-
 int root(){
-    float width = rsgGetWidth();
-    float height = rsgGetHeight();
-    
-    
-    
-    rsgClearColor(0.0f, 0.f, 0.f, 0.5f);
-    
-    rsgBindProgramStore(storeAdd);
-    
-    // bg
-    rsgBindProgramVertex(vertBg);
-    rsgBindProgramFragment(fragBg);
-    
-    rsgBindTexture(fragBg, 0, textureBg);
-    rsgDrawRect(0.0f, 0.0f, width, height, 0.0f);
-    
-    
+    rsgClearColor(0.0, 0.0, 0.0, 1.0f);
+
+    VertexColor* vert = vertexColors;
+    int size = rsAllocationGetDimX(rsGetAllocation(vertexColors));
+    for(int i=0; i<size; i++){
+        vert->offsetX = xOffset;
+        vert++;
+    }
+
     rsgBindProgramVertex(vertDots);
     rsgBindProgramFragment(fragDots);
     rsgBindTexture(fragDots, 0, textureDot);
-    
-    // dots
-    Particle_t* particle = dotParticles;
-    int size = rsAllocationGetDimX(rsGetAllocation(dotParticles));
-    for(int i=0; i<size; i++){
-        
-        if(particle->life < 0 || particle->position.x < -1.1 || particle->position.x >1.1 || particle->position.y < -1.7 || particle->position.y >1.7){
-            particle->position.x = rsRand(-1.0f, 1.0f);
-            particle->position.y = rsRand(-1.0f, 1.0f);
-
-            particle->speed = rsRand(0.0002f, 0.02f);
-            particle->wander = rsRand(0.50f, 1.5f);
-            particle->life = rsRand(300.0f, 800.0f);
-            particle->alphaStart = rsRand(0.01f, 1.0f);
-            particle->alpha = particle->alphaStart;
-            
-            particle->death = 0.0;
-        }
-        
-        
-        
-        
-            float noiseval = noisef2(particle->position.x*0.65, particle->position.y*0.65);
-            
-            float speed = noiseval * particle->speed + 0.01;
-            float angle = 360 * noiseval * particle->wander;
-            float rads = angle * 3.14159265 / 180.0;
-        
-            particle->position.x += cos(rads) * speed * 0.24;
-            particle->position.y += sin(rads) * speed * 0.24;
-        
-    
-            particle->life--;
-            particle->death++;
-        
-            float dist = sqrt(particle->position.x*particle->position.x + particle->position.y*particle->position.y);
-            if(dist < 0.75){
-                dist = 0;
-                particle->alphaStart *= (1-dist);
-                
-            } else {
-                dist = dist-0.75;
-                if(particle->alphaStart < 1.0f){
-                    particle->alphaStart +=0.01;
-                    particle->alphaStart *= (1-dist);
-                    
-                    
-                }
-            }
-            
-        
-            if(particle->death < 101.0){
-                particle->alpha = (particle->alphaStart)*(particle->death)/100.0;
-            } else if(particle->life < 101.0){
-                particle->alpha = particle->alpha*particle->life/100.0;
-            } else {
-                particle->alpha = particle->alphaStart;
-            }
-        
-            particle->offsetX = xOffset;
-        
-        
-        
-        particle++;
-    }
-    
-    
     rsgDrawMesh(dotMesh);
 
+    // bg
+    rsgBindProgramVertex(vertBg);
+    rsgBindProgramFragment(fragBg);
+    rsgDrawMesh(gBackgroundMesh);
+
+    // dots
+    Particle_t* particle = dotParticles;
+    size = rsAllocationGetDimX(rsGetAllocation(dotParticles));
+    for(int i=0; i<size; i++){
+
+        if(particle->life < 0 || particle->position.x < -1.2 ||
+           particle->position.x >1.2 || particle->position.y < -1.7 ||
+           particle->position.y >1.7){
+            particle->position.x = rsRand(-1.0f, 1.0f);
+            particle->position.y = rsRand(-1.0f, 1.0f);
+            particle->speed = rsRand(0.0002f, 0.02f);
+            particle->wander = rsRand(0.50f, 1.5f);
+            particle->death = 0;
+            particle->life = rsRand(300, 800);
+            particle->alphaStart = rsRand(0.01f, 1.0f);
+            particle->alpha = particle->alphaStart;
+        }
+
+        float noiseval = noisef2(particle->position.x, particle->position.y);
+
+        float speed = noiseval * particle->speed + 0.01;
+        float angle = 360 * noiseval * particle->wander;
+        float rads = angle * 3.14159265 / 180.0;
+
+        particle->position.x += cos(rads) * speed * 0.24;
+        particle->position.y += sin(rads) * speed * 0.24;
+
+        particle->life--;
+        particle->death++;
+
+        float dist = sqrt(particle->position.x*particle->position.x +
+                          particle->position.y*particle->position.y);
+        if(dist < 0.95){
+            dist = 0;
+            particle->alphaStart *= (1-dist);
+
+        } else {
+            dist = dist-0.95;
+            if(particle->alphaStart < 1.0f){
+                particle->alphaStart +=0.01;
+                particle->alphaStart *= (1-dist);
+            }
+        }
+
+        if(particle->death < 101){
+            particle->alpha = (particle->alphaStart)*(particle->death)/100.0;
+        } else if(particle->life < 101){
+            particle->alpha = particle->alpha*particle->life/100.0;
+        } else {
+            particle->alpha = particle->alphaStart;
+        }
+
+        particle++;
+    }
+
     return 35;
+
 }