Merge "Removing Live Wallpaper Description - Bug 5462731"
diff --git a/res/drawable-nodpi/bg.png b/res/drawable-nodpi/bg.png
index 0102d9f..feb8ec4 100644
--- a/res/drawable-nodpi/bg.png
+++ b/res/drawable-nodpi/bg.png
Binary files differ
diff --git a/res/drawable-nodpi/fgstar.png b/res/drawable-nodpi/fgstar.png
deleted file mode 100644
index 100250f..0000000
--- a/res/drawable-nodpi/fgstar.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-nodpi/staticstar.png b/res/drawable-nodpi/staticstar.png
new file mode 100644
index 0000000..169d9e9
--- /dev/null
+++ b/res/drawable-nodpi/staticstar.png
Binary files differ
diff --git a/res/drawable-nodpi/staticstar2.png b/res/drawable-nodpi/staticstar2.png
new file mode 100644
index 0000000..3bf88f0
--- /dev/null
+++ b/res/drawable-nodpi/staticstar2.png
Binary files differ
diff --git a/res/drawable-nodpi/wallpaper_thumb.png b/res/drawable-nodpi/wallpaper_thumb.png
index 41a355c..7b101c2 100644
--- a/res/drawable-nodpi/wallpaper_thumb.png
+++ b/res/drawable-nodpi/wallpaper_thumb.png
Binary files differ
diff --git a/res/raw/bgstar_vs.glsl b/res/raw/bgstar_vs.glsl
index ac35d9f..4a41c55 100644
--- a/res/raw/bgstar_vs.glsl
+++ b/res/raw/bgstar_vs.glsl
@@ -1,7 +1,7 @@
 varying vec4 varColor;
 
 void main() {
-    float dist = ATTRIB_position.y;
+    float dist = ATTRIB_position.y * UNI_scaleSize;
     float angle = ATTRIB_position.x;
 
     float x = dist * sin(angle);
@@ -14,7 +14,7 @@
     pos.y = s*x - t*y;
     pos.z = ATTRIB_position.z;
     pos.w = 1.0;
-    
+
     pos.y = pos.y * 0.5;
     gl_Position = UNI_MVP * pos;
     varColor = vec4(1.0, 1.0, 1.0, 0.5);
diff --git a/res/raw/spacecloud_fs.glsl b/res/raw/spacecloud_fs.glsl
index 75adcd2..819f5a8 100644
--- a/res/raw/spacecloud_fs.glsl
+++ b/res/raw/spacecloud_fs.glsl
@@ -1,12 +1,8 @@
-varying vec4 varColor;
 
 void main()  {
     lowp vec4 texColor;
     texColor = texture2D(UNI_Tex0, gl_PointCoord);
-    
-    // texColor = texture2D(UNI_Tex1, gl_PointCoord);
-    
+
     gl_FragColor.rgb = texColor.rgb;
     gl_FragColor.a = 0.1;
-    // gl_FragColor = varColor;
 }
\ No newline at end of file
diff --git a/res/raw/spacecloud_vs.glsl b/res/raw/spacecloud_vs.glsl
index 0056328..3ddbd6f 100644
--- a/res/raw/spacecloud_vs.glsl
+++ b/res/raw/spacecloud_vs.glsl
@@ -1,10 +1,9 @@
-varying vec4 varColor;
 varying float pointSize;
 
 void main() {
     float dist = ATTRIB_position.y / 4.0;
     float angle = ATTRIB_position.x;
-    
+
     float x = dist * sin(angle) * 0.8;
     float y = dist * cos(angle) * 0.8;
     float p = dist * 7.5;
@@ -17,10 +16,9 @@
     pos.w = 1.0;
     pos.y = pos.y * 0.5;
     gl_Position = UNI_MVP * pos;
-    varColor = vec4(1.0, 1.0, 1.0, 1.0);
     pointSize = 170.0-(pos.y*pos.y*1.2*1.2 + pos.x*pos.x)*400.0;
-    if(pointSize<=30.0){
+    if (pointSize<=30.0) {
         pointSize = 30.0;
     }
-    gl_PointSize = pointSize;// - snoise(pos.xy)*5.0;
+    gl_PointSize = pointSize;
 }
\ No newline at end of file
diff --git a/res/raw/staticstar_fs.glsl b/res/raw/staticstar_fs.glsl
new file mode 100644
index 0000000..ce03eee
--- /dev/null
+++ b/res/raw/staticstar_fs.glsl
@@ -0,0 +1,9 @@
+varying float pointSize;
+
+void main()  {
+    if (pointSize > 4.0) {
+        gl_FragColor = texture2D(UNI_Tex1, gl_PointCoord);
+    } else {
+        gl_FragColor = texture2D(UNI_Tex0, gl_PointCoord);
+    }
+}
\ No newline at end of file
diff --git a/res/raw/staticstar_vs.glsl b/res/raw/staticstar_vs.glsl
new file mode 100644
index 0000000..92b0bc6
--- /dev/null
+++ b/res/raw/staticstar_vs.glsl
@@ -0,0 +1,13 @@
+varying float pointSize;
+
+void main() {
+    vec4 pos;
+    pos.x = ATTRIB_position.x;
+    pos.y = ATTRIB_position.y;
+    pos.z = ATTRIB_position.z;
+    pos.w = 1.0;
+
+    gl_Position = UNI_MVP * pos;
+    pointSize = ATTRIB_pointSize;
+    gl_PointSize = pointSize*UNI_scaleSize;
+}
\ No newline at end of file
diff --git a/src/com/android/galaxy4/Galaxy4Wallpaper.java b/src/com/android/galaxy4/Galaxy4Wallpaper.java
index 1192e1c..d952df8 100644
--- a/src/com/android/galaxy4/Galaxy4Wallpaper.java
+++ b/src/com/android/galaxy4/Galaxy4Wallpaper.java
@@ -22,9 +22,12 @@
 import android.os.Message;
 import android.renderscript.RenderScript;
 import android.renderscript.RenderScriptGL;
+import android.util.DisplayMetrics;
 import android.service.wallpaper.WallpaperService;
 import android.view.Surface;
 import android.view.SurfaceHolder;
+import android.view.WindowManager;
+import android.app.Service;
 
 public class Galaxy4Wallpaper extends WallpaperService {
 
@@ -36,6 +39,7 @@
     private class RenderScriptEngine extends Engine {
         private RenderScriptGL mRenderScript = null;
         private GalaxyRS mWallpaperRS = null;
+        private int mDensityDPI;
 
         @Override
         public void onCreate(SurfaceHolder surfaceHolder) {
@@ -43,6 +47,11 @@
             setTouchEventsEnabled(true);
             surfaceHolder.setSizeFromLayout();
             surfaceHolder.setFormat(PixelFormat.RGBA_8888);
+
+            DisplayMetrics metrics = new DisplayMetrics();
+            ((WindowManager) getApplication().getSystemService(Service.WINDOW_SERVICE))
+                    .getDefaultDisplay().getMetrics(metrics);
+            mDensityDPI = metrics.densityDpi;
         }
 
         @Override
@@ -80,7 +89,8 @@
         }
 
         @Override
-        public void onSurfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
+        public void onSurfaceChanged(SurfaceHolder surfaceHolder,
+                                     int format, int width, int height) {
             super.onSurfaceChanged(surfaceHolder, format, width, height);
 
             if (mRenderScript != null) {
@@ -89,11 +99,12 @@
 
             if (mWallpaperRS == null) {
                 mWallpaperRS = new GalaxyRS();
-                mWallpaperRS.init(mRenderScript, getResources(), width, height);
+                mWallpaperRS.init(mDensityDPI, mRenderScript, getResources(), width, height);
                 mWallpaperRS.start();
+            } else {
+                mWallpaperRS.resize(width, height);
             }
 
-            // mWallpaperRS.resize(width, height);
         }
 
         @Override
@@ -116,11 +127,5 @@
                 }
             }
         }
-
-        @Override
-        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
-                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
-            // mWallpaperRS.setOffset(xOffset, yOffset, xPixelOffset, yPixelOffset);
-        }
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/galaxy4/GalaxyRS.java b/src/com/android/galaxy4/GalaxyRS.java
index c568296..292c06f 100644
--- a/src/com/android/galaxy4/GalaxyRS.java
+++ b/src/com/android/galaxy4/GalaxyRS.java
@@ -24,30 +24,36 @@
 public class GalaxyRS {
     public static final int BG_STAR_COUNT = 11000;
     public static final int SPACE_CLOUDSTAR_COUNT = 25;
+    public static final int STATIC_STAR_COUNT = 50;
     private Resources mRes;
-    // rendering context
+
     private RenderScriptGL mRS;
     private ScriptC_galaxy mScript;
 
-    // shader constants
     private ScriptField_VpConsts mPvConsts;
-    private ScriptField_Particle spaceClouds;
-    private ScriptField_Particle bgStars;
-    private Mesh spaceCloudsMesh;
-    private Mesh bgStarsMesh;
+    private ScriptField_Particle mSpaceClouds;
+    private ScriptField_Particle mBgStars;
+    private ScriptField_Particle mStaticStars;
+    private Mesh mSpaceCloudsMesh;
+    private Mesh mBgStarsMesh;
+    private Mesh mStaticStarsMesh;
 
-    int mHeight;
-    int mWidth;
-    boolean inited = false;
+    private int mHeight;
+    private int mWidth;
+    private boolean mInited = false;
+    private int mDensityDPI;
 
     private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
 
-    private Allocation cloudAllocation;
-    private Allocation fgStarAllocation;
-    private Allocation bgAllocation;
+    private Allocation mCloudAllocation;
+    private Allocation mStaticStarAllocation;
+    private Allocation mStaticStar2Allocation;
+    private Allocation mBgAllocation;
 
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        if (!inited) {
+    public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) {
+        if (!mInited) {
+            mDensityDPI = dpi;
+
             mRS = rs;
             mRes = res;
 
@@ -57,23 +63,31 @@
             mOptionsARGB.inScaled = false;
             mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
 
-            spaceClouds = new ScriptField_Particle(mRS, SPACE_CLOUDSTAR_COUNT);
+            mSpaceClouds = new ScriptField_Particle(mRS, SPACE_CLOUDSTAR_COUNT);
             Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-            smb.addVertexAllocation(spaceClouds.getAllocation());
+            smb.addVertexAllocation(mSpaceClouds.getAllocation());
             smb.addIndexSetType(Mesh.Primitive.POINT);
-            spaceCloudsMesh = smb.create();
+            mSpaceCloudsMesh = smb.create();
 
-            bgStars = new ScriptField_Particle(mRS, BG_STAR_COUNT);
+            mBgStars = new ScriptField_Particle(mRS, BG_STAR_COUNT);
             Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
-            smb2.addVertexAllocation(bgStars.getAllocation());
+            smb2.addVertexAllocation(mBgStars.getAllocation());
             smb2.addIndexSetType(Mesh.Primitive.POINT);
-            bgStarsMesh = smb2.create();
+            mBgStarsMesh = smb2.create();
+
+            mStaticStars = new ScriptField_Particle(mRS, STATIC_STAR_COUNT);
+            Mesh.AllocationBuilder smb3 = new Mesh.AllocationBuilder(mRS);
+            smb3.addVertexAllocation(mStaticStars.getAllocation());
+            smb3.addIndexSetType(Mesh.Primitive.POINT);
+            mStaticStarsMesh = smb3.create();
 
             mScript = new ScriptC_galaxy(mRS, mRes, R.raw.galaxy);
-            mScript.set_spaceCloudsMesh(spaceCloudsMesh);
-            mScript.bind_spaceClouds(spaceClouds);
-            mScript.set_bgStarsMesh(bgStarsMesh);
-            mScript.bind_bgStars(bgStars);
+            mScript.set_spaceCloudsMesh(mSpaceCloudsMesh);
+            mScript.bind_spaceClouds(mSpaceClouds);
+            mScript.set_bgStarsMesh(mBgStarsMesh);
+            mScript.bind_bgStars(mBgStars);
+            mScript.set_staticStarsMesh(mStaticStarsMesh);
+            mScript.bind_staticStars(mStaticStars);
 
             mPvConsts = new ScriptField_VpConsts(mRS, 1);
 
@@ -84,13 +98,11 @@
 
             loadTextures();
 
+            mScript.set_densityDPI(mDensityDPI);
             mRS.bindRootScript(mScript);
-
             mScript.invoke_positionParticles();
-
-            inited = true;
+            mInited = true;
         }
-
     }
 
     private Allocation loadTexture(int id) {
@@ -98,24 +110,18 @@
         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() {
-        fgStarAllocation = loadTexture(R.drawable.fgstar);
-        cloudAllocation = loadTexture(R.drawable.cloud);
-        bgAllocation = loadTexture(R.drawable.bg);
-        mScript.set_textureSpaceCloud(cloudAllocation);
-        mScript.set_textureFGStar(fgStarAllocation);
-        mScript.set_textureBg(bgAllocation);
+        mStaticStarAllocation = loadTexture(R.drawable.staticstar);
+        mStaticStar2Allocation = loadTexture(R.drawable.staticstar2);
+        mCloudAllocation = loadTexture(R.drawable.cloud);
+        mBgAllocation = loadTexture(R.drawable.bg);
+        mScript.set_textureSpaceCloud(mCloudAllocation);
+        mScript.set_textureStaticStar(mStaticStarAllocation);
+        mScript.set_textureStaticStar2(mStaticStar2Allocation);
+        mScript.set_textureBg(mBgAllocation);
     }
 
     private Matrix4f getProjectionNormalized(int w, int h) {
-        // range -1,1 in the narrow axis at z = 0.
         Matrix4f m1 = new Matrix4f();
         Matrix4f m2 = new Matrix4f();
 
@@ -129,33 +135,28 @@
 
         m2.loadRotate(180, 0, 1, 0);
         m1.loadMultiply(m1, m2);
-
         m2.loadScale(-1, 1, 1);
         m1.loadMultiply(m1, m2);
-
         m2.loadTranslate(0, 0, 1);
         m1.loadMultiply(m1, m2);
         return m1;
     }
 
-    private void updateProjectionMatrices() {
+    private void updateProjectionMatrices(int w, int h) {
+        mWidth = w;
+        mHeight = h;
         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);
-
+        mScript.invoke_positionParticles();
     }
 
-    private void createProgramVertex() {
-
-        // /////////////////// fixed function bg
-        ProgramVertexFixedFunction.Constants mPvOrthoAlloc = 
+    public void createProgramVertex() {
+        ProgramVertexFixedFunction.Constants mPvOrthoAlloc =
             new ProgramVertexFixedFunction.Constants(mRS);
         Matrix4f proj = new Matrix4f();
         proj.loadOrthoWindow(mWidth, mHeight);
@@ -165,17 +166,13 @@
         ProgramVertex pv = pvb.create();
         ((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc);
         mScript.set_vertBg(pv);
-
-        // ///////////////////////////////////////////////////////////////////////
-        // //////////////////////////////////////////////////////////////////
-
-        updateProjectionMatrices();
+        updateProjectionMatrices(mWidth, mHeight);
 
         // cloud
         ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
         builder.setShader(mRes, R.raw.spacecloud_vs);
         builder.addConstant(mPvConsts.getType());
-        builder.addInput(spaceCloudsMesh.getVertexAllocation(0).getType().getElement());
+        builder.addInput(mSpaceCloudsMesh.getVertexAllocation(0).getType().getElement());
         ProgramVertex pvs = builder.create();
         pvs.bindConstants(mPvConsts.getAllocation(), 0);
         mRS.bindProgramVertex(pvs);
@@ -186,24 +183,33 @@
         builder = new ProgramVertex.Builder(mRS);
         builder.setShader(mRes, R.raw.bgstar_vs);
         builder.addConstant(mPvConsts.getType());
-        builder.addInput(bgStarsMesh.getVertexAllocation(0).getType().getElement());
+        builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement());
         pvs = builder.create();
         pvs.bindConstants(mPvConsts.getAllocation(), 0);
         mRS.bindProgramVertex(pvs);
         mScript.set_vertBgStars(pvs);
+
+        // static stars
+        builder = new ProgramVertex.Builder(mRS);
+        builder.setShader(mRes, R.raw.staticstar_vs);
+        builder.addConstant(mPvConsts.getType());
+        builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement());
+        pvs = builder.create();
+        pvs.bindConstants(mPvConsts.getAllocation(), 0);
+        mRS.bindProgramVertex(pvs);
+        mScript.set_vertStaticStars(pvs);
     }
 
     private void createProgramFragment() {
-        // fixed function bg
-
+        // bg
         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
-        samplerBuilder.setMinification(NEAREST);
-        samplerBuilder.setMagnification(NEAREST);
+        samplerBuilder.setMinification(LINEAR);
+        samplerBuilder.setMagnification(LINEAR);
         samplerBuilder.setWrapS(WRAP);
         samplerBuilder.setWrapT(WRAP);
         Sampler sn = samplerBuilder.create();
-        ProgramFragmentFixedFunction.Builder builderff = 
-            new ProgramFragmentFixedFunction.Builder(mRS);
+        ProgramFragmentFixedFunction.Builder builderff =
+                new ProgramFragmentFixedFunction.Builder(mRS);
         builderff = new ProgramFragmentFixedFunction.Builder(mRS);
         builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
                 ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
@@ -211,31 +217,32 @@
         mScript.set_fragBg(pfff);
         pfff.bindSampler(sn, 0);
 
-        ////////////////////////////////////////////////////////////////////
-
-        // cloud fragment
+        // cloud
         ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
 
         builder.setShader(mRes, R.raw.spacecloud_fs);
-        // multiple textures
-        builder.addTexture(Program.TextureType.TEXTURE_2D);
         builder.addTexture(Program.TextureType.TEXTURE_2D);
 
         ProgramFragment pf = builder.create();
         pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
         mScript.set_fragSpaceClouds(pf);
 
-        // bg star fragment
+        // bg stars
         builder = new ProgramFragment.Builder(mRS);
         builder.setShader(mRes, R.raw.bgstar_fs);
         pf = builder.create();
         mScript.set_fragBgStars(pf);
 
+        // static stars
+        builder = new ProgramFragment.Builder(mRS);
+        builder.setShader(mRes, R.raw.staticstar_fs);
+        builder.addTexture(Program.TextureType.TEXTURE_2D);
+        builder.addTexture(Program.TextureType.TEXTURE_2D);
+        pf = builder.create();
+        mScript.set_fragStaticStars(pf);
     }
 
     private void createProgramRaster() {
-        // Program raster is primarily used to specify whether point sprites are enabled and
-        // to control the culling mode. By default, back faces are culled.
         ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
         builder.setPointSpriteEnabled(true);
         ProgramRaster pr = builder.create();
@@ -243,23 +250,9 @@
     }
 
     private void createProgramFragmentStore() {
-        // ProgramStore contains a set of parameters that control how the graphics hardware handles
-        // writes to the framebuffer.
-        // 
-        // It could be used to:
-        //     enable/disable depth testing
-        //     specify wheather depth writes are performed
-        //     setup various blending modes for use in effects like transparency
-        //     define write masks for color components written into the framebuffer
-
         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);
         mRS.bindProgramStore(builder.create());
-
     }
 
     public void start() {
@@ -270,8 +263,9 @@
         mRS.bindRootScript(null);
     }
 
-    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
-        mScript.set_xOffset(xOffset);
+    public void resize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        createProgramVertex();
     }
-
-}
+}
\ No newline at end of file
diff --git a/src/com/android/galaxy4/GalaxyView.java b/src/com/android/galaxy4/GalaxyView.java
index ce0d33f..d9d3727 100644
--- a/src/com/android/galaxy4/GalaxyView.java
+++ b/src/com/android/galaxy4/GalaxyView.java
@@ -6,6 +6,10 @@
 import android.renderscript.RenderScriptGL;
 import android.renderscript.RenderScriptGL.SurfaceConfig;
 import android.view.SurfaceHolder;
+import android.view.WindowManager;
+import android.app.Service;
+import android.util.Log;
+import android.util.DisplayMetrics;
 
 public class GalaxyView extends RSSurfaceView {
 
@@ -16,21 +20,25 @@
         super(context);
         setFocusable(true);
         setFocusableInTouchMode(true);
-        // getHolder().setFormat(PixelFormat.TRANSPARENT);
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
-
         if (mRS == null) {
             RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
             mRS = createRenderScriptGL(sc);
             mRS.setSurface(holder, w, h);
 
-            mRender = new GalaxyRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
+            DisplayMetrics metrics = new DisplayMetrics();
+            ((WindowManager) getContext()
+                    .getSystemService(Service.WINDOW_SERVICE))
+                    .getDefaultDisplay().getMetrics(metrics);
 
+            mRender = new GalaxyRS();
+            mRender.init(metrics.densityDpi, mRS, getResources(), w, h);
+        } else {
+            mRender.createProgramVertex();
+        }
     }
 
     @Override
diff --git a/src/com/android/galaxy4/galaxy.rs b/src/com/android/galaxy4/galaxy.rs
index 5117024..34f2411 100644
--- a/src/com/android/galaxy4/galaxy.rs
+++ b/src/com/android/galaxy4/galaxy.rs
@@ -7,38 +7,46 @@
 
 typedef struct __attribute__((packed, aligned(4))) Particle {
     float3 position;
-    uchar4 color;
+    float pointSize;
 } Particle_t;
 
 typedef struct VpConsts {
     rs_matrix4x4 MVP;
+    float scaleSize;
 } VpConsts_t;
 VpConsts_t *vpConstants;
 
-
-// hold clouds
 Particle_t *spaceClouds;
-
-// hold bg stars
 Particle_t *bgStars;
+Particle_t *staticStars;
 
 rs_mesh spaceCloudsMesh;
 rs_mesh bgStarsMesh;
+rs_mesh staticStarsMesh;
 
 rs_program_vertex vertSpaceClouds;
 rs_program_vertex vertBgStars;
+rs_program_vertex vertStaticStars;
 rs_program_fragment fragSpaceClouds;
 rs_program_fragment fragBgStars;
+rs_program_fragment fragStaticStars;
 rs_program_vertex vertBg;
 rs_program_fragment fragBg;
 
 rs_allocation textureSpaceCloud;
-rs_allocation textureFGStar;
+rs_allocation textureStaticStar;
+rs_allocation textureStaticStar2;
 rs_allocation textureBg;
 
-static int gGalaxyRadius = 250;
+float densityDPI;
 
-float xOffset;
+static int gGalaxyRadius = 300;
+static float screenWidth;
+static float screenHeight;
+
+static int numBgStars;
+static int numClouds;
+static int numStaticStars;
 
 #define PI 3.1415f
 #define TWO_PI 6.283f
@@ -65,115 +73,115 @@
     return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
 }
 
+void positionParticles() {
+    screenWidth = rsgGetWidth();
+    screenHeight = rsgGetHeight();
 
+    float wRatio = 1.0f;
+    float hRatio = 1.0f;
 
-void positionParticles(){
-    rsDebug("************************&&&&&&&&&&&&&&& Called positionBGStars", rsUptimeMillis());
+    if (screenWidth > screenHeight) {
+        wRatio = screenWidth/screenHeight;
+        screenHeight = screenWidth;
+    } else {
+        hRatio = screenHeight/screenWidth;
+        screenWidth = screenHeight;
+    }
 
-    float width = rsgGetWidth();
-    float height = rsgGetHeight();
-    
-    float scale = gGalaxyRadius / (width * 0.5f);
-    
-    // space clouds 
+    float scale = gGalaxyRadius / (screenWidth * 0.5f);
+
+    // clouds
     Particle_t* particle = spaceClouds;
-    int size = rsAllocationGetDimX(rsGetAllocation(spaceClouds));
-    for(int i=0; i<size; i++){
-    
+    numClouds = rsAllocationGetDimX(rsGetAllocation(spaceClouds));
+    for (int i=0; i<numClouds; i++) {
         float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
-    
         d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
-        
         float id = d / gGalaxyRadius;
         float z = randomGauss() * 0.4f * (1.0f - id);
-        
         if (d > gGalaxyRadius * 0.15f) {
             z *= 0.6f * (1.0f - id);
         } else {
             z *= 0.72f;
         }
-        
         particle->position.x = rsRand(TWO_PI);
         particle->position.y = d;
+        particle->pointSize = 1.0f;
         particle->position.z = z/5.0f;
-        particle->color = rsPackColorTo8888(1.0f, 0.0f, 1.0f);
         particle++;
     }
-    
+
     // bg stars
-    size = rsAllocationGetDimX(rsGetAllocation(bgStars));
+    numBgStars = rsAllocationGetDimX(rsGetAllocation(bgStars));
     particle = bgStars;
-    for(int i=0; i<size; i++){
+    for (int i=0; i<numBgStars; i++) {
         float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
-    
         d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
-        
         float id = d / gGalaxyRadius;
         float z = randomGauss() * 0.4f * (1.0f - id);
-        
         if (d > gGalaxyRadius * 0.15f) {
             z *= 0.6f * (1.0f - id);
         } else {
             z *= 0.72f;
         }
-        
         particle->position.x = rsRand(TWO_PI);
         particle->position.y = d;
+        particle->pointSize = 1.0f;
         particle->position.z = z/5.0f;
-        particle->color = rsPackColorTo8888(1.0f, 0.0f, 1.0f);
         particle++;
     }
-    
-    
+
+    // static stars
+    numStaticStars = rsAllocationGetDimX(rsGetAllocation(staticStars));
+    particle = staticStars;
+    for (int i=0; i<numStaticStars; i++) {
+        particle->position.x = rsRand(-wRatio, wRatio);
+        particle->position.y = rsRand(-hRatio, hRatio);
+        particle->pointSize = rsRand(1.0f, 10.0f);
+        particle++;
+    }
 }
 
-static void drawBg(int width, int height){
-    rsgBindTexture(fragBg, 0, textureBg);
-    rsgDrawRect(0.0f, 0.0f, width, height, 0.0f);
-}
+int root() {
+    float xpos = 0.0f;
+    float ypos = 0.0f;
+    xpos = -(screenWidth-rsgGetWidth())/2.0f;
+    ypos = -(screenHeight-rsgGetHeight())/2.0f;
 
-int root(){
-    float width = rsgGetWidth();
-    float height = rsgGetHeight();
-    
-    
     rsgClearColor(0.0f, 0.f, 0.f, 0.5f);
-    
+
     // bg
     rsgBindProgramVertex(vertBg);
     rsgBindProgramFragment(fragBg);
-    drawBg(width, height);
-    
-    
+    rsgBindTexture(fragBg, 0, textureBg);
+    rsgDrawRect(xpos, ypos, screenWidth+xpos, screenHeight+ypos, 0.0f);
+
     // space cloud
     rsgBindProgramVertex(vertSpaceClouds);
-    int size = rsAllocationGetDimX(rsGetAllocation(spaceClouds));
     Particle_t *particle = spaceClouds;
-    
-    for(int i=0; i<size; i++){
+    for (int i=0; i<numClouds; i++) {
         particle->position.x -= .065;
         particle++;
     }
     rsgBindProgramFragment(fragSpaceClouds);
     rsgBindTexture(fragSpaceClouds, 0, textureSpaceCloud);
-    rsgBindTexture(fragSpaceClouds, 1, textureFGStar);
     rsgDrawMesh(spaceCloudsMesh);
-    
-    
-    
+
     // bg stars
     rsgBindProgramVertex(vertBgStars);
-    size = rsAllocationGetDimX(rsGetAllocation(bgStars));
     particle = bgStars;
-    
-    for(int i=0; i<size; i++){
+    for (int i=0; i<numBgStars; i++) {
         particle->position.x -= .007;
         particle++;
     }
     rsgBindProgramFragment(fragBgStars);
     rsgDrawMesh(bgStarsMesh);
 
+    // static stars
+    rsgBindTexture(fragStaticStars, 0, textureStaticStar);
+    rsgBindTexture(fragStaticStars, 1, textureStaticStar2);
+    rsgBindProgramVertex(vertStaticStars);
+    rsgBindProgramFragment(fragStaticStars);
+    rsgDrawMesh(staticStarsMesh);
 
     return 40;
-}
-
+}
\ No newline at end of file