1185268942b946028b65f5cff9b335af97f9aeab8Romain Guy/*
2185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Copyright (C) 2011 The Android Open Source Project
3185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
4185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * you may not use this file except in compliance with the License.
6185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * You may obtain a copy of the License at
7185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
8185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
10185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Unless required by applicable law or agreed to in writing, software
11185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * See the License for the specific language governing permissions and
14185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * limitations under the License.
15185268942b946028b65f5cff9b335af97f9aeab8Romain Guy */
16185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
17185268942b946028b65f5cff9b335af97f9aeab8Romain Guypackage com.android.shaderstest;
18185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
19185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.content.res.Resources;
20185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Allocation;
21185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Element;
22185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Element.DataKind;
23185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Element.DataType;
24185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.FileA3D;
25185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Mesh;
26185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Program;
27185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramFragment;
28185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramFragmentFixedFunction;
29185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramStore;
30185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramStore.DepthFunc;
31185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramVertex;
32185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.ProgramVertexFixedFunction;
33185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.RSRuntimeException;
34185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.RenderScriptGL;
35185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Sampler;
36185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.Type.Builder;
37185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
38185268942b946028b65f5cff9b335af97f9aeab8Romain Guy@SuppressWarnings({"FieldCanBeLocal"})
39185268942b946028b65f5cff9b335af97f9aeab8Romain Guypublic class ShadersTestRS {
40185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public ShadersTestRS() {
41185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
42185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
43185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void init(RenderScriptGL rs, Resources res) {
44185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mRS = rs;
45185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mRes = res;
46185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initRS();
47185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
48185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
49185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void surfaceChanged() {
50185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initBuffers(mRS.getWidth(), mRS.getHeight());
51185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
52185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
53185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Resources mRes;
54185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private RenderScriptGL mRS;
55185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Sampler mLinearClamp;
56185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Sampler mNearestClamp;
57185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ProgramStore mPSBackground;
58185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ProgramFragment mPFBackground;
59185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ProgramVertex mPVBackground;
60185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ProgramVertexFixedFunction.Constants mPVA;
61185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
62185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ProgramFragment mPFVignette;
63185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ScriptField_VignetteConstants_s mFSVignetteConst;
64185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
65185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Allocation mMeshTexture;
66185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Allocation mScreen;
67185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private Allocation mScreenDepth;
68185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
69185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ScriptField_MeshInfo mMeshes;
70185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ScriptC_shaderstest mScript;
71185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
72185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
73185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void onActionDown(float x, float y) {
74185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.invoke_onActionDown(x, y);
75185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
76185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
77185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void onActionScale(float scale) {
78185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.invoke_onActionScale(scale);
79185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
80185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
81185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void onActionMove(float x, float y) {
82185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.invoke_onActionMove(x, y);
83185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
84185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
85185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initPFS() {
86185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ProgramStore.Builder b = new ProgramStore.Builder(mRS);
87185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
88185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setDepthFunc(DepthFunc.LESS);
89185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setDitherEnabled(false);
90185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setDepthMaskEnabled(true);
91185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPSBackground = b.create();
92185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
93185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gPFSBackground(mPSBackground);
94185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
95185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
96185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initPF() {
97185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
98185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gLinear(mLinearClamp);
99185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
100185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
101185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gNearest(mNearestClamp);
102185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
103185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
104185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
105185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
106185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPFBackground = b.create();
107185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPFBackground.bindSampler(mLinearClamp, 0);
108185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gPFBackground(mPFBackground);
109185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
110185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mFSVignetteConst = new ScriptField_VignetteConstants_s(mRS, 1);
111185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.bind_gFSVignetteConstants(mFSVignetteConst);
112185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
113185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ProgramFragment.Builder fs;
114185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
115185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        fs = new ProgramFragment.Builder(mRS);
116185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        fs.setShader(mRes, R.raw.vignette_fs);
117185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        fs.addConstant(mFSVignetteConst.getAllocation().getType());
118185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        fs.addTexture(Program.TextureType.TEXTURE_2D);
119185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPFVignette = fs.create();
120185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPFVignette.bindConstants(mFSVignetteConst.getAllocation(), 0);
121185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gPFVignette(mPFVignette);
122185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
123185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
124185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initPV() {
125185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
126185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPVBackground = pvb.create();
127185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
128185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
129185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ((ProgramVertexFixedFunction) mPVBackground).bindConstants(mPVA);
130185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
131185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gPVBackground(mPVBackground);
132185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
133185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
134185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void loadImage() {
135185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mMeshTexture = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
136185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
137185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                Allocation.USAGE_GRAPHICS_TEXTURE);
138185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gTMesh(mMeshTexture);
139185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
140185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
141185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initMeshes(FileA3D model) {
142185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        int numEntries = model.getIndexEntryCount();
143185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        int numMeshes = 0;
144185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        for (int i = 0; i < numEntries; i ++) {
145185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            FileA3D.IndexEntry entry = model.getIndexEntry(i);
146185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
147185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                numMeshes ++;
148185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            }
149185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
150185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
151185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        if (numMeshes > 0) {
152185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
153185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
154185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            for (int i = 0; i < numEntries; i ++) {
155185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                FileA3D.IndexEntry entry = model.getIndexEntry(i);
156185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
157185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                    Mesh mesh = entry.getMesh();
158185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                    mMeshes.set_mMesh(i, mesh, false);
159185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                    mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
160185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                }
161185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            }
162185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mMeshes.copyAll();
163185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        } else {
164185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            throw new RSRuntimeException("No valid meshes in file");
165185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
166185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
167185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.bind_gMeshes(mMeshes);
168185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.invoke_updateMeshInfo();
169185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
170185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
171185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initRS() {
172185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript = new ScriptC_shaderstest(mRS, mRes, R.raw.shaderstest);
173185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
174185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initPFS();
175185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initPF();
176185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initPV();
177185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
178185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        loadImage();
179185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
180185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initBuffers(1, 1);
181185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
182185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
183185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        initMeshes(model);
184185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
185185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mRS.bindRootScript(mScript);
186185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
187185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
188185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void initBuffers(int width, int height) {
189185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        Builder b;
190185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b = new Builder(mRS, Element.RGBA_8888(mRS));
191185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setX(width).setY(height);
192185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScreen = Allocation.createTyped(mRS, b.create(),
193185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET);
194185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gScreen(mScreen);
195185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
196185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b = new Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16, DataKind.PIXEL_DEPTH));
197185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        b.setX(width).setY(height);
198185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScreenDepth = Allocation.createTyped(mRS, b.create(),
199185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                Allocation.USAGE_GRAPHICS_RENDER_TARGET);
200185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScript.set_gScreenDepth(mScreenDepth);
201185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
202185268942b946028b65f5cff9b335af97f9aeab8Romain Guy}
203