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 Allocation.MipmapControl.MIPMAP_NONE, 111 Allocation.USAGE_GRAPHICS_TEXTURE); 112 return allocation; 113 } 114 115 private void loadTextures() { 116 mStaticStarAllocation = loadTexture(R.drawable.staticstar); 117 mStaticStar2Allocation = loadTexture(R.drawable.staticstar2); 118 mCloudAllocation = loadTexture(R.drawable.cloud); 119 mBgAllocation = loadTexture(R.drawable.bg); 120 mScript.set_textureSpaceCloud(mCloudAllocation); 121 mScript.set_textureStaticStar(mStaticStarAllocation); 122 mScript.set_textureStaticStar2(mStaticStar2Allocation); 123 mScript.set_textureBg(mBgAllocation); 124 } 125 126 private Matrix4f getProjectionNormalized(int w, int h) { 127 Matrix4f m1 = new Matrix4f(); 128 Matrix4f m2 = new Matrix4f(); 129 130 if (w > h) { 131 float aspect = ((float) w) / h; 132 m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100); 133 } else { 134 float aspect = ((float) h) / w; 135 m1.loadFrustum(-1, 1, -aspect, aspect, 1, 100); 136 } 137 138 m2.loadRotate(180, 0, 1, 0); 139 m1.loadMultiply(m1, m2); 140 m2.loadScale(-1, 1, 1); 141 m1.loadMultiply(m1, m2); 142 m2.loadTranslate(0, 0, 1); 143 m1.loadMultiply(m1, m2); 144 return m1; 145 } 146 147 private void updateProjectionMatrices(int w, int h) { 148 mWidth = w; 149 mHeight = h; 150 Matrix4f proj = new Matrix4f(); 151 proj.loadOrthoWindow(mWidth, mHeight); 152 Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight); 153 ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); 154 i.MVP = projNorm; 155 i.scaleSize = mDensityDPI / 120.0f; 156 mPvConsts.set(i, 0, true); 157 mScript.invoke_positionParticles(); 158 } 159 160 public void createProgramVertex() { 161 ProgramVertexFixedFunction.Constants mPvOrthoAlloc = 162 new ProgramVertexFixedFunction.Constants(mRS); 163 Matrix4f proj = new Matrix4f(); 164 proj.loadOrthoWindow(mWidth, mHeight); 165 mPvOrthoAlloc.setProjection(proj); 166 167 ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); 168 ProgramVertex pv = pvb.create(); 169 ((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc); 170 mScript.set_vertBg(pv); 171 updateProjectionMatrices(mWidth, mHeight); 172 173 // cloud 174 ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS); 175 builder.setShader(mRes, R.raw.spacecloud_vs); 176 builder.addConstant(mPvConsts.getType()); 177 builder.addInput(mSpaceCloudsMesh.getVertexAllocation(0).getType().getElement()); 178 ProgramVertex pvs = builder.create(); 179 pvs.bindConstants(mPvConsts.getAllocation(), 0); 180 mRS.bindProgramVertex(pvs); 181 182 mScript.set_vertSpaceClouds(pvs); 183 184 // bg stars 185 builder = new ProgramVertex.Builder(mRS); 186 builder.setShader(mRes, R.raw.bgstar_vs); 187 builder.addConstant(mPvConsts.getType()); 188 builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement()); 189 pvs = builder.create(); 190 pvs.bindConstants(mPvConsts.getAllocation(), 0); 191 mRS.bindProgramVertex(pvs); 192 mScript.set_vertBgStars(pvs); 193 194 // static stars 195 builder = new ProgramVertex.Builder(mRS); 196 builder.setShader(mRes, R.raw.staticstar_vs); 197 builder.addConstant(mPvConsts.getType()); 198 builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement()); 199 pvs = builder.create(); 200 pvs.bindConstants(mPvConsts.getAllocation(), 0); 201 mRS.bindProgramVertex(pvs); 202 mScript.set_vertStaticStars(pvs); 203 } 204 205 private void createProgramFragment() { 206 // bg 207 Sampler.Builder samplerBuilder = new Sampler.Builder(mRS); 208 samplerBuilder.setMinification(LINEAR); 209 samplerBuilder.setMagnification(LINEAR); 210 samplerBuilder.setWrapS(WRAP); 211 samplerBuilder.setWrapT(WRAP); 212 Sampler sn = samplerBuilder.create(); 213 ProgramFragmentFixedFunction.Builder builderff = 214 new ProgramFragmentFixedFunction.Builder(mRS); 215 builderff = new ProgramFragmentFixedFunction.Builder(mRS); 216 builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 217 ProgramFragmentFixedFunction.Builder.Format.RGB, 0); 218 ProgramFragment pfff = builderff.create(); 219 mScript.set_fragBg(pfff); 220 pfff.bindSampler(sn, 0); 221 222 // cloud 223 ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS); 224 225 builder.setShader(mRes, R.raw.spacecloud_fs); 226 builder.addTexture(Program.TextureType.TEXTURE_2D); 227 228 ProgramFragment pf = builder.create(); 229 pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); 230 mScript.set_fragSpaceClouds(pf); 231 232 // bg stars 233 builder = new ProgramFragment.Builder(mRS); 234 builder.setShader(mRes, R.raw.bgstar_fs); 235 pf = builder.create(); 236 mScript.set_fragBgStars(pf); 237 238 // static stars 239 builder = new ProgramFragment.Builder(mRS); 240 builder.setShader(mRes, R.raw.staticstar_fs); 241 builder.addTexture(Program.TextureType.TEXTURE_2D); 242 builder.addTexture(Program.TextureType.TEXTURE_2D); 243 pf = builder.create(); 244 mScript.set_fragStaticStars(pf); 245 } 246 247 private void createProgramRaster() { 248 ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS); 249 builder.setPointSpriteEnabled(true); 250 ProgramRaster pr = builder.create(); 251 mRS.bindProgramRaster(pr); 252 } 253 254 private void createProgramFragmentStore() { 255 ProgramStore.Builder builder = new ProgramStore.Builder(mRS); 256 builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); 257 mRS.bindProgramStore(builder.create()); 258 } 259 260 public void start() { 261 mRS.bindRootScript(mScript); 262 } 263 264 public void stop() { 265 mRS.bindRootScript(null); 266 } 267 268 public void resize(int width, int height) { 269 mWidth = width; 270 mHeight = height; 271 createProgramVertex(); 272 } 273 }