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