OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / packages / wallpapers / Basic / src / com / android / wallpaper / galaxy / GalaxyRS.java
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.wallpaper.galaxy;
18
19 import android.renderscript.ScriptC;
20 import android.renderscript.ProgramFragment;
21 import android.renderscript.ProgramStore;
22 import android.renderscript.ProgramVertex;
23 import android.renderscript.ProgramRaster;
24 import android.renderscript.Allocation;
25 import android.renderscript.Sampler;
26 import android.renderscript.Element;
27 import android.renderscript.SimpleMesh;
28 import android.renderscript.Primitive;
29 import android.renderscript.Type;
30 import static android.renderscript.Sampler.Value.LINEAR;
31 import static android.renderscript.Sampler.Value.NEAREST;
32 import static android.renderscript.Sampler.Value.WRAP;
33 import static android.renderscript.ProgramStore.DepthFunc.*;
34 import static android.renderscript.ProgramStore.BlendDstFunc;
35 import static android.renderscript.ProgramStore.BlendSrcFunc;
36 import static android.renderscript.Element.*;
37 import android.graphics.Bitmap;
38 import android.graphics.BitmapFactory;
39
40 import java.util.TimeZone;
41
42 import com.android.wallpaper.R;
43 import com.android.wallpaper.RenderScriptScene;
44
45 class GalaxyRS extends RenderScriptScene {
46     private static final int GALAXY_RADIUS = 300;
47     private static final int PARTICLES_COUNT = 12000;
48
49     private static final int RSID_STATE = 0;
50     private static final int RSID_PARTICLES_BUFFER = 1;
51
52     private static final int TEXTURES_COUNT = 3;
53     private static final int RSID_TEXTURE_SPACE = 0;
54     private static final int RSID_TEXTURE_LIGHT1 = 1;
55     private static final int RSID_TEXTURE_FLARES = 2;
56
57     private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
58
59     @SuppressWarnings({"FieldCanBeLocal"})
60     private ProgramFragment mPfBackground;
61     @SuppressWarnings({"FieldCanBeLocal"})
62     private ProgramFragment mPfStars;
63     @SuppressWarnings({"FieldCanBeLocal"})
64     private ProgramStore mPfsBackground;
65     @SuppressWarnings({"FieldCanBeLocal"})
66     private ProgramStore mPfsLights;
67     @SuppressWarnings({"FieldCanBeLocal"})
68     private ProgramVertex mPvBkOrtho;
69     @SuppressWarnings({"FieldCanBeLocal"})
70     private ProgramVertex mPvBkProj;
71     @SuppressWarnings({"FieldCanBeLocal"})
72     private ProgramVertex mPvStars;
73     @SuppressWarnings({"FieldCanBeLocal"})
74     private Sampler mSampler;
75     @SuppressWarnings({"FieldCanBeLocal"})
76     private Sampler mStarSampler;
77     @SuppressWarnings({"FieldCanBeLocal"})
78     private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
79     @SuppressWarnings({"FieldCanBeLocal"})
80     private ProgramVertex.MatrixAllocation mPvProjectionAlloc;
81     @SuppressWarnings({"FieldCanBeLocal"})
82     private Allocation[] mTextures;
83
84     private GalaxyState mGalaxyState;
85     private Type mStateType;
86     private Allocation mState;
87     private Allocation mParticlesBuffer;
88     @SuppressWarnings({"FieldCanBeLocal"})
89     private SimpleMesh mParticlesMesh;
90     private ScriptC.Invokable mInitParticles;
91
92     GalaxyRS(int width, int height) {
93         super(width, height);
94
95         mOptionsARGB.inScaled = false;
96         mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
97     }
98
99     @Override
100     protected ScriptC createScript() {
101         createScriptStructures();
102         createProgramVertex();
103         createProgramRaster();
104         createProgramFragmentStore();
105         createProgramFragment();
106         loadTextures();
107
108         ScriptC.Builder sb = new ScriptC.Builder(mRS);
109         sb.setType(mStateType, "State", RSID_STATE);
110         sb.setType(mParticlesMesh.getVertexType(0), "Particles", RSID_PARTICLES_BUFFER);
111         mInitParticles = sb.addInvokable("initParticles");
112         sb.setScript(mResources, R.raw.galaxy);
113         sb.setRoot(true);
114
115         ScriptC script = sb.create();
116         script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
117         script.setTimeZone(TimeZone.getDefault().getID());
118
119         script.bindAllocation(mState, RSID_STATE);
120         script.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER);
121         mInitParticles.execute();
122
123         return script;
124     }
125
126     private void createScriptStructures() {
127         createState();
128         createParticlesMesh();
129     }
130
131     private void createParticlesMesh() {
132         final Builder elementBuilder = new Builder(mRS);
133         elementBuilder.add(Element.createAttrib(mRS, Element.DataType.UNSIGNED_8,
134                 Element.DataKind.USER, 4), "color");
135         elementBuilder.add(Element.createAttrib(mRS, Element.DataType.FLOAT_32,
136                 Element.DataKind.USER, 3), "position");
137         final Element vertexElement = elementBuilder.create();
138
139         final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
140         final int vertexSlot = meshBuilder.addVertexType(vertexElement, PARTICLES_COUNT);
141         meshBuilder.setPrimitive(Primitive.POINT);
142         mParticlesMesh = meshBuilder.create();
143         mParticlesMesh.setName("ParticlesMesh");
144
145         mParticlesBuffer = mParticlesMesh.createVertexAllocation(vertexSlot);
146         mParticlesBuffer.setName("ParticlesBuffer");
147         mParticlesMesh.bindVertexAllocation(mParticlesBuffer, 0);
148     }
149
150     @Override
151     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
152         mGalaxyState.xOffset = xOffset;
153         mState.data(mGalaxyState);
154     }
155
156     @Override
157     public void resize(int width, int height) {
158         super.resize(width, height);
159
160         mGalaxyState.width = width;
161         mGalaxyState.height = height;
162         mGalaxyState.scale = width > height ? 1 : 0;
163         mState.data(mGalaxyState);
164
165         mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
166         mPvProjectionAlloc.setupProjectionNormalized(mWidth, mHeight);
167
168         mInitParticles.execute();
169     }
170
171     static class GalaxyState {
172         public int width;
173         public int height;
174         public int particlesCount;
175         public int galaxyRadius;
176         public float xOffset;
177         public int isPreview;
178         public int scale;
179     }
180
181     private void createState() {
182         boolean isPreview = isPreview();
183
184         mGalaxyState = new GalaxyState();
185         mGalaxyState.width = mWidth;
186         mGalaxyState.height = mHeight;
187         mGalaxyState.scale = mWidth > mHeight ? 1 : 0;
188         mGalaxyState.particlesCount = PARTICLES_COUNT;
189         mGalaxyState.galaxyRadius = GALAXY_RADIUS;
190         mGalaxyState.isPreview = isPreview ? 1 : 0;
191         if (isPreview) {
192             mGalaxyState.xOffset = 0.5f;
193         }
194
195         mStateType = Type.createFromClass(mRS, GalaxyState.class, 1, "GalaxyState");
196         mState = Allocation.createTyped(mRS, mStateType);
197         mState.data(mGalaxyState);
198     }
199
200     private void loadTextures() {
201         mTextures = new Allocation[TEXTURES_COUNT];
202
203         final Allocation[] textures = mTextures;
204         textures[RSID_TEXTURE_SPACE] = loadTexture(R.drawable.space, "TSpace");
205         textures[RSID_TEXTURE_LIGHT1] = loadTexture(R.drawable.light1, "TLight1");
206         textures[RSID_TEXTURE_FLARES] = loadTextureARGB(R.drawable.flares, "TFlares");
207
208         final int count = textures.length;
209         for (int i = 0; i < count; i++) {
210             textures[i].uploadToTexture(0);
211         }
212     }
213
214     private Allocation loadTexture(int id, String name) {
215         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
216                 id, RGB_565(mRS), false);
217         allocation.setName(name);
218         return allocation;
219     }
220
221     // TODO: Fix Allocation.createFromBitmapResource() to do this when RGBA_8888 is specified
222     private Allocation loadTextureARGB(int id, String name) {
223         Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
224         final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888(mRS), false);
225         allocation.setName(name);
226         return allocation;
227     }
228
229     private void createProgramFragment() {
230         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
231         samplerBuilder.setMin(NEAREST);
232         samplerBuilder.setMag(NEAREST);
233         samplerBuilder.setWrapS(WRAP);
234         samplerBuilder.setWrapT(WRAP);
235         mSampler = samplerBuilder.create();
236
237         ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
238         builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
239                            ProgramFragment.Builder.Format.RGB, 0);
240         mPfBackground = builder.create();
241         mPfBackground.setName("PFBackground");
242         mPfBackground.bindSampler(mSampler, 0);
243
244         samplerBuilder = new Sampler.Builder(mRS);
245         samplerBuilder.setMin(LINEAR);
246         samplerBuilder.setMag(LINEAR);
247         samplerBuilder.setWrapS(WRAP);
248         samplerBuilder.setWrapT(WRAP);
249         mStarSampler = samplerBuilder.create();
250
251         builder = new ProgramFragment.Builder(mRS);
252         builder.setPointSpriteTexCoordinateReplacement(true);
253         builder.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
254                            ProgramFragment.Builder.Format.RGBA, 0);
255         mPfStars = builder.create();
256         mPfStars.setName("PFStars");
257         mPfBackground.bindSampler(mStarSampler, 0);
258     }
259
260     private void createProgramFragmentStore() {
261         ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
262         builder.setDepthFunc(ALWAYS);
263         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
264         builder.setDitherEnable(false);
265         builder.setDepthMask(false);
266         mPfsBackground = builder.create();
267         mPfsBackground.setName("PFSBackground");
268
269         builder = new ProgramStore.Builder(mRS, null, null);
270         builder.setDepthFunc(ALWAYS);
271         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
272         builder.setDitherEnable(false);
273         mPfsLights = builder.create();
274         mPfsLights.setName("PFSLights");
275     }
276
277     private void createProgramVertex() {
278         mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
279         mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
280
281         ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
282         mPvBkOrtho = builder.create();
283         mPvBkOrtho.bindAllocation(mPvOrthoAlloc);
284         mPvBkOrtho.setName("PVBkOrtho");
285
286         mPvProjectionAlloc = new ProgramVertex.MatrixAllocation(mRS);
287         mPvProjectionAlloc.setupProjectionNormalized(mWidth, mHeight);
288
289         builder = new ProgramVertex.Builder(mRS, null, null);
290         mPvBkProj = builder.create();
291         mPvBkProj.bindAllocation(mPvProjectionAlloc);
292         mPvBkProj.setName("PVBkProj");
293
294         ProgramVertex.ShaderBuilder sb = new ProgramVertex.ShaderBuilder(mRS);
295         String t = "void main() {\n" +
296                     "  float dist = ATTRIB_position.y;\n" +
297                     "  float angle = ATTRIB_position.x;\n" +
298                     "  float x = dist * sin(angle);\n" +
299                     "  float y = dist * cos(angle) * 0.892;\n" +
300                     "  float p = dist * 5.5;\n" +
301                     "  float s = cos(p);\n" +
302                     "  float t = sin(p);\n" +
303                     "  vec4 pos;\n" +
304                     "  pos.x = t * x + s * y;\n" +
305                     "  pos.y = s * x - t * y;\n" +
306                     "  pos.z = ATTRIB_position.z;\n" +
307                     "  pos.w = 1.0;\n" +
308                     "  gl_Position = UNI_MVP * pos;\n" +
309                     "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
310                     "  varColor.rgb = ATTRIB_color.rgb;\n" +
311                     "  varColor.a = 1.0;\n" +
312                     "}\n";
313         sb.setShader(t);
314         sb.addInput(mParticlesMesh.getVertexType(0).getElement());
315         mPvStars = sb.create();
316         mPvStars.bindAllocation(mPvProjectionAlloc);
317         mPvStars.setName("PVStars");
318     }
319
320     private void createProgramRaster() {
321         ProgramRaster.Builder b = new ProgramRaster.Builder(mRS, null, null);
322         b.setPointSmoothEnable(true);
323         b.setPointSpriteEnable(true);
324         mRS.contextBindProgramRaster(b.create());
325     }
326
327 }