#define ELLIPSE_RATIO 0.892f
+float angle;
+float distance;
+
+void init() {
+ angle = 0.0f;
+ distance = 0.0f;
+}
+
void drawSpace(float xOffset, int width, int height) {
bindTexture(NAMED_PFBackground, 0, NAMED_TSpace);
drawQuadTexCoords(
}
void drawLights(float xOffset, int width, int height) {
- float x = (width - 512.0f) * 0.5f + xOffset;
- float y = (height - 512.0f) * 0.5f;
-
- // increase the size of the texture by 5% on each side
- x -= 512.0f * 0.05f;
-
+ bindProgramVertex(NAMED_PVStars);
bindProgramFragment(NAMED_PFBackground);
bindTexture(NAMED_PFBackground, 0, NAMED_TLight1);
- drawQuad(x + 512.0f * 1.1f, y , 0.0f,
- x , y , 0.0f,
- x , y + 512.0f, 0.0f,
- x + 512.0f * 1.1f, y + 512.0f, 0.0f);
+
+ float scale = 512.0f / width;
+ float x = -scale + xOffset - scale * 0.05f;
+ float y = -scale;
+
+ scale *= 2.0f;
+
+ drawQuad(x, y, 0.0f,
+ x + scale * 1.1f, y, 0.0f,
+ x + scale * 1.1f, y + scale, 0.0f,
+ x, y + scale, 0.0f);
}
void drawParticles(float xOffset, int width, int height) {
- bindProgramFragment(NAMED_PFBasic);
+ bindProgramVertex(NAMED_PVStars);
+ bindProgramFragment(NAMED_PFStars);
bindProgramFragmentStore(NAMED_PFSLights);
+ bindTexture(NAMED_PFStars, 0, NAMED_TFlares);
+
+ float matrix[16];
+ matrixLoadTranslate(matrix, 0.0f, 0.0f, 10.0f - 6.0f * distance);
+ matrixScale(matrix, 6.15f, 6.0f, 1.0f);
+ matrixRotate(matrix, angle, 1.0f, 0.5f, 0.0f);
+ vpLoadModelMatrix(matrix);
+
+ // quadratic attenuation
+ pointAttenuation(0.1f, 0.0f, 0.06f);
int radius = State->galaxyRadius;
int particlesCount = State->particlesCount;
- float w = width * 0.5f + xOffset;
- float h = height * 0.5f;
+ float w = xOffset;
- int i = 0;
struct Stars_s *star = Stars;
- struct Parts_s *vtx = Parts;
+ struct Particles_s *vtx = Particles;
+
+ int i = 0;
for ( ; i < particlesCount; i++) {
float a = star->angle + star->speed;
float x = star->distance * sinf(a);
float y = star->distance * cosf(a) * ELLIPSE_RATIO;
vtx->x = star->t * x + star->s * y + w;
- vtx->y = star->s * x - star->t * y + h;
+ vtx->y = star->s * x - star->t * y;
star->angle = a;
- star ++;
- vtx ++;
+ star++;
+ vtx++;
}
uploadToBufferObject(NAMED_ParticlesBuffer);
int width = State->width;
int height = State->height;
- float w = width * 0.5f;
- float x = lerpf(w, -w, State->xOffset);
+ float x = lerpf(1.0f, -1.0f, State->xOffset);
drawSpace(x, width, height);
drawParticles(x, width, height);
drawLights(x, width, height);
+
+// if (angle < 68.0f) {
+// angle += 0.4f;
+// distance = angle / 68.0f;
+// }
+
return 1;
}
import android.renderscript.SimpleMesh;
import android.renderscript.Primitive;
import android.renderscript.Type;
+import static android.renderscript.Sampler.Value.LINEAR;
import static android.renderscript.Sampler.Value.NEAREST;
import static android.renderscript.Sampler.Value.WRAP;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendSrcFunc;
import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.Element.*;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
import static android.util.MathUtils.*;
import java.util.TimeZone;
private static final int RSID_PARTICLES = 1;
private static final int RSID_PARTICLES_BUFFER = 2;
- private static final int TEXTURES_COUNT = 2;
+ private static final int TEXTURES_COUNT = 3;
private static final int RSID_TEXTURE_SPACE = 0;
private static final int RSID_TEXTURE_LIGHT1 = 1;
-
-
- private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+ private static final int RSID_TEXTURE_FLARES = 2;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramFragment mPfBackground;
@SuppressWarnings({"FieldCanBeLocal"})
- private ProgramFragment mPfBasic;
+ private ProgramFragment mPfStars;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramStore mPfsBackground;
@SuppressWarnings({"FieldCanBeLocal"})
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertex mPvBackground;
@SuppressWarnings({"FieldCanBeLocal"})
+ private ProgramVertex mPvStars;
+ @SuppressWarnings({"FieldCanBeLocal"})
private Sampler mSampler;
@SuppressWarnings({"FieldCanBeLocal"})
+ private Sampler mStarSampler;
+ @SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
@SuppressWarnings({"FieldCanBeLocal"})
+ private ProgramVertex.MatrixAllocation mPvProjectionAlloc;
+ @SuppressWarnings({"FieldCanBeLocal"})
private Allocation[] mTextures;
private GalaxyState mGalaxyState;
@SuppressWarnings({"FieldCanBeLocal"})
private SimpleMesh mParticlesMesh;
- private final float[] mFloatData3 = new float[4];
+ private final float[] mFloatData = new float[5];
GalaxyRS(int width, int height) {
super(width, height);
- mOptionsARGB.inScaled = false;
- mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
}
@Override
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setType(mStateType, "State", RSID_STATE);
- sb.setType(mParticlesMesh.getVertexType(0), "Parts", RSID_PARTICLES_BUFFER);
+ sb.setType(mParticlesMesh.getVertexType(0), "Particles", RSID_PARTICLES_BUFFER);
sb.setType(mParticlesType, "Stars", RSID_PARTICLES);
sb.setScript(mResources, R.raw.galaxy);
sb.setRoot(true);
ScriptC script = sb.create();
- script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ script.setClearColor(1.0f, 0.0f, 0.0f, 1.0f);
script.setTimeZone(TimeZone.getDefault().getID());
script.bindAllocation(mState, RSID_STATE);
private void createParticlesMesh() {
final Builder elementBuilder = new Builder(mRS);
elementBuilder.addUNorm8RGBA("");
- elementBuilder.addFloatXY("");
- elementBuilder.addFloatPointSize("PS");
+ elementBuilder.addFloatXYZ("");
+ elementBuilder.addFloatPointSize("");
final Element vertexElement = elementBuilder.create();
final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
mParticlesType = Type.createFromClass(mRS, GalaxyParticle.class, PARTICLES_COUNT, "Particle");
mParticles = Allocation.createTyped(mRS, mParticlesType);
+ final float scale = GALAXY_RADIUS / (mWidth * 0.5f);
+
for (int i = 0; i < PARTICLES_COUNT; i ++) {
- createParticle(gp, i);
+ createParticle(gp, i, scale);
}
}
@SuppressWarnings({"PointlessArithmeticExpression"})
- private void createParticle(GalaxyParticle gp, int index) {
+ private void createParticle(GalaxyParticle gp, int index, float scale) {
float d = abs(randomGauss()) * GALAXY_RADIUS / 2.0f + random(-4.0f, 4.0f);
- //float z = randomGauss() * 0.5f * 0.8f * ((GALAXY_RADIUS - d) / (float) GALAXY_RADIUS);
- //z += 1.0f;
- float p = d * ELLIPSE_TWIST;
+ float z = randomGauss() * 0.5f * 0.8f * ((GALAXY_RADIUS - d) / (float) GALAXY_RADIUS);
+ float p = -d * ELLIPSE_TWIST;
- gp.angle = random(0.0f, (float) (Math.PI * 2.0));
- gp.distance = d;
- gp.speed = random(0.0015f, 0.0025f) * (0.5f + (0.5f * (float) GALAXY_RADIUS / d)) * 0.7f;
- gp.s = (float) Math.cos(p);
- gp.t = (float) Math.sin(p);
+ final float nd = d / (float) GALAXY_RADIUS;
- int red, green, blue;
+ int red, green, blue, alpha;
if (d < GALAXY_RADIUS / 3.0f) {
- red = (int) (220 + (d / (float) GALAXY_RADIUS) * 35);
+ red = (int) (220 + nd * 35);
green = 220;
blue = 220;
} else {
red = 180;
green = 180;
- blue = (int) constrain(140 + (d / (float) GALAXY_RADIUS) * 115, 140, 255);
+ blue = (int) constrain(140 + nd * 115, 140, 255);
}
+ alpha = (int) (40 + nd * 215);
+ int color = red | green << 8 | blue << 16 | alpha << 24;
- final int color = red | green << 8 | blue << 16 | 0xff000000;
+ // Map to the projection coordinates (viewport.x = -1.0 -> 1.0)
+ d = map(-4.0f, GALAXY_RADIUS + 4.0f, 0.0f, scale, d);
- final float[] floatData = mFloatData3;
+ gp.angle = random(0.0f, (float) (Math.PI * 2.0));
+ gp.distance = d;
+ gp.speed = random(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f;
+ gp.s = (float) Math.cos(p);
+ gp.t = (float) Math.sin(p);
+ final float[] floatData = mFloatData;
floatData[0] = Float.intBitsToFloat(color);
- floatData[3] = random(0.5f, 1.5f);
+ floatData[3] = z / 5.0f;
+ floatData[4] = random(1.2f, 2.1f) * 6f;
+
mParticlesBuffer.subData1D(index, 1, floatData);
mParticles.subData(index, gp);
}
} while (w >= 1.0f);
w = (float) Math.sqrt(-2.0 * log(w) / w);
+
return x1 * w;
}
final Allocation[] textures = mTextures;
textures[RSID_TEXTURE_SPACE] = loadTexture(R.drawable.space, "TSpace");
- textures[RSID_TEXTURE_LIGHT1] = loadTextureARGB(R.drawable.light1, "TLight1");
+ textures[RSID_TEXTURE_LIGHT1] = loadTexture(R.drawable.light1, "TLight1");
+ textures[RSID_TEXTURE_FLARES] = loadTexture(R.drawable.flares, "TFlares");
final int count = textures.length;
for (int i = 0; i < count; i++) {
return allocation;
}
- private Allocation loadTextureARGB(int id, String name) {
- Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
- final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
- allocation.setName(name);
- return allocation;
- }
-
private void createProgramFragment() {
- Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
- sampleBuilder.setMin(NEAREST);
- sampleBuilder.setMag(NEAREST);
- sampleBuilder.setWrapS(WRAP);
- sampleBuilder.setWrapT(WRAP);
- mSampler = sampleBuilder.create();
+ Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
+ samplerBuilder.setMin(NEAREST);
+ samplerBuilder.setMag(NEAREST);
+ samplerBuilder.setWrapS(WRAP);
+ samplerBuilder.setWrapT(WRAP);
+ mSampler = samplerBuilder.create();
ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
builder.setTexEnable(true, 0);
mPfBackground.setName("PFBackground");
mPfBackground.bindSampler(mSampler, 0);
+ samplerBuilder = new Sampler.Builder(mRS);
+ samplerBuilder.setMin(LINEAR);
+ samplerBuilder.setMag(LINEAR);
+ samplerBuilder.setWrapS(WRAP);
+ samplerBuilder.setWrapT(WRAP);
+ mStarSampler = samplerBuilder.create();
+
builder = new ProgramFragment.Builder(mRS, null, null);
- mPfBasic = builder.create();
- mPfBasic.setName("PFBasic");
+ builder.setPointSpriteTexCoordinateReplacement(true);
+ builder.setTexEnable(true, 0);
+ builder.setTexEnvMode(MODULATE, 0);
+ mPfStars = builder.create();
+ mPfStars.setName("PFStars");
+ mPfBackground.bindSampler(mStarSampler, 0);
}
private void createProgramFragmentStore() {
builder.setDepthFunc(ALWAYS);
builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
builder.setDitherEnable(false);
+ builder.setDepthMask(false);
mPfsBackground = builder.create();
mPfsBackground.setName("PFSBackground");
builder = new ProgramStore.Builder(mRS, null, null);
builder.setDepthFunc(ALWAYS);
- builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
builder.setDitherEnable(false);
mPfsLights = builder.create();
mPfsLights.setName("PFSLights");
mPvBackground = builder.create();
mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");
+
+ mPvProjectionAlloc = new ProgramVertex.MatrixAllocation(mRS);
+ mPvProjectionAlloc.setupProjectionNormalized(mWidth, mHeight);
+
+ builder = new ProgramVertex.Builder(mRS, null, null);
+ mPvStars = builder.create();
+ mPvStars.bindAllocation(mPvProjectionAlloc);
+ mPvStars.setName("PVStars");
}
-}
\ No newline at end of file
+}