summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2011-09-20 18:29:28 -0700
committerWinson Chung <winsonc@google.com>2011-09-22 16:44:51 -0700
commit76d6ea97b0d3e64787398a179e015443dde9c024 (patch)
tree254735e61582a56f19bbb4d9c2cf28d80b747066
parentb80063d5b23cdde2d460cc9b17191af4c76ca07f (diff)
downloadNoiseField-76d6ea97b0d3e64787398a179e015443dde9c024.tar.gz
Adding the NoiseField wallpaper.
Change-Id: I79f19604531e70b26f77a87c60a4d103ff2eeb68
-rw-r--r--Android.mk29
-rw-r--r--AndroidManifest.xml23
-rw-r--r--default.properties11
-rw-r--r--proguard.cfg40
-rw-r--r--res/drawable-nodpi/bg.pngbin0 -> 6460 bytes
-rw-r--r--res/drawable-nodpi/dot.pngbin0 -> 6287 bytes
-rw-r--r--res/drawable-nodpi/icon.pngbin0 -> 4147 bytes
-rw-r--r--res/drawable-nodpi/vignette.pngbin0 -> 4327 bytes
-rw-r--r--res/drawable-nodpi/wallpaper_thumb.pngbin0 -> 32610 bytes
-rw-r--r--res/layout/main.xml10
-rw-r--r--res/raw/noisefield_fs.glsl8
-rw-r--r--res/raw/noisefield_vs.glsl17
-rw-r--r--res/values/strings.xml6
-rw-r--r--res/xml/wallpaper.xml6
-rw-r--r--src/com/android/noisefield/NoiseField.java16
-rw-r--r--src/com/android/noisefield/NoiseFieldRS.java245
-rw-r--r--src/com/android/noisefield/NoiseFieldView.java42
-rw-r--r--src/com/android/noisefield/NoiseFieldWallpaper.java117
-rw-r--r--src/com/android/noisefield/noisefield.rs299
19 files changed, 869 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..ecb8cde
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := NoiseField
+LOCAL_CERTIFICATE := shared
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
+
+include $(BUILD_PACKAGE)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..d391541
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.noisefield"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="13" />
+
+ <uses-feature android:name="android.software.live_wallpaper" />
+
+
+ <application android:icon="@drawable/icon" android:label="@string/wallpaper_label">
+ <service
+ android:name=".NoiseFieldWallpaper"
+ android:label="@string/wallpaper_label"
+ android:launchMode="singleInstance"
+ android:permission="android.permission.BIND_WALLPAPER">
+ <intent-filter>
+ <action android:name="android.service.wallpaper.WallpaperService" />
+ </intent-filter>
+ <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" />
+ </service>
+ </application>
+</manifest> \ No newline at end of file
diff --git a/default.properties b/default.properties
new file mode 100644
index 0000000..ac9e1a0
--- /dev/null
+++ b/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-13
diff --git a/proguard.cfg b/proguard.cfg
new file mode 100644
index 0000000..b1cdf17
--- /dev/null
+++ b/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/res/drawable-nodpi/bg.png b/res/drawable-nodpi/bg.png
new file mode 100644
index 0000000..569e3e9
--- /dev/null
+++ b/res/drawable-nodpi/bg.png
Binary files differ
diff --git a/res/drawable-nodpi/dot.png b/res/drawable-nodpi/dot.png
new file mode 100644
index 0000000..fd8729f
--- /dev/null
+++ b/res/drawable-nodpi/dot.png
Binary files differ
diff --git a/res/drawable-nodpi/icon.png b/res/drawable-nodpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/res/drawable-nodpi/icon.png
Binary files differ
diff --git a/res/drawable-nodpi/vignette.png b/res/drawable-nodpi/vignette.png
new file mode 100644
index 0000000..1c6f19d
--- /dev/null
+++ b/res/drawable-nodpi/vignette.png
Binary files differ
diff --git a/res/drawable-nodpi/wallpaper_thumb.png b/res/drawable-nodpi/wallpaper_thumb.png
new file mode 100644
index 0000000..b0f604d
--- /dev/null
+++ b/res/drawable-nodpi/wallpaper_thumb.png
Binary files differ
diff --git a/res/layout/main.xml b/res/layout/main.xml
new file mode 100644
index 0000000..047dc86
--- /dev/null
+++ b/res/layout/main.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/wallpaper_label" />
+</LinearLayout>
diff --git a/res/raw/noisefield_fs.glsl b/res/raw/noisefield_fs.glsl
new file mode 100644
index 0000000..8d8163e
--- /dev/null
+++ b/res/raw/noisefield_fs.glsl
@@ -0,0 +1,8 @@
+varying float alpha;
+
+void main() {
+ lowp vec4 texColor;
+ texColor = texture2D(UNI_Tex0, gl_PointCoord);
+ texColor.a = texColor.a*alpha;
+ gl_FragColor = texColor;
+} \ No newline at end of file
diff --git a/res/raw/noisefield_vs.glsl b/res/raw/noisefield_vs.glsl
new file mode 100644
index 0000000..ea38887
--- /dev/null
+++ b/res/raw/noisefield_vs.glsl
@@ -0,0 +1,17 @@
+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;
+ gl_Position = UNI_MVP * pos;
+
+ float pointSize = 1.0 + ATTRIB_speed * ATTRIB_scaleSize * 3000.0;
+ alpha = ATTRIB_alpha;
+ gl_PointSize = pointSize;
+}
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..300b45a
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="wallpaper_label">Bubble</string>
+ <string name="wallpaper_author">Google</string>
+ <string name="wallpaper_description">DESC</string>
+</resources>
diff --git a/res/xml/wallpaper.xml b/res/xml/wallpaper.xml
new file mode 100644
index 0000000..a3b5502
--- /dev/null
+++ b/res/xml/wallpaper.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
+ android:author="@string/wallpaper_author"
+ android:description="@string/wallpaper_description"
+ android:thumbnail="@drawable/wallpaper_thumb" />
diff --git a/src/com/android/noisefield/NoiseField.java b/src/com/android/noisefield/NoiseField.java
new file mode 100644
index 0000000..f0cff59
--- /dev/null
+++ b/src/com/android/noisefield/NoiseField.java
@@ -0,0 +1,16 @@
+package com.android.noisefield;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class NoiseField extends Activity {
+
+ private NoiseFieldView mView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mView = new NoiseFieldView(this);
+ setContentView(mView);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/noisefield/NoiseFieldRS.java b/src/com/android/noisefield/NoiseFieldRS.java
new file mode 100644
index 0000000..0ce7ca1
--- /dev/null
+++ b/src/com/android/noisefield/NoiseFieldRS.java
@@ -0,0 +1,245 @@
+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.Matrix4f;
+import android.renderscript.Mesh;
+import android.renderscript.Program;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramFragmentFixedFunction;
+import android.renderscript.ProgramRaster;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.ProgramVertexFixedFunction;
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Sampler;
+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;
+ int mHeight;
+ int mWidth;
+ private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+ private ScriptField_VpConsts mPvConsts;
+ private Allocation dotAllocation;
+ private Allocation bgAllocation;
+ private Allocation vignetteAllocation;
+
+ private ScriptField_Particle dotParticles;
+ private Mesh dotMesh;
+
+ private int densityDPI;
+
+ boolean inited = false;
+
+ public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) {
+ if (!inited) {
+ densityDPI = dpi;
+
+ mRS = rs;
+ mRes = res;
+
+ mWidth = width;
+ mHeight = height;
+
+ mOptionsARGB.inScaled = false;
+ mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+
+ 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);
+
+ mPvConsts = new ScriptField_VpConsts(mRS, 1);
+
+ createProgramVertex();
+ createProgramRaster();
+ createProgramFragmentStore();
+ createProgramFragment();
+ loadTextures();
+
+ mScript.set_densityDPI(densityDPI);
+
+ mRS.bindRootScript(mScript);
+
+ mScript.invoke_positionParticles();
+ inited = true;
+ }
+ }
+
+ 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();
+
+ if (w > h) {
+ float aspect = ((float) w) / h;
+ m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100);
+ } else {
+ float aspect = ((float) h) / w;
+ m1.loadFrustum(-1, 1, -aspect, aspect, 1, 100);
+ }
+
+ 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() {
+ 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;
+ mPvConsts.set(i, 0, true);
+ }
+
+ 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);
+ }
+
+ 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);
+
+ updateProjectionMatrices();
+
+ ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
+ builder = new ProgramVertex.Builder(mRS);
+ builder.setShader(mRes, R.raw.noisefield_vs);
+ builder.addConstant(mPvConsts.getType());
+ builder.addInput(dotMesh.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 builder = new ProgramFragment.Builder(mRS);
+ builder = new ProgramFragment.Builder(mRS);
+ builder.addTexture(Program.TextureType.TEXTURE_2D);
+ builder.setShader(mRes, R.raw.noisefield_fs);
+ ProgramFragment pf = builder.create();
+ pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+ mScript.set_fragDots(pf);
+ }
+
+ private void createProgramRaster() {
+ ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
+ builder.setPointSpriteEnabled(true);
+ ProgramRaster pr = builder.create();
+ mRS.bindProgramRaster(pr);
+ }
+
+ 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);
+ 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() {
+ mRS.bindRootScript(mScript);
+ }
+
+ public void stop() {
+ mRS.bindRootScript(null);
+
+ }
+
+ public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+ mScript.set_xOffset(xOffset - 0.5f);
+ }
+
+ 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/NoiseFieldView.java b/src/com/android/noisefield/NoiseFieldView.java
new file mode 100644
index 0000000..aa9bf6a
--- /dev/null
+++ b/src/com/android/noisefield/NoiseFieldView.java
@@ -0,0 +1,42 @@
+package com.android.noisefield;
+
+import android.content.Context;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+import android.view.SurfaceHolder;
+
+public class NoiseFieldView extends RSSurfaceView {
+
+ private RenderScriptGL mRS;
+ private NoiseFieldRS mRender;
+
+ public NoiseFieldView(Context context) {
+ super(context);
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ }
+
+ 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 NoiseFieldRS();
+ mRender.init(240, mRS, getResources(), w, h);
+ }
+
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mRS != null) {
+ mRS.setSurface(null, 0, 0);
+ mRS = null;
+ destroyRenderScriptGL();
+ }
+ }
+
+}
diff --git a/src/com/android/noisefield/NoiseFieldWallpaper.java b/src/com/android/noisefield/NoiseFieldWallpaper.java
new file mode 100644
index 0000000..7d26bd9
--- /dev/null
+++ b/src/com/android/noisefield/NoiseFieldWallpaper.java
@@ -0,0 +1,117 @@
+package com.android.noisefield;
+
+import android.app.Service;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+import android.service.wallpaper.WallpaperService;
+import android.service.wallpaper.WallpaperService.Engine;
+import android.util.DisplayMetrics;
+import android.view.SurfaceHolder;
+import android.view.WindowManager;
+
+public class NoiseFieldWallpaper extends WallpaperService {
+
+ @Override
+ public Engine onCreateEngine() {
+ return new RenderScriptEngine();
+ }
+
+ private class RenderScriptEngine extends Engine {
+ private RenderScriptGL mRenderScript = null;
+ private NoiseFieldRS mWallpaperRS = null;
+ private int densityDPI;
+
+ @Override
+ public void onCreate(SurfaceHolder surfaceHolder) {
+ super.onCreate(surfaceHolder);
+ setTouchEventsEnabled(true);
+ surfaceHolder.setSizeFromLayout();
+ surfaceHolder.setFormat(PixelFormat.RGBA_8888);
+
+ DisplayMetrics metrics = new DisplayMetrics();
+ ((WindowManager) getApplication().getSystemService(Service.WINDOW_SERVICE))
+ .getDefaultDisplay().getMetrics(metrics);
+ densityDPI = metrics.densityDpi;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ destroyRenderer();
+ }
+
+ public void destroyRenderer() {
+ if (mWallpaperRS != null) {
+ mWallpaperRS.stop();
+ mWallpaperRS = null;
+ }
+
+ if (mRenderScript != null) {
+ mRenderScript.setSurface(null, 0, 0);
+ mRenderScript.destroy();
+ mRenderScript = null;
+ }
+ }
+
+ @Override
+ public void onSurfaceCreated(SurfaceHolder surfaceHolder) {
+ super.onSurfaceCreated(surfaceHolder);
+
+ RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+ mRenderScript = new RenderScriptGL(NoiseFieldWallpaper.this, sc);
+ mRenderScript.setPriority(RenderScript.Priority.LOW);
+ }
+
+ @Override
+ public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) {
+ super.onSurfaceDestroyed(surfaceHolder);
+ destroyRenderer();
+ }
+
+ @Override
+ public void onSurfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
+ super.onSurfaceChanged(surfaceHolder, format, width, height);
+
+ if (mRenderScript != null) {
+ mRenderScript.setSurface(surfaceHolder, width, height);
+ }
+
+ if (mWallpaperRS == null) {
+ mWallpaperRS = new NoiseFieldRS();
+ mWallpaperRS.init(densityDPI, mRenderScript, getResources(), width, height);
+ mWallpaperRS.start();
+ }
+
+ mWallpaperRS.resize(width, height);
+ }
+
+ @Override
+ public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
+ boolean resultRequested) {
+ if (mWallpaperRS != null) {
+ // return mWallpaperRS.onCommand(action, x, y, z, extras, resultRequested);
+ }
+ return null;
+ }
+
+ @Override
+ public void onVisibilityChanged(boolean visible) {
+ super.onVisibilityChanged(visible);
+ if (mWallpaperRS != null) {
+ if (visible) {
+ mWallpaperRS.start();
+ } else {
+ mWallpaperRS.stop();
+ }
+ }
+ }
+
+ @Override
+ public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
+ float yOffsetStep, int xPixelOffset, int yPixelOffset) {
+ mWallpaperRS.setOffset(xOffset, yOffset, xPixelOffset, yPixelOffset);
+ }
+ }
+}
diff --git a/src/com/android/noisefield/noisefield.rs b/src/com/android/noisefield/noisefield.rs
new file mode 100644
index 0000000..1fb2ad9
--- /dev/null
+++ b/src/com/android/noisefield/noisefield.rs
@@ -0,0 +1,299 @@
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.noisefield)
+
+#include "rs_graphics.rsh"
+#pragma stateVertex(parent);
+#pragma stateStore(parent);
+
+
+rs_allocation textureDot;
+rs_allocation textureBg;
+rs_allocation textureVignette;
+
+rs_program_vertex vertBg;
+rs_program_fragment fragBg;
+
+rs_program_vertex vertDots;
+rs_program_fragment fragDots;
+
+rs_program_store storeAlpha;
+rs_program_store storeAdd;
+
+typedef struct __attribute__((packed, aligned(4))) Particle {
+ float3 position;
+ float offsetX;
+ float scaleSize;
+ float speed;
+ float wander;
+ float alphaStart;
+ float alpha;
+ float life;
+ float death;
+} Particle_t;
+
+typedef struct VpConsts {
+ rs_matrix4x4 MVP;
+} VpConsts_t;
+VpConsts_t *vpConstants;
+
+Particle_t *dotParticles;
+rs_mesh dotMesh;
+
+
+float densityDPI;
+float xOffset;
+
+
+
+
+
+#define B 0x100
+#define BM 0xff
+#define N 0x1000
+
+static int p[B + B + 2];
+static float g3[B + B + 2][3];
+static float g2[B + B + 2][2];
+static float g1[B + B + 2];
+
+static float noise_sCurve(float t)
+{
+ return t * t * (3.0f - 2.0f * t);
+}
+
+static void normalizef2(float v[])
+{
+ float s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+}
+
+static void normalizef3(float v[])
+{
+ float s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+ v[2] = v[2] / s;
+}
+
+void init()
+{
+ int i, j, k;
+
+ for (i = 0; i < B; i++) {
+ p[i] = i;
+
+ g1[i] = (float)(rsRand(B * 2) - B) / B;
+
+ for (j = 0; j < 2; j++)
+ g2[i][j] = (float)(rsRand(B * 2) - B) / B;
+ normalizef2(g2[i]);
+
+ for (j = 0; j < 3; j++)
+ g3[i][j] = (float)(rsRand(B * 2) - B) / B;
+ normalizef3(g3[i]);
+ }
+
+ for (i = B-1; i >= 0; i--) {
+ k = p[i];
+ p[i] = p[j = rsRand(B)];
+ p[j] = k;
+ }
+
+ for (i = 0; i < B + 2; i++) {
+ p[B + i] = p[i];
+ g1[B + i] = g1[i];
+ for (j = 0; j < 2; j++)
+ g2[B + i][j] = g2[i][j];
+ for (j = 0; j < 3; j++)
+ g3[B + i][j] = g3[i][j];
+ }
+}
+
+static float noisef2(float x, float y)
+{
+ int bx0, bx1, by0, by1, b00, b10, b01, b11;
+ float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
+ float *q;
+ int i, j;
+
+ t = x + N;
+ bx0 = ((int)t) & BM;
+ bx1 = (bx0+1) & BM;
+ rx0 = t - (int)t;
+ rx1 = rx0 - 1.0f;
+
+ t = y + N;
+ by0 = ((int)t) & BM;
+ by1 = (by0+1) & BM;
+ ry0 = t - (int)t;
+ ry1 = ry0 - 1.0f;
+
+ i = p[bx0];
+ j = p[bx1];
+
+ b00 = p[i + by0];
+ b10 = p[j + by0];
+ b01 = p[i + by1];
+ b11 = p[j + by1];
+
+ sx = noise_sCurve(rx0);
+ sy = noise_sCurve(ry0);
+
+ q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
+ q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
+ a = mix(u, v, sx);
+
+ q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
+ 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);
+}
+
+
+
+
+
+
+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->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);
+
+
+ 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);
+
+ return 35;
+}