Loading core/java/android/util/MathUtils.java 0 → 100644 +168 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 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 android.util; import java.util.Random; /** * A class that contains utility methods related to numbers. * * @hide Pending API council approval */ public final class MathUtils { private static final Random sRandom = new Random(); private static final float DEG_TO_RAD = 3.1415926f / 180.0f; private static final float RAD_TO_DEG = 180.0f / 3.1415926f; private MathUtils() { } public static float abs(float v) { return v > 0 ? v : -v; } public static int constrain(int amount, int low, int high) { return amount < low ? low : (amount > high ? high : amount); } public static float constrain(float amount, float low, float high) { return amount < low ? low : (amount > high ? high : amount); } public static float log(float a) { return (float) Math.log(a); } public static float exp(float a) { return (float) Math.exp(a); } public static float pow(float a, float b) { return (float) Math.pow(a, b); } public static float max(float a, float b) { return a > b ? a : b; } public static float max(int a, int b) { return a > b ? a : b; } public static float max(float a, float b, float c) { return a > b ? (a > c ? a : c) : (b > c ? b : c); } public static float max(int a, int b, int c) { return a > b ? (a > c ? a : c) : (b > c ? b : c); } public static float min(float a, float b) { return a < b ? a : b; } public static float min(int a, int b) { return a < b ? a : b; } public static float min(float a, float b, float c) { return a < b ? (a < c ? a : c) : (b < c ? b : c); } public static float min(int a, int b, int c) { return a < b ? (a < c ? a : c) : (b < c ? b : c); } public static float dist(float x1, float y1, float x2, float y2) { final float x = (x2 - x1); final float y = (y2 - y1); return (float) Math.sqrt(x * x + y * y); } public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) { final float x = (x2 - x1); final float y = (y2 - y1); final float z = (z2 - z1); return (float) Math.sqrt(x * x + y * y + z * z); } public static float mag(float a, float b) { return (float) Math.sqrt(a * a + b * b); } public static float mag(float a, float b, float c) { return (float) Math.sqrt(a * a + b * b + c * c); } public static float sq(float v) { return v * v; } public static float radians(float degrees) { return degrees * DEG_TO_RAD; } public static float degress(float radians) { return radians * RAD_TO_DEG; } public static float acos(float value) { return (float) Math.acos(value); } public static float asin(float value) { return (float) Math.asin(value); } public static float atan(float value) { return (float) Math.atan(value); } public static float atan2(float a, float b) { return (float) Math.atan2(a, b); } public static float tan(float angle) { return (float) Math.tan(angle); } public static float lerp(float start, float stop, float amount) { return start + (stop - start) * amount; } public static int random(int howbig) { return (int) (sRandom.nextFloat() * howbig); } public static int random(int howsmall, int howbig) { if (howsmall >= howbig) return howsmall; return (int) (sRandom.nextFloat() * (howbig - howsmall) + howsmall); } public static float random(float howbig) { return sRandom.nextFloat() * howbig; } public static float random(float howsmall, float howbig) { if (howsmall >= howbig) return howsmall; return sRandom.nextFloat() * (howbig - howsmall) + howsmall; } public static void randomSeed(long seed) { sRandom.setSeed(seed); } } graphics/java/android/graphics/Color.java +182 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.graphics; import android.util.MathUtils; import java.util.HashMap; import java.util.Locale; Loading Loading @@ -104,6 +106,92 @@ public class Color { return (alpha << 24) | (red << 16) | (green << 8) | blue; } /** * Returns the hue component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float hue(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); int temp = Math.min(b, Math.min(r, g)); float H; if (V == temp) { H = 0; } else { final float vtemp = (float) (V - temp); final float cr = (V - r) / vtemp; final float cg = (V - g) / vtemp; final float cb = (V - b) / vtemp; if (r == V) { H = cb - cg; } else if (g == V) { H = 2 + cr - cb; } else { H = 4 + cg - cr; } H /= 6.f; if (H < 0) { H++; } } return H; } /** * Returns the saturation component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float saturation(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); int temp = Math.min(b, Math.min(r, g)); float S; if (V == temp) { S = 0; } else { S = (V - temp) / (float) V; } return S; } /** * Returns the brightness component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float brightness(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); return (V / 255.f); } /** * Parse the color string, and return the corresponding color-int. * If the string cannot be parsed, throws an IllegalArgumentException Loading Loading @@ -133,6 +221,87 @@ public class Color { throw new IllegalArgumentException("Unknown color"); } /** * Convert HSB components to an ARGB color. Alpha set to 0xFF. * hsv[0] is Hue [0 .. 1) * hsv[1] is Saturation [0...1] * hsv[2] is Value [0...1] * If hsv values are out of range, they are pinned. * @param hsb 3 element array which holds the input HSB components. * @return the resulting argb color * * @hide Pending API council */ public static int HSBtoColor(float[] hsb) { return HSBtoColor(hsb[0], hsb[1], hsb[2]); } /** * Convert HSB components to an ARGB color. Alpha set to 0xFF. * hsv[0] is Hue [0 .. 1) * hsv[1] is Saturation [0...1] * hsv[2] is Value [0...1] * If hsv values are out of range, they are pinned. * @param h Hue component * @param s Saturation component * @param b Brightness component * @return the resulting argb color * * @hide Pending API council */ public static int HSBtoColor(float h, float s, float b) { h = MathUtils.constrain(h, 0.0f, 1.0f); s = MathUtils.constrain(s, 0.0f, 1.0f); b = MathUtils.constrain(b, 0.0f, 1.0f); float red = 0.0f; float green = 0.0f; float blue = 0.0f; final float hf = (h - (int) h) * 6.0f; final int ihf = (int) hf; final float f = hf - ihf; final float pv = b * (1.0f - s); final float qv = b * (1.0f - s * f); final float tv = b * (1.0f - s * (1.0f - f)); switch (ihf) { case 0: // Red is the dominant color red = b; green = tv; blue = pv; break; case 1: // Green is the dominant color red = qv; green = b; blue = pv; break; case 2: red = pv; green = b; blue = tv; break; case 3: // Blue is the dominant color red = pv; green = qv; blue = b; break; case 4: red = tv; green = pv; blue = b; break; case 5: // Red is the dominant color red = b; green = pv; blue = qv; break; } return 0xFF000000 | (((int) (red * 255.0f)) << 16) | (((int) (green * 255.0f)) << 8) | ((int) (blue * 255.0f)); } /** * Convert RGB components to HSV. * hsv[0] is Hue [0 .. 360) Loading Loading @@ -193,25 +362,24 @@ public class Color { return nativeHSVToColor(alpha, hsv); } private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native int nativeHSVToColor(int alpha, float hsv[]); private static final HashMap<String, Integer> sColorNameMap; static { sColorNameMap = new HashMap(); sColorNameMap.put("black", Integer.valueOf(BLACK)); sColorNameMap.put("darkgray", Integer.valueOf(DKGRAY)); sColorNameMap.put("gray", Integer.valueOf(GRAY)); sColorNameMap.put("lightgray", Integer.valueOf(LTGRAY)); sColorNameMap.put("white", Integer.valueOf(WHITE)); sColorNameMap.put("red", Integer.valueOf(RED)); sColorNameMap.put("green", Integer.valueOf(GREEN)); sColorNameMap.put("blue", Integer.valueOf(BLUE)); sColorNameMap.put("yellow", Integer.valueOf(YELLOW)); sColorNameMap.put("cyan", Integer.valueOf(CYAN)); sColorNameMap.put("magenta", Integer.valueOf(MAGENTA)); sColorNameMap = new HashMap<String, Integer>(); sColorNameMap.put("black", BLACK); sColorNameMap.put("darkgray", DKGRAY); sColorNameMap.put("gray", GRAY); sColorNameMap.put("lightgray", LTGRAY); sColorNameMap.put("white", WHITE); sColorNameMap.put("red", RED); sColorNameMap.put("green", GREEN); sColorNameMap.put("blue", BLUE); sColorNameMap.put("yellow", YELLOW); sColorNameMap.put("cyan", CYAN); sColorNameMap.put("magenta", MAGENTA); } } libs/rs/java/Grass/res/raw/grass.c +110 −22 Original line number Diff line number Diff line /* * Copyright (C) 2008 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. */ // Copyright (C) 2009 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. #pragma version(1) #pragma stateVertex(default) #pragma stateVertex(PVBackground) #pragma stateFragment(PFBackground) #pragma stateFragmentStore(PFSBackground) Loading @@ -23,7 +21,8 @@ #define WVGA_PORTRAIT_HEIGHT 762.0f #define RSID_STATE 0 #define RSID_FRAMECOUNT 0 #define RSID_FRAME_COUNT 0 #define RSID_BLADES_COUNT 1 #define RSID_SKY_TEXTURES 1 #define RSID_SKY_TEXTURE_NIGHT 0 Loading @@ -31,6 +30,21 @@ #define RSID_SKY_TEXTURE_NOON 2 #define RSID_SKY_TEXTURE_SUNSET 3 #define RSID_BLADES 2 #define BLADE_STRUCT_FIELDS_COUNT 12 #define BLADE_STRUCT_DEGREE 0 #define BLADE_STRUCT_SIZE 1 #define BLADE_STRUCT_XPOS 2 #define BLADE_STRUCT_YPOS 3 #define BLADE_STRUCT_OFFSET 4 #define BLADE_STRUCT_SCALE 5 #define BLADE_STRUCT_LENGTHX 6 #define BLADE_STRUCT_LENGTHY 7 #define BLADE_STRUCT_HARDNESS 8 #define BLADE_STRUCT_H 9 #define BLADE_STRUCT_S 10 #define BLADE_STRUCT_B 11 #define MIDNIGHT 0.0f #define MORNING 0.375f #define AFTERNOON 0.6f Loading @@ -38,6 +52,8 @@ #define SECONDS_IN_DAY 24.0f * 3600.0f #define PI 3.1415926f #define REAL_TIME 0 float time(int frameCount) { Loading Loading @@ -76,8 +92,78 @@ void drawSunset() { drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f); } void drawBlade(int index, float now) { float h = loadF(RSID_BLADES, index + BLADE_STRUCT_H); float s = loadF(RSID_BLADES, index + BLADE_STRUCT_S); float b = loadF(RSID_BLADES, index + BLADE_STRUCT_B); float newB = 1.0f; if (now >= MIDNIGHT && now < MORNING) { newB = now / MORNING; } if (now >= AFTERNOON && now < DUSK) { newB = 1.0f - ((now - AFTERNOON) / (DUSK - AFTERNOON)); } if (now >= DUSK) { newB = 0.0f; } hsb(h, s, lerpf(0, b, newB), 1.0f); float scale = loadF(RSID_BLADES, index + BLADE_STRUCT_SCALE); float degree = loadF(RSID_BLADES, index + BLADE_STRUCT_DEGREE); float hardness = loadF(RSID_BLADES, index + BLADE_STRUCT_HARDNESS); float targetDegree = 0.0f; // TODO Compute degree += (targetDegree - degree) * 0.3f; float xpos = loadF(RSID_BLADES, index + BLADE_STRUCT_XPOS); float ypos = loadF(RSID_BLADES, index + BLADE_STRUCT_YPOS); float lengthX = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHX); float lengthY = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHY); float angle = PI / 2.0f; float currentX = xpos; float currentY = ypos; int size = loadF(RSID_BLADES, index + BLADE_STRUCT_SIZE); int i = size; for ( ; i > 0; i--) { float nextX = currentX - cosf(angle) * size * lengthX; float nextY = currentY - sinf(angle) * size * lengthY; angle += degree * hardness; drawQuad(nextX + (i - 1) * scale, nextY, 0.0f, nextX - (i - 1) * scale, nextY, 0.0f, currentX - i * scale, currentY + 0.7f, 0.0f, currentX + i * scale, currentY + 0.7f, 0.0f); currentX = nextX; currentY = nextY; } storeF(RSID_BLADES, index + BLADE_STRUCT_DEGREE, degree); } void drawBlades(float now) { bindTexture(NAMED_PFBackground, 0, 0); int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT); int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT; int i = 0; for ( ; i < count; i += BLADE_STRUCT_FIELDS_COUNT) { drawBlade(i, now); } } int main(int launchID) { int frameCount = loadI32(RSID_STATE, RSID_FRAMECOUNT); int frameCount = loadI32(RSID_STATE, RSID_FRAME_COUNT); float now = time(frameCount); alpha(1.0f); Loading @@ -100,13 +186,15 @@ int main(int launchID) { } if (now >= DUSK) { drawSunset(); alpha(norm(now, DUSK, 1.0f)); drawNight(); alpha(1.0f - norm(now, DUSK, 1.0f)); drawSunset(); } drawBlades(now); frameCount++; storeI32(RSID_STATE, RSID_FRAMECOUNT, frameCount); storeI32(RSID_STATE, RSID_FRAME_COUNT, frameCount); return 1; } libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java +74 −7 Original line number Diff line number Diff line Loading @@ -23,21 +23,46 @@ import static android.renderscript.RenderScript.EnvMode.*; import static android.renderscript.RenderScript.DepthFunc.*; import static android.renderscript.RenderScript.BlendSrcFunc; import static android.renderscript.RenderScript.BlendDstFunc; import android.renderscript.RenderScript; import android.renderscript.Element; import android.renderscript.Allocation; import android.renderscript.ProgramVertexAlloc; import static android.renderscript.Element.*; import static android.util.MathUtils.*; import java.util.TimeZone; class GrassRS { private static final int RSID_STATE = 0; private static final int RSID_STATE_FRAMECOUNT = 0; private static final int RSID_STATE_BLADES_COUNT = 1; private static final int RSID_SKY_TEXTURES = 1; private static final int SKY_TEXTURES_COUNT = 4; private static final int RSID_BLADES = 2; private static final int BLADES_COUNT = 100; private static final int BLADE_STRUCT_FIELDS_COUNT = 12; private static final int BLADE_STRUCT_DEGREE = 0; private static final int BLADE_STRUCT_SIZE = 1; private static final int BLADE_STRUCT_XPOS = 2; private static final int BLADE_STRUCT_YPOS = 3; private static final int BLADE_STRUCT_OFFSET = 4; private static final int BLADE_STRUCT_SCALE = 5; private static final int BLADE_STRUCT_LENGTHX = 6; private static final int BLADE_STRUCT_LENGTHY = 7; private static final int BLADE_STRUCT_HARDNESS = 8; private static final int BLADE_STRUCT_H = 9; private static final int BLADE_STRUCT_S = 10; private static final int BLADE_STRUCT_B = 11; private Resources mResources; private RenderScript mRS; private final int mWidth; private final int mHeight; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.Script mScript; @SuppressWarnings({"FieldCanBeLocal"}) Loading @@ -46,6 +71,10 @@ class GrassRS { private RenderScript.ProgramFragment mPfBackground; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.ProgramFragmentStore mPfsBackground; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.ProgramVertex mPvBackground; @SuppressWarnings({"FieldCanBeLocal"}) private ProgramVertexAlloc mPvOrthoAlloc; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mSkyTexturesIDs; Loading @@ -55,8 +84,12 @@ class GrassRS { private int[] mSkyBufferIDs; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mState; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mBlades; public GrassRS() { public GrassRS(int width, int height) { mWidth = width; mHeight = height; } public void init(RenderScript rs, Resources res) { Loading @@ -82,20 +115,46 @@ class GrassRS { loadSkyTextures(); mScript.bindAllocation(mState, RSID_STATE); mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES); mScript.bindAllocation(mBlades, RSID_BLADES); mRS.contextBindRootScript(mScript); } private void createScriptStructures() { mState = Allocation.createSized(mRS, Element.USER_I32, 1); mState.data(new int[1]); final int[] data = new int[2]; mState = Allocation.createSized(mRS, USER_I32, data.length); data[RSID_STATE_FRAMECOUNT] = 0; data[RSID_STATE_BLADES_COUNT] = BLADES_COUNT; mState.data(data); final float[] blades = new float[BLADES_COUNT * BLADE_STRUCT_FIELDS_COUNT]; mBlades = Allocation.createSized(mRS, USER_FLOAT, blades.length); for (int i = 0; i < blades.length; i+= BLADE_STRUCT_FIELDS_COUNT) { createBlade(blades, i); } mBlades.data(blades); } private void createBlade(float[] blades, int index) { //noinspection PointlessArithmeticExpression blades[index + BLADE_STRUCT_DEGREE] = 0.0f; blades[index + BLADE_STRUCT_SIZE] = random(4.0f) + 4.0f; blades[index + BLADE_STRUCT_XPOS] = random(mWidth); blades[index + BLADE_STRUCT_YPOS] = mHeight; blades[index + BLADE_STRUCT_OFFSET] = random(0.2f) - 0.1f; blades[index + BLADE_STRUCT_SCALE] = random(0.6f) + 0.2f; blades[index + BLADE_STRUCT_LENGTHX] = random(4.5f) + 3.0f; blades[index + BLADE_STRUCT_LENGTHY] = random(5.5f) + 2.0f; blades[index + BLADE_STRUCT_HARDNESS] = random(1.0f) + 0.2f; blades[index + BLADE_STRUCT_H] = (51.0f + random(5.0f)) / 255.0f; blades[index + BLADE_STRUCT_S] = (200.0f + random(55.0f)) / 255.0f; blades[index + BLADE_STRUCT_B] = (90.0f + random(165.0f)) / 255.0f; } private void loadSkyTextures() { mSkyBufferIDs = new int[SKY_TEXTURES_COUNT]; mSkyTextures = new Allocation[SKY_TEXTURES_COUNT]; mSkyTexturesIDs = Allocation.createSized( mRS, Element.USER_FLOAT, SKY_TEXTURES_COUNT); mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT); final Allocation[] textures = mSkyTextures; textures[0] = loadTexture(R.drawable.night, "night"); Loading Loading @@ -149,5 +208,13 @@ class GrassRS { } private void createProgramVertex() { mPvOrthoAlloc = new ProgramVertexAlloc(mRS); mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight); mRS.programVertexBegin(null, null); mRS.programVertexSetTextureMatrixEnable(true); mPvBackground = mRS.programVertexCreate(); mPvBackground.bindAllocation(0, mPvOrthoAlloc.mAlloc); mPvBackground.setName("PVBackground"); } } libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ class GrassView extends RSSurfaceView { super.surfaceChanged(holder, format, w, h); RenderScript RS = createRenderScript(); GrassRS render = new GrassRS(); GrassRS render = new GrassRS(w, h); render.init(RS, getResources()); } } Loading
core/java/android/util/MathUtils.java 0 → 100644 +168 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 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 android.util; import java.util.Random; /** * A class that contains utility methods related to numbers. * * @hide Pending API council approval */ public final class MathUtils { private static final Random sRandom = new Random(); private static final float DEG_TO_RAD = 3.1415926f / 180.0f; private static final float RAD_TO_DEG = 180.0f / 3.1415926f; private MathUtils() { } public static float abs(float v) { return v > 0 ? v : -v; } public static int constrain(int amount, int low, int high) { return amount < low ? low : (amount > high ? high : amount); } public static float constrain(float amount, float low, float high) { return amount < low ? low : (amount > high ? high : amount); } public static float log(float a) { return (float) Math.log(a); } public static float exp(float a) { return (float) Math.exp(a); } public static float pow(float a, float b) { return (float) Math.pow(a, b); } public static float max(float a, float b) { return a > b ? a : b; } public static float max(int a, int b) { return a > b ? a : b; } public static float max(float a, float b, float c) { return a > b ? (a > c ? a : c) : (b > c ? b : c); } public static float max(int a, int b, int c) { return a > b ? (a > c ? a : c) : (b > c ? b : c); } public static float min(float a, float b) { return a < b ? a : b; } public static float min(int a, int b) { return a < b ? a : b; } public static float min(float a, float b, float c) { return a < b ? (a < c ? a : c) : (b < c ? b : c); } public static float min(int a, int b, int c) { return a < b ? (a < c ? a : c) : (b < c ? b : c); } public static float dist(float x1, float y1, float x2, float y2) { final float x = (x2 - x1); final float y = (y2 - y1); return (float) Math.sqrt(x * x + y * y); } public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) { final float x = (x2 - x1); final float y = (y2 - y1); final float z = (z2 - z1); return (float) Math.sqrt(x * x + y * y + z * z); } public static float mag(float a, float b) { return (float) Math.sqrt(a * a + b * b); } public static float mag(float a, float b, float c) { return (float) Math.sqrt(a * a + b * b + c * c); } public static float sq(float v) { return v * v; } public static float radians(float degrees) { return degrees * DEG_TO_RAD; } public static float degress(float radians) { return radians * RAD_TO_DEG; } public static float acos(float value) { return (float) Math.acos(value); } public static float asin(float value) { return (float) Math.asin(value); } public static float atan(float value) { return (float) Math.atan(value); } public static float atan2(float a, float b) { return (float) Math.atan2(a, b); } public static float tan(float angle) { return (float) Math.tan(angle); } public static float lerp(float start, float stop, float amount) { return start + (stop - start) * amount; } public static int random(int howbig) { return (int) (sRandom.nextFloat() * howbig); } public static int random(int howsmall, int howbig) { if (howsmall >= howbig) return howsmall; return (int) (sRandom.nextFloat() * (howbig - howsmall) + howsmall); } public static float random(float howbig) { return sRandom.nextFloat() * howbig; } public static float random(float howsmall, float howbig) { if (howsmall >= howbig) return howsmall; return sRandom.nextFloat() * (howbig - howsmall) + howsmall; } public static void randomSeed(long seed) { sRandom.setSeed(seed); } }
graphics/java/android/graphics/Color.java +182 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.graphics; import android.util.MathUtils; import java.util.HashMap; import java.util.Locale; Loading Loading @@ -104,6 +106,92 @@ public class Color { return (alpha << 24) | (red << 16) | (green << 8) | blue; } /** * Returns the hue component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float hue(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); int temp = Math.min(b, Math.min(r, g)); float H; if (V == temp) { H = 0; } else { final float vtemp = (float) (V - temp); final float cr = (V - r) / vtemp; final float cg = (V - g) / vtemp; final float cb = (V - b) / vtemp; if (r == V) { H = cb - cg; } else if (g == V) { H = 2 + cr - cb; } else { H = 4 + cg - cr; } H /= 6.f; if (H < 0) { H++; } } return H; } /** * Returns the saturation component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float saturation(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); int temp = Math.min(b, Math.min(r, g)); float S; if (V == temp) { S = 0; } else { S = (V - temp) / (float) V; } return S; } /** * Returns the brightness component of a color int. * * @return A value between 0.0f and 1.0f * * @hide Pending API council */ public static float brightness(int color) { int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; int V = Math.max(b, Math.max(r, g)); return (V / 255.f); } /** * Parse the color string, and return the corresponding color-int. * If the string cannot be parsed, throws an IllegalArgumentException Loading Loading @@ -133,6 +221,87 @@ public class Color { throw new IllegalArgumentException("Unknown color"); } /** * Convert HSB components to an ARGB color. Alpha set to 0xFF. * hsv[0] is Hue [0 .. 1) * hsv[1] is Saturation [0...1] * hsv[2] is Value [0...1] * If hsv values are out of range, they are pinned. * @param hsb 3 element array which holds the input HSB components. * @return the resulting argb color * * @hide Pending API council */ public static int HSBtoColor(float[] hsb) { return HSBtoColor(hsb[0], hsb[1], hsb[2]); } /** * Convert HSB components to an ARGB color. Alpha set to 0xFF. * hsv[0] is Hue [0 .. 1) * hsv[1] is Saturation [0...1] * hsv[2] is Value [0...1] * If hsv values are out of range, they are pinned. * @param h Hue component * @param s Saturation component * @param b Brightness component * @return the resulting argb color * * @hide Pending API council */ public static int HSBtoColor(float h, float s, float b) { h = MathUtils.constrain(h, 0.0f, 1.0f); s = MathUtils.constrain(s, 0.0f, 1.0f); b = MathUtils.constrain(b, 0.0f, 1.0f); float red = 0.0f; float green = 0.0f; float blue = 0.0f; final float hf = (h - (int) h) * 6.0f; final int ihf = (int) hf; final float f = hf - ihf; final float pv = b * (1.0f - s); final float qv = b * (1.0f - s * f); final float tv = b * (1.0f - s * (1.0f - f)); switch (ihf) { case 0: // Red is the dominant color red = b; green = tv; blue = pv; break; case 1: // Green is the dominant color red = qv; green = b; blue = pv; break; case 2: red = pv; green = b; blue = tv; break; case 3: // Blue is the dominant color red = pv; green = qv; blue = b; break; case 4: red = tv; green = pv; blue = b; break; case 5: // Red is the dominant color red = b; green = pv; blue = qv; break; } return 0xFF000000 | (((int) (red * 255.0f)) << 16) | (((int) (green * 255.0f)) << 8) | ((int) (blue * 255.0f)); } /** * Convert RGB components to HSV. * hsv[0] is Hue [0 .. 360) Loading Loading @@ -193,25 +362,24 @@ public class Color { return nativeHSVToColor(alpha, hsv); } private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native int nativeHSVToColor(int alpha, float hsv[]); private static final HashMap<String, Integer> sColorNameMap; static { sColorNameMap = new HashMap(); sColorNameMap.put("black", Integer.valueOf(BLACK)); sColorNameMap.put("darkgray", Integer.valueOf(DKGRAY)); sColorNameMap.put("gray", Integer.valueOf(GRAY)); sColorNameMap.put("lightgray", Integer.valueOf(LTGRAY)); sColorNameMap.put("white", Integer.valueOf(WHITE)); sColorNameMap.put("red", Integer.valueOf(RED)); sColorNameMap.put("green", Integer.valueOf(GREEN)); sColorNameMap.put("blue", Integer.valueOf(BLUE)); sColorNameMap.put("yellow", Integer.valueOf(YELLOW)); sColorNameMap.put("cyan", Integer.valueOf(CYAN)); sColorNameMap.put("magenta", Integer.valueOf(MAGENTA)); sColorNameMap = new HashMap<String, Integer>(); sColorNameMap.put("black", BLACK); sColorNameMap.put("darkgray", DKGRAY); sColorNameMap.put("gray", GRAY); sColorNameMap.put("lightgray", LTGRAY); sColorNameMap.put("white", WHITE); sColorNameMap.put("red", RED); sColorNameMap.put("green", GREEN); sColorNameMap.put("blue", BLUE); sColorNameMap.put("yellow", YELLOW); sColorNameMap.put("cyan", CYAN); sColorNameMap.put("magenta", MAGENTA); } }
libs/rs/java/Grass/res/raw/grass.c +110 −22 Original line number Diff line number Diff line /* * Copyright (C) 2008 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. */ // Copyright (C) 2009 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. #pragma version(1) #pragma stateVertex(default) #pragma stateVertex(PVBackground) #pragma stateFragment(PFBackground) #pragma stateFragmentStore(PFSBackground) Loading @@ -23,7 +21,8 @@ #define WVGA_PORTRAIT_HEIGHT 762.0f #define RSID_STATE 0 #define RSID_FRAMECOUNT 0 #define RSID_FRAME_COUNT 0 #define RSID_BLADES_COUNT 1 #define RSID_SKY_TEXTURES 1 #define RSID_SKY_TEXTURE_NIGHT 0 Loading @@ -31,6 +30,21 @@ #define RSID_SKY_TEXTURE_NOON 2 #define RSID_SKY_TEXTURE_SUNSET 3 #define RSID_BLADES 2 #define BLADE_STRUCT_FIELDS_COUNT 12 #define BLADE_STRUCT_DEGREE 0 #define BLADE_STRUCT_SIZE 1 #define BLADE_STRUCT_XPOS 2 #define BLADE_STRUCT_YPOS 3 #define BLADE_STRUCT_OFFSET 4 #define BLADE_STRUCT_SCALE 5 #define BLADE_STRUCT_LENGTHX 6 #define BLADE_STRUCT_LENGTHY 7 #define BLADE_STRUCT_HARDNESS 8 #define BLADE_STRUCT_H 9 #define BLADE_STRUCT_S 10 #define BLADE_STRUCT_B 11 #define MIDNIGHT 0.0f #define MORNING 0.375f #define AFTERNOON 0.6f Loading @@ -38,6 +52,8 @@ #define SECONDS_IN_DAY 24.0f * 3600.0f #define PI 3.1415926f #define REAL_TIME 0 float time(int frameCount) { Loading Loading @@ -76,8 +92,78 @@ void drawSunset() { drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f); } void drawBlade(int index, float now) { float h = loadF(RSID_BLADES, index + BLADE_STRUCT_H); float s = loadF(RSID_BLADES, index + BLADE_STRUCT_S); float b = loadF(RSID_BLADES, index + BLADE_STRUCT_B); float newB = 1.0f; if (now >= MIDNIGHT && now < MORNING) { newB = now / MORNING; } if (now >= AFTERNOON && now < DUSK) { newB = 1.0f - ((now - AFTERNOON) / (DUSK - AFTERNOON)); } if (now >= DUSK) { newB = 0.0f; } hsb(h, s, lerpf(0, b, newB), 1.0f); float scale = loadF(RSID_BLADES, index + BLADE_STRUCT_SCALE); float degree = loadF(RSID_BLADES, index + BLADE_STRUCT_DEGREE); float hardness = loadF(RSID_BLADES, index + BLADE_STRUCT_HARDNESS); float targetDegree = 0.0f; // TODO Compute degree += (targetDegree - degree) * 0.3f; float xpos = loadF(RSID_BLADES, index + BLADE_STRUCT_XPOS); float ypos = loadF(RSID_BLADES, index + BLADE_STRUCT_YPOS); float lengthX = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHX); float lengthY = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHY); float angle = PI / 2.0f; float currentX = xpos; float currentY = ypos; int size = loadF(RSID_BLADES, index + BLADE_STRUCT_SIZE); int i = size; for ( ; i > 0; i--) { float nextX = currentX - cosf(angle) * size * lengthX; float nextY = currentY - sinf(angle) * size * lengthY; angle += degree * hardness; drawQuad(nextX + (i - 1) * scale, nextY, 0.0f, nextX - (i - 1) * scale, nextY, 0.0f, currentX - i * scale, currentY + 0.7f, 0.0f, currentX + i * scale, currentY + 0.7f, 0.0f); currentX = nextX; currentY = nextY; } storeF(RSID_BLADES, index + BLADE_STRUCT_DEGREE, degree); } void drawBlades(float now) { bindTexture(NAMED_PFBackground, 0, 0); int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT); int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT; int i = 0; for ( ; i < count; i += BLADE_STRUCT_FIELDS_COUNT) { drawBlade(i, now); } } int main(int launchID) { int frameCount = loadI32(RSID_STATE, RSID_FRAMECOUNT); int frameCount = loadI32(RSID_STATE, RSID_FRAME_COUNT); float now = time(frameCount); alpha(1.0f); Loading @@ -100,13 +186,15 @@ int main(int launchID) { } if (now >= DUSK) { drawSunset(); alpha(norm(now, DUSK, 1.0f)); drawNight(); alpha(1.0f - norm(now, DUSK, 1.0f)); drawSunset(); } drawBlades(now); frameCount++; storeI32(RSID_STATE, RSID_FRAMECOUNT, frameCount); storeI32(RSID_STATE, RSID_FRAME_COUNT, frameCount); return 1; }
libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java +74 −7 Original line number Diff line number Diff line Loading @@ -23,21 +23,46 @@ import static android.renderscript.RenderScript.EnvMode.*; import static android.renderscript.RenderScript.DepthFunc.*; import static android.renderscript.RenderScript.BlendSrcFunc; import static android.renderscript.RenderScript.BlendDstFunc; import android.renderscript.RenderScript; import android.renderscript.Element; import android.renderscript.Allocation; import android.renderscript.ProgramVertexAlloc; import static android.renderscript.Element.*; import static android.util.MathUtils.*; import java.util.TimeZone; class GrassRS { private static final int RSID_STATE = 0; private static final int RSID_STATE_FRAMECOUNT = 0; private static final int RSID_STATE_BLADES_COUNT = 1; private static final int RSID_SKY_TEXTURES = 1; private static final int SKY_TEXTURES_COUNT = 4; private static final int RSID_BLADES = 2; private static final int BLADES_COUNT = 100; private static final int BLADE_STRUCT_FIELDS_COUNT = 12; private static final int BLADE_STRUCT_DEGREE = 0; private static final int BLADE_STRUCT_SIZE = 1; private static final int BLADE_STRUCT_XPOS = 2; private static final int BLADE_STRUCT_YPOS = 3; private static final int BLADE_STRUCT_OFFSET = 4; private static final int BLADE_STRUCT_SCALE = 5; private static final int BLADE_STRUCT_LENGTHX = 6; private static final int BLADE_STRUCT_LENGTHY = 7; private static final int BLADE_STRUCT_HARDNESS = 8; private static final int BLADE_STRUCT_H = 9; private static final int BLADE_STRUCT_S = 10; private static final int BLADE_STRUCT_B = 11; private Resources mResources; private RenderScript mRS; private final int mWidth; private final int mHeight; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.Script mScript; @SuppressWarnings({"FieldCanBeLocal"}) Loading @@ -46,6 +71,10 @@ class GrassRS { private RenderScript.ProgramFragment mPfBackground; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.ProgramFragmentStore mPfsBackground; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript.ProgramVertex mPvBackground; @SuppressWarnings({"FieldCanBeLocal"}) private ProgramVertexAlloc mPvOrthoAlloc; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mSkyTexturesIDs; Loading @@ -55,8 +84,12 @@ class GrassRS { private int[] mSkyBufferIDs; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mState; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mBlades; public GrassRS() { public GrassRS(int width, int height) { mWidth = width; mHeight = height; } public void init(RenderScript rs, Resources res) { Loading @@ -82,20 +115,46 @@ class GrassRS { loadSkyTextures(); mScript.bindAllocation(mState, RSID_STATE); mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES); mScript.bindAllocation(mBlades, RSID_BLADES); mRS.contextBindRootScript(mScript); } private void createScriptStructures() { mState = Allocation.createSized(mRS, Element.USER_I32, 1); mState.data(new int[1]); final int[] data = new int[2]; mState = Allocation.createSized(mRS, USER_I32, data.length); data[RSID_STATE_FRAMECOUNT] = 0; data[RSID_STATE_BLADES_COUNT] = BLADES_COUNT; mState.data(data); final float[] blades = new float[BLADES_COUNT * BLADE_STRUCT_FIELDS_COUNT]; mBlades = Allocation.createSized(mRS, USER_FLOAT, blades.length); for (int i = 0; i < blades.length; i+= BLADE_STRUCT_FIELDS_COUNT) { createBlade(blades, i); } mBlades.data(blades); } private void createBlade(float[] blades, int index) { //noinspection PointlessArithmeticExpression blades[index + BLADE_STRUCT_DEGREE] = 0.0f; blades[index + BLADE_STRUCT_SIZE] = random(4.0f) + 4.0f; blades[index + BLADE_STRUCT_XPOS] = random(mWidth); blades[index + BLADE_STRUCT_YPOS] = mHeight; blades[index + BLADE_STRUCT_OFFSET] = random(0.2f) - 0.1f; blades[index + BLADE_STRUCT_SCALE] = random(0.6f) + 0.2f; blades[index + BLADE_STRUCT_LENGTHX] = random(4.5f) + 3.0f; blades[index + BLADE_STRUCT_LENGTHY] = random(5.5f) + 2.0f; blades[index + BLADE_STRUCT_HARDNESS] = random(1.0f) + 0.2f; blades[index + BLADE_STRUCT_H] = (51.0f + random(5.0f)) / 255.0f; blades[index + BLADE_STRUCT_S] = (200.0f + random(55.0f)) / 255.0f; blades[index + BLADE_STRUCT_B] = (90.0f + random(165.0f)) / 255.0f; } private void loadSkyTextures() { mSkyBufferIDs = new int[SKY_TEXTURES_COUNT]; mSkyTextures = new Allocation[SKY_TEXTURES_COUNT]; mSkyTexturesIDs = Allocation.createSized( mRS, Element.USER_FLOAT, SKY_TEXTURES_COUNT); mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT); final Allocation[] textures = mSkyTextures; textures[0] = loadTexture(R.drawable.night, "night"); Loading Loading @@ -149,5 +208,13 @@ class GrassRS { } private void createProgramVertex() { mPvOrthoAlloc = new ProgramVertexAlloc(mRS); mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight); mRS.programVertexBegin(null, null); mRS.programVertexSetTextureMatrixEnable(true); mPvBackground = mRS.programVertexCreate(); mPvBackground.bindAllocation(0, mPvOrthoAlloc.mAlloc); mPvBackground.setName("PVBackground"); } }
libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ class GrassView extends RSSurfaceView { super.surfaceChanged(holder, format, w, h); RenderScript RS = createRenderScript(); GrassRS render = new GrassRS(); GrassRS render = new GrassRS(w, h); render.init(RS, getResources()); } }