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