• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.*;
20 import android.renderscript.Mesh.Primitive;
21 import static android.renderscript.ProgramStore.DepthFunc.*;
22 import static android.renderscript.ProgramStore.BlendDstFunc;
23 import static android.renderscript.ProgramStore.BlendSrcFunc;
24 import static android.renderscript.Element.*;
25 import android.graphics.Bitmap;
26 import android.graphics.BitmapFactory;
27 
28 import java.util.TimeZone;
29 
30 import com.android.wallpaper.R;
31 import com.android.wallpaper.RenderScriptScene;
32 
33 class GalaxyRS extends RenderScriptScene {
34     private static final int PARTICLES_COUNT = 12000;
35     private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
36     private ProgramVertexFixedFunction.Constants mPvOrthoAlloc;
37     private ProgramVertexFixedFunction.Constants mPvProjectionAlloc;
38     private ScriptField_VpConsts mPvStarAlloc;
39     private Mesh mParticlesMesh;
40     private ScriptC_galaxy mScript;
41 
GalaxyRS(int width, int height)42     GalaxyRS(int width, int height) {
43         super(width, height);
44 
45         mOptionsARGB.inScaled = false;
46         mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
47     }
48 
49     @Override
createScript()50     protected ScriptC createScript() {
51         mScript = new ScriptC_galaxy(mRS, mResources, R.raw.galaxy);
52         mScript.set_gIsPreview(isPreview() ? 1 : 0);
53         if (isPreview()) {
54             mScript.set_gXOffset(0.5f);
55         }
56 
57 
58         createParticlesMesh();
59         createProgramVertex();
60         createProgramRaster();
61         createProgramFragmentStore();
62         createProgramFragment();
63         loadTextures();
64 
65         mScript.setTimeZone(TimeZone.getDefault().getID());
66         return mScript;
67     }
68 
createParticlesMesh()69     private void createParticlesMesh() {
70         ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT);
71 
72         final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
73         meshBuilder.addVertexAllocation(p.getAllocation());
74         final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex();
75         meshBuilder.addIndexSetType(Primitive.POINT);
76         mParticlesMesh = meshBuilder.create();
77 
78         mScript.set_gParticlesMesh(mParticlesMesh);
79         mScript.bind_Particles(p);
80     }
81 
getProjectionNormalized(int w, int h)82     private Matrix4f getProjectionNormalized(int w, int h) {
83         // range -1,1 in the narrow axis at z = 0.
84         Matrix4f m1 = new Matrix4f();
85         Matrix4f m2 = new Matrix4f();
86 
87         if(w > h) {
88             float aspect = ((float)w) / h;
89             m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
90         } else {
91             float aspect = ((float)h) / w;
92             m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
93         }
94 
95         m2.loadRotate(180, 0, 1, 0);
96         m1.loadMultiply(m1, m2);
97 
98         m2.loadScale(-2, 2, 1);
99         m1.loadMultiply(m1, m2);
100 
101         m2.loadTranslate(0, 0, 2);
102         m1.loadMultiply(m1, m2);
103         return m1;
104     }
105 
updateProjectionMatrices()106     private void updateProjectionMatrices() {
107         Matrix4f proj = new Matrix4f();
108         proj.loadOrthoWindow(mWidth, mHeight);
109         mPvOrthoAlloc.setProjection(proj);
110 
111         Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
112         ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
113         i.Proj = projNorm;
114         i.MVP = projNorm;
115         mPvStarAlloc.set(i, 0, true);
116         mPvProjectionAlloc.setProjection(projNorm);
117     }
118 
119     @Override
setOffset(float xOffset, float yOffset, int xPixels, int yPixels)120     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
121         mScript.set_gXOffset(xOffset);
122     }
123 
124     @Override
resize(int width, int height)125     public void resize(int width, int height) {
126         super.resize(width, height);
127 
128         updateProjectionMatrices();
129     }
130 
loadTextures()131     private void loadTextures() {
132         mScript.set_gTSpace(loadTexture(R.drawable.space));
133         mScript.set_gTLight1(loadTexture(R.drawable.light1));
134         mScript.set_gTFlares(loadTextureARGB(R.drawable.flares));
135     }
136 
loadTexture(int id)137     private Allocation loadTexture(int id) {
138         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id,
139                                            Allocation.MipmapControl.MIPMAP_NONE,
140                                            Allocation.USAGE_GRAPHICS_TEXTURE);
141         return allocation;
142     }
143 
144     // TODO: Fix Allocation.createFromBitmapResource() to do this when RGBA_8888 is specified
loadTextureARGB(int id)145     private Allocation loadTextureARGB(int id) {
146         Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
147         final Allocation allocation = Allocation.createFromBitmap(mRS, b,
148                                            Allocation.MipmapControl.MIPMAP_NONE,
149                                            Allocation.USAGE_GRAPHICS_TEXTURE);
150         return allocation;
151     }
152 
createProgramFragment()153     private void createProgramFragment() {
154         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
155         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
156                            ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
157         ProgramFragment pfb = builder.create();
158         pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0);
159         mScript.set_gPFBackground(pfb);
160 
161         builder = new ProgramFragmentFixedFunction.Builder(mRS);
162         builder.setPointSpriteTexCoordinateReplacement(true);
163         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
164                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
165         builder.setVaryingColor(true);
166         ProgramFragment pfs = builder.create();
167         pfs.bindSampler(Sampler.WRAP_LINEAR(mRS), 0);
168         mScript.set_gPFStars(pfs);
169     }
170 
createProgramFragmentStore()171     private void createProgramFragmentStore() {
172         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
173         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
174         mRS.bindProgramStore(builder.create());
175 
176         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
177         mScript.set_gPSLights(builder.create());
178     }
179 
createProgramVertex()180     private void createProgramVertex() {
181         mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
182 
183         ProgramVertexFixedFunction.Builder builder = new ProgramVertexFixedFunction.Builder(mRS);
184         ProgramVertex pvbo = builder.create();
185         ((ProgramVertexFixedFunction)pvbo).bindConstants(mPvOrthoAlloc);
186         mRS.bindProgramVertex(pvbo);
187 
188         mPvStarAlloc = new ScriptField_VpConsts(mRS, 1);
189         mScript.bind_vpConstants(mPvStarAlloc);
190         mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS);
191         updateProjectionMatrices();
192 
193         builder = new ProgramVertexFixedFunction.Builder(mRS);
194         ProgramVertex pvbp = builder.create();
195         ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc);
196         mScript.set_gPVBkProj(pvbp);
197 
198         ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
199         String t =  "varying vec4 varColor;\n" +
200                     "varying vec2 varTex0;\n" +
201                     "void main() {\n" +
202                     "  float dist = ATTRIB_position.y;\n" +
203                     "  float angle = ATTRIB_position.x;\n" +
204                     "  float x = dist * sin(angle);\n" +
205                     "  float y = dist * cos(angle) * 0.892;\n" +
206                     "  float p = dist * 5.5;\n" +
207                     "  float s = cos(p);\n" +
208                     "  float t = sin(p);\n" +
209                     "  vec4 pos;\n" +
210                     "  pos.x = t * x + s * y;\n" +
211                     "  pos.y = s * x - t * y;\n" +
212                     "  pos.z = ATTRIB_position.z;\n" +
213                     "  pos.w = 1.0;\n" +
214                     "  gl_Position = UNI_MVP * pos;\n" +
215                     "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
216                     "  varColor.rgb = ATTRIB_color.rgb;\n" +
217                     "  varColor.a = 1.0;\n" +
218                     "}\n";
219         sb.setShader(t);
220         sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement());
221         sb.addConstant(mPvStarAlloc.getType());
222         ProgramVertex pvs = sb.create();
223         pvs.bindConstants(mPvStarAlloc.getAllocation(), 0);
224         mScript.set_gPVStars(pvs);
225     }
226 
createProgramRaster()227     private void createProgramRaster() {
228         ProgramRaster.Builder b = new ProgramRaster.Builder(mRS);
229         b.setPointSpriteEnabled(true);
230         ProgramRaster pr = b.create();
231         mRS.bindProgramRaster(pr);
232     }
233 
234 }
235