• 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         return allocation;
140     }
141 
142     // TODO: Fix Allocation.createFromBitmapResource() to do this when RGBA_8888 is specified
loadTextureARGB(int id)143     private Allocation loadTextureARGB(int id) {
144         Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
145         final Allocation allocation = Allocation.createFromBitmap(mRS, b);
146         return allocation;
147     }
148 
createProgramFragment()149     private void createProgramFragment() {
150         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
151         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
152                            ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
153         ProgramFragment pfb = builder.create();
154         pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0);
155         mScript.set_gPFBackground(pfb);
156 
157         builder = new ProgramFragmentFixedFunction.Builder(mRS);
158         builder.setPointSpriteTexCoordinateReplacement(true);
159         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
160                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
161         builder.setVaryingColor(true);
162         ProgramFragment pfs = builder.create();
163         pfs.bindSampler(Sampler.WRAP_LINEAR(mRS), 0);
164         mScript.set_gPFStars(pfs);
165     }
166 
createProgramFragmentStore()167     private void createProgramFragmentStore() {
168         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
169         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
170         mRS.bindProgramStore(builder.create());
171 
172         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
173         mScript.set_gPSLights(builder.create());
174     }
175 
createProgramVertex()176     private void createProgramVertex() {
177         mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
178 
179         ProgramVertexFixedFunction.Builder builder = new ProgramVertexFixedFunction.Builder(mRS);
180         ProgramVertex pvbo = builder.create();
181         ((ProgramVertexFixedFunction)pvbo).bindConstants(mPvOrthoAlloc);
182         mRS.bindProgramVertex(pvbo);
183 
184         mPvStarAlloc = new ScriptField_VpConsts(mRS, 1);
185         mScript.bind_vpConstants(mPvStarAlloc);
186         mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS);
187         updateProjectionMatrices();
188 
189         builder = new ProgramVertexFixedFunction.Builder(mRS);
190         ProgramVertex pvbp = builder.create();
191         ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc);
192         mScript.set_gPVBkProj(pvbp);
193 
194         ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
195         String t =  "varying vec4 varColor;\n" +
196                     "varying vec2 varTex0;\n" +
197                     "void main() {\n" +
198                     "  float dist = ATTRIB_position.y;\n" +
199                     "  float angle = ATTRIB_position.x;\n" +
200                     "  float x = dist * sin(angle);\n" +
201                     "  float y = dist * cos(angle) * 0.892;\n" +
202                     "  float p = dist * 5.5;\n" +
203                     "  float s = cos(p);\n" +
204                     "  float t = sin(p);\n" +
205                     "  vec4 pos;\n" +
206                     "  pos.x = t * x + s * y;\n" +
207                     "  pos.y = s * x - t * y;\n" +
208                     "  pos.z = ATTRIB_position.z;\n" +
209                     "  pos.w = 1.0;\n" +
210                     "  gl_Position = UNI_MVP * pos;\n" +
211                     "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
212                     "  varColor.rgb = ATTRIB_color.rgb;\n" +
213                     "  varColor.a = 1.0;\n" +
214                     "}\n";
215         sb.setShader(t);
216         sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement());
217         sb.addConstant(mPvStarAlloc.getType());
218         ProgramVertex pvs = sb.create();
219         pvs.bindConstants(mPvStarAlloc.getAllocation(), 0);
220         mScript.set_gPVStars(pvs);
221     }
222 
createProgramRaster()223     private void createProgramRaster() {
224         ProgramRaster.Builder b = new ProgramRaster.Builder(mRS);
225         b.setPointSpriteEnabled(true);
226         ProgramRaster pr = b.create();
227         mRS.bindProgramRaster(pr);
228     }
229 
230 }
231