1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams/*
2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Copyright (C) 2008 The Android Open Source Project
3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * you may not use this file except in compliance with the License.
6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * You may obtain a copy of the License at
7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Unless required by applicable law or agreed to in writing, software
11572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * See the License for the specific language governing permissions and
14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * limitations under the License.
15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams */
16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samspackage com.example.android.rs.balls;
18572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.content.res.Resources;
20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.renderscript.*;
21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.util.Log;
22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
23572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samspublic class BallsRS {
25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public static final int PART_COUNT = 4000;
26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public BallsRS() {
28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Resources mRes;
31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private RenderScriptGL mRS;
32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptC_balls mScript;
33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptC_ball_physics mPhysicsScript;
34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ProgramFragment mPFPoints;
35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_Point mPoints;
36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_VpConsts mVpConsts;
37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_BallGrid mGrid;
38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_Ball mBalls;
39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Allocation mGridCache;
40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    void updateProjectionMatrices() {
42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mVpConsts = new ScriptField_VpConsts(mRS, 1,
43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                                             Allocation.USAGE_SCRIPT |
44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                                             Allocation.USAGE_GRAPHICS_CONSTANTS);
45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Matrix4f mvp = new Matrix4f();
47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        i.MVP = mvp;
49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mVpConsts.set(i, 0, true);
50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void createProgramVertex() {
53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        updateProjectionMatrices();
54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        String t =  "varying vec4 varColor;\n" +
57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "void main() {\n" +
58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  pos.xy = ATTRIB_position;\n" +
60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  gl_Position = UNI_MVP * pos;\n" +
61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  varColor = ATTRIB_color;\n" +
62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  gl_PointSize = 12.0;\n" +
63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "}\n";
64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.setShader(t);
65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.addConstant(mVpConsts.getType());
66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.addInput(mPoints.getElement());
67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramVertex pvs = sb.create();
68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pvs.bindConstants(mVpConsts.getAllocation(), 0);
69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindProgramVertex(pvs);
70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Allocation loadTexture(int id) {
73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        final Allocation allocation =
74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            Allocation.createFromBitmapResource(mRS, mRes,
75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                id, Allocation.MipmapControl.MIPMAP_NONE,
76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                Allocation.USAGE_GRAPHICS_TEXTURE);
77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        return allocation;
78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDitherEnabled(false);
85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDepthMaskEnabled(false);
86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        return builder.create();
87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void createPF(int width, int height) {
90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(mRS);
91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setPointSpriteTexCoordinateReplacement(true);
92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setVaryingColor(true);
95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPFPoints = pfb.create();
96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void init(RenderScriptGL rs, Resources res, int width, int height) {
99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS = rs;
100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRes = res;
101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        createPF(width, height);
103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        smb.addVertexAllocation(mPoints.getAllocation());
110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        smb.addIndexSetType(Mesh.Primitive.POINT);
111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Mesh smP = smb.create();
112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mGrid = ScriptField_BallGrid.create2D(mRS, (width + 99) / 100, (height + 99) / 100);
114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mGridCache = Allocation.createSized(mRS, Element.F32_2(mRS), PART_COUNT);
115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mBalls = new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
116572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
117572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript = new ScriptC_ball_physics(mRS);
118572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGridCache(mGridCache);
119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gBalls(mBalls.getAllocation());
120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
121572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript = new ScriptC_balls(mRS);
122572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_partMesh(smP);
123572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_physics_script(mPhysicsScript);
124572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_point(mPoints);
125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_balls(mBalls);
126572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_gGrid(mGrid.getAllocation());
127572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_gGridCache(mGridCache);
128572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
129572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_gPFPoints(mPFPoints);
130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        createProgramVertex();
131572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
132572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
133572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
134572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gMinPos(new Float2(5, 5));
135572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
136572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGrid(mGrid.getAllocation());
137572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
138572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.invoke_initParts(width, height);
139572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
140572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindRootScript(mScript);
141572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
142572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
143572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void newTouchPosition(float x, float y, float pressure, int id) {
144572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.invoke_touch(x, y, pressure * mRS.getWidth() / 1280, id);
145572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
146572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
147572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void setAccel(float x, float y) {
148572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGravityVector(new Float2(x, y));
149572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
150572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
151572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}
152