diff --git a/samples/CubeLiveWallpaper/Android.mk b/samples/CubeLiveWallpaper/Android.mk new file mode 100644 index 000000000..7227394d3 --- /dev/null +++ b/samples/CubeLiveWallpaper/Android.mk @@ -0,0 +1,27 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# LOCAL_MODULE_TAGS := user + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := CubeLiveWallpapers +LOCAL_CERTIFICATE := shared + +include $(BUILD_PACKAGE) diff --git a/samples/CubeLiveWallpaper/AndroidManifest.xml b/samples/CubeLiveWallpaper/AndroidManifest.xml new file mode 100644 index 000000000..8d24c4a60 --- /dev/null +++ b/samples/CubeLiveWallpaper/AndroidManifest.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/CubeLiveWallpaper/MODULE_LICENSE_APACHE2 b/samples/CubeLiveWallpaper/MODULE_LICENSE_APACHE2 new file mode 100644 index 000000000..e69de29bb diff --git a/samples/CubeLiveWallpaper/NOTICE b/samples/CubeLiveWallpaper/NOTICE new file mode 100644 index 000000000..c5b1efa7a --- /dev/null +++ b/samples/CubeLiveWallpaper/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/samples/CubeLiveWallpaper/res/drawable/ic_launcher_wallpaper.png b/samples/CubeLiveWallpaper/res/drawable/ic_launcher_wallpaper.png new file mode 100644 index 000000000..965fb7143 Binary files /dev/null and b/samples/CubeLiveWallpaper/res/drawable/ic_launcher_wallpaper.png differ diff --git a/samples/CubeLiveWallpaper/res/raw/cube.rs b/samples/CubeLiveWallpaper/res/raw/cube.rs new file mode 100644 index 000000000..407d63bb4 --- /dev/null +++ b/samples/CubeLiveWallpaper/res/raw/cube.rs @@ -0,0 +1,50 @@ +// 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(PVBackground) + +#define RSID_POINTS 0 + +void dumpState() { + +// debugF("@@@@@ yrot: ", State->yRotation); + +} + +int main(int launchID) { + + int i; + + // Change the model matrix to account for the large model + // and to do the necessary rotations. + float mat1[16]; + float rads = ((float)startTimeMillis()) / 1000; + float xrot = degf(-rads); + float yrot = State->yRotation; + float scale = 1.0/900.0; + matrixLoadScale(mat1, scale, scale, scale); + matrixRotate(mat1, yrot, 0.f, 1.f, 0.f); + matrixRotate(mat1, xrot, 1.f, 0.f, 0.f); + vpLoadModelMatrix(mat1); + + // Draw the cube. The default color will be used, + // but we can also set the color here with the color() + // function, or specify the color(s) as part of + // the vertex data. + uploadToBufferObject(NAMED_PointBuffer); + drawSimpleMesh(NAMED_CubeMesh); + + return 1; +} diff --git a/samples/CubeLiveWallpaper/res/values/shapes.xml b/samples/CubeLiveWallpaper/res/values/shapes.xml new file mode 100644 index 000000000..49bdaf9e8 --- /dev/null +++ b/samples/CubeLiveWallpaper/res/values/shapes.xml @@ -0,0 +1,121 @@ + + + + + + + "Cube" + "Dodecahedron" + + + + "cube" + "dodecahedron" + + + + + + "-400 -400 -400" + "400 -400 -400" + "400 400 -400" + "-400 400 -400" + "-400 -400 400" + "400 -400 400" + "400 400 400" + "-400 400 400" + + + + + + "0 1" + "1 2" + "2 3" + "3 0" + + + "4 5" + "5 6" + "6 7" + "7 4" + + + "0 4" + "1 5" + "2 6" + "3 7" + + + + "333.850000 0.000000 437.250000" + "103.400000 317.350000 437.250000" + "-270.050000 196.350000 437.250000" + "-270.050000 -196.350000 437.250000" + "103.400000 -317.350000 437.250000" + "540.100000 0.000000 103.400000" + "167.200000 513.700000 103.400000" + "-437.250000 317.350000 103.400000" + "-437.250000 -317.350000 103.400000" + "167.200000 -513.700000 103.400000" + "437.250000 317.350000 -103.400000" + "-167.200000 513.700000 -103.400000" + "-540.100000 0.000000 -103.400000" + "-167.200000 -513.700000 -103.400000" + "437.250000 -317.350000 -103.400000" + "270.050000 196.350000 -437.250000" + "-103.400000 317.350000 -437.250000" + "-333.850000 0.000000 -437.250000" + "-103.400000 -317.350000 -437.250000" + "270.050000 -196.350000 -437.250000" + + + + "0 1" + "0 4" + "0 5" + "1 2" + "1 6" + "2 3" + "2 7" + "3 4" + "3 8" + "4 9" + "5 10" + "5 14" + "6 10" + "6 11" + "7 11" + "7 12" + "8 12" + "8 13" + "9 13" + "9 14" + "10 15" + "11 16" + "12 17" + "13 18" + "14 19" + "15 16" + "15 19" + "16 17" + "17 18" + "18 19" + + diff --git a/samples/CubeLiveWallpaper/res/values/strings.xml b/samples/CubeLiveWallpaper/res/values/strings.xml new file mode 100644 index 000000000..3302058b5 --- /dev/null +++ b/samples/CubeLiveWallpaper/res/values/strings.xml @@ -0,0 +1,38 @@ + + + + + + + + Example Wallpapers + + + Cube + + + Cube - resource + + + Cube - RenderScript + + Settings + Select shape + Choose whether to display a cube or a dodecahedron + diff --git a/samples/CubeLiveWallpaper/res/xml/cube1.xml b/samples/CubeLiveWallpaper/res/xml/cube1.xml new file mode 100644 index 000000000..5c7fca50d --- /dev/null +++ b/samples/CubeLiveWallpaper/res/xml/cube1.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/samples/CubeLiveWallpaper/res/xml/cube2.xml b/samples/CubeLiveWallpaper/res/xml/cube2.xml new file mode 100644 index 000000000..bf9054c4c --- /dev/null +++ b/samples/CubeLiveWallpaper/res/xml/cube2.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/samples/CubeLiveWallpaper/res/xml/cube2_settings.xml b/samples/CubeLiveWallpaper/res/xml/cube2_settings.xml new file mode 100644 index 000000000..50a28aea0 --- /dev/null +++ b/samples/CubeLiveWallpaper/res/xml/cube2_settings.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/samples/CubeLiveWallpaper/res/xml/cube3.xml b/samples/CubeLiveWallpaper/res/xml/cube3.xml new file mode 100644 index 000000000..5c7fca50d --- /dev/null +++ b/samples/CubeLiveWallpaper/res/xml/cube3.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube1/CubeWallpaper1.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube1/CubeWallpaper1.java new file mode 100644 index 000000000..9279065c2 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube1/CubeWallpaper1.java @@ -0,0 +1,240 @@ +/* + * 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 com.android.livecubes.cube1; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.os.Handler; +import android.os.SystemClock; +import android.service.wallpaper.WallpaperService; +import android.util.Log; +import android.view.MotionEvent; +import android.view.SurfaceHolder; + +/* + * This animated wallpaper draws a rotating wireframe cube. + */ +public class CubeWallpaper1 extends WallpaperService { + + private final Handler mHandler = new Handler(); + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public Engine onCreateEngine() { + return new CubeEngine(); + } + + class CubeEngine extends Engine { + + private final Paint mPaint = new Paint(); + private float mOffset; + private float mTouchX = -1; + private float mTouchY = -1; + private long mStartTime; + private float mCenterX; + private float mCenterY; + + private final Runnable mDrawCube = new Runnable() { + public void run() { + drawFrame(); + } + }; + private boolean mVisible; + + CubeEngine() { + // Create a Paint to draw the lines for our cube + final Paint paint = mPaint; + paint.setColor(0xffffffff); + paint.setAntiAlias(true); + paint.setStrokeWidth(2); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStyle(Paint.Style.STROKE); + + mStartTime = SystemClock.elapsedRealtime(); + } + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + + // By default we don't get touch events, so enable them. + setTouchEventsEnabled(true); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mHandler.removeCallbacks(mDrawCube); + } + + @Override + public void onVisibilityChanged(boolean visible) { + mVisible = visible; + if (visible) { + drawFrame(); + } else { + mHandler.removeCallbacks(mDrawCube); + } + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + super.onSurfaceChanged(holder, format, width, height); + // store the center of the surface, so we can draw the cube in the right spot + mCenterX = width/2.0f; + mCenterY = height/2.0f; + drawFrame(); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mVisible = false; + mHandler.removeCallbacks(mDrawCube); + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, int xPixels, int yPixels) { + mOffset = xOffset; + drawFrame(); + } + + /* + * Store the position of the touch event so we can use it for drawing later + */ + @Override + public void onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_MOVE) { + mTouchX = event.getX(); + mTouchY = event.getY(); + } else { + mTouchX = -1; + mTouchY = -1; + } + super.onTouchEvent(event); + } + + /* + * Draw one frame of the animation. This method gets called repeatedly + * by posting a delayed Runnable. You can do any drawing you want in + * here. This example draws a wireframe cube. + */ + void drawFrame() { + final SurfaceHolder holder = getSurfaceHolder(); + + Canvas c = null; + try { + c = holder.lockCanvas(); + if (c != null) { + // draw something + drawCube(c); + drawTouchPoint(c); + } + } finally { + if (c != null) holder.unlockCanvasAndPost(c); + } + + // Reschedule the next redraw + mHandler.removeCallbacks(mDrawCube); + if (mVisible) { + mHandler.postDelayed(mDrawCube, 1000 / 25); + } + } + + /* + * Draw a wireframe cube by drawing 12 3 dimensional lines between + * adjacent corners of the cube + */ + void drawCube(Canvas c) { + c.save(); + c.translate(mCenterX, mCenterY); + c.drawColor(0xff000000); + drawLine(c, -400, -400, -400, 400, -400, -400); + drawLine(c, 400, -400, -400, 400, 400, -400); + drawLine(c, 400, 400, -400, -400, 400, -400); + drawLine(c, -400, 400, -400, -400, -400, -400); + + drawLine(c, -400, -400, 400, 400, -400, 400); + drawLine(c, 400, -400, 400, 400, 400, 400); + drawLine(c, 400, 400, 400, -400, 400, 400); + drawLine(c, -400, 400, 400, -400, -400, 400); + + drawLine(c, -400, -400, 400, -400, -400, -400); + drawLine(c, 400, -400, 400, 400, -400, -400); + drawLine(c, 400, 400, 400, 400, 400, -400); + drawLine(c, -400, 400, 400, -400, 400, -400); + c.restore(); + } + + /* + * Draw a 3 dimensional line on to the screen + */ + void drawLine(Canvas c, int x1, int y1, int z1, int x2, int y2, int z2) { + long now = SystemClock.elapsedRealtime(); + float xrot = ((float)(now - mStartTime)) / 1000; + float yrot = (0.5f - mOffset) * 2.0f; + float zrot = 0; + + // 3D transformations + + // rotation around X-axis + float newy1 = (float)(Math.sin(xrot) * z1 + Math.cos(xrot) * y1); + float newy2 = (float)(Math.sin(xrot) * z2 + Math.cos(xrot) * y2); + float newz1 = (float)(Math.cos(xrot) * z1 - Math.sin(xrot) * y1); + float newz2 = (float)(Math.cos(xrot) * z2 - Math.sin(xrot) * y2); + + // rotation around Y-axis + float newx1 = (float)(Math.sin(yrot) * newz1 + Math.cos(yrot) * x1); + float newx2 = (float)(Math.sin(yrot) * newz2 + Math.cos(yrot) * x2); + newz1 = (float)(Math.cos(yrot) * newz1 - Math.sin(yrot) * x1); + newz2 = (float)(Math.cos(yrot) * newz2 - Math.sin(yrot) * x2); + + // 3D-to-2D projection + float startX = newx1 / (4 - newz1 / 400); + float startY = newy1 / (4 - newz1 / 400); + float stopX = newx2 / (4 - newz2 / 400); + float stopY = newy2 / (4 - newz2 / 400); + + c.drawLine(startX, startY, stopX, stopY, mPaint); + } + + /* + * Draw a circle around the current touch point, if any. + */ + void drawTouchPoint(Canvas c) { + if (mTouchX >=0 && mTouchY >= 0) { + c.drawCircle(mTouchX, mTouchY, 80, mPaint); + } + } + + } +} diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2.java new file mode 100644 index 000000000..43f132613 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2.java @@ -0,0 +1,296 @@ +/* + * 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 com.android.livecubes.cube2; + +import com.android.livecubes.R; + +import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.os.Handler; +import android.os.SystemClock; +import android.service.wallpaper.WallpaperService; +import android.util.Log; +import android.view.MotionEvent; +import android.view.SurfaceHolder; + +/* + * This animated wallpaper draws a rotating wireframe shape. It is similar to + * example #1, but has a choice of 2 shapes, which are user selectable and + * defined in resources instead of in code. + */ + +public class CubeWallpaper2 extends WallpaperService { + + public static final String SHARED_PREFS_NAME="cube2settings"; + + static class ThreeDPoint { + float x; + float y; + float z; + } + + static class ThreeDLine { + int startPoint; + int endPoint; + } + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public Engine onCreateEngine() { + return new CubeEngine(); + } + + class CubeEngine extends Engine + implements SharedPreferences.OnSharedPreferenceChangeListener { + + private final Handler mHandler = new Handler(); + + ThreeDPoint [] mOriginalPoints; + ThreeDPoint [] mRotatedPoints; + ThreeDLine [] mLines; + private final Paint mPaint = new Paint(); + private float mOffset; + private float mTouchX = -1; + private float mTouchY = -1; + private long mStartTime; + private float mCenterX; + private float mCenterY; + + private final Runnable mDrawCube = new Runnable() { + public void run() { + drawFrame(); + } + }; + private boolean mVisible; + private SharedPreferences mPrefs; + + CubeEngine() { + // Create a Paint to draw the lines for our cube + final Paint paint = mPaint; + paint.setColor(0xffffffff); + paint.setAntiAlias(true); + paint.setStrokeWidth(2); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStyle(Paint.Style.STROKE); + + mStartTime = SystemClock.elapsedRealtime(); + + mPrefs = CubeWallpaper2.this.getSharedPreferences(SHARED_PREFS_NAME, 0); + mPrefs.registerOnSharedPreferenceChangeListener(this); + onSharedPreferenceChanged(mPrefs, null); + } + + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + + String shape = prefs.getString("cube2_shape", "cube"); + + // read the 3D model from the resource + readModel(shape); + } + + private void readModel(String prefix) { + // Read the model definition in from a resource. + + // get the resource identifiers for the arrays for the selected shape + int pid = getResources().getIdentifier(prefix + "points", "array", getPackageName()); + int lid = getResources().getIdentifier(prefix + "lines", "array", getPackageName()); + + String [] p = getResources().getStringArray(pid); + int numpoints = p.length; + mOriginalPoints = new ThreeDPoint[numpoints]; + mRotatedPoints = new ThreeDPoint[numpoints]; + + for (int i = 0; i < numpoints; i++) { + mOriginalPoints[i] = new ThreeDPoint(); + mRotatedPoints[i] = new ThreeDPoint(); + String [] coord = p[i].split(" "); + mOriginalPoints[i].x = Float.valueOf(coord[0]); + mOriginalPoints[i].y = Float.valueOf(coord[1]); + mOriginalPoints[i].z = Float.valueOf(coord[2]); + } + + String [] l = getResources().getStringArray(lid); + int numlines = l.length; + mLines = new ThreeDLine[numlines]; + + for (int i = 0; i < numlines; i++) { + mLines[i] = new ThreeDLine(); + String [] idx = l[i].split(" "); + mLines[i].startPoint = Integer.valueOf(idx[0]); + mLines[i].endPoint = Integer.valueOf(idx[1]); + } + } + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + setTouchEventsEnabled(true); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mHandler.removeCallbacks(mDrawCube); + } + + @Override + public void onVisibilityChanged(boolean visible) { + mVisible = visible; + if (visible) { + drawFrame(); + } else { + mHandler.removeCallbacks(mDrawCube); + } + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + super.onSurfaceChanged(holder, format, width, height); + // store the center of the surface, so we can draw the cube in the right spot + mCenterX = width/2.0f; + mCenterY = height/2.0f; + drawFrame(); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mVisible = false; + mHandler.removeCallbacks(mDrawCube); + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, int xPixels, int yPixels) { + mOffset = xOffset; + drawFrame(); + } + + /* + * Store the position of the touch event so we can use it for drawing later + */ + @Override + public void onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_MOVE) { + mTouchX = event.getX(); + mTouchY = event.getY(); + } else { + mTouchX = -1; + mTouchY = -1; + } + super.onTouchEvent(event); + } + + /* + * Draw one frame of the animation. This method gets called repeatedly + * by posting a delayed Runnable. You can do any drawing you want in + * here. This example draws a wireframe cube. + */ + void drawFrame() { + final SurfaceHolder holder = getSurfaceHolder(); + final Rect frame = holder.getSurfaceFrame(); + final int width = frame.width(); + final int height = frame.height(); + + Canvas c = null; + try { + c = holder.lockCanvas(); + if (c != null) { + // draw something + drawCube(c); + drawTouchPoint(c); + } + } finally { + if (c != null) holder.unlockCanvasAndPost(c); + } + + mHandler.removeCallbacks(mDrawCube); + if (mVisible) { + mHandler.postDelayed(mDrawCube, 1000 / 25); + } + } + + void drawCube(Canvas c) { + c.save(); + c.translate(mCenterX, mCenterY); + c.drawColor(0xff000000); + + long now = SystemClock.elapsedRealtime(); + float xrot = ((float)(now - mStartTime)) / 1000; + float yrot = (0.5f - mOffset) * 2.0f; + rotateAndProjectPoints(xrot, yrot); + drawLines(c); + c.restore(); + } + + void rotateAndProjectPoints(float xrot, float yrot) { + int n = mOriginalPoints.length; + for (int i = 0; i < n; i++) { + // rotation around X-axis + ThreeDPoint p = mOriginalPoints[i]; + float x = p.x; + float y = p.y; + float z = p.z; + float newy = (float)(Math.sin(xrot) * z + Math.cos(xrot) * y); + float newz = (float)(Math.cos(xrot) * z - Math.sin(xrot) * y); + + // rotation around Y-axis + float newx = (float)(Math.sin(yrot) * newz + Math.cos(yrot) * x); + newz = (float)(Math.cos(yrot) * newz - Math.sin(yrot) * x); + + // 3D-to-2D projection + float screenX = newx / (4 - newz / 400); + float screenY = newy / (4 - newz / 400); + + mRotatedPoints[i].x = screenX; + mRotatedPoints[i].y = screenY; + mRotatedPoints[i].z = 0; + } + } + + void drawLines(Canvas c) { + int n = mLines.length; + for (int i = 0; i < n; i++) { + ThreeDLine l = mLines[i]; + ThreeDPoint start = mRotatedPoints[l.startPoint]; + ThreeDPoint end = mRotatedPoints[l.endPoint]; + c.drawLine(start.x, start.y, end.x, end.y, mPaint); + } + } + + void drawTouchPoint(Canvas c) { + if (mTouchX >=0 && mTouchY >= 0) { + c.drawCircle(mTouchX, mTouchY, 80, mPaint); + } + } + } +} diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2Settings.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2Settings.java new file mode 100644 index 000000000..feeb0bdc2 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube2/CubeWallpaper2Settings.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * 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.livecubes.cube2; + +import com.android.livecubes.R; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.service.wallpaper.WallpaperSettingsActivity; + +public class CubeWallpaper2Settings extends WallpaperSettingsActivity + implements SharedPreferences.OnSharedPreferenceChangeListener { + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + getPreferenceManager().setSharedPreferencesName( + CubeWallpaper2.SHARED_PREFS_NAME); + addPreferencesFromResource(R.xml.cube2_settings); + getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener( + this); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onDestroy() { + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener( + this); + super.onDestroy(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + //(new BackupManager(this)).dataChanged(); + } +} diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/Cube3RS.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/Cube3RS.java new file mode 100644 index 000000000..5cfad140f --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/Cube3RS.java @@ -0,0 +1,242 @@ +/* + * 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 com.android.livecubes.cube3; + +import com.android.livecubes.R; +import com.android.livecubes.RenderScriptScene; + +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Primitive; +import android.renderscript.ProgramRaster; +import android.renderscript.ProgramVertex; +import android.renderscript.ScriptC; +import android.renderscript.SimpleMesh; +import android.renderscript.Type; +import android.renderscript.Element.Builder; + +import java.util.TimeZone; + +/* + * This example draws a shape whose definition is read from resources (though + * it's not user selectable like in example #2), but does the drawing using + * RenderScript. + */ +class Cube3RS extends RenderScriptScene { + + static class ThreeDPoint { + public float x; + public float y; + public float z; + } + + static class ThreeDLine { + int startPoint; + int endPoint; + } + + static class WorldState { + public float yRotation; + public float mCenterX; + public float mCenterY; + } + ThreeDPoint [] mOriginalPoints; + ThreeDLine [] mLines; + + WorldState mWorldState = new WorldState(); + private Type mStateType; + private Allocation mState; + + private SimpleMesh mCubeMesh; + + private Allocation mPointAlloc; + private float [] mPointData; + + private Allocation mLineIdxAlloc; + private short [] mIndexData; + + private ProgramVertex mPVBackground; + private ProgramVertex.MatrixAllocation mPVAlloc; + + private int mWidth; + private int mHeight; + + private static final int RSID_STATE = 0; + private static final int RSID_POINTS = 1; + private static final int RSID_LINES = 2; + private static final int RSID_PROGRAMVERTEX = 3; + + + Cube3RS(int width, int height) { + super(width, height); + mWidth = width; + mHeight = height; + } + + @Override + public void resize(int width, int height) { + super.resize(width, height); + mWidth = width; + mHeight = height; + } + + @Override + protected ScriptC createScript() { + + // Read the model in to our point/line objects + readModel(); + + // Create a renderscript type from a java class. The specified name doesn't + // really matter; the name by which we refer to the object in RenderScript + // will be specified later. + mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState"); + // Create an allocation from the type we just created. + mState = Allocation.createTyped(mRS, mStateType); + // set our java object as the data for the renderscript allocation + mWorldState.yRotation = (-0.5f) * 2 * 180 / (float) Math.PI; + mState.data(mWorldState); + + /* + * Now put our model in to a form that renderscript can work with: + * - create a buffer of floats that are the coordinates for the points that define the cube + * - create a buffer of integers that are the indices of the points that form lines + * - combine the two in to a mesh + */ + + // First set up the coordinate system and such + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); + mPVBackground = pvb.create(); + mPVBackground.setName("PVBackground"); + mPVAlloc = new ProgramVertex.MatrixAllocation(mRS); + mPVBackground.bindAllocation(mPVAlloc); + mPVAlloc.setupProjectionNormalized(mWidth, mHeight); + + // Start creating the mesh + final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS); + + // Create the Element for the points + Builder elementBuilder = new Builder(mRS); + // By specifying a prefix, even an empty one, the members will be accessible + // in the renderscript. If we just called addFloatXYZ(), the members would be + // unnamed in the renderscript struct definition. + elementBuilder.addFloatXYZ(""); + final Element vertexElement = elementBuilder.create(); + final int vertexSlot = meshBuilder.addVertexType(vertexElement, mOriginalPoints.length); + // Specify the type and number of indices we need. We'll allocate them later. + meshBuilder.setIndexType(Element.INDEX_16(mRS), mLines.length * 2); + // This will be a line mesh + meshBuilder.setPrimitive(Primitive.LINE); + + // Create the Allocation for the vertices + mCubeMesh = meshBuilder.create(); + mCubeMesh.setName("CubeMesh"); + mPointAlloc = mCubeMesh.createVertexAllocation(vertexSlot); + mPointAlloc.setName("PointBuffer"); + + // Create the Allocation for the indices + mLineIdxAlloc = mCubeMesh.createIndexAllocation(); + + // Bind the allocations to the mesh + mCubeMesh.bindVertexAllocation(mPointAlloc, 0); + mCubeMesh.bindIndexAllocation(mLineIdxAlloc); + + /* + * put the vertex and index data in their respective buffers + */ + // one float each for x, y and z, and the 4th float will hold rgba + mPointData = new float[mOriginalPoints.length * 3]; + for(int i = 0; i < mOriginalPoints.length; i ++) { + mPointData[i*3] = mOriginalPoints[i].x; + mPointData[i*3+1] = mOriginalPoints[i].y; + mPointData[i*3+2] = mOriginalPoints[i].z; + } + mIndexData = new short[mLines.length * 2]; + for(int i = 0; i < mLines.length; i++) { + mIndexData[i * 2] = (short)(mLines[i].startPoint); + mIndexData[i * 2 + 1] = (short)(mLines[i].endPoint); + } + + /* + * upload the vertex and index data + */ + mPointAlloc.data(mPointData); + mPointAlloc.uploadToBufferObject(); + mLineIdxAlloc.data(mIndexData); + mLineIdxAlloc.uploadToBufferObject(); + + // Time to create the script + ScriptC.Builder sb = new ScriptC.Builder(mRS); + // Specify the name by which to refer to the WorldState object in the + // renderscript. + sb.setType(mStateType, "State", RSID_STATE); + sb.setType(mCubeMesh.getVertexType(0), "Points", RSID_POINTS); + // this crashes when uncommented + //sb.setType(mCubeMesh.getIndexType(), "Lines", RSID_LINES); + + // Set the render script that will make use of the objects we defined above + sb.setScript(mResources, R.raw.cube); + sb.setRoot(true); + + ScriptC script = sb.create(); + script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); + script.setTimeZone(TimeZone.getDefault().getID()); + + script.bindAllocation(mState, RSID_STATE); + script.bindAllocation(mPointAlloc, RSID_POINTS); + script.bindAllocation(mLineIdxAlloc, RSID_LINES); + script.bindAllocation(mPVAlloc.mAlloc, RSID_PROGRAMVERTEX); + + return script; + } + + @Override + public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) { + // update our state, then push it to the renderscript + mWorldState.yRotation = (xOffset - 0.5f) * 2 * 180 / (float) Math.PI; + mState.data(mWorldState); + } + + /* + * Read the model definition from the resource. + */ + private void readModel() { + + String [] p = mResources.getStringArray(R.array.cubepoints); + int numpoints = p.length; + mOriginalPoints = new ThreeDPoint[numpoints]; + + for (int i = 0; i < numpoints; i++) { + mOriginalPoints[i] = new ThreeDPoint(); + String [] coord = p[i].split(" "); + mOriginalPoints[i].x = Float.valueOf(coord[0]); + mOriginalPoints[i].y = Float.valueOf(coord[1]); + mOriginalPoints[i].z = Float.valueOf(coord[2]); + } + + String [] l = mResources.getStringArray(R.array.cubelines); + int numlines = l.length; + mLines = new ThreeDLine[numlines]; + + for (int i = 0; i < numlines; i++) { + mLines[i] = new ThreeDLine(); + String [] idx = l[i].split(" "); + mLines[i].startPoint = Integer.valueOf(idx[0]); + mLines[i].endPoint = Integer.valueOf(idx[1]); + } + } + +} diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/CubeWallpaper3.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/CubeWallpaper3.java new file mode 100644 index 000000000..8f09388b3 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/CubeWallpaper3.java @@ -0,0 +1,28 @@ +/* + * 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 com.android.livecubes.cube3; + +import com.android.livecubes.RenderScriptWallpaper; + +public class CubeWallpaper3 extends RenderScriptWallpaper { + + @Override + protected Cube3RS createScene(int width, int height) { + return new Cube3RS(width, height); + } +} + diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptScene.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptScene.java new file mode 100644 index 000000000..429e93d01 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptScene.java @@ -0,0 +1,86 @@ +/* + * 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 com.android.livecubes; + +import android.content.res.Resources; +import android.renderscript.RenderScript; +import android.renderscript.ScriptC; + +public abstract class RenderScriptScene { + protected int mWidth; + protected int mHeight; + protected boolean mPreview; + protected Resources mResources; + protected RenderScript mRS; + protected ScriptC mScript; + + public RenderScriptScene(int width, int height) { + mWidth = width; + mHeight = height; + } + + public void init(RenderScript rs, Resources res, boolean isPreview) { + mRS = rs; + mResources = res; + mPreview = isPreview; + mScript = createScript(); + } + + public boolean isPreview() { + return mPreview; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public Resources getResources() { + return mResources; + } + + public RenderScript getRS() { + return mRS; + } + + public ScriptC getScript() { + return mScript; + } + + protected abstract ScriptC createScript(); + + public void stop() { + mRS.contextBindRootScript(null); + } + + public void start() { + mRS.contextBindRootScript(mScript); + } + + public void resize(int width, int height) { + mWidth = width; + mHeight = height; + } + + @SuppressWarnings({"UnusedDeclaration"}) + public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) { + } +} diff --git a/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptWallpaper.java b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptWallpaper.java new file mode 100644 index 000000000..c30a61973 --- /dev/null +++ b/samples/CubeLiveWallpaper/src/com/android/livecubes/cube3/RenderScriptWallpaper.java @@ -0,0 +1,106 @@ +/* + * 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 com.android.livecubes; + +import android.service.wallpaper.WallpaperService; +import android.renderscript.RenderScript; +import android.view.SurfaceHolder; +import android.view.Surface; + +public abstract class RenderScriptWallpaper extends WallpaperService { + public Engine onCreateEngine() { + return new RenderScriptEngine(); + } + + protected abstract T createScene(int width, int height); + + private class RenderScriptEngine extends Engine { + private RenderScript mRs; + private T mRenderer; + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + setTouchEventsEnabled(false); + surfaceHolder.setSizeFromLayout(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + destroyRenderer(); + } + + private void destroyRenderer() { + if (mRenderer != null) { + mRenderer.stop(); + mRenderer = null; + } + if (mRs != null) { + mRs.destroy(); + mRs = null; + } + } + + @Override + public void onVisibilityChanged(boolean visible) { + super.onVisibilityChanged(visible); + if (mRenderer != null) { + if (visible) { + mRenderer.start(); + } else { + mRenderer.stop(); + } + } + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + super.onSurfaceChanged(holder, format, width, height); + if (mRenderer == null) { + mRenderer = createScene(width, height); + mRenderer.init(mRs, getResources(), isPreview()); + mRenderer.start(); + } else { + mRenderer.resize(width, height); + } + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, int xPixels, int yPixels) { + mRenderer.setOffset(xOffset, yOffset, xPixels, yPixels); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + + Surface surface = null; + while (surface == null) { + surface = holder.getSurface(); + } + mRs = new RenderScript(surface, false, false); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + destroyRenderer(); + } + } +}