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
19ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen
20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.content.res.Resources;
21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.renderscript.*;
22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.util.Log;
23ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chenimport android.graphics.BitmapFactory;
24ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chenimport android.graphics.Bitmap;
25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samspublic class BallsRS {
28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public static final int PART_COUNT = 4000;
29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public BallsRS() {
31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Resources mRes;
34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private RenderScriptGL mRS;
35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptC_balls mScript;
36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptC_ball_physics mPhysicsScript;
37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ProgramFragment mPFPoints;
38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_Point mPoints;
39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_VpConsts mVpConsts;
40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_BallGrid mGrid;
41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private ScriptField_Ball mBalls;
42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Allocation mGridCache;
43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    void updateProjectionMatrices() {
45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mVpConsts = new ScriptField_VpConsts(mRS, 1,
46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                                             Allocation.USAGE_SCRIPT |
47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                                             Allocation.USAGE_GRAPHICS_CONSTANTS);
48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Matrix4f mvp = new Matrix4f();
50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        i.MVP = mvp;
52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mVpConsts.set(i, 0, true);
53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void createProgramVertex() {
56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        updateProjectionMatrices();
57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        String t =  "varying vec4 varColor;\n" +
60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "void main() {\n" +
61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  pos.xy = ATTRIB_position;\n" +
63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  gl_Position = UNI_MVP * pos;\n" +
64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  varColor = ATTRIB_color;\n" +
65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "  gl_PointSize = 12.0;\n" +
66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    "}\n";
67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.setShader(t);
68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.addConstant(mVpConsts.getType());
69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sb.addInput(mPoints.getElement());
70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramVertex pvs = sb.create();
71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pvs.bindConstants(mVpConsts.getAllocation(), 0);
72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindProgramVertex(pvs);
73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Allocation loadTexture(int id) {
76ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen        BitmapFactory.Options options = new BitmapFactory.Options();
77ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen        options.inScaled = false;
78ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen        Bitmap bp = BitmapFactory.decodeResource(mRes, id, options);
79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        final Allocation allocation =
80ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen            Allocation.createFromBitmap(mRS, bp,
81ebfc261ad12c1062929a0274a7000d2775cdcf00Yong Chen                Allocation.MipmapControl.MIPMAP_NONE,
82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                Allocation.USAGE_GRAPHICS_TEXTURE);
83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        return allocation;
84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDitherEnabled(false);
91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        builder.setDepthMaskEnabled(false);
92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        return builder.create();
93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void createPF(int width, int height) {
96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(mRS);
97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setPointSpriteTexCoordinateReplacement(true);
98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        pfb.setVaryingColor(true);
101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPFPoints = pfb.create();
102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void init(RenderScriptGL rs, Resources res, int width, int height) {
105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS = rs;
106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRes = res;
107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        createPF(width, height);
109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        smb.addVertexAllocation(mPoints.getAllocation());
116572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        smb.addIndexSetType(Mesh.Primitive.POINT);
117572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Mesh smP = smb.create();
118572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mGrid = ScriptField_BallGrid.create2D(mRS, (width + 99) / 100, (height + 99) / 100);
120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mGridCache = Allocation.createSized(mRS, Element.F32_2(mRS), PART_COUNT);
121572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mBalls = new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
122572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
123572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript = new ScriptC_ball_physics(mRS);
124572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGridCache(mGridCache);
125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gBalls(mBalls.getAllocation());
126572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
127572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript = new ScriptC_balls(mRS);
128572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_partMesh(smP);
129572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_physics_script(mPhysicsScript);
130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_point(mPoints);
131572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_balls(mBalls);
132572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_gGrid(mGrid.getAllocation());
133572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.bind_gGridCache(mGridCache);
134572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
135572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.set_gPFPoints(mPFPoints);
136572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        createProgramVertex();
137572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
138572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
139572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
140572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gMinPos(new Float2(5, 5));
141572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
142572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGrid(mGrid.getAllocation());
143572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
144572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mScript.invoke_initParts(width, height);
145572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
146572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS.bindRootScript(mScript);
147572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
148572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
149572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void newTouchPosition(float x, float y, float pressure, int id) {
150572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.invoke_touch(x, y, pressure * mRS.getWidth() / 1280, id);
151572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
152572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
153572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void setAccel(float x, float y) {
154572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPhysicsScript.set_gGravityVector(new Float2(x, y));
155572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
156572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
157572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}
158