RsRenderStatesRS.java revision e5f2f66f8c802d64ecf869081036ae13d4e9e19c
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.miscsamples;
18
19import android.content.res.Resources;
20import android.graphics.Bitmap;
21import android.graphics.BitmapFactory;
22import android.renderscript.*;
23import android.renderscript.Font.Style;
24import android.renderscript.Program.TextureType;
25import android.renderscript.ProgramStore.DepthFunc;
26import android.renderscript.ProgramStore.BlendSrcFunc;
27import android.renderscript.ProgramStore.BlendDstFunc;
28import android.renderscript.Sampler.Value;
29import android.util.Log;
30
31
32public class RsRenderStatesRS {
33
34    int mWidth;
35    int mHeight;
36
37    public RsRenderStatesRS() {
38    }
39
40    public void init(RenderScriptGL rs, Resources res) {
41        mRS = rs;
42        mWidth = mRS.getWidth();
43        mHeight = mRS.getHeight();
44        mRes = res;
45        mOptionsARGB.inScaled = false;
46        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
47        mMode = 0;
48        mMaxModes = 0;
49        initRS();
50    }
51
52    public void surfaceChanged() {
53        mWidth = mRS.getWidth();
54        mHeight = mRS.getHeight();
55
56        Matrix4f proj = new Matrix4f();
57        proj.loadOrthoWindow(mWidth, mHeight);
58        mPVA.setProjection(proj);
59    }
60
61    private Resources mRes;
62    private RenderScriptGL mRS;
63
64    private Sampler mLinearClamp;
65    private Sampler mLinearWrap;
66    private Sampler mMipLinearWrap;
67    private Sampler mNearestClamp;
68    private Sampler mMipLinearAniso8;
69    private Sampler mMipLinearAniso15;
70
71    private ProgramStore mProgStoreBlendNoneDepth;
72    private ProgramStore mProgStoreBlendNone;
73    private ProgramStore mProgStoreBlendAlpha;
74    private ProgramStore mProgStoreBlendAdd;
75
76    private ProgramFragment mProgFragmentTexture;
77    private ProgramFragment mProgFragmentColor;
78
79    private ProgramVertex mProgVertex;
80    private ProgramVertexFixedFunction.Constants mPVA;
81
82    // Custom shaders
83    private ProgramVertex mProgVertexCustom;
84    private ProgramFragment mProgFragmentCustom;
85    private ProgramFragment mProgFragmentMultitex;
86    private ScriptField_VertexShaderConstants_s mVSConst;
87    private ScriptField_VertexShaderConstants2_s mVSConst2;
88    private ScriptField_FragentShaderConstants_s mFSConst;
89    private ScriptField_FragentShaderConstants2_s mFSConst2;
90
91    private ProgramVertex mProgVertexCustom2;
92    private ProgramFragment mProgFragmentCustom2;
93
94    private ProgramVertex mProgVertexCube;
95    private ProgramFragment mProgFragmentCube;
96
97    private ProgramRaster mCullBack;
98    private ProgramRaster mCullFront;
99    private ProgramRaster mCullNone;
100
101    private Allocation mTexTorus;
102    private Allocation mTexOpaque;
103    private Allocation mTexTransparent;
104    private Allocation mTexChecker;
105    private Allocation mTexCube;
106
107    private Mesh mMbyNMesh;
108    private Mesh mTorus;
109
110    Font mFontSans;
111    Font mFontSerif;
112    Font mFontSerifBold;
113    Font mFontSerifItalic;
114    Font mFontSerifBoldItalic;
115    Font mFontMono;
116    private Allocation mTextAlloc;
117
118    private ScriptC_rsrenderstates mScript;
119
120    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
121
122    int mMode;
123    int mMaxModes;
124
125    public void onActionDown(int x, int y) {
126        mMode ++;
127        mMode = mMode % mMaxModes;
128        mScript.set_gDisplayMode(mMode);
129    }
130
131    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
132        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
133        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
134        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
135        builder.setDitherEnabled(false);
136        builder.setDepthMaskEnabled(false);
137        return builder.create();
138    }
139
140    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
141
142        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
143                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
144
145        for (int y = 0; y <= hResolution; y++) {
146            final float normalizedY = (float)y / hResolution;
147            final float yOffset = (normalizedY - 0.5f) * height;
148            for (int x = 0; x <= wResolution; x++) {
149                float normalizedX = (float)x / wResolution;
150                float xOffset = (normalizedX - 0.5f) * width;
151                tmb.setTexture(normalizedX, normalizedY);
152                tmb.addVertex(xOffset, yOffset);
153             }
154        }
155
156        for (int y = 0; y < hResolution; y++) {
157            final int curY = y * (wResolution + 1);
158            final int belowY = (y + 1) * (wResolution + 1);
159            for (int x = 0; x < wResolution; x++) {
160                int curV = curY + x;
161                int belowV = belowY + x;
162                tmb.addTriangle(curV, belowV, curV + 1);
163                tmb.addTriangle(belowV, belowV + 1, curV + 1);
164            }
165        }
166
167        return tmb.create(true);
168    }
169
170    private void initProgramStore() {
171        // Use stock the stock program store object
172        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
173        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
174
175        // Create a custom program store
176        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
177        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
178        builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
179                             ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
180        builder.setDitherEnabled(false);
181        builder.setDepthMaskEnabled(false);
182        mProgStoreBlendAlpha = builder.create();
183
184        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
185
186        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
187        mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
188        mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
189        mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
190    }
191
192    private void initProgramFragment() {
193
194        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
195        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
196                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
197        mProgFragmentTexture = texBuilder.create();
198        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
199
200        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
201        colBuilder.setVaryingColor(false);
202        mProgFragmentColor = colBuilder.create();
203
204        mScript.set_gProgFragmentColor(mProgFragmentColor);
205        mScript.set_gProgFragmentTexture(mProgFragmentTexture);
206    }
207
208    private void initProgramVertex() {
209        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
210        mProgVertex = pvb.create();
211
212        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
213        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
214        Matrix4f proj = new Matrix4f();
215        proj.loadOrthoWindow(mWidth, mHeight);
216        mPVA.setProjection(proj);
217
218        mScript.set_gProgVertex(mProgVertex);
219    }
220
221    private void initCustomShaders() {
222        mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
223        mVSConst2 = new ScriptField_VertexShaderConstants2_s(mRS, 1);
224        mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
225        mFSConst2 = new ScriptField_FragentShaderConstants2_s(mRS, 1);
226
227        mScript.bind_gVSConstants(mVSConst);
228        mScript.bind_gVSConstants2(mVSConst2);
229        mScript.bind_gFSConstants(mFSConst);
230        mScript.bind_gFSConstants2(mFSConst2);
231
232        // Initialize the shader builder
233        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
234        // Specify the resource that contains the shader string
235        pvbCustom.setShader(mRes, R.raw.shaderv);
236        // Use a script field to spcify the input layout
237        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
238        // Define the constant input layout
239        pvbCustom.addConstant(mVSConst.getAllocation().getType());
240        mProgVertexCustom = pvbCustom.create();
241        // Bind the source of constant data
242        mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
243
244        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
245        // Specify the resource that contains the shader string
246        pfbCustom.setShader(mRes, R.raw.shaderf);
247        //Tell the builder how many textures we have
248        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
249        // Define the constant input layout
250        pfbCustom.addConstant(mFSConst.getAllocation().getType());
251        mProgFragmentCustom = pfbCustom.create();
252        // Bind the source of constant data
253        mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
254
255        pvbCustom = new ProgramVertex.Builder(mRS);
256        pvbCustom.setShader(mRes, R.raw.shaderarrayv);
257        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
258        pvbCustom.addConstant(mVSConst2.getAllocation().getType());
259        mProgVertexCustom2 = pvbCustom.create();
260        mProgVertexCustom2.bindConstants(mVSConst2.getAllocation(), 0);
261
262        pfbCustom = new ProgramFragment.Builder(mRS);
263        pfbCustom.setShader(mRes, R.raw.shaderarrayf);
264        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
265        pfbCustom.addConstant(mFSConst2.getAllocation().getType());
266        mProgFragmentCustom2 = pfbCustom.create();
267        mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
268
269        // Cubemap test shaders
270        pvbCustom = new ProgramVertex.Builder(mRS);
271        pvbCustom.setShader(mRes, R.raw.shadercubev);
272        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
273        pvbCustom.addConstant(mVSConst.getAllocation().getType());
274        mProgVertexCube = pvbCustom.create();
275        mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
276
277        pfbCustom = new ProgramFragment.Builder(mRS);
278        pfbCustom.setShader(mRes, R.raw.shadercubef);
279        pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
280        mProgFragmentCube = pfbCustom.create();
281
282        pfbCustom = new ProgramFragment.Builder(mRS);
283        pfbCustom.setShader(mRes, R.raw.multitexf);
284        for (int texCount = 0; texCount < 3; texCount ++) {
285            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
286        }
287        mProgFragmentMultitex = pfbCustom.create();
288
289        mScript.set_gProgVertexCustom(mProgVertexCustom);
290        mScript.set_gProgFragmentCustom(mProgFragmentCustom);
291        mScript.set_gProgVertexCustom2(mProgVertexCustom2);
292        mScript.set_gProgFragmentCustom2(mProgFragmentCustom2);
293        mScript.set_gProgVertexCube(mProgVertexCube);
294        mScript.set_gProgFragmentCube(mProgFragmentCube);
295        mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
296    }
297
298    private Allocation loadTextureRGB(int id) {
299        return Allocation.createFromBitmapResource(mRS, mRes, id,
300                                                   Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
301                                                   Allocation.USAGE_GRAPHICS_TEXTURE);
302    }
303
304    private Allocation loadTextureARGB(int id) {
305        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
306        return Allocation.createFromBitmap(mRS, b,
307                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
308                                           Allocation.USAGE_GRAPHICS_TEXTURE);
309    }
310
311    private void loadImages() {
312        mTexTorus = loadTextureRGB(R.drawable.torusmap);
313        mTexOpaque = loadTextureRGB(R.drawable.data);
314        mTexTransparent = loadTextureARGB(R.drawable.leaf);
315        mTexChecker = loadTextureRGB(R.drawable.checker);
316        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
317        mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
318
319        mScript.set_gTexTorus(mTexTorus);
320        mScript.set_gTexOpaque(mTexOpaque);
321        mScript.set_gTexTransparent(mTexTransparent);
322        mScript.set_gTexChecker(mTexChecker);
323        mScript.set_gTexCube(mTexCube);
324    }
325
326    private void initFonts() {
327        // Sans font by family name
328        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
329        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
330        // Create fonts by family and style
331        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
332        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
333        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
334        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
335
336        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
337
338        mScript.set_gFontSans(mFontSans);
339        mScript.set_gFontSerif(mFontSerif);
340        mScript.set_gFontSerifBold(mFontSerifBold);
341        mScript.set_gFontSerifItalic(mFontSerifItalic);
342        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
343        mScript.set_gFontMono(mFontMono);
344        mScript.set_gTextAlloc(mTextAlloc);
345    }
346
347    private void initMesh() {
348        mMbyNMesh = getMbyNMesh(256, 256, 10, 10);
349        mScript.set_gMbyNMesh(mMbyNMesh);
350
351        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
352        FileA3D.IndexEntry entry = model.getIndexEntry(0);
353        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
354            Log.e("rs", "could not load model");
355        } else {
356            mTorus = (Mesh)entry.getObject();
357            mScript.set_gTorusMesh(mTorus);
358        }
359    }
360
361    private void initSamplers() {
362        Sampler.Builder bs = new Sampler.Builder(mRS);
363        bs.setMinification(Sampler.Value.LINEAR);
364        bs.setMagnification(Sampler.Value.LINEAR);
365        bs.setWrapS(Sampler.Value.WRAP);
366        bs.setWrapT(Sampler.Value.WRAP);
367        mLinearWrap = bs.create();
368
369        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
370        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
371        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
372
373        bs = new Sampler.Builder(mRS);
374        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
375        bs.setMagnification(Sampler.Value.LINEAR);
376        bs.setWrapS(Sampler.Value.WRAP);
377        bs.setWrapT(Sampler.Value.WRAP);
378        bs.setAnisotropy(8.0f);
379        mMipLinearAniso8 = bs.create();
380        bs.setAnisotropy(15.0f);
381        mMipLinearAniso15 = bs.create();
382
383        mScript.set_gLinearClamp(mLinearClamp);
384        mScript.set_gLinearWrap(mLinearWrap);
385        mScript.set_gMipLinearWrap(mMipLinearWrap);
386        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
387        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
388        mScript.set_gNearestClamp(mNearestClamp);
389    }
390
391    private void initProgramRaster() {
392        mCullBack = ProgramRaster.CULL_BACK(mRS);
393        mCullFront = ProgramRaster.CULL_FRONT(mRS);
394        mCullNone = ProgramRaster.CULL_NONE(mRS);
395
396        mScript.set_gCullBack(mCullBack);
397        mScript.set_gCullFront(mCullFront);
398        mScript.set_gCullNone(mCullNone);
399    }
400
401    private void initRS() {
402
403        mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates);
404
405        mMaxModes = mScript.get_gMaxModes();
406
407        initSamplers();
408        initProgramStore();
409        initProgramFragment();
410        initProgramVertex();
411        initFonts();
412        loadImages();
413        initMesh();
414        initProgramRaster();
415        initCustomShaders();
416
417        mRS.bindRootScript(mScript);
418    }
419}
420
421
422
423