blob: f6136ae78b1b79dc5fa64073d4d8ec1af580bc3b [file] [log] [blame]
package com.android.galaxy4;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.renderscript.Allocation;
import android.renderscript.Matrix4f;
import android.renderscript.Mesh;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramFragmentFixedFunction;
import android.renderscript.ProgramRaster;
import android.renderscript.ProgramStore;
import android.renderscript.Sampler;
import android.renderscript.ProgramStore.BlendDstFunc;
import android.renderscript.ProgramStore.BlendSrcFunc;
import android.renderscript.ProgramVertex;
import android.renderscript.ProgramVertexFixedFunction;
import android.renderscript.RenderScriptGL;
import android.renderscript.ProgramVertexFixedFunction.Builder;
import android.util.Log;
import android.renderscript.Program;
import static android.renderscript.Sampler.Value.*;
public class GalaxyRS {
public static final int BG_STAR_COUNT = 11000;
public static final int SPACE_CLOUDSTAR_COUNT = 25;
public static final int STATIC_STAR_COUNT = 50;
private Resources mRes;
private RenderScriptGL mRS;
private ScriptC_galaxy mScript;
private ScriptField_VpConsts mPvConsts;
private ScriptField_Particle mSpaceClouds;
private ScriptField_Particle mBgStars;
private ScriptField_Particle mStaticStars;
private Mesh mSpaceCloudsMesh;
private Mesh mBgStarsMesh;
private Mesh mStaticStarsMesh;
private int mHeight;
private int mWidth;
private boolean mInited = false;
private int mDensityDPI;
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
private Allocation mCloudAllocation;
private Allocation mStaticStarAllocation;
private Allocation mStaticStar2Allocation;
private Allocation mBgAllocation;
public void init(int dpi, RenderScriptGL rs, Resources res, int width, int height) {
if (!mInited) {
mDensityDPI = dpi;
mRS = rs;
mRes = res;
mWidth = width;
mHeight = height;
mOptionsARGB.inScaled = false;
mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
mSpaceClouds = new ScriptField_Particle(mRS, SPACE_CLOUDSTAR_COUNT);
Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
smb.addVertexAllocation(mSpaceClouds.getAllocation());
smb.addIndexSetType(Mesh.Primitive.POINT);
mSpaceCloudsMesh = smb.create();
mBgStars = new ScriptField_Particle(mRS, BG_STAR_COUNT);
Mesh.AllocationBuilder smb2 = new Mesh.AllocationBuilder(mRS);
smb2.addVertexAllocation(mBgStars.getAllocation());
smb2.addIndexSetType(Mesh.Primitive.POINT);
mBgStarsMesh = smb2.create();
mStaticStars = new ScriptField_Particle(mRS, STATIC_STAR_COUNT);
Mesh.AllocationBuilder smb3 = new Mesh.AllocationBuilder(mRS);
smb3.addVertexAllocation(mStaticStars.getAllocation());
smb3.addIndexSetType(Mesh.Primitive.POINT);
mStaticStarsMesh = smb3.create();
mScript = new ScriptC_galaxy(mRS, mRes, R.raw.galaxy);
mScript.set_spaceCloudsMesh(mSpaceCloudsMesh);
mScript.bind_spaceClouds(mSpaceClouds);
mScript.set_bgStarsMesh(mBgStarsMesh);
mScript.bind_bgStars(mBgStars);
mScript.set_staticStarsMesh(mStaticStarsMesh);
mScript.bind_staticStars(mStaticStars);
mPvConsts = new ScriptField_VpConsts(mRS, 1);
createProgramVertex();
createProgramRaster();
createProgramFragmentStore();
createProgramFragment();
loadTextures();
mScript.set_densityDPI(mDensityDPI);
mRS.bindRootScript(mScript);
mScript.invoke_positionParticles();
mInited = true;
}
}
private Allocation loadTexture(int id) {
final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, id,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_GRAPHICS_TEXTURE);
return allocation;
}
private void loadTextures() {
mStaticStarAllocation = loadTexture(R.drawable.staticstar);
mStaticStar2Allocation = loadTexture(R.drawable.staticstar2);
mCloudAllocation = loadTexture(R.drawable.cloud);
mBgAllocation = loadTexture(R.drawable.bg);
mScript.set_textureSpaceCloud(mCloudAllocation);
mScript.set_textureStaticStar(mStaticStarAllocation);
mScript.set_textureStaticStar2(mStaticStar2Allocation);
mScript.set_textureBg(mBgAllocation);
}
private Matrix4f getProjectionNormalized(int w, int h) {
Matrix4f m1 = new Matrix4f();
Matrix4f m2 = new Matrix4f();
if (w > h) {
float aspect = ((float) w) / h;
m1.loadFrustum(-aspect, aspect, -1, 1, 1, 100);
} else {
float aspect = ((float) h) / w;
m1.loadFrustum(-1, 1, -aspect, aspect, 1, 100);
}
m2.loadRotate(180, 0, 1, 0);
m1.loadMultiply(m1, m2);
m2.loadScale(-1, 1, 1);
m1.loadMultiply(m1, m2);
m2.loadTranslate(0, 0, 1);
m1.loadMultiply(m1, m2);
return m1;
}
private void updateProjectionMatrices(int w, int h) {
mWidth = w;
mHeight = h;
Matrix4f proj = new Matrix4f();
proj.loadOrthoWindow(mWidth, mHeight);
Matrix4f projNorm = getProjectionNormalized(mWidth, mHeight);
ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
i.MVP = projNorm;
i.scaleSize = mDensityDPI / 240.0f;
mPvConsts.set(i, 0, true);
mScript.invoke_positionParticles();
}
public void createProgramVertex() {
ProgramVertexFixedFunction.Constants mPvOrthoAlloc =
new ProgramVertexFixedFunction.Constants(mRS);
Matrix4f proj = new Matrix4f();
proj.loadOrthoWindow(mWidth, mHeight);
mPvOrthoAlloc.setProjection(proj);
ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
ProgramVertex pv = pvb.create();
((ProgramVertexFixedFunction) pv).bindConstants(mPvOrthoAlloc);
mScript.set_vertBg(pv);
updateProjectionMatrices(mWidth, mHeight);
// cloud
ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS);
builder.setShader(mRes, R.raw.spacecloud_vs);
builder.addConstant(mPvConsts.getType());
builder.addInput(mSpaceCloudsMesh.getVertexAllocation(0).getType().getElement());
ProgramVertex pvs = builder.create();
pvs.bindConstants(mPvConsts.getAllocation(), 0);
mRS.bindProgramVertex(pvs);
mScript.set_vertSpaceClouds(pvs);
// bg stars
builder = new ProgramVertex.Builder(mRS);
builder.setShader(mRes, R.raw.bgstar_vs);
builder.addConstant(mPvConsts.getType());
builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement());
pvs = builder.create();
pvs.bindConstants(mPvConsts.getAllocation(), 0);
mRS.bindProgramVertex(pvs);
mScript.set_vertBgStars(pvs);
// static stars
builder = new ProgramVertex.Builder(mRS);
builder.setShader(mRes, R.raw.staticstar_vs);
builder.addConstant(mPvConsts.getType());
builder.addInput(mBgStarsMesh.getVertexAllocation(0).getType().getElement());
pvs = builder.create();
pvs.bindConstants(mPvConsts.getAllocation(), 0);
mRS.bindProgramVertex(pvs);
mScript.set_vertStaticStars(pvs);
}
private void createProgramFragment() {
// bg
Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
samplerBuilder.setMinification(LINEAR);
samplerBuilder.setMagnification(LINEAR);
samplerBuilder.setWrapS(WRAP);
samplerBuilder.setWrapT(WRAP);
Sampler sn = samplerBuilder.create();
ProgramFragmentFixedFunction.Builder builderff =
new ProgramFragmentFixedFunction.Builder(mRS);
builderff = new ProgramFragmentFixedFunction.Builder(mRS);
builderff.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
ProgramFragment pfff = builderff.create();
mScript.set_fragBg(pfff);
pfff.bindSampler(sn, 0);
// cloud
ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
builder.setShader(mRes, R.raw.spacecloud_fs);
builder.addTexture(Program.TextureType.TEXTURE_2D);
ProgramFragment pf = builder.create();
pf.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
mScript.set_fragSpaceClouds(pf);
// bg stars
builder = new ProgramFragment.Builder(mRS);
builder.setShader(mRes, R.raw.bgstar_fs);
pf = builder.create();
mScript.set_fragBgStars(pf);
// static stars
builder = new ProgramFragment.Builder(mRS);
builder.setShader(mRes, R.raw.staticstar_fs);
builder.addTexture(Program.TextureType.TEXTURE_2D);
builder.addTexture(Program.TextureType.TEXTURE_2D);
pf = builder.create();
mScript.set_fragStaticStars(pf);
}
private void createProgramRaster() {
ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
builder.setPointSpriteEnabled(true);
ProgramRaster pr = builder.create();
mRS.bindProgramRaster(pr);
}
private void createProgramFragmentStore() {
ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
mRS.bindProgramStore(builder.create());
}
public void start() {
mRS.bindRootScript(mScript);
}
public void stop() {
mRS.bindRootScript(null);
}
public void resize(int width, int height) {
mWidth = width;
mHeight = height;
createProgramVertex();
}
}