Optimizations and animation update

- changed global vars used only in .rs to static
- New background, new colors, more chroma shifts
- Added description
- Updated thumbnail

Change-Id: I17be3b785bac07258b606a70fdc7fd39a78e5b26
diff --git a/res/drawable-nodpi/beam.png b/res/drawable-nodpi/beam.png
index e687f12..5e6a563 100644
--- a/res/drawable-nodpi/beam.png
+++ b/res/drawable-nodpi/beam.png
Binary files differ
diff --git a/res/drawable-nodpi/bg.png b/res/drawable-nodpi/bg.png
deleted file mode 100644
index 987555d..0000000
--- a/res/drawable-nodpi/bg.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-nodpi/dot.png b/res/drawable-nodpi/dot.png
index 0a541da..a452f86 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 29d7a70..28cefdf 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..8eb23b3
--- /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/3.5, ATTRIB_position.y, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/res/raw/dot_vs.glsl b/res/raw/dot_vs.glsl
index 3a82eba..e4ebeed 100644
--- a/res/raw/dot_vs.glsl
+++ b/res/raw/dot_vs.glsl
@@ -2,8 +2,8 @@
 
 void main() {
     vec4 objPos = vec4(ATTRIB_position, 1.0);
-    float tmpPointSize = objPos.z*10.0;
-    pointSize = 0.5-tmpPointSize/800.0;
+    float tmpPointSize = objPos.z*7.0;
+    pointSize = 0.5-tmpPointSize/1000.0;
     objPos.z = 0.0;
     objPos.x = objPos.x - ATTRIB_offsetX * tmpPointSize/100.0;
     gl_Position = objPos;
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 67f209d..9fb302b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2,5 +2,5 @@
 <resources>
     <string name="wallpaper_label">Phase Beam</string>
     <string name="wallpaper_author">Google</string>
-    <string name="wallpaper_description">DESC</string>
+    <string name="wallpaper_description">Phase beam themed wallpaper</string>
 </resources>
diff --git a/src/com/android/phasebeam/PhaseBeamRS.java b/src/com/android/phasebeam/PhaseBeamRS.java
index 0bf126d..547f5f5 100644
--- a/src/com/android/phasebeam/PhaseBeamRS.java
+++ b/src/com/android/phasebeam/PhaseBeamRS.java
@@ -18,10 +18,14 @@
 import android.renderscript.Sampler;
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.Mesh.Primitive;
+import android.graphics.Color;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
 
 public class PhaseBeamRS {
 
-    public static final int DOT_COUNT = 18;
+    public static final int DOT_COUNT = 28;
     private Resources mRes;
     private RenderScriptGL mRS;
     private ScriptC_phasebeam mScript;
@@ -31,7 +35,6 @@
     private ScriptField_VpConsts mPvConsts;
     private Allocation dotAllocation;
     private Allocation beamAllocation;
-    private Allocation bgAllocation;
 
     private ScriptField_Particle dotParticles;
     private Mesh dotMesh;
@@ -39,6 +42,8 @@
     private ScriptField_Particle beamParticles;
     private Mesh beamMesh;
 
+    private ScriptField_VertexColor_s vertexColors;
+
     private int densityDPI;
 
     boolean inited = false;
@@ -77,6 +82,7 @@
             createProgramRaster();
             createProgramFragmentStore();
             createProgramFragment();
+            createBackgroundMesh();
             loadTextures();
 
             mScript.set_densityDPI(densityDPI);
@@ -120,6 +126,132 @@
         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.
+
+        vertexColors = new ScriptField_VertexColor_s(mRS, 48);
+
+        Float3 a = new Float3(-1.25f, 1.0f, 0.0f);
+        Float3 b = new Float3(0.0f, 1.0f, 0.0f);
+        Float3 c = new Float3(1.25f, 1.0f, 0.0f);
+        Float3 d = new Float3(-0.875f, 0.3f, 0.0f);
+        Float3 e = new Float3(-0.5f, 0.4f, 0.0f);
+        Float3 f = new Float3(0.25f, 0.2f, 0.0f);
+        Float3 g = new Float3(0.0f, 0.2f, 0.0f);
+        Float3 h = new Float3(-0.625f, 0.1f, 0.0f);
+        Float3 i = new Float3(-1.25f, -0.2f, 0.0f);
+        Float3 j = new Float3(-0.125f, -0.6f, 0.0f);
+        Float3 k = new Float3(-1.25f, -1.0f, 0.0f);
+        Float3 l = new Float3(1.25f, -1.0f, 0.0f);
+        vertexColors.set_position(0, a, false);
+        vertexColors.set_color(0, (new Float4(0.0f,0.584f,1.0f, 1.0f)), false);
+        vertexColors.set_position(1, i, false);
+        vertexColors.set_color(1, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(2, d, false);
+        vertexColors.set_color(2, (new Float4(0.51f,0.549f,0.929f, 1.0f)), false);
+        vertexColors.set_position(3, a, false);
+        vertexColors.set_color(3, (new Float4(0.0f,0.584f,1.0f, 1.0f)), false);
+        vertexColors.set_position(4, d, false);
+        vertexColors.set_color(4, (new Float4(0.51f,0.549f,0.929f, 1.0f)), false);
+        vertexColors.set_position(5, e, false);
+        vertexColors.set_color(5, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(6, a, false);
+        vertexColors.set_color(6, (new Float4(0.0f,0.584f,1.0f, 1.0f)), false);
+        vertexColors.set_position(7, e, false);
+        vertexColors.set_color(7, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(8, b, false);
+        vertexColors.set_color(8, (new Float4(0.573f,0.863f,1.0f, 1.0f)), false);
+        vertexColors.set_position(9, b, false);
+        vertexColors.set_color(9, (new Float4(0.573f,0.863f,1.0f, 1.0f)), false);
+        vertexColors.set_position(10, e, false);
+        vertexColors.set_color(10, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(11, f, false);
+        vertexColors.set_color(11, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(12, b, false);
+        vertexColors.set_color(12, (new Float4(0.573f,0.863f,1.0f, 1.0f)), false);
+        vertexColors.set_position(13, f, false);
+        vertexColors.set_color(13, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(14, c, false);
+        vertexColors.set_color(14, (new Float4(0.188f,0.533f,0.882f, 1.0f)), false);
+        vertexColors.set_position(15, c, false);
+        vertexColors.set_color(15, (new Float4(0.188f,0.533f,0.882f, 1.0f)), false);
+        vertexColors.set_position(16, f, false);
+        vertexColors.set_color(16, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(17, l, false);
+        vertexColors.set_color(17, (new Float4(0.29f,0.31f,0.392f, 1.0f)), false);
+        vertexColors.set_position(18, f, false);
+        vertexColors.set_color(18, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(19, e, false);
+        vertexColors.set_color(19, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(20, g, false);
+        vertexColors.set_color(20, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(21, f, false);
+        vertexColors.set_color(21, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(22, g, false);
+        vertexColors.set_color(22, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(23, l, false);
+        vertexColors.set_color(23, (new Float4(0.29f,0.31f,0.392f, 1.0f)), false);
+        vertexColors.set_position(24, g, false);
+        vertexColors.set_color(24, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(25, e, false);
+        vertexColors.set_color(25, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(26, h, false);
+        vertexColors.set_color(26, (new Float4(0.251f,0.62f,0.851f, 1.0f)), false);
+        vertexColors.set_position(27, h, false);
+        vertexColors.set_color(27, (new Float4(0.251f,0.62f,0.851f, 1.0f)), false);
+        vertexColors.set_position(28, e, false);
+        vertexColors.set_color(28, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(29, d, false);
+        vertexColors.set_color(29, (new Float4(0.51f,0.549f,0.929f, 1.0f)), false);
+        vertexColors.set_position(30, d, false);
+        vertexColors.set_color(30, (new Float4(0.51f,0.549f,0.929f, 1.0f)), false);
+        vertexColors.set_position(31, i, false);
+        vertexColors.set_color(31, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(32, h, false);
+        vertexColors.set_color(32, (new Float4(0.251f,0.62f,0.851f, 1.0f)), false);
+        vertexColors.set_position(33, j, false);
+        vertexColors.set_color(33, (new Float4(0.157f,0.122f,0.506f, 1.0f)), false);
+        vertexColors.set_position(34, h, false);
+        vertexColors.set_color(34, (new Float4(0.251f,0.62f,0.851f, 1.0f)), false);
+        vertexColors.set_position(35, i, false);
+        vertexColors.set_color(35, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(36, j, false);
+        vertexColors.set_color(36, (new Float4(0.157f,0.122f,0.506f, 1.0f)), false);
+        vertexColors.set_position(37, i, false);
+        vertexColors.set_color(37, (new Float4(0.196f,0.745f,1.0f, 1.0f)), false);
+        vertexColors.set_position(38, k, false);
+        vertexColors.set_color(38, (new Float4(0.357f,0.0f,0.408f, 1.0f)), false);
+        vertexColors.set_position(39, l, false);
+        vertexColors.set_color(39, (new Float4(0.29f,0.31f,0.392f, 1.0f)), false);
+        vertexColors.set_position(40, j, false);
+        vertexColors.set_color(40, (new Float4(0.157f,0.122f,0.506f, 1.0f)), false);
+        vertexColors.set_position(41, k, false);
+        vertexColors.set_color(41, (new Float4(0.357f,0.0f,0.408f, 1.0f)), false);
+        vertexColors.set_position(42, g, false);
+        vertexColors.set_color(42, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(43, h, false);
+        vertexColors.set_color(43, (new Float4(0.251f,0.62f,0.851f, 1.0f)), false);
+        vertexColors.set_position(44, j, false);
+        vertexColors.set_color(44, (new Float4(0.157f,0.122f,0.506f, 1.0f)), false);
+        vertexColors.set_position(45, l, false);
+        vertexColors.set_color(45, (new Float4(0.29f,0.31f,0.392f, 1.0f)), false);
+        vertexColors.set_position(46, g, false);
+        vertexColors.set_color(46, (new Float4(0.467f,0.522f,0.827f, 1.0f)), false);
+        vertexColors.set_position(47, j, false);
+        vertexColors.set_color(47, (new Float4(0.157f,0.122f,0.506f, 1.0f)), false);
+
+        vertexColors.copyAll();
+
+        Mesh.AllocationBuilder backgroundBuilder = new Mesh.AllocationBuilder(mRS);
+        backgroundBuilder.addIndexSetType(Primitive.TRIANGLE);
+        backgroundBuilder.addVertexAllocation(vertexColors.getAllocation());
+        mScript.set_gBackgroundMesh(backgroundBuilder.create());
+
+        mScript.bind_vertexColors(vertexColors);
+
+    }
+
     private Allocation loadTexture(int id) {
         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id);
         return allocation;
@@ -128,22 +260,16 @@
     private void loadTextures() {
         dotAllocation = loadTexture(R.drawable.dot);
         beamAllocation = loadTexture(R.drawable.beam);
-        bgAllocation = loadTexture(R.drawable.bg);
         mScript.set_textureDot(dotAllocation);
         mScript.set_textureBeam(beamAllocation);
-        mScript.set_textureBg(bgAllocation);
     }
 
     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();
 
@@ -159,20 +285,10 @@
     }
 
     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 = new ProgramFragmentFixedFunction.Builder(mRS);
-        builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
-        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.setShader(mRes, R.raw.dot_fs);
@@ -209,17 +325,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/phasebeam/phasebeam.rs b/src/com/android/phasebeam/phasebeam.rs
index c7dd513..77472ca 100644
--- a/src/com/android/phasebeam/phasebeam.rs
+++ b/src/com/android/phasebeam/phasebeam.rs
@@ -8,7 +8,6 @@
 
 rs_allocation textureDot;
 rs_allocation textureBeam;
-rs_allocation textureBg;
 
 rs_program_vertex vertBg;
 rs_program_fragment fragBg;
@@ -16,8 +15,8 @@
 rs_program_vertex vertDots;
 rs_program_fragment fragDots;
 
-int numBeamParticles;
-int numDotParticles;
+static int numBeamParticles;
+static int numDotParticles;
 
 typedef struct __attribute__((packed, aligned(4))) Particle {
     float3 position;
@@ -30,41 +29,55 @@
 } VpConsts_t;
 VpConsts_t *vpConstants;
 
+typedef struct VertexColor_s {
+    float3 position;
+    float offsetX;
+    float4 color;
+} VertexColor;
+
+VertexColor* vertexColors;
 Particle_t *dotParticles;
 Particle_t *beamParticles;
 rs_mesh dotMesh;
 rs_mesh beamMesh;
+rs_mesh gBackgroundMesh;
 
 float densityDPI;
 float xOffset = 0.5;
 
-float screenWidth;
-float screenHeight;
-float halfScreenWidth;
-float quarterScreenWidth;
+static float screenWidth;
+static float screenHeight;
+static float halfScreenWidth;
+static float quarterScreenWidth;
+static float quarterScreenHeight;
+static float halfScreenHeight;
 
-float newOffset = 0.5;
+static float newOffset = 0.5;
+static float oldOffset = 0.5;
 
 void positionParticles(){
     screenWidth = rsgGetWidth();
     screenHeight = rsgGetHeight();
     halfScreenWidth = screenWidth/2.0f;
+    halfScreenHeight = screenHeight/2.0f;
     quarterScreenWidth = screenWidth/4.0f;
-
+    quarterScreenHeight = screenHeight/4.0f;
     Particle_t* particle = dotParticles;
     numDotParticles = rsAllocationGetDimX(rsGetAllocation(dotParticles));
     for(int i=0; i<numDotParticles; i++){
+
+
         particle->position.x = rsRand(0.0f, 3.0f);
         particle->position.y = rsRand(-1.25f, 1.25f);
 
         float z;
-        if(i < 2){
+        if(i < 3){
             z = 14.0f;
-        } if(i < 3){
+        } if(i < 7){
             z = 25.0f;
         } else if(i < 4){
             z = rsRand(10.f, 20.f);
-        } else if(i == 5){
+        } else if(i == 10){
             z = 24.0f;
             particle->position.x = 1.0;
         } else {
@@ -76,11 +89,12 @@
         particle++;
     }
 
+
     Particle_t* beam = beamParticles;
     numBeamParticles = rsAllocationGetDimX(rsGetAllocation(beamParticles));
     for(int i=0; i<numBeamParticles; i++){
         float z;
-        if(i < 10){
+        if(i < 20){
             z = rsRand(4.0f, 10.0f)/2.0f;
         } else {
             z = rsRand(4.0f, 35.0f)/2.0f;
@@ -96,37 +110,67 @@
 
 int root(){
 
+    newOffset = xOffset*2;
     rsgClearColor(0.0f, 0.f, 0.f,1.0f);
 
+
+
+    VertexColor* vert = vertexColors;
+    for(int i=0; i<48; i++){
+        vert->offsetX = -xOffset/2.0;
+        vert++;
+    }
+
+
     rsgBindProgramVertex(vertBg);
     rsgBindProgramFragment(fragBg);
-    rsgBindTexture(fragBg, 0, textureBg);
-    rsgDrawRect(-quarterScreenWidth + xOffset*quarterScreenWidth, 0.0f,
-        screenWidth+halfScreenWidth + xOffset*quarterScreenWidth, screenHeight, 0.0f);
+
+    rsgDrawMesh(gBackgroundMesh);
+
 
     Particle_t* beam = beamParticles;
     Particle_t* particle = dotParticles;
-    newOffset = xOffset*2;
+
     for(int i=0; i<numDotParticles; i++){
-        if(beam->position.y > 1.05){
-            beam->position.y = -1.05;
-        } else {
-            beam->position.y = beam->position.y + 0.000160*beam->position.z;
+
+        if(newOffset==oldOffset){
+            if(beam->position.x/beam->position.z > 0.5){
+                beam->position.x = -1.0;
+            }
+            if(particle->position.x/particle->position.z > 0.5){
+                particle->position.x = -1.0;
+            }
+
+            if(beam->position.y > 1.05){
+                beam->position.y = -1.05;
+                beam->position.x = rsRand(-1.25f, 1.25f);
+            } else {
+                beam->position.y = beam->position.y + 0.000160*beam->position.z;
+            }
+            if(particle->position.y > 1.25){
+                particle->position.y = -1.25;
+                particle->position.x = rsRand(0.0f, 3.0f);
+
+            } else {
+                particle->position.y = particle->position.y + 0.00022*particle->position.z;
+            }
+
+
         }
 
+
+
+
+        beam->position.x = beam->position.x + 0.0001010*beam->position.z;
         beam->offsetX = newOffset;
         beam++;
-
-        if(particle->position.y > 1.25){
-            particle->position.y = -1.25;
-        } else {
-            particle->position.y = particle->position.y + 0.00022*particle->position.z;
-        }
-
         particle->offsetX = newOffset;
+        particle->position.x = particle->position.x + 0.0001560*beam->position.z;
         particle++;
     }
 
+
+
     rsgBindProgramVertex(vertDots);
     rsgBindProgramFragment(fragDots);
 
@@ -136,5 +180,8 @@
     rsgBindTexture(fragDots, 0, textureDot);
     rsgDrawMesh(dotMesh);
 
-    return 45;
+    oldOffset = newOffset;
+
+    return 55;
+
 }