diff options
Diffstat (limited to 'src/com/android/galaxy4')
-rw-r--r-- | src/com/android/galaxy4/Galaxy4.java | 16 | ||||
-rw-r--r-- | src/com/android/galaxy4/Galaxy4Wallpaper.java | 126 | ||||
-rw-r--r-- | src/com/android/galaxy4/GalaxyRS.java | 277 | ||||
-rw-r--r-- | src/com/android/galaxy4/GalaxyView.java | 45 | ||||
-rw-r--r-- | src/com/android/galaxy4/galaxy.rs | 179 |
5 files changed, 643 insertions, 0 deletions
diff --git a/src/com/android/galaxy4/Galaxy4.java b/src/com/android/galaxy4/Galaxy4.java new file mode 100644 index 0000000..6985de3 --- /dev/null +++ b/src/com/android/galaxy4/Galaxy4.java @@ -0,0 +1,16 @@ +package com.android.galaxy4; + +import android.app.Activity; +import android.os.Bundle; + +public class Galaxy4 extends Activity { + + private GalaxyView mView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mView = new GalaxyView(this); + setContentView(mView); + } +}
\ No newline at end of file diff --git a/src/com/android/galaxy4/Galaxy4Wallpaper.java b/src/com/android/galaxy4/Galaxy4Wallpaper.java new file mode 100644 index 0000000..1192e1c --- /dev/null +++ b/src/com/android/galaxy4/Galaxy4Wallpaper.java @@ -0,0 +1,126 @@ +/* + * 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. + */ + +package com.android.galaxy4; + +import android.graphics.PixelFormat; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; +import android.service.wallpaper.WallpaperService; +import android.view.Surface; +import android.view.SurfaceHolder; + +public class Galaxy4Wallpaper extends WallpaperService { + + @Override + public Engine onCreateEngine() { + return new RenderScriptEngine(); + } + + private class RenderScriptEngine extends Engine { + private RenderScriptGL mRenderScript = null; + private GalaxyRS mWallpaperRS = null; + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + setTouchEventsEnabled(true); + surfaceHolder.setSizeFromLayout(); + surfaceHolder.setFormat(PixelFormat.RGBA_8888); + } + + @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(Galaxy4Wallpaper.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 GalaxyRS(); + mWallpaperRS.init(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/galaxy4/GalaxyRS.java b/src/com/android/galaxy4/GalaxyRS.java new file mode 100644 index 0000000..c568296 --- /dev/null +++ b/src/com/android/galaxy4/GalaxyRS.java @@ -0,0 +1,277 @@ +package com.android.galaxy4; + +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.ProgramFragment; +import android.renderscript.ProgramFragmentFixedFunction; +import android.renderscript.ProgramRaster; +import android.renderscript.ProgramStore; +import android.renderscript.Sampler; +import android.renderscript.ProgramStore.BlendDstFunc; +import android.renderscript.ProgramStore.BlendSrcFunc; +import android.renderscript.ProgramVertex; +import android.renderscript.ProgramVertexFixedFunction; +import android.renderscript.RenderScriptGL; +import android.renderscript.ProgramVertexFixedFunction.Builder; +import android.util.Log; +import android.renderscript.Program; +import static android.renderscript.Sampler.Value.*; + +public class GalaxyRS { + public static final int BG_STAR_COUNT = 11000; + public static final int SPACE_CLOUDSTAR_COUNT = 25; + 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; + + int mHeight; + int mWidth; + boolean inited = false; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + private Allocation cloudAllocation; + private Allocation fgStarAllocation; + private Allocation bgAllocation; + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + if (!inited) { + mRS = rs; + mRes = res; + + mWidth = width; + mHeight = height; + + mOptionsARGB.inScaled = false; + mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; + + spaceClouds = new ScriptField_Particle(mRS, SPACE_CLOUDSTAR_COUNT); + Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); + smb.addVertexAllocation(spaceClouds.getAllocation()); + smb.addIndexSetType(Mesh.Primitive.POINT); + spaceCloudsMesh = smb.create(); + + bgStars = new ScriptField_Particle(mRS, BG_STAR_COUNT); + Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS); + smb2.addVertexAllocation(bgStars.getAllocation()); + smb2.addIndexSetType(Mesh.Primitive.POINT); + bgStarsMesh = smb2.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); + + mPvConsts = new ScriptField_VpConsts(mRS, 1); + + createProgramVertex(); + createProgramRaster(); + createProgramFragmentStore(); + createProgramFragment(); + + loadTextures(); + + mRS.bindRootScript(mScript); + + mScript.invoke_positionParticles(); + + inited = 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() { + 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); + } + + 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 void createProgramVertex() { + + // /////////////////// fixed function bg + 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(); + + // 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()); + ProgramVertex pvs = builder.create(); + pvs.bindConstants(mPvConsts.getAllocation(), 0); + mRS.bindProgramVertex(pvs); + + mScript.set_vertSpaceClouds(pvs); + + // bg stars + builder = new ProgramVertex.Builder(mRS); + builder.setShader(mRes, R.raw.bgstar_vs); + builder.addConstant(mPvConsts.getType()); + builder.addInput(bgStarsMesh.getVertexAllocation(0).getType().getElement()); + pvs = builder.create(); + pvs.bindConstants(mPvConsts.getAllocation(), 0); + mRS.bindProgramVertex(pvs); + mScript.set_vertBgStars(pvs); + } + + private void createProgramFragment() { + // fixed function bg + + Sampler.Builder samplerBuilder = new Sampler.Builder(mRS); + samplerBuilder.setMinification(NEAREST); + samplerBuilder.setMagnification(NEAREST); + samplerBuilder.setWrapS(WRAP); + samplerBuilder.setWrapT(WRAP); + Sampler sn = samplerBuilder.create(); + ProgramFragmentFixedFunction.Builder builderff = + new ProgramFragmentFixedFunction.Builder(mRS); + builderff = new ProgramFragmentFixedFunction.Builder(mRS); + builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGB, 0); + ProgramFragment pfff = builderff.create(); + mScript.set_fragBg(pfff); + pfff.bindSampler(sn, 0); + + //////////////////////////////////////////////////////////////////// + + // cloud fragment + 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 + builder = new ProgramFragment.Builder(mRS); + builder.setShader(mRes, R.raw.bgstar_fs); + pf = builder.create(); + mScript.set_fragBgStars(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(); + mRS.bindProgramRaster(pr); + } + + 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() { + mRS.bindRootScript(mScript); + } + + public void stop() { + mRS.bindRootScript(null); + } + + public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) { + mScript.set_xOffset(xOffset); + } + +} diff --git a/src/com/android/galaxy4/GalaxyView.java b/src/com/android/galaxy4/GalaxyView.java new file mode 100644 index 0000000..ce0d33f --- /dev/null +++ b/src/com/android/galaxy4/GalaxyView.java @@ -0,0 +1,45 @@ +package com.android.galaxy4; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScriptGL; +import android.renderscript.RenderScriptGL.SurfaceConfig; +import android.view.SurfaceHolder; + +public class GalaxyView extends RSSurfaceView { + + private RenderScriptGL mRS; + private GalaxyRS mRender; + + public GalaxyView(Context context) { + 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); + } + + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRS.setSurface(null, 0, 0); + mRS = null; + destroyRenderScriptGL(); + } + } + +} diff --git a/src/com/android/galaxy4/galaxy.rs b/src/com/android/galaxy4/galaxy.rs new file mode 100644 index 0000000..5117024 --- /dev/null +++ b/src/com/android/galaxy4/galaxy.rs @@ -0,0 +1,179 @@ +#pragma version(1) + +#pragma rs java_package_name(com.android.galaxy4) +#include "rs_graphics.rsh" +#pragma stateVertex(parent); +#pragma stateStore(parent); + +typedef struct __attribute__((packed, aligned(4))) Particle { + float3 position; + uchar4 color; +} Particle_t; + +typedef struct VpConsts { + rs_matrix4x4 MVP; +} VpConsts_t; +VpConsts_t *vpConstants; + + +// hold clouds +Particle_t *spaceClouds; + +// hold bg stars +Particle_t *bgStars; + +rs_mesh spaceCloudsMesh; +rs_mesh bgStarsMesh; + +rs_program_vertex vertSpaceClouds; +rs_program_vertex vertBgStars; +rs_program_fragment fragSpaceClouds; +rs_program_fragment fragBgStars; +rs_program_vertex vertBg; +rs_program_fragment fragBg; + +rs_allocation textureSpaceCloud; +rs_allocation textureFGStar; +rs_allocation textureBg; + +static int gGalaxyRadius = 250; + +float xOffset; + +#define PI 3.1415f +#define TWO_PI 6.283f + +/** + * Helper function to generate the stars. + */ +static float randomGauss() { + float x1; + float x2; + float w = 2.f; + + while (w >= 1.0f) { + x1 = rsRand(2.0f) - 1.0f; + x2 = rsRand(2.0f) - 1.0f; + w = x1 * x1 + x2 * x2; + } + + w = sqrt(-2.0f * log(w) / w); + return x1 * w; +} + +static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) { + return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart)); +} + + + +void positionParticles(){ + rsDebug("************************&&&&&&&&&&&&&&& Called positionBGStars", rsUptimeMillis()); + + float width = rsgGetWidth(); + float height = rsgGetHeight(); + + float scale = gGalaxyRadius / (width * 0.5f); + + // space clouds + Particle_t* particle = spaceClouds; + int size = rsAllocationGetDimX(rsGetAllocation(spaceClouds)); + for(int i=0; i<size; 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->position.z = z/5.0f; + particle->color = rsPackColorTo8888(1.0f, 0.0f, 1.0f); + particle++; + } + + // bg stars + size = rsAllocationGetDimX(rsGetAllocation(bgStars)); + particle = bgStars; + for(int i=0; i<size; 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->position.z = z/5.0f; + particle->color = rsPackColorTo8888(1.0f, 0.0f, 1.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 width = rsgGetWidth(); + float height = rsgGetHeight(); + + + rsgClearColor(0.0f, 0.f, 0.f, 0.5f); + + // bg + rsgBindProgramVertex(vertBg); + rsgBindProgramFragment(fragBg); + drawBg(width, height); + + + // space cloud + rsgBindProgramVertex(vertSpaceClouds); + int size = rsAllocationGetDimX(rsGetAllocation(spaceClouds)); + Particle_t *particle = spaceClouds; + + for(int i=0; i<size; 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++){ + particle->position.x -= .007; + particle++; + } + rsgBindProgramFragment(fragBgStars); + rsgDrawMesh(bgStarsMesh); + + + return 40; +} + |