1 /*
2  * Copyright (C) 2011 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.android.shaderstest;
18 
19 import android.content.res.Resources;
20 import android.renderscript.Allocation;
21 import android.renderscript.Element;
22 import android.renderscript.Element.DataKind;
23 import android.renderscript.Element.DataType;
24 import android.renderscript.FileA3D;
25 import android.renderscript.Mesh;
26 import android.renderscript.Program;
27 import android.renderscript.ProgramFragment;
28 import android.renderscript.ProgramFragmentFixedFunction;
29 import android.renderscript.ProgramStore;
30 import android.renderscript.ProgramStore.DepthFunc;
31 import android.renderscript.ProgramVertex;
32 import android.renderscript.ProgramVertexFixedFunction;
33 import android.renderscript.RSRuntimeException;
34 import android.renderscript.RenderScriptGL;
35 import android.renderscript.Sampler;
36 import android.renderscript.Type.Builder;
37 
38 @SuppressWarnings({"FieldCanBeLocal"})
39 public class ShadersTestRS {
ShadersTestRS()40     public ShadersTestRS() {
41     }
42 
init(RenderScriptGL rs, Resources res)43     public void init(RenderScriptGL rs, Resources res) {
44         mRS = rs;
45         mRes = res;
46         initRS();
47     }
48 
surfaceChanged()49     public void surfaceChanged() {
50         initBuffers(mRS.getWidth(), mRS.getHeight());
51     }
52 
53     private Resources mRes;
54     private RenderScriptGL mRS;
55     private Sampler mLinearClamp;
56     private Sampler mNearestClamp;
57     private ProgramStore mPSBackground;
58     private ProgramFragment mPFBackground;
59     private ProgramVertex mPVBackground;
60     private ProgramVertexFixedFunction.Constants mPVA;
61 
62     private ProgramFragment mPFVignette;
63     private ScriptField_VignetteConstants_s mFSVignetteConst;
64 
65     private Allocation mMeshTexture;
66     private Allocation mScreen;
67     private Allocation mScreenDepth;
68 
69     private ScriptField_MeshInfo mMeshes;
70     private ScriptC_shaderstest mScript;
71 
72 
onActionDown(float x, float y)73     public void onActionDown(float x, float y) {
74         mScript.invoke_onActionDown(x, y);
75     }
76 
onActionScale(float scale)77     public void onActionScale(float scale) {
78         mScript.invoke_onActionScale(scale);
79     }
80 
onActionMove(float x, float y)81     public void onActionMove(float x, float y) {
82         mScript.invoke_onActionMove(x, y);
83     }
84 
initPFS()85     private void initPFS() {
86         ProgramStore.Builder b = new ProgramStore.Builder(mRS);
87 
88         b.setDepthFunc(DepthFunc.LESS);
89         b.setDitherEnabled(false);
90         b.setDepthMaskEnabled(true);
91         mPSBackground = b.create();
92 
93         mScript.set_gPFSBackground(mPSBackground);
94     }
95 
initPF()96     private void initPF() {
97         mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
98         mScript.set_gLinear(mLinearClamp);
99 
100         mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
101         mScript.set_gNearest(mNearestClamp);
102 
103         ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
104         b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
105                      ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
106         mPFBackground = b.create();
107         mPFBackground.bindSampler(mLinearClamp, 0);
108         mScript.set_gPFBackground(mPFBackground);
109 
110         mFSVignetteConst = new ScriptField_VignetteConstants_s(mRS, 1);
111         mScript.bind_gFSVignetteConstants(mFSVignetteConst);
112 
113         ProgramFragment.Builder fs;
114 
115         fs = new ProgramFragment.Builder(mRS);
116         fs.setShader(mRes, R.raw.vignette_fs);
117         fs.addConstant(mFSVignetteConst.getAllocation().getType());
118         fs.addTexture(Program.TextureType.TEXTURE_2D);
119         mPFVignette = fs.create();
120         mPFVignette.bindConstants(mFSVignetteConst.getAllocation(), 0);
121         mScript.set_gPFVignette(mPFVignette);
122     }
123 
initPV()124     private void initPV() {
125         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
126         mPVBackground = pvb.create();
127 
128         mPVA = new ProgramVertexFixedFunction.Constants(mRS);
129         ((ProgramVertexFixedFunction) mPVBackground).bindConstants(mPVA);
130 
131         mScript.set_gPVBackground(mPVBackground);
132     }
133 
loadImage()134     private void loadImage() {
135         mMeshTexture = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
136                 Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
137                 Allocation.USAGE_GRAPHICS_TEXTURE);
138         mScript.set_gTMesh(mMeshTexture);
139     }
140 
initMeshes(FileA3D model)141     private void initMeshes(FileA3D model) {
142         int numEntries = model.getIndexEntryCount();
143         int numMeshes = 0;
144         for (int i = 0; i < numEntries; i ++) {
145             FileA3D.IndexEntry entry = model.getIndexEntry(i);
146             if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
147                 numMeshes ++;
148             }
149         }
150 
151         if (numMeshes > 0) {
152             mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
153 
154             for (int i = 0; i < numEntries; i ++) {
155                 FileA3D.IndexEntry entry = model.getIndexEntry(i);
156                 if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
157                     Mesh mesh = entry.getMesh();
158                     mMeshes.set_mMesh(i, mesh, false);
159                     mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
160                 }
161             }
162             mMeshes.copyAll();
163         } else {
164             throw new RSRuntimeException("No valid meshes in file");
165         }
166 
167         mScript.bind_gMeshes(mMeshes);
168         mScript.invoke_updateMeshInfo();
169     }
170 
initRS()171     private void initRS() {
172         mScript = new ScriptC_shaderstest(mRS, mRes, R.raw.shaderstest);
173 
174         initPFS();
175         initPF();
176         initPV();
177 
178         loadImage();
179 
180         initBuffers(1, 1);
181 
182         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
183         initMeshes(model);
184 
185         mRS.bindRootScript(mScript);
186     }
187 
initBuffers(int width, int height)188     private void initBuffers(int width, int height) {
189         Builder b;
190         b = new Builder(mRS, Element.RGBA_8888(mRS));
191         b.setX(width).setY(height);
192         mScreen = Allocation.createTyped(mRS, b.create(),
193                 Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET);
194         mScript.set_gScreen(mScreen);
195 
196         b = new Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16, DataKind.PIXEL_DEPTH));
197         b.setX(width).setY(height);
198         mScreenDepth = Allocation.createTyped(mRS, b.create(),
199                 Allocation.USAGE_GRAPHICS_RENDER_TARGET);
200         mScript.set_gScreenDepth(mScreenDepth);
201     }
202 }
203