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
17package com.example.android.rs.balls;
18
19
20import android.content.res.Resources;
21import android.renderscript.*;
22import android.util.Log;
23import android.graphics.BitmapFactory;
24import android.graphics.Bitmap;
25
26
27public 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