Home | History | Annotate | Download | only in galaxy
      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 
     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
     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 
     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 
     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 
    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
    120     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
    121         mScript.set_gXOffset(xOffset);
    122     }
    123 
    124     @Override
    125     public void resize(int width, int height) {
    126         super.resize(width, height);
    127 
    128         updateProjectionMatrices();
    129     }
    130 
    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 
    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
    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 
    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 
    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 
    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 
    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