diff options
-rw-r--r-- | AndroidManifest.xml | 2 | ||||
-rw-r--r-- | res/raw/grass.rs | 82 | ||||
-rw-r--r-- | src/com/android/wallpaper/grass/GrassRS.java | 122 | ||||
-rw-r--r-- | src/com/android/wallpaper/grass/GrassView.java | 2 | ||||
-rw-r--r-- | src/com/android/wallpaper/grass/GrassWallpaper.java | 2 |
5 files changed, 166 insertions, 44 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fdd3052..685ec59 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -21,6 +21,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.wallpaper"> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <application android:label="@string/wallpapers" android:icon="@drawable/ic_launcher_wallpaper"> diff --git a/res/raw/grass.rs b/res/raw/grass.rs index 09a5ecb..56405b8 100644 --- a/res/raw/grass.rs +++ b/res/raw/grass.rs @@ -41,11 +41,6 @@ #define MAX_BEND 0.09f -#define MIDNIGHT 0.0f -#define MORNING 0.3f -#define AFTERNOON 0.75f -#define DUSK 0.84f - #define SECONDS_IN_DAY 86400.0f #define PI 3.1415926f @@ -57,7 +52,7 @@ float time() { if (REAL_TIME) { return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY; } - float t = uptimeMillis() / 20000.0f; + float t = uptimeMillis() / 40000.0f; return t - (int) t; } @@ -93,7 +88,9 @@ void drawSunset(int width, int height) { drawRect(0.0f, 0.0f, width, height, 0.0f); } -int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now, float xOffset) { +int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, + float brightness, float xOffset) { + float offset = bladeStruct[BLADE_STRUCT_OFFSET]; float scale = bladeStruct[BLADE_STRUCT_SCALE]; float angle = bladeStruct[BLADE_STRUCT_ANGLE]; @@ -112,20 +109,7 @@ int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now float s = bladeStruct[BLADE_STRUCT_S]; float b = bladeStruct[BLADE_STRUCT_B]; - float newB = 1.0f; - if (now >= MIDNIGHT && now < MORNING) { - newB = now / MORNING; - } - - if (now >= AFTERNOON && now < DUSK) { - newB = 1.0f - normf(AFTERNOON, DUSK, now); - } - - if (now >= DUSK) { - newB = 0.0f; - } - - int color = hsbToAbgr(h, s, lerpf(0, b, newB), 1.0f); + int color = hsbToAbgr(h, s, lerpf(0, b, brightness), 1.0f); float newAngle = turbulencef2(turbulenceX, uptimeMillis() * 0.00004f, 4.0f) - 0.5f; newAngle *= 0.5f; @@ -203,7 +187,7 @@ int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now return triangles * 15; } -void drawBlades(float now, float xOffset) { +void drawBlades(float brightness, float xOffset) { // For anti-aliasing bindTexture(NAMED_PFBackground, 0, NAMED_TAa); @@ -216,7 +200,7 @@ void drawBlades(float now, float xOffset) { int *bladeColor = loadArrayI32(RSID_BLADES_BUFFER, 0); for ( ; i < bladesCount; i += 1) { - int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, now, xOffset); + int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, brightness, xOffset); bladeBuffer += offset; bladeColor += offset; bladeStruct += BLADE_STRUCT_FIELDS_COUNT; @@ -235,25 +219,49 @@ int main(int launchID) { float now = time(); alpha(1.0f); - if (now >= MIDNIGHT && now < MORNING) { + float newB = 1.0f; + float dawn = State->dawn; + float morning = State->morning; + float afternoon = State->afternoon; + float dusk = State->dusk; + + if (now >= 0.0f && now < dawn) { // Draw night drawNight(width, height); - alpha(normf(MIDNIGHT, MORNING, now)); - drawSunrise(width, height); - } else if (now >= MORNING && now < AFTERNOON) { - drawSunrise(width, height); - alpha(normf(MORNING, AFTERNOON, now)); - drawNoon(width, height); - } else if (now >= AFTERNOON && now < DUSK) { + newB = 0.0f; + } else if (now >= dawn && now <= morning) { // Draw sunrise + float half = dawn + (morning - dawn) * 0.5f; + if (now <= half) { // Draw night->sunrise + drawNight(width, height); + newB = normf(dawn, half, now); + alpha(newB); + drawSunrise(width, height); + } else { // Draw sunrise->day + drawSunrise(width, height); + alpha(normf(half, morning, now)); + drawNoon(width, height); + } + } else if (now > morning && now < afternoon) { // Draw day drawNoon(width, height); - alpha(normf(AFTERNOON, DUSK, now)); - drawSunset(width, height); - } else if (now >= DUSK) { + } else if (now >= afternoon && now <= dusk) { // Draw sunset + float half = afternoon + (dusk - afternoon) * 0.5f; + if (now <= half) { // Draw day->sunset + drawNoon(width, height); + newB = normf(afternoon, half, now); + alpha(newB); + newB = 1.0f - newB; + drawSunset(width, height); + } else { // Draw sunset->night + drawSunset(width, height); + alpha(normf(half, dusk, now)); + drawNight(width, height); + newB = 0.0f; + } + } else if (now > dusk) { // Draw night drawNight(width, height); - alpha(1.0f - normf(DUSK, 1.0f, now)); - drawSunset(width, height); + newB = 0.0f; } - drawBlades(now, x); + drawBlades(newB, x); return 1; } diff --git a/src/com/android/wallpaper/grass/GrassRS.java b/src/com/android/wallpaper/grass/GrassRS.java index 8e01b6b..e824d7e 100644 --- a/src/com/android/wallpaper/grass/GrassRS.java +++ b/src/com/android/wallpaper/grass/GrassRS.java @@ -34,18 +34,29 @@ import android.renderscript.Element; import android.renderscript.SimpleMesh; import android.renderscript.Primitive; import static android.renderscript.Sampler.Value.*; +import android.content.Context; +import android.content.IntentFilter; +import android.content.Intent; +import android.content.BroadcastReceiver; +import android.location.LocationManager; +import android.location.LocationListener; +import android.location.Location; +import android.os.Bundle; +import android.text.format.Time; import com.android.wallpaper.R; import com.android.wallpaper.RenderScriptScene; import java.util.TimeZone; +import java.util.Calendar; class GrassRS extends RenderScriptScene { - private static final float TESSELATION = 0.5f; - - private static final int RSID_STATE = 0; + private static final int LOCATION_UPDATE_MIN_TIME = 60 * 60 * 1000; // 1 hour + private static final int LOCATION_UPDATE_MIN_DISTANCE = 150 * 1000; // 150 km + private static final float TESSELATION = 0.5f; private static final int TEXTURES_COUNT = 5; + private static final int RSID_STATE = 0; private static final int RSID_BLADES = 1; private static final int BLADES_COUNT = 200; private static final int BLADE_STRUCT_FIELDS_COUNT = 13; @@ -88,12 +99,60 @@ class GrassRS extends RenderScriptScene { private SimpleMesh mBladesMesh; private int mTriangles; + private float[] mBladesData; private final float[] mFloatData5 = new float[5]; + private WorldState mWorldState; - private float[] mBladesData; - GrassRS(int width, int height) { + private final Context mContext; + private final LocationManager mLocationManager; + + private LocationUpdater mLocationUpdater; + private GrassRS.TimezoneTracker mTimezoneTracker; + + GrassRS(Context context, int width, int height) { super(width, height); + + mContext = context; + mLocationManager = (LocationManager) + context.getSystemService(Context.LOCATION_SERVICE); + } + + @Override + public void start() { + super.start(); + + if (mTimezoneTracker == null) { + mTimezoneTracker = new TimezoneTracker(); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + + mContext.registerReceiver(mTimezoneTracker, filter); + } + + if (mLocationUpdater == null) { + mLocationUpdater = new LocationUpdater(); + mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, + LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, mLocationUpdater); + } + + updateLocation(); + } + + @Override + public void stop() { + super.stop(); + + if (mTimezoneTracker != null) { + mContext.unregisterReceiver(mTimezoneTracker); + mTimezoneTracker = null; + } + + if (mLocationUpdater != null) { + mLocationManager.removeUpdates(mLocationUpdater); + mLocationUpdater = null; + } } @Override @@ -154,6 +213,10 @@ class GrassRS extends RenderScriptScene { public int width; public int height; public float xOffset; + public float dawn; + public float morning; + public float afternoon; + public float dusk; } private void createState() { @@ -342,4 +405,53 @@ class GrassRS extends RenderScriptScene { mPvBackground.bindAllocation(mPvOrthoAlloc); mPvBackground.setName("PVBackground"); } + + private void updateLocation() { + updateLocation(mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); + } + + private void updateLocation(Location location) { + if (location != null) { + final String timeZone = Time.getCurrentTimezone(); + final SunCalculator calculator = new SunCalculator(location, timeZone); + final Calendar now = Calendar.getInstance(); + + final double sunrise = calculator.computeSunriseTime(SunCalculator.ZENITH_CIVIL, now); + mWorldState.dawn = SunCalculator.timeToDayFraction(sunrise); + + final double sunset = calculator.computeSunsetTime(SunCalculator.ZENITH_CIVIL, now); + mWorldState.dusk = SunCalculator.timeToDayFraction(sunset); + } else { + mWorldState.dawn = 0.3f; + mWorldState.dusk = 0.75f; + } + + mWorldState.morning = mWorldState.dawn + 1.0f / 12.0f; // 2 hours for sunrise + mWorldState.afternoon = mWorldState.dusk - 1.0f / 12.0f; // 2 hours for sunset + + // Send the new data to RenderScript + mState.data(mWorldState); + } + + private class LocationUpdater implements LocationListener { + public void onLocationChanged(Location location) { + updateLocation(location); + } + + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + public void onProviderEnabled(String provider) { + } + + public void onProviderDisabled(String provider) { + } + } + + private class TimezoneTracker extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + getScript().setTimeZone(Time.getCurrentTimezone()); + updateLocation(); + } + } } diff --git a/src/com/android/wallpaper/grass/GrassView.java b/src/com/android/wallpaper/grass/GrassView.java index 3c1b167..80ecf8f 100644 --- a/src/com/android/wallpaper/grass/GrassView.java +++ b/src/com/android/wallpaper/grass/GrassView.java @@ -34,7 +34,7 @@ class GrassView extends RSSurfaceView { super.surfaceChanged(holder, format, w, h); RenderScript RS = createRenderScript(false); - GrassRS render = new GrassRS(w, h); + GrassRS render = new GrassRS(getContext(), w, h); render.init(RS, getResources(), false); render.setOffset(0.5f, 0.0f, 0, 0); render.start(); diff --git a/src/com/android/wallpaper/grass/GrassWallpaper.java b/src/com/android/wallpaper/grass/GrassWallpaper.java index eabc170..01329a8 100644 --- a/src/com/android/wallpaper/grass/GrassWallpaper.java +++ b/src/com/android/wallpaper/grass/GrassWallpaper.java @@ -21,7 +21,7 @@ import com.android.wallpaper.RenderScriptScene; public class GrassWallpaper extends RenderScriptWallpaper { protected RenderScriptScene createScene(int width, int height) { - return new GrassRS(width, height); + return new GrassRS(this, width, height); } } |