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.android.film;
18
19import java.io.Writer;
20
21import android.content.Context;
22import android.content.res.Resources;
23import android.graphics.Bitmap;
24import android.util.Log;
25
26import android.renderscript.*;
27
28public class FilmRS {
29    class StripPosition {
30        public float translate;
31        public float rotate;
32        public float focus;
33        public int triangleOffsetCount;
34    }
35    StripPosition mPos = new StripPosition();
36
37
38    private final int STATE_LAST_FOCUS = 1;
39
40    public FilmRS() {
41    }
42
43    public void init(RenderScript rs, Resources res, int width, int height) {
44        mRS = rs;
45        mRes = res;
46        initRS();
47    }
48
49    public void setFilmStripPosition(int x, int y)
50    {
51        if (x < 50) {
52            x = 50;
53        }
54        if (x > 270) {
55            x = 270;
56        }
57
58        float anim = ((float)x-50) / 270.f;
59        mPos.translate = 2f * anim + 0.5f;   // translation
60        mPos.rotate = (anim * 40);  // rotation
61        mPos.focus = ((float)y) / 16.f - 10.f;  // focusPos
62        mPos.triangleOffsetCount = mFSM.mTriangleOffsetsCount;
63        mAllocPos.data(mPos);
64    }
65
66
67    private Resources mRes;
68    private RenderScript mRS;
69    private Script mScriptStrip;
70    private Script mScriptImage;
71    private Sampler mSampler;
72    private ProgramStore mPSBackground;
73    private ProgramStore mPSImages;
74    private ProgramFragment mPFBackground;
75    private ProgramFragment mPFImages;
76    private ProgramVertex mPVBackground;
77    private ProgramVertex mPVImages;
78    private ProgramVertex.MatrixAllocation mPVA;
79    private Type mStripPositionType;
80
81    private Allocation mImages[];
82    private Allocation mAllocIDs;
83    private Allocation mAllocPos;
84    private Allocation mAllocState;
85    private Allocation mAllocPV;
86    private Allocation mAllocOffsetsTex;
87    private Allocation mAllocOffsets;
88
89    private SimpleMesh mMesh;
90    private Light mLight;
91
92    private FilmStripMesh mFSM;
93
94    private int[] mBufferIDs;
95    private float[] mBufferPos = new float[3];
96    private int[] mBufferState;
97
98    private void initPFS() {
99        ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null);
100
101        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
102        b.setDitherEnable(true);
103        b.setDepthMask(true);
104        mPSBackground = b.create();
105        mPSBackground.setName("PSBackground");
106
107        b.setDepthFunc(ProgramStore.DepthFunc.EQUAL);
108        b.setDitherEnable(false);
109        b.setDepthMask(false);
110        b.setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
111                       ProgramStore.BlendDstFunc.ONE);
112        mPSImages = b.create();
113        mPSImages.setName("PSImages");
114    }
115
116    private void initPF() {
117        Sampler.Builder bs = new Sampler.Builder(mRS);
118        bs.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR);
119        bs.setMag(Sampler.Value.LINEAR);
120        bs.setWrapS(Sampler.Value.CLAMP);
121        bs.setWrapT(Sampler.Value.WRAP);
122        mSampler = bs.create();
123
124        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS, null, null);
125
126        mPFBackground = b.create();
127        mPFBackground.setName("PFBackground");
128
129        b.setTexEnable(true, 0);
130        b.setTexEnvMode(ProgramFragment.EnvMode.REPLACE, 0);
131        mPFImages = b.create();
132        mPFImages.bindSampler(mSampler, 0);
133        mPFImages.setName("PFImages");
134    }
135
136    private void initPV() {
137        mLight = (new Light.Builder(mRS)).create();
138        mLight.setPosition(0, -0.5f, -1.0f);
139
140        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
141        pvb.addLight(mLight);
142        mPVBackground = pvb.create();
143        mPVBackground.setName("PVBackground");
144
145        pvb = new ProgramVertex.Builder(mRS, null, null);
146        pvb.setTextureMatrixEnable(true);
147        mPVImages = pvb.create();
148        mPVImages.setName("PVImages");
149    }
150
151    private void loadImages() {
152        mBufferIDs = new int[13];
153        mImages = new Allocation[13];
154        mAllocIDs = Allocation.createSized(mRS,
155            Element.USER_F32(mRS), mBufferIDs.length);
156
157        Element ie = Element.RGB_565(mRS);
158        mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true);
159        mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true);
160        mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true);
161        mImages[3] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p04, ie, true);
162        mImages[4] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p05, ie, true);
163        mImages[5] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p06, ie, true);
164        mImages[6] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p07, ie, true);
165        mImages[7] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p08, ie, true);
166        mImages[8] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p09, ie, true);
167        mImages[9] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p10, ie, true);
168        mImages[10] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p11, ie, true);
169        mImages[11] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p12, ie, true);
170        mImages[12] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p13, ie, true);
171
172        int black[] = new int[1024];
173        for(int ct=0; ct < mImages.length; ct++) {
174            Allocation.Adapter2D a = mImages[ct].createAdapter2D();
175
176            int size = 512;
177            int mip = 0;
178            while(size >= 2) {
179                a.subData(0, 0, 2, size, black);
180                a.subData(size-2, 0, 2, size, black);
181                a.subData(0, 0, size, 2, black);
182                a.subData(0, size-2, size, 2, black);
183                size >>= 1;
184                mip++;
185                a.setConstraint(Dimension.LOD, mip);
186            }
187
188            mImages[ct].uploadToTexture(1);
189            mBufferIDs[ct] = mImages[ct].getID();
190        }
191        mAllocIDs.data(mBufferIDs);
192    }
193
194    private void initState()
195    {
196        mBufferState = new int[10];
197        mAllocState = Allocation.createSized(mRS,
198            Element.USER_F32(mRS), mBufferState.length);
199        mBufferState[STATE_LAST_FOCUS] = -1;
200        mAllocState.data(mBufferState);
201    }
202
203    private void initRS() {
204        mFSM = new FilmStripMesh();
205        mMesh = mFSM.init(mRS);
206        mMesh.setName("mesh");
207
208        initPFS();
209        initPF();
210        initPV();
211
212        Log.e("rs", "Done loading named");
213
214        mStripPositionType = Type.createFromClass(mRS, StripPosition.class, 1);
215
216        ScriptC.Builder sb = new ScriptC.Builder(mRS);
217        sb.setScript(mRes, R.raw.filmstrip);
218        sb.setRoot(true);
219        sb.setType(mStripPositionType, "Pos", 1);
220        mScriptStrip = sb.create();
221        mScriptStrip.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
222
223        mAllocPos = Allocation.createTyped(mRS, mStripPositionType);
224
225        loadImages();
226        initState();
227
228        mPVA = new ProgramVertex.MatrixAllocation(mRS);
229        mPVBackground.bindAllocation(mPVA);
230        mPVImages.bindAllocation(mPVA);
231        mPVA.setupProjectionNormalized(320, 480);
232
233
234        mScriptStrip.bindAllocation(mAllocIDs, 0);
235        mScriptStrip.bindAllocation(mAllocPos, 1);
236        mScriptStrip.bindAllocation(mAllocState, 2);
237        mScriptStrip.bindAllocation(mPVA.mAlloc, 3);
238
239
240        mAllocOffsets = Allocation.createSized(mRS,
241            Element.USER_I32(mRS), mFSM.mTriangleOffsets.length);
242        mAllocOffsets.data(mFSM.mTriangleOffsets);
243        mScriptStrip.bindAllocation(mAllocOffsets, 4);
244
245        mAllocOffsetsTex = Allocation.createSized(mRS,
246            Element.USER_F32(mRS), mFSM.mTriangleOffsetsTex.length);
247        mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex);
248        mScriptStrip.bindAllocation(mAllocOffsetsTex, 5);
249
250        setFilmStripPosition(0, 0);
251        mRS.contextBindRootScript(mScriptStrip);
252    }
253}
254
255
256
257