Home | History | Annotate | Download | only in balls
      1 /*
      2  * Copyright (C) 2008 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.example.android.rs.balls;
     18 
     19 
     20 import android.content.res.Resources;
     21 import android.renderscript.*;
     22 import android.util.Log;
     23 import android.graphics.BitmapFactory;
     24 import android.graphics.Bitmap;
     25 
     26 
     27 public class BallsRS {
     28     public static final int PART_COUNT = 4000;
     29 
     30     public BallsRS() {
     31     }
     32 
     33     private Resources mRes;
     34     private RenderScriptGL mRS;
     35     private ScriptC_balls mScript;
     36     private ScriptC_ball_physics mPhysicsScript;
     37     private ProgramFragment mPFPoints;
     38     private ScriptField_Point mPoints;
     39     private ScriptField_VpConsts mVpConsts;
     40     private ScriptField_BallGrid mGrid;
     41     private ScriptField_Ball mBalls;
     42     private Allocation mGridCache;
     43 
     44     void updateProjectionMatrices() {
     45         mVpConsts = new ScriptField_VpConsts(mRS, 1,
     46                                              Allocation.USAGE_SCRIPT |
     47                                              Allocation.USAGE_GRAPHICS_CONSTANTS);
     48         ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
     49         Matrix4f mvp = new Matrix4f();
     50         mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
     51         i.MVP = mvp;
     52         mVpConsts.set(i, 0, true);
     53     }
     54 
     55     private void createProgramVertex() {
     56         updateProjectionMatrices();
     57 
     58         ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
     59         String t =  "varying vec4 varColor;\n" +
     60                     "void main() {\n" +
     61                     "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
     62                     "  pos.xy = ATTRIB_position;\n" +
     63                     "  gl_Position = UNI_MVP * pos;\n" +
     64                     "  varColor = ATTRIB_color;\n" +
     65                     "  gl_PointSize = 12.0;\n" +
     66                     "}\n";
     67         sb.setShader(t);
     68         sb.addConstant(mVpConsts.getType());
     69         sb.addInput(mPoints.getElement());
     70         ProgramVertex pvs = sb.create();
     71         pvs.bindConstants(mVpConsts.getAllocation(), 0);
     72         mRS.bindProgramVertex(pvs);
     73     }
     74 
     75     private Allocation loadTexture(int id) {
     76         BitmapFactory.Options options = new BitmapFactory.Options();
     77         options.inScaled = false;
     78         Bitmap bp = BitmapFactory.decodeResource(mRes, id, options);
     79         final Allocation allocation =
     80             Allocation.createFromBitmap(mRS, bp,
     81                 Allocation.MipmapControl.MIPMAP_NONE,
     82                 Allocation.USAGE_GRAPHICS_TEXTURE);
     83         return allocation;
     84     }
     85 
     86     ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
     87         ProgramStore.Builder builder = new ProgramStore.Builder(rs);
     88         builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
     89         builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
     90         builder.setDitherEnabled(false);
     91         builder.setDepthMaskEnabled(false);
     92         return builder.create();
     93     }
     94 
     95     private void createPF(int width, int height) {
     96         ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(mRS);
     97         pfb.setPointSpriteTexCoordinateReplacement(true);
     98         pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
     99                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
    100         pfb.setVaryingColor(true);
    101         mPFPoints = pfb.create();
    102     }
    103 
    104     public void init(RenderScriptGL rs, Resources res, int width, int height) {
    105         mRS = rs;
    106         mRes = res;
    107 
    108         createPF(width, height);
    109 
    110         mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
    111 
    112         mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
    113 
    114         Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
    115         smb.addVertexAllocation(mPoints.getAllocation());
    116         smb.addIndexSetType(Mesh.Primitive.POINT);
    117         Mesh smP = smb.create();
    118 
    119         mGrid = ScriptField_BallGrid.create2D(mRS, (width + 99) / 100, (height + 99) / 100);
    120         mGridCache = Allocation.createSized(mRS, Element.F32_2(mRS), PART_COUNT);
    121         mBalls = new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
    122 
    123         mPhysicsScript = new ScriptC_ball_physics(mRS);
    124         mPhysicsScript.set_gGridCache(mGridCache);
    125         mPhysicsScript.set_gBalls(mBalls.getAllocation());
    126 
    127         mScript = new ScriptC_balls(mRS);
    128         mScript.set_partMesh(smP);
    129         mScript.set_physics_script(mPhysicsScript);
    130         mScript.bind_point(mPoints);
    131         mScript.bind_balls(mBalls);
    132         mScript.set_gGrid(mGrid.getAllocation());
    133         mScript.bind_gGridCache(mGridCache);
    134 
    135         mScript.set_gPFPoints(mPFPoints);
    136         createProgramVertex();
    137 
    138         mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
    139 
    140         mPhysicsScript.set_gMinPos(new Float2(5, 5));
    141         mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
    142         mPhysicsScript.set_gGrid(mGrid.getAllocation());
    143 
    144         mScript.invoke_initParts(width, height);
    145 
    146         mRS.bindRootScript(mScript);
    147     }
    148 
    149     public void newTouchPosition(float x, float y, float pressure, int id) {
    150         mPhysicsScript.invoke_touch(x, y, pressure * mRS.getWidth() / 1280, id);
    151     }
    152 
    153     public void setAccel(float x, float y) {
    154         mPhysicsScript.set_gGravityVector(new Float2(x, y));
    155     }
    156 
    157 }
    158