diff options
-rw-r--r-- | Android.mk | 29 | ||||
-rw-r--r-- | AndroidManifest.xml | 23 | ||||
-rw-r--r-- | default.properties | 11 | ||||
-rw-r--r-- | proguard.cfg | 40 | ||||
-rw-r--r-- | res/drawable-nodpi/bg.png | bin | 0 -> 6460 bytes | |||
-rw-r--r-- | res/drawable-nodpi/dot.png | bin | 0 -> 6287 bytes | |||
-rw-r--r-- | res/drawable-nodpi/icon.png | bin | 0 -> 4147 bytes | |||
-rw-r--r-- | res/drawable-nodpi/vignette.png | bin | 0 -> 4327 bytes | |||
-rw-r--r-- | res/drawable-nodpi/wallpaper_thumb.png | bin | 0 -> 32610 bytes | |||
-rw-r--r-- | res/layout/main.xml | 10 | ||||
-rw-r--r-- | res/raw/noisefield_fs.glsl | 8 | ||||
-rw-r--r-- | res/raw/noisefield_vs.glsl | 17 | ||||
-rw-r--r-- | res/values/strings.xml | 6 | ||||
-rw-r--r-- | res/xml/wallpaper.xml | 6 | ||||
-rw-r--r-- | src/com/android/noisefield/NoiseField.java | 16 | ||||
-rw-r--r-- | src/com/android/noisefield/NoiseFieldRS.java | 245 | ||||
-rw-r--r-- | src/com/android/noisefield/NoiseFieldView.java | 42 | ||||
-rw-r--r-- | src/com/android/noisefield/NoiseFieldWallpaper.java | 117 | ||||
-rw-r--r-- | src/com/android/noisefield/noisefield.rs | 299 |
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 Binary files differnew file mode 100644 index 0000000..569e3e9 --- /dev/null +++ b/res/drawable-nodpi/bg.png diff --git a/res/drawable-nodpi/dot.png b/res/drawable-nodpi/dot.png Binary files differnew file mode 100644 index 0000000..fd8729f --- /dev/null +++ b/res/drawable-nodpi/dot.png diff --git a/res/drawable-nodpi/icon.png b/res/drawable-nodpi/icon.png Binary files differnew file mode 100644 index 0000000..8074c4c --- /dev/null +++ b/res/drawable-nodpi/icon.png diff --git a/res/drawable-nodpi/vignette.png b/res/drawable-nodpi/vignette.png Binary files differnew file mode 100644 index 0000000..1c6f19d --- /dev/null +++ b/res/drawable-nodpi/vignette.png diff --git a/res/drawable-nodpi/wallpaper_thumb.png b/res/drawable-nodpi/wallpaper_thumb.png Binary files differnew file mode 100644 index 0000000..b0f604d --- /dev/null +++ b/res/drawable-nodpi/wallpaper_thumb.png 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; +} |