1 package com.android.galaxy4; 2 3 import android.content.res.Resources; 4 import android.graphics.Bitmap; 5 import android.graphics.BitmapFactory; 6 import android.renderscript.Allocation; 7 import android.renderscript.Matrix4f; 8 import android.renderscript.Mesh; 9 import android.renderscript.ProgramFragment; 10 import android.renderscript.ProgramFragmentFixedFunction; 11 import android.renderscript.ProgramRaster; 12 import android.renderscript.ProgramStore; 13 import android.renderscript.Sampler; 14 import android.renderscript.ProgramStore.BlendDstFunc; 15 import android.renderscript.ProgramStore.BlendSrcFunc; 16 import android.renderscript.ProgramVertex; 17 import android.renderscript.ProgramVertexFixedFunction; 18 import android.renderscript.RenderScriptGL; 19 import android.renderscript.ProgramVertexFixedFunction.Builder; 20 import android.util.Log; 21 import android.renderscript.Program; 22 import static android.renderscript.Sampler.Value.*; 23 24 public class GalaxyRS { 25 public static final int BG_STAR_COUNT = 11000; 26 public static final int SPACE_CLOUDSTAR_COUNT = 25; 27 public static final int STATIC_STAR_COUNT = 50; 28 private Resources mRes; 29 30 private RenderScriptGL mRS; 31 private ScriptC_galaxy mScript; 32 33 private ScriptField_VpConsts mPvConsts; 34 private ScriptField_Particle mSpaceClouds; 35 private ScriptField_Particle mBgStars; 36 private ScriptField_Particle mStaticStars; 37 private Mesh mSpaceCloudsMesh; 38 private Mesh mBgStarsMesh; 39 private Mesh mStaticStarsMesh; 40 41 private int mHeight; 42 private int mWidth; 43 private boolean mInited = false; 44 private int mDensityDPI; 45 46 private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); 47 48 private Allocation mCloudAllocation; 49 private Allocation mStaticStarAllocation; 50 private Allocation mStaticStar2Allocation; 51 private Allocation mBgAllocation; 52 53 public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) { 54 if (!mInited) { 55 mDensityDPI = dpi; 56 57 mRS = rs; 58 mRes = res; 59 60 mWidth = width; 61 mHeight = height; 62 63 mOptionsARGB.inScaled = false; 64 mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; 65 66 mSpaceClouds = new ScriptField_Particle(mRS, SPACE_CLOUDSTAR_COUNT); 67 Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); 68 smb.addVertexAllocation(mSpaceClouds.getAllocation()); 69 smb.addIndexSetType(Mesh.Primitive.POINT); 70 mSpaceCloudsMesh = smb.create(); 71 72 mBgStars = new ScriptField_Particle(mRS, BG_STAR_COUNT); 73 Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS); 74 smb2.addVertexAllocation(mBgStars.getAllocation()); 75 smb2.addIndexSetType(Mesh.Primitive.POINT); 76 mBgStarsMesh = smb2.create(); 77 78 mStaticStars = new ScriptField_Particle(mRS, STATIC_STAR_COUNT); 79 Mesh.AllocationBuilder smb3 = new Mesh.AllocationBuilder(mRS); 80 smb3.addVertexAllocation(mStaticStars.getAllocation()); 81 smb3.addIndexSetType(Mesh.Primitive.POINT); 82 mStaticStarsMesh = smb3.create(); 83 84 mScript = new ScriptC_galaxy(mRS, mRes, R.raw.galaxy); 85 mScript.set_spaceCloudsMesh(mSpaceCloudsMesh); 86 mScript.bind_spaceClouds(mSpaceClouds); 87 mScript.set_bgStarsMesh(mBgStarsMesh); 88 mScript.bind_bgStars(mBgStars); 89 mScript.set_staticStarsMesh(mStaticStarsMesh); 90 mScript.bind_staticStars(mStaticStars); 91 92 mPvConsts = new ScriptField_VpConsts(mRS, 1); 93 94 createProgramVertex(); 95 createProgramRaster(); 96 createProgramFragmentStore(); 97 createProgramFragment(); 98 99 loadTextures(); 100 101 mScript.set_densityDPI(mDensityDPI); 102 mRS.bindRootScript(mScript); 103 mScript.invoke_positionParticles(); 104 mInited = true; 105 } 106 } 107 108 private Allocation loadTexture(int id) { 109 final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id); 110 return allocation; 111 } 112 113 private void loadTextures() { 114 mStaticStarAllocation = loadTexture(R.drawable.staticstar); 115 mStaticStar2Allocation = loadTexture(R.drawable.staticstar2); 116 mCloudAllocation = loadTexture(R.drawable.cloud); 117 mBgAllocation = loadTexture(R.drawable.bg); 118 mScript.set_textureSpaceCloud(mCloudAllocation); 119 mScript.set_textureStaticStar(mStaticStarAllocation); 120 mScript.set_textureStaticStar2(mStaticStar2Allocation); 121 mScript.set_textureBg(mBgAllocation); 122 } 123 124 private Matrix4f getProjectionNormalized(int w, int h) { 125 Matrix4f m1 = new Matrix4f(); 126 Matrix4f m2 = new Matrix4f(); 127 128 if (w > h) { 129 float aspect = ((float) w) / h; 130 m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100); 131 } else { 132 float aspect = ((float) h) / w; 133 m1.loadFrustum(-1, 1, -aspect, aspect, 1, 100); 134 } 135 136 m2.loadRotate(180, 0, 1, 0); 137 m1.loadMultiply(m1, m2); 138 m2.loadScale(-1, 1, 1); 139 m1.loadMultiply(m1, m2); 140 m2.loadTranslate(0, 0, 1); 141 m1.loadMultiply(m1, m2); 142 return m1; 143 } 144 145 private void updateProjectionMatrices(int w, int h) { 146 mWidth = w; 147 mHeight = h; 148 Matrix4f proj = new Matrix4f(); 149 proj.loadOrthoWindow(mWidth, mHeight); 150 Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight); 151 ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); 152 i.MVP = projNorm; 153 i.scaleSize = mDensityDPI / 240.0f; 154 mPvConsts.set(i, 0, true); 155 mScript.invoke_positionParticles(); 156 } 157 158 public void createProgramVertex() { 159 ProgramVertexFixedFunction.Constants mPvOrthoAlloc = 160 new ProgramVertexFixedFunction.Constants(mRS); 161 Matrix4f proj = new Matrix4f(); 162 proj.loadOrthoWindow(mWidth, mHeight); 163 mPvOrthoAlloc.setProjection(proj); 164 165 ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); 166 ProgramVertex pv = pvb.create(); 167 ((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc); 168 mScript.set_vertBg(pv); 169 updateProjectionMatrices(mWidth, mHeight); 170 171 // cloud 172 ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS); 173 builder.setShader(mRes, R.raw.spacecloud_vs); 174 builder.addConstant(mPvConsts.getType()); 175 builder.addInput(mSpaceCloudsMesh.getVertexAllocation(0).getType().getElement()); 176 ProgramVertex pvs = builder.create(); 177 pvs.bindConstants(mPvConsts.getAllocation(), 0); 178 mRS.bindProgramVertex(pvs); 179 180 mScript.set_vertSpaceClouds(pvs); 181 182 // bg stars 183 builder = new ProgramVertex.Builder(mRS); 184 builder.setShader(mRes, R.raw.bgstar_vs); 185 builder.addConstant(mPvConsts.getType()); 186 builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement()); 187 pvs = builder.create(); 188 pvs.bindConstants(mPvConsts.getAllocation(), 0); 189 mRS.bindProgramVertex(pvs); 190 mScript.set_vertBgStars(pvs); 191 192 // static stars 193 builder = new ProgramVertex.Builder(mRS); 194 builder.setShader(mRes, R.raw.staticstar_vs); 195 builder.addConstant(mPvConsts.getType()); 196 builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement()); 197 pvs = builder.create(); 198 pvs.bindConstants(mPvConsts.getAllocation(), 0); 199 mRS.bindProgramVertex(pvs); 200 mScript.set_vertStaticStars(pvs); 201 } 202 203 private void createProgramFragment() { 204 // bg 205 Sampler.Builder samplerBuilder = new Sampler.Builder(mRS); 206 samplerBuilder.setMinification(LINEAR); 207 samplerBuilder.setMagnification(LINEAR); 208 samplerBuilder.setWrapS(WRAP); 209 samplerBuilder.setWrapT(WRAP); 210 Sampler sn = samplerBuilder.create(); 211 ProgramFragmentFixedFunction.Builder builderff = 212 new ProgramFragmentFixedFunction.Builder(mRS); 213 builderff = new ProgramFragmentFixedFunction.Builder(mRS); 214 builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 215 ProgramFragmentFixedFunction.Builder.Format.RGB, 0); 216 ProgramFragment pfff = builderff.create(); 217 mScript.set_fragBg(pfff); 218 pfff.bindSampler(sn, 0); 219 220 // cloud 221 ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS); 222 223 builder.setShader(mRes, R.raw.spacecloud_fs); 224 builder.addTexture(Program.TextureType.TEXTURE_2D); 225 226 ProgramFragment pf = builder.create(); 227 pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); 228 mScript.set_fragSpaceClouds(pf); 229 230 // bg stars 231 builder = new ProgramFragment.Builder(mRS); 232 builder.setShader(mRes, R.raw.bgstar_fs); 233 pf = builder.create(); 234 mScript.set_fragBgStars(pf); 235 236 // static stars 237 builder = new ProgramFragment.Builder(mRS); 238 builder.setShader(mRes, R.raw.staticstar_fs); 239 builder.addTexture(Program.TextureType.TEXTURE_2D); 240 builder.addTexture(Program.TextureType.TEXTURE_2D); 241 pf = builder.create(); 242 mScript.set_fragStaticStars(pf); 243 } 244 245 private void createProgramRaster() { 246 ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS); 247 builder.setPointSpriteEnabled(true); 248 ProgramRaster pr = builder.create(); 249 mRS.bindProgramRaster(pr); 250 } 251 252 private void createProgramFragmentStore() { 253 ProgramStore.Builder builder = new ProgramStore.Builder(mRS); 254 builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); 255 mRS.bindProgramStore(builder.create()); 256 } 257 258 public void start() { 259 mRS.bindRootScript(mScript); 260 } 261 262 public void stop() { 263 mRS.bindRootScript(null); 264 } 265 266 public void resize(int width, int height) { 267 mWidth = width; 268 mHeight = height; 269 createProgramVertex(); 270 } 271 }