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         return allocation;
    140     }
    141 
    142     // TODO: Fix Allocation.createFromBitmapResource() to do this when RGBA_8888 is specified
    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 
    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 
    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 
    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 
    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