xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.wallpaper">
+ <uses-feature android:name="android.software.live_wallpaper" />
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
float g_DT;
int g_LastTime;
-struct vert_s {
- float x;
- float y;
- float z;
- float s;
- float t;
-};
-
struct drop_s {
float ampS;
float ampE;
float spread;
- float spread2;
- float invSpread;
- float invSpread2;
float x;
float y;
};
};
struct Leaves_s gLeavesStore[LEAVES_COUNT];
-
struct Leaves_s* gLeaves[LEAVES_COUNT];
-
struct Leaves_s* gNextLeaves[LEAVES_COUNT];
void init() {
gDrops[ct].ampS = 0;
gDrops[ct].ampE = 0;
gDrops[ct].spread = 1;
- gDrops[ct].spread2 = gDrops[ct].spread * gDrops[ct].spread;
- gDrops[ct].invSpread = 1 / gDrops[ct].spread;
- gDrops[ct].invSpread2 = gDrops[ct].invSpread * gDrops[ct].invSpread;
}
}
void updateDrop(int ct) {
gDrops[ct].spread += 30.f * g_DT;
- gDrops[ct].spread2 = gDrops[ct].spread * gDrops[ct].spread;
- gDrops[ct].invSpread = 1 / gDrops[ct].spread;
- gDrops[ct].invSpread2 = gDrops[ct].invSpread * gDrops[ct].invSpread;
- gDrops[ct].ampE = gDrops[ct].ampS * gDrops[ct].invSpread;
+ gDrops[ct].ampE = gDrops[ct].ampS / gDrops[ct].spread;
}
void drop(int x, int y, float s) {
}
void generateRipples() {
- int rippleMapSize = State->rippleMapSize;
- int width = State->meshWidth;
- int height = State->meshHeight;
- int index = State->rippleIndex;
- float ratio = (float)State->meshWidth / State->glWidth;
- float xShift = State->xOffset * ratio * 2;
-
- float *vertices = loadSimpleMeshVerticesF(NAMED_WaterMesh, 0);
- struct vert_s *vert = (struct vert_s *)vertices;
-
- float fw = 1.0f / width;
- float fh = 1.0f / height;
- int x, y, ct;
- struct vert_s *v = vert;
- for (y=0; y < height; y++) {
- for (x=0; x < width; x++) {
- struct drop_s * d = &gDrops[0];
- float z = 0;
-
- for (ct = 0; ct < gMaxDrops; ct++) {
- if (d->ampE > 0.01f) {
- float dx = (d->x - xShift) - x;
- float dy = d->y - y;
- float dist2 = dx*dx + dy*dy;
- if (dist2 < d->spread2) {
- float dist = sqrtf(dist2);
- float a = d->ampE * (dist * d->invSpread);
- z += sinf(d->spread - dist) * a;
- }
- }
- d++;
- }
- v->z = z;
- v ++;
- }
- }
+ int ct;
for (ct = 0; ct < gMaxDrops; ct++) {
- updateDrop(ct);
+ struct drop_s * d = &gDrops[ct];
+ vecF32_4_t *v = &Constants->Drop01;
+ v += ct;
+ v->x = d->x;
+ v->y = d->y;
+ v->z = d->ampE * 0.12f;
+ v->w = d->spread;
}
+ Constants->Offset.x = State->xOffset;
- v = vert;
- for (y = 0; y < height; y += 1) {
- for (x = 0; x < width; x += 1) {
- struct vec3_s n1, n2, n3;
- vec3Sub(&n1, (struct vec3_s *)&(v+1)->x, (struct vec3_s *)&v->x);
- vec3Sub(&n2, (struct vec3_s *)&(v+width)->x, (struct vec3_s *)&v->x);
- vec3Cross(&n3, &n1, &n2);
-
- // Average of previous normal and N1 x N2
- vec3Sub(&n1, (struct vec3_s *)&(v+width+1)->x, (struct vec3_s *)&v->x);
- vec3Cross(&n2, &n1, &n2);
- vec3Add(&n3, &n3, &n2);
- //vec3Norm(&n3); // Not necessary for our constrained mesh.
-
- v->s = (float)x * fw + n3.x;// * 0.2;
- v->t = (float)y * fh + n3.y;// * 0.2;
- v->z = 0;
- v += 1;
- }
+ for (ct = 0; ct < gMaxDrops; ct++) {
+ updateDrop(ct);
}
}
void drawRiverbed() {
bindTexture(NAMED_PFBackground, 0, NAMED_TRiverbed);
-
- float matrix[16];
- matrixLoadScale(matrix, 0.5f * 960.0f / 1024.0f, -1.0f * 800.0f / 1024.0f, 1.0f);
- matrixTranslate(matrix, State->xOffset, 0.0f, 0.0f);
- vpLoadTextureMatrix(matrix);
-
- drawSimpleMesh(NAMED_WaterMesh);
-
- matrixLoadIdentity(matrix);
- vpLoadTextureMatrix(matrix);
-}
-
-/*
-void drawSky() {
- color(1.0f, 1.0f, 1.0f, 0.5f);
-
- bindProgramFragment(NAMED_PFSky);
- bindProgramFragmentStore(NAMED_PFSLeaf);
- bindTexture(NAMED_PFSky, 0, NAMED_TSky);
-
- float x = skyOffsetX + State->skySpeedX;
- float y = skyOffsetY + State->skySpeedY;
-
- if (x > 1.0f) x = 0.0f;
- if (x < -1.0f) x = 0.0f;
- if (y > 1.0f) y = 0.0f;
-
- skyOffsetX = x;
- skyOffsetY = y;
-
- float matrix[16];
- matrixLoadTranslate(matrix, x + State->xOffset, y, 0.0f);
- vpLoadTextureMatrix(matrix);
-
drawSimpleMesh(NAMED_WaterMesh);
-
- matrixLoadIdentity(matrix);
- vpLoadTextureMatrix(matrix);
}
-*/
int main(int index) {
// Compute dt in seconds.
genLeafDrop(gLeaves[i], randf(0.3f) + 0.1f);
}
- generateRipples();
- updateSimpleMesh(NAMED_WaterMesh);
-
if (State->rotate) {
float matrix[16];
matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
vpLoadModelMatrix(matrix);
}
+ bindProgramVertex(NAMED_PVWater);
+ generateRipples();
drawRiverbed();
- // drawSky();
+
+ bindProgramVertex(NAMED_PVSky);
drawLeaves();
return 30;
// limitations under the License.
#pragma version(1)
-#pragma stateVertex(PVBackground)
+#pragma stateVertex(PVBkOrtho)
#pragma stateRaster(parent)
#pragma stateFragment(PFBackground)
#pragma stateStore(PFSBackground)
return x1 * w;
}
+float gSpeed[12000];
+
/**
* Generates the properties for a given star.
*/
-void createParticle(struct Stars_s *star, struct Particles_s *part, float scale) {
+void createParticle(struct Particles_s *part, int idx, float scale) {
float d = fabsf(randomGauss()) * State->galaxyRadius * 0.5f + randf(64.0f);
float id = d / State->galaxyRadius;
float z = randomGauss() * 0.4f * (1.0f - id);
float p = -d * ELLIPSE_TWIST;
+ int r,g,b,a;
if (d < State->galaxyRadius * 0.33f) {
- part->r = (int) (220 + id * 35);
- part->g = 220;
- part->b = 220;
+ r = (int) (220 + id * 35);
+ g = 220;
+ b = 220;
} else {
- part->r= 180;
- part->g = 180;
- part->b = (int) clampf(140.f + id * 115.f, 140.f, 255.f);
+ r = 180;
+ g = 180;
+ b = (int) clampf(140.f + id * 115.f, 140.f, 255.f);
}
- part->a = (int) (140 + (1.0f - id) * 115);
+ // Stash point size * 10 in Alpha
+ a = (int) (randf2(1.2f, 2.1f) * 60);
+ part->color = r | g<<8 | b<<16 | a<<24;
if (d > State->galaxyRadius * 0.15f) {
z *= 0.6f * (1.0f - id);
// Map to the projection coordinates (viewport.x = -1.0 -> 1.0)
d = mapf(-4.0f, State->galaxyRadius + 4.0f, 0.0f, scale, d);
- star->angle = randf(TWO_PI);
- star->distance = d;
- star->speed = randf2(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f;
- star->s = cosf(p);
- star->t = sinf(p);
+ part->position.x = randf(TWO_PI);
+ part->position.y = d;
+ gSpeed[idx] = randf2(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f;
- part->z = z / 5.0f;
- part->pointSize = randf2(1.2f, 2.1f) * 6;
+ part->position.z = z / 5.0f;
}
/**
angle = 0.0f;
}
- struct Stars_s *star = Stars;
struct Particles_s *part = Particles;
int particlesCount = State->particlesCount;
float scale = State->galaxyRadius / (State->width * 0.5f);
int i;
for (i = 0; i < particlesCount; i ++) {
- createParticle(star, part, scale);
- star++;
+ createParticle(part, i, scale);
part++;
}
}
}
void drawLights(float xOffset, int width, int height) {
- bindProgramVertex(NAMED_PVStars);
+ bindProgramVertex(NAMED_PVBkProj);
bindProgramFragment(NAMED_PFBackground);
bindTexture(NAMED_PFBackground, 0, NAMED_TLight1);
vpLoadModelMatrix(matrix);
// quadratic attenuation
- pointAttenuation(0.1f + 0.3f * fabsf(offset), 0.0f, 0.06f + 0.1f * fabsf(offset));
+ //pointAttenuation(0.1f + 0.3f * fabsf(offset), 0.0f, 0.06f + 0.1f * fabsf(offset));
int radius = State->galaxyRadius;
int particlesCount = State->particlesCount;
- struct Stars_s *star = Stars;
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 + xOffset;
- vtx->y = star->s * x - star->t * y;
-
- star->angle = a;
-
- star++;
+ vtx->position.x = vtx->position.x + gSpeed[i];
vtx++;
}
#pragma stateFragment(PFBackground)
#pragma stateStore(PFSBackground)
-#define RSID_STATE 0
-#define RSID_BLADES 1
#define RSID_BLADES_BUFFER 2
-#define BLADE_STRUCT_FIELDS_COUNT 13
-#define BLADE_STRUCT_ANGLE 0
-#define BLADE_STRUCT_SIZE 1
-#define BLADE_STRUCT_XPOS 2
-#define BLADE_STRUCT_YPOS 3
-#define BLADE_STRUCT_OFFSET 4
-#define BLADE_STRUCT_SCALE 5
-#define BLADE_STRUCT_LENGTHX 6
-#define BLADE_STRUCT_LENGTHY 7
-#define BLADE_STRUCT_HARDNESS 8
-#define BLADE_STRUCT_H 9
-#define BLADE_STRUCT_S 10
-#define BLADE_STRUCT_B 11
-#define BLADE_STRUCT_TURBULENCEX 12
-
#define TESSELATION 0.5f
#define HALF_TESSELATION 0.25f
#define REAL_TIME 1
+void updateBlades()
+{
+ int bladesCount = State->bladesCount;
+ struct Blades_s *bladeStruct = Blades;
+
+ int i;
+ for (i = 0; i < bladesCount; i ++) {
+ float xpos = randf2(-State->width, State->width);
+ bladeStruct->xPos = xpos;
+ bladeStruct->turbulencex = xpos * 0.006f;
+ bladeStruct->yPos = State->height;
+ bladeStruct++;
+ }
+}
+
float time(int isPreview) {
if (REAL_TIME && !isPreview) {
return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY;
drawRect(0.0f, 0.0f, width, height, 0.0f);
}
-int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor,
+int drawBlade(struct Blades_s *bladeStruct, float *bladeBuffer, int *bladeColor,
float brightness, float xOffset, float now) {
- float offset = bladeStruct[BLADE_STRUCT_OFFSET];
- float scale = bladeStruct[BLADE_STRUCT_SCALE];
- float angle = bladeStruct[BLADE_STRUCT_ANGLE];
- float hardness = bladeStruct[BLADE_STRUCT_HARDNESS];
- float turbulenceX = bladeStruct[BLADE_STRUCT_TURBULENCEX];
-
- float xpos = bladeStruct[BLADE_STRUCT_XPOS] + xOffset;
- float ypos = bladeStruct[BLADE_STRUCT_YPOS];
+ float scale = bladeStruct->scale;
+ float angle = bladeStruct->angle;
+ float xpos = bladeStruct->xPos + xOffset;
+ int size = bladeStruct->size;
- float lengthX = bladeStruct[BLADE_STRUCT_LENGTHX];
- float lengthY = bladeStruct[BLADE_STRUCT_LENGTHY];
+ int color = hsbToAbgr(bladeStruct->h, bladeStruct->s,
+ lerpf(0, bladeStruct->b, brightness), 1.0f);
- int size = bladeStruct[BLADE_STRUCT_SIZE];
-
- float h = bladeStruct[BLADE_STRUCT_H];
- float s = bladeStruct[BLADE_STRUCT_S];
- float b = bladeStruct[BLADE_STRUCT_B];
-
- int color = hsbToAbgr(h, s, lerpf(0, b, brightness), 1.0f);
-
- float newAngle = (turbulencef2(turbulenceX, now, 4.0f) - 0.5f) * 0.5f;
- angle = clampf(angle + (newAngle + offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
+ float newAngle = (turbulencef2(bladeStruct->turbulencex, now, 4.0f) - 0.5f) * 0.5f;
+ angle = clampf(angle + (newAngle + bladeStruct->offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
float currentAngle = HALF_PI;
float bottomX = xpos;
- float bottomY = ypos;
+ float bottomY = bladeStruct->yPos;
- float d = angle * hardness;
+ float d = angle * bladeStruct->hardness;
- int triangles = size * 2;
+
+ float si = size * scale;
+ float bottomLeft = bottomX - si;
+ float bottomRight = bottomX + si;
+ float bottom = bottomY + HALF_TESSELATION;
+
+ bladeColor[0] = color; // V1.ABGR
+ bladeBuffer[1] = bottomLeft; // V1.X
+ bladeBuffer[2] = bottom; // V1.Y
+ bladeColor[5] = color; // V2.ABGR
+ bladeBuffer[6] = bottomRight; // V2.X
+ bladeBuffer[7] = bottom; // V2.Y
+ bladeBuffer += 10;
+ bladeColor += 10;
for ( ; size > 0; size -= 1) {
- float topX = bottomX - cosf_fast(currentAngle) * lengthX;
- float topY = bottomY - sinf_fast(currentAngle) * lengthY;
+ float topX = bottomX - cosf_fast(currentAngle) * bladeStruct->lengthX;
+ float topY = bottomY - sinf_fast(currentAngle) * bladeStruct->lengthY;
- float si = size * scale;
+ si = (float)size * scale;
float spi = si - scale;
- float bottomLeft = bottomX - si;
- float bottomRight = bottomX + si;
float topLeft = topX - spi;
float topRight = topX + spi;
- float bottom = bottomY + HALF_TESSELATION;
- // First triangle
bladeColor[0] = color; // V1.ABGR
+ bladeBuffer[1] = topLeft; // V2.X
+ bladeBuffer[2] = topY; // V2.Y
- bladeBuffer[1] = bottomLeft; // V1.X
- bladeBuffer[2] = bottom; // V1.Y
-
- bladeColor[5] = color; // V1.ABGR
-
- bladeBuffer[6] = topLeft; // V2.X
- bladeBuffer[7] = topY; // V2.Y
-
- bladeColor[10] = color; // V3.ABGR
-
- bladeBuffer[11] = topRight; // V3.X
- bladeBuffer[12] = topY; // V3.Y
-
- // Second triangle
- bladeBuffer += 15;
- bladeColor += 15;
-
- bladeColor[0] = color; // V1.ABGR
-
- bladeBuffer[1] = bottomLeft; // V1.X
- bladeBuffer[2] = bottom; // V1.Y
-
- bladeColor[5] = color; // V2.ABGR
-
- bladeBuffer[6] = topRight; // V2.X
- bladeBuffer[7] = topY; // V2.Y
-
- bladeColor[10] = color; // V3.ABGR
-
- bladeBuffer[11] = bottomRight; // V3.X
- bladeBuffer[12] = bottom; // V3.Y
+ bladeColor[5] = color; // V3.ABGR
+ bladeBuffer[6] = topRight; // V3.X
+ bladeBuffer[7] = topY; // V3.Y
- bladeBuffer += 15;
- bladeColor += 15;
+ bladeBuffer += 10;
+ bladeColor += 10;
bottomX = topX;
bottomY = topY;
currentAngle += d;
}
- bladeStruct[BLADE_STRUCT_ANGLE] = angle;
+ bladeStruct->angle = angle;
- // 3 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
- return triangles * 15;
+ // 2 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
+ return bladeStruct->size * 10 + 10;
}
void drawBlades(float brightness, float xOffset) {
// For anti-aliasing
- bindTexture(NAMED_PFBackground, 0, NAMED_TAa);
+ bindTexture(NAMED_PFGrass, 0, NAMED_TAa);
int bladesCount = State->bladesCount;
- int trianglesCount = State->trianglesCount;
int i = 0;
- float *bladeStruct = loadArrayF(RSID_BLADES, 0);
+ struct Blades_s *bladeStruct = Blades;
float *bladeBuffer = loadArrayF(RSID_BLADES_BUFFER, 0);
int *bladeColor = loadArrayI32(RSID_BLADES_BUFFER, 0);
int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, brightness, xOffset, now);
bladeBuffer += offset;
bladeColor += offset;
- bladeStruct += BLADE_STRUCT_FIELDS_COUNT;
+ bladeStruct ++;
}
uploadToBufferObject(NAMED_BladesBuffer);
- drawSimpleMeshRange(NAMED_BladesMesh, 0, trianglesCount * 3);
+ drawSimpleMeshRange(NAMED_BladesMesh, 0, State->indexCount);
}
int main(int launchID) {
newB = 0.0f;
}
+ bindProgramFragment(NAMED_PFGrass);
drawBlades(newB, x);
- return 30;
+ return 50;
}
#pragma version(1)
#pragma stateVertex(PVOrtho)
-#pragma stateFragment(PFTexture)
#pragma stateStore(PSSolid)
#define MAX_PULSES 20
void setColor(int c) {
- if (c == 0) {
+ if (State->mode == 1) {
+ // sholes red
+ color(0.9f, 0.1f, 0.1f, 0.8f);
+ } else if (c == 0) {
// red
- color(1.0f, 0.0f, 0.0f, 1.0f);
+ color(1.0f, 0.0f, 0.0f, 0.8f);
} else if (c == 1) {
// green
- color(0.0f, 0.6f, 0.0f, 1.0f);
+ color(0.0f, 0.8f, 0.0f, 0.8f);
} else if (c == 2) {
// blue
- color(0.0f, 0.4f, 0.8f, 1.0f);
+ color(0.0f, 0.4f, 0.9f, 0.8f);
} else if (c == 3) {
// yellow
- color(1.0f, 0.8f, 0.0f, 1.0f);
+ color(1.0f, 0.8f, 0.0f, 0.8f);
}
}
}
void drawBackground(int width, int height) {
- bindTexture(NAMED_PFTexture, 0, NAMED_TBackground);
+ bindProgramFragment(NAMED_PFTexture565);
+ bindTexture(NAMED_PFTexture565, 0, NAMED_TBackground);
color(1.0f, 1.0f, 1.0f, 1.0f);
if (State->rotate) {
drawRect(0.0f, 0.0f, height*2, width, 0.0f);
gNow = uptimeMillis();
if (Command->command != 0) {
- debugF("x", Command->x);
- debugF("y", Command->y);
+ //debugF("x", Command->x);
+ //debugF("y", Command->y);
Command->command = 0;
addTap(Command->x, Command->y);
}
--- /dev/null
+<resources>
+ <integer name="nexus_mode">0</integer>
+</resources>
package com.android.wallpaper.fall;
import android.os.Bundle;
+import android.renderscript.Element;
import android.renderscript.ScriptC;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramStore;
import android.renderscript.SimpleMesh;
import android.renderscript.Script;
import static android.renderscript.Sampler.Value.LINEAR;
-import static android.renderscript.Sampler.Value.WRAP;
+import static android.renderscript.Sampler.Value.CLAMP;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendDstFunc;
import static android.renderscript.ProgramStore.BlendSrcFunc;
-import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.Element.*;
import android.app.WallpaperManager;
private static final int MESH_RESOLUTION = 48;
private static final int RSID_STATE = 0;
+ private static final int RSID_CONSTANTS = 1;
+ private static final int RSID_DROP = 2;
private static final int TEXTURES_COUNT = 2;
private static final int RSID_TEXTURE_RIVERBED = 0;
private static final int RSID_TEXTURE_LEAVES = 1;
private static final int RSID_TEXTURE_SKY = 2;
- private static final int RSID_RIPPLE_MAP = 1;
- private static final int RSID_DROP = 2;
+ static class Defines {
+
+ };
+
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramStore mPfsLeaf;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertex mPvSky;
+ private ProgramVertex mPvWater;
private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
@SuppressWarnings({"FieldCanBeLocal"})
private Sampler mSampler;
private Type mStateType;
private Type mDropType;
private int mMeshWidth;
+ private Allocation mUniformAlloc;
private int mMeshHeight;
@SuppressWarnings({"FieldCanBeLocal"})
private SimpleMesh mMesh;
private WorldState mWorldState;
- private Allocation mRippleMap;
-
private float mGlHeight;
public FallRS(int width, int height) {
}
return null;
}
-
+
@Override
public void start() {
super.start();
@Override
protected ScriptC createScript() {
+ createMesh();
+ createState();
createProgramVertex();
createProgramFragmentStore();
createProgramFragment();
- createMesh();
- createScriptStructures();
loadTextures();
+
+
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setType(mStateType, "State", RSID_STATE);
sb.setType(mDropType, "Drop", RSID_DROP);
+ sb.setType(mUniformAlloc.getType(), "Constants", RSID_CONSTANTS);
sb.setScript(mResources, R.raw.fall);
Script.Invokable invokable = sb.addInvokable("initLeaves");
sb.setRoot(true);
script.setTimeZone(TimeZone.getDefault().getID());
script.bindAllocation(mState, RSID_STATE);
- script.bindAllocation(mRippleMap, RSID_RIPPLE_MAP);
+ script.bindAllocation(mUniformAlloc, RSID_CONSTANTS);
script.bindAllocation(mDropState, RSID_DROP);
invokable.execute();
}
private void createMesh() {
- SimpleMesh.TriangleMeshBuilder tmb = new SimpleMesh.TriangleMeshBuilder(mRS, 3,
- SimpleMesh.TriangleMeshBuilder.TEXTURE_0);
+ SimpleMesh.TriangleMeshBuilder tmb = new SimpleMesh.TriangleMeshBuilder(mRS, 2, 0);
final int width = mWidth > mHeight ? mHeight : mWidth;
final int height = mWidth > mHeight ? mWidth : mHeight;
hResolution += 2;
for (int y = 0; y <= hResolution; y++) {
- final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight;
- final float t = 1.0f - y / (float) hResolution;
+ final float yOffset = (((float)y / hResolution) * 2.f - 1.f) * height / width;
for (int x = 0; x <= wResolution; x++) {
- tmb.setTexture(x / (float) wResolution, t);
- tmb.addVertex(-1.0f + x * quadWidth - quadWidth, yOffset, 0.0f);
+ tmb.addVertex(((float)x / wResolution) * 2.f - 1.f, yOffset);
}
}
mMeshHeight = hResolution + 1;
}
- private void createScriptStructures() {
- final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2);
-
- createState(rippleMapSize);
- createRippleMap(rippleMapSize);
- }
-
- private void createRippleMap(int rippleMapSize) {
- final int[] rippleMap = new int[rippleMapSize * 2];
- mRippleMap = Allocation.createSized(mRS, USER_I32(mRS), rippleMap.length);
- mRippleMap.data(rippleMap);
- }
-
static class WorldState {
public int frameCount;
public int width;
public int height;
public int meshWidth;
public int meshHeight;
- public int rippleMapSize;
public int rippleIndex;
public int leavesCount;
public float glWidth;
public int dropY;
}
- private void createState(int rippleMapSize) {
+ private void createState() {
mWorldState = new WorldState();
mWorldState.width = mWidth;
mWorldState.height = mHeight;
mWorldState.meshWidth = mMeshWidth;
mWorldState.meshHeight = mMeshHeight;
- mWorldState.rippleMapSize = rippleMapSize;
mWorldState.rippleIndex = 0;
mWorldState.glWidth = 2.0f;
mWorldState.glHeight = mGlHeight;
mDropState = Allocation.createTyped(mRS, mDropType);
mDropState.data(mDrop);
}
-
+
private void loadTextures() {
final Allocation[] textures = new Allocation[TEXTURES_COUNT];
textures[RSID_TEXTURE_RIVERBED] = loadTexture(R.drawable.pond, "TRiverbed");
Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
sampleBuilder.setMin(LINEAR);
sampleBuilder.setMag(LINEAR);
- sampleBuilder.setWrapS(WRAP);
- sampleBuilder.setWrapT(WRAP);
+ sampleBuilder.setWrapS(CLAMP);
+ sampleBuilder.setWrapT(CLAMP);
mSampler = sampleBuilder.create();
- ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(REPLACE, 0);
+ ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.RGBA, 0);
mPfBackground = builder.create();
mPfBackground.setName("PFBackground");
mPfBackground.bindSampler(mSampler, 0);
- builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(MODULATE, 0);
+ builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
+ ProgramFragment.Builder.Format.RGBA, 0);
mPfSky = builder.create();
mPfSky.setName("PFSky");
mPfSky.bindSampler(mSampler, 0);
mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight);
ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
- builder.setTextureMatrixEnable(true);
mPvSky = builder.create();
mPvSky.bindAllocation(mPvOrthoAlloc);
mPvSky.setName("PVSky");
+
+ float dw = 480.f / mMeshWidth;
+ float dh = 800.f / mMeshHeight;
+
+ Element.Builder eb = new Element.Builder(mRS);
+ // Make this an array when we can.
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop01");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop02");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop03");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop04");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop05");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop06");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop07");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop08");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop09");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Drop10");
+ eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 4), "Offset");
+ Element e = eb.create();
+
+ mUniformAlloc = Allocation.createSized(mRS, e, 1);
+
+
+ ProgramVertex.ShaderBuilder sb = new ProgramVertex.ShaderBuilder(mRS);
+ String t = new String("void main() {\n" +
+ " vec4 pos;\n" +
+ " pos.x = ATTRIB_position.x;\n" +
+ " pos.y = ATTRIB_position.y;\n" +
+ " pos.z = 0.0;\n" +
+ " pos.w = 1.0;\n" +
+ " gl_Position = pos;\n" +
+
+ // When we resize the texture we will need to tweak this.
+ " varTex0.x = (pos.x + 1.0) * 0.25;\n" +
+ " varTex0.x += UNI_Offset.x * 0.5 * 0.85;\n" +
+ " varTex0.y = (pos.y + 1.6666) * 0.33;\n" +
+ " varTex0.w = 0.0;\n" +
+ " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
+
+ " pos.x += UNI_Offset.x * 2.0;\n" +
+ " pos.x += 1.0;\n" +
+ " pos.y += 1.0;\n" +
+ " pos.x *= 25.0;\n" +
+ " pos.y *= 42.0;\n" +
+
+ " vec2 delta;\n" +
+ " float dist;\n" +
+ " float amp;\n" +
+
+ " delta = UNI_Drop01.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop01.w) { \n" +
+ " amp = UNI_Drop01.z * dist;\n" +
+ " amp /= UNI_Drop01.w * UNI_Drop01.w;\n" +
+ " amp *= sin(UNI_Drop01.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop02.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop02.w) { \n" +
+ " amp = UNI_Drop02.z * dist;\n" +
+ " amp /= UNI_Drop02.w * UNI_Drop02.w;\n" +
+ " amp *= sin(UNI_Drop02.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop03.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop03.w) { \n" +
+ " amp = UNI_Drop03.z * dist;\n" +
+ " amp /= UNI_Drop03.w * UNI_Drop03.w;\n" +
+ " amp *= sin(UNI_Drop03.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop04.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop04.w) { \n" +
+ " amp = UNI_Drop04.z * dist;\n" +
+ " amp /= UNI_Drop04.w * UNI_Drop04.w;\n" +
+ " amp *= sin(UNI_Drop04.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop05.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop05.w) { \n" +
+ " amp = UNI_Drop05.z * dist;\n" +
+ " amp /= UNI_Drop05.w * UNI_Drop05.w;\n" +
+ " amp *= sin(UNI_Drop05.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop06.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop06.w) { \n" +
+ " amp = UNI_Drop06.z * dist;\n" +
+ " amp /= UNI_Drop06.w * UNI_Drop06.w;\n" +
+ " amp *= sin(UNI_Drop06.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop07.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop07.w) { \n" +
+ " amp = UNI_Drop07.z * dist;\n" +
+ " amp /= UNI_Drop07.w * UNI_Drop07.w;\n" +
+ " amp *= sin(UNI_Drop07.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop08.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop08.w) { \n" +
+ " amp = UNI_Drop08.z * dist;\n" +
+ " amp /= UNI_Drop08.w * UNI_Drop08.w;\n" +
+ " amp *= sin(UNI_Drop08.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop09.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop09.w) { \n" +
+ " amp = UNI_Drop09.z * dist;\n" +
+ " amp /= UNI_Drop09.w * UNI_Drop09.w;\n" +
+ " amp *= sin(UNI_Drop09.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+ " delta = UNI_Drop10.xy - pos.xy;\n" +
+ " dist = length(delta);\n" +
+ " if (dist < UNI_Drop10.w) { \n" +
+ " amp = UNI_Drop10.z * dist;\n" +
+ " amp /= UNI_Drop10.w * UNI_Drop10.w;\n" +
+ " amp *= sin(UNI_Drop10.w - dist);\n" +
+ " varTex0.xy += delta * amp;\n" +
+ " }\n" +
+
+
+ "}\n");
+ sb.setShader(t);
+ sb.addConstant(mUniformAlloc.getType());
+ sb.addInput(mMesh.getVertexType(0).getElement());
+ mPvWater = sb.create();
+ mPvWater.bindAllocation(mPvOrthoAlloc);
+ mPvWater.setName("PVWater");
+ mPvWater.bindConstants(mUniformAlloc, 1);
+
}
void addDrop(float x, float y) {
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendDstFunc;
import static android.renderscript.ProgramStore.BlendSrcFunc;
-import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.Element.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
private static final int PARTICLES_COUNT = 12000;
private static final int RSID_STATE = 0;
- private static final int RSID_PARTICLES = 1;
- private static final int RSID_PARTICLES_BUFFER = 2;
+ private static final int RSID_PARTICLES_BUFFER = 1;
private static final int TEXTURES_COUNT = 3;
private static final int RSID_TEXTURE_SPACE = 0;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramStore mPfsLights;
@SuppressWarnings({"FieldCanBeLocal"})
- private ProgramVertex mPvBackground;
+ private ProgramVertex mPvBkOrtho;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private ProgramVertex mPvBkProj;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertex mPvStars;
@SuppressWarnings({"FieldCanBeLocal"})
private GalaxyState mGalaxyState;
private Type mStateType;
private Allocation mState;
- private Allocation mParticles;
- private Type mParticlesType;
private Allocation mParticlesBuffer;
@SuppressWarnings({"FieldCanBeLocal"})
private SimpleMesh mParticlesMesh;
@Override
protected ScriptC createScript() {
+ createScriptStructures();
createProgramVertex();
createProgramRaster();
createProgramFragmentStore();
createProgramFragment();
- createScriptStructures();
loadTextures();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setType(mStateType, "State", RSID_STATE);
sb.setType(mParticlesMesh.getVertexType(0), "Particles", RSID_PARTICLES_BUFFER);
- sb.setType(mParticlesType, "Stars", RSID_PARTICLES);
mInitParticles = sb.addInvokable("initParticles");
sb.setScript(mResources, R.raw.galaxy);
sb.setRoot(true);
script.setTimeZone(TimeZone.getDefault().getID());
script.bindAllocation(mState, RSID_STATE);
- script.bindAllocation(mParticles, RSID_PARTICLES);
script.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER);
mInitParticles.execute();
private void createScriptStructures() {
createState();
createParticlesMesh();
- createParticles();
}
private void createParticlesMesh() {
final Builder elementBuilder = new Builder(mRS);
- elementBuilder.addUNorm8RGBA("");
- elementBuilder.addFloatXYZ("");
- elementBuilder.addFloatPointSize("");
+ elementBuilder.add(Element.createAttrib(mRS, Element.DataType.UNSIGNED_8,
+ Element.DataKind.USER, 4), "color");
+ elementBuilder.add(Element.createAttrib(mRS, Element.DataType.FLOAT_32,
+ Element.DataKind.USER, 3), "position");
final Element vertexElement = elementBuilder.create();
final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
mState.data(mGalaxyState);
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+ mPvProjectionAlloc.setupProjectionNormalized(mWidth, mHeight);
+
mInitParticles.execute();
}
public int scale;
}
- static class GalaxyParticle {
- public float angle;
- public float distance;
- public float speed;
- public float s;
- public float t;
- }
-
private void createState() {
boolean isPreview = isPreview();
mState.data(mGalaxyState);
}
- private void createParticles() {
- mParticlesType = Type.createFromClass(mRS, GalaxyParticle.class, PARTICLES_COUNT, "Particle");
- mParticles = Allocation.createTyped(mRS, mParticlesType);
- }
-
private void loadTextures() {
mTextures = new Allocation[TEXTURES_COUNT];
samplerBuilder.setWrapT(WRAP);
mSampler = samplerBuilder.create();
- ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(REPLACE, 0);
+ ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.RGB, 0);
mPfBackground = builder.create();
mPfBackground.setName("PFBackground");
mPfBackground.bindSampler(mSampler, 0);
samplerBuilder.setWrapT(WRAP);
mStarSampler = samplerBuilder.create();
- builder = new ProgramFragment.Builder(mRS, null, null);
+ builder = new ProgramFragment.Builder(mRS);
builder.setPointSpriteTexCoordinateReplacement(true);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(MODULATE, 0);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
+ ProgramFragment.Builder.Format.RGBA, 0);
mPfStars = builder.create();
mPfStars.setName("PFStars");
mPfBackground.bindSampler(mStarSampler, 0);
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
- mPvBackground = builder.create();
- mPvBackground.bindAllocation(mPvOrthoAlloc);
- mPvBackground.setName("PVBackground");
+ mPvBkOrtho = builder.create();
+ mPvBkOrtho.bindAllocation(mPvOrthoAlloc);
+ mPvBkOrtho.setName("PVBkOrtho");
mPvProjectionAlloc = new ProgramVertex.MatrixAllocation(mRS);
mPvProjectionAlloc.setupProjectionNormalized(mWidth, mHeight);
builder = new ProgramVertex.Builder(mRS, null, null);
- mPvStars = builder.create();
+ mPvBkProj = builder.create();
+ mPvBkProj.bindAllocation(mPvProjectionAlloc);
+ mPvBkProj.setName("PVBkProj");
+
+ ProgramVertex.ShaderBuilder sb = new ProgramVertex.ShaderBuilder(mRS);
+ String t = "void main() {\n" +
+ " float dist = ATTRIB_position.y;\n" +
+ " float angle = ATTRIB_position.x;\n" +
+ " float x = dist * sin(angle);\n" +
+ " float y = dist * cos(angle) * 0.892;\n" +
+ " float p = dist * 5.5;\n" +
+ " float s = cos(p);\n" +
+ " float t = sin(p);\n" +
+ " vec4 pos;\n" +
+ " pos.x = t * x + s * y;\n" +
+ " pos.y = s * x - t * y;\n" +
+ " pos.z = ATTRIB_position.z;\n" +
+ " pos.w = 1.0;\n" +
+ " gl_Position = UNI_MVP * pos;\n" +
+ " gl_PointSize = ATTRIB_color.a * 10.0;\n" +
+ " varColor.rgb = ATTRIB_color.rgb;\n" +
+ " varColor.a = 1.0;\n" +
+ "}\n";
+ sb.setShader(t);
+ sb.addInput(mParticlesMesh.getVertexType(0).getElement());
+ mPvStars = sb.create();
mPvStars.bindAllocation(mPvProjectionAlloc);
mPvStars.setName("PVStars");
}
package com.android.wallpaper.grass;
import android.renderscript.Sampler;
-import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendSrcFunc;
import static android.renderscript.ProgramStore.BlendDstFunc;
@SuppressWarnings({"UnusedDeclaration"})
private static final String LOG_TAG = "Grass";
private static final boolean DEBUG = false;
-
+
private static final int LOCATION_UPDATE_MIN_TIME = DEBUG ? 5 * 60 * 1000 : 60 * 60 * 1000; // 1 hour
private static final int LOCATION_UPDATE_MIN_DISTANCE = DEBUG ? 10 : 150 * 1000; // 150 km
private static final int RSID_STATE = 0;
private static final int RSID_BLADES = 1;
private static final int BLADES_COUNT = 200;
- private static final int BLADE_STRUCT_FIELDS_COUNT = 13;
- private static final int BLADE_STRUCT_ANGLE = 0;
- private static final int BLADE_STRUCT_SIZE = 1;
- private static final int BLADE_STRUCT_XPOS = 2;
- private static final int BLADE_STRUCT_YPOS = 3;
- private static final int BLADE_STRUCT_OFFSET = 4;
- private static final int BLADE_STRUCT_SCALE = 5;
- private static final int BLADE_STRUCT_LENGTHX = 6;
- private static final int BLADE_STRUCT_LENGTHY = 7;
- private static final int BLADE_STRUCT_HARDNESS = 8;
- private static final int BLADE_STRUCT_H = 9;
- private static final int BLADE_STRUCT_S = 10;
- private static final int BLADE_STRUCT_B = 11;
- private static final int BLADE_STRUCT_TURBULENCEX = 12;
+
+ class BladesStruct {
+ public float angle;
+ public int size;
+ public float xPos;
+ public float yPos;
+ public float offset;
+ public float scale;
+ public float lengthX;
+ public float lengthY;
+ public float hardness;
+ public float h;
+ public float s;
+ public float b;
+ public float turbulencex;
+ };
private static final int RSID_BLADES_BUFFER = 2;
+ private ScriptC.Invokable mUpdateBladesInvokable;
@SuppressWarnings({ "FieldCanBeLocal" })
private ProgramFragment mPfBackground;
@SuppressWarnings({ "FieldCanBeLocal" })
+ private ProgramFragment mPfGrass;
+ @SuppressWarnings({ "FieldCanBeLocal" })
private ProgramStore mPfsBackground;
@SuppressWarnings({ "FieldCanBeLocal" })
private ProgramVertex mPvBackground;
@SuppressWarnings({"FieldCanBeLocal"})
- private Sampler mSampler;
- @SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
@SuppressWarnings({ "FieldCanBeLocal" })
private Type mStateType;
private Allocation mState;
+ private Type mBladesType;
private Allocation mBlades;
private Allocation mBladesBuffer;
+ private Allocation mBladesIndicies;
@SuppressWarnings({"FieldCanBeLocal"})
private SimpleMesh mBladesMesh;
- private int mTriangles;
- private float[] mBladesData;
+
+ private int mVerticies;
+ private int mIndicies;
+ private int[] mBladeSizes;
private final float[] mFloatData5 = new float[5];
private WorldState mWorldState;
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-
+
mContext.registerReceiver(mTimezoneTracker, filter);
}
mContext.unregisterReceiver(mTimezoneTracker);
mTimezoneTracker = null;
}
-
+
if (mLocationUpdater != null) {
mLocationManager.removeUpdates(mLocationUpdater);
mLocationUpdater = null;
mWorldState.height = height;
mState.data(mWorldState);
- final float[] blades = mBladesData;
- for (int i = 0; i < blades.length; i+= BLADE_STRUCT_FIELDS_COUNT) {
- updateBlade(blades, i);
- }
- mBlades.data(blades);
-
- mPvOrthoAlloc.setupOrthoWindow(width, height);
+ mUpdateBladesInvokable.execute();
+ mPvOrthoAlloc.setupOrthoWindow(width, height);
}
@Override
protected ScriptC createScript() {
createProgramVertex();
createProgramFragmentStore();
+ loadTextures();
createProgramFragment();
createScriptStructures();
- loadTextures();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setType(mStateType, "State", RSID_STATE);
+ sb.setType(mBladesType, "Blades", RSID_BLADES);
sb.setScript(mResources, R.raw.grass);
sb.setRoot(true);
+ mUpdateBladesInvokable = sb.addInvokable("updateBlades");
ScriptC script = sb.create();
script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
static class WorldState {
public int bladesCount;
- public int trianglesCount;
+ public int indexCount;
public int width;
public int height;
public float xOffset;
mWorldState.width = mWidth;
mWorldState.height = mHeight;
mWorldState.bladesCount = BLADES_COUNT;
- mWorldState.trianglesCount = mTriangles;
+ mWorldState.indexCount = mIndicies;
mWorldState.isPreview = isPreview ? 1 : 0;
if (isPreview) {
mWorldState.xOffset = 0.5f;
}
private void createBlades() {
- int triangles = 0;
-
- mBladesData = new float[BLADES_COUNT * BLADE_STRUCT_FIELDS_COUNT];
-
- final float[] blades = mBladesData;
- for (int i = 0; i < blades.length; i+= BLADE_STRUCT_FIELDS_COUNT) {
- triangles += createBlade(blades, i);
+ mVerticies = 0;
+ mIndicies = 0;
+
+ mBladesType = Type.createFromClass(mRS, BladesStruct.class, BLADES_COUNT, "Blade");
+ mBlades = Allocation.createTyped(mRS, mBladesType);
+ BladesStruct bs = new BladesStruct();
+
+ mBladeSizes = new int[BLADES_COUNT];
+ for (int i = 0; i < BLADES_COUNT; i++) {
+ createBlade(bs);
+ mIndicies += bs.size * 2 * 3;
+ mVerticies += bs.size + 2;
+ mBlades.subData(i, bs);
+ mBladeSizes[i] = bs.size;
}
- mBlades = Allocation.createSized(mRS, USER_F32(mRS), blades.length);
- mBlades.data(blades);
-
- mTriangles = triangles;
-
- createMesh(triangles);
+ createMesh();
}
- private void createMesh(int triangles) {
+ private void createMesh() {
Builder elementBuilder = new Builder(mRS);
- elementBuilder.addUNorm8RGBA();
- elementBuilder.addFloatXY();
- elementBuilder.addFloatST();
+ elementBuilder.add(Element.ATTRIB_COLOR_U8_4(mRS), "color");
+ elementBuilder.add(Element.ATTRIB_POSITION_2(mRS), "position");
+ elementBuilder.add(Element.ATTRIB_TEXTURE_2(mRS), "texture");
final Element vertexElement = elementBuilder.create();
final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
- final int vertexSlot = meshBuilder.addVertexType(vertexElement, triangles * 3);
+ final int vertexSlot = meshBuilder.addVertexType(vertexElement, mVerticies * 2);
+ meshBuilder.setIndexType(Element.INDEX_16(mRS), mIndicies);
meshBuilder.setPrimitive(Primitive.TRIANGLE);
mBladesMesh = meshBuilder.create();
mBladesMesh.setName("BladesMesh");
mBladesBuffer = mBladesMesh.createVertexAllocation(vertexSlot);
mBladesBuffer.setName("BladesBuffer");
mBladesMesh.bindVertexAllocation(mBladesBuffer, 0);
+ mBladesIndicies = mBladesMesh.createIndexAllocation();
+ mBladesMesh.bindIndexAllocation(mBladesIndicies);
// Assign the texture coordinates of each triangle
final float[] floatData = mFloatData5;
final Allocation buffer = mBladesBuffer;
- int bufferIndex = 0;
- for (int i = 0; i < triangles; i += 2) {
- floatData[3] = 0.0f;
- floatData[4] = 1.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ short[] idx = new short[mIndicies];
+ int bufferIndex = 0;
+ int i2 = 0;
+ for (int i = 0; i < mVerticies; i +=2) {
floatData[3] = 0.0f;
floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ buffer.subData1D(bufferIndex++, 1, floatData);
floatData[3] = 1.0f;
floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
-
- floatData[3] = 0.0f;
- floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
-
- floatData[3] = 1.0f;
- floatData[4] = 1.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ buffer.subData1D(bufferIndex++, 1, floatData);
+ }
- floatData[3] = 1.0f;
- floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ int idxIdx = 0;
+ int vtxIdx = 0;
+ for (int i = 0; i < mBladeSizes.length; i++) {
+ for (int ct = 0; ct < mBladeSizes[i]; ct ++) {
+ idx[idxIdx + 0] = (short)(vtxIdx + 0);
+ idx[idxIdx + 1] = (short)(vtxIdx + 1);
+ idx[idxIdx + 2] = (short)(vtxIdx + 2);
+ idx[idxIdx + 3] = (short)(vtxIdx + 1);
+ idx[idxIdx + 4] = (short)(vtxIdx + 3);
+ idx[idxIdx + 5] = (short)(vtxIdx + 2);
+ idxIdx += 6;
+ vtxIdx += 2;
+ }
+ vtxIdx += 2;
}
- }
- private void updateBlade(float[] blades, int index) {
- final int xpos = random(-mWidth, mWidth);
- blades[index + BLADE_STRUCT_XPOS] = xpos;
- blades[index + BLADE_STRUCT_TURBULENCEX] = xpos * 0.006f;
- blades[index + BLADE_STRUCT_YPOS] = mHeight;
+ mBladesIndicies.data(idx);
+ mBladesIndicies.uploadToBufferObject();
}
- private int createBlade(float[] blades, int index) {
+ private void createBlade(BladesStruct blades) {
final float size = random(4.0f) + 4.0f;
final int xpos = random(-mWidth, mWidth);
//noinspection PointlessArithmeticExpression
- blades[index + BLADE_STRUCT_ANGLE] = 0.0f;
- blades[index + BLADE_STRUCT_SIZE] = size / TESSELATION;
- blades[index + BLADE_STRUCT_XPOS] = xpos;
- blades[index + BLADE_STRUCT_YPOS] = mHeight;
- blades[index + BLADE_STRUCT_OFFSET] = random(0.2f) - 0.1f;
- blades[index + BLADE_STRUCT_SCALE] = 4.0f / (size / TESSELATION) +
- (random(0.6f) + 0.2f) * TESSELATION;
- blades[index + BLADE_STRUCT_LENGTHX] = (random(4.5f) + 3.0f) * TESSELATION * size;
- blades[index + BLADE_STRUCT_LENGTHY] = (random(5.5f) + 2.0f) * TESSELATION * size;
- blades[index + BLADE_STRUCT_HARDNESS] = (random(1.0f) + 0.2f) * TESSELATION;
- blades[index + BLADE_STRUCT_H] = random(0.02f) + 0.2f;
- blades[index + BLADE_STRUCT_S] = random(0.22f) + 0.78f;
- blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f;
- blades[index + BLADE_STRUCT_TURBULENCEX] = xpos * 0.006f;
-
- // Each blade is made of "size" quads, so we double to count the triangles
- return (int) (blades[index + BLADE_STRUCT_SIZE]) * 2;
+ blades.angle = 0.0f;
+ blades.size = (int)(size / TESSELATION);
+ blades.xPos = xpos;
+ blades.yPos = mHeight;
+ blades.offset = random(0.2f) - 0.1f;
+ blades.scale = 4.0f / (size / TESSELATION) + (random(0.6f) + 0.2f) * TESSELATION;
+ blades.lengthX = (random(4.5f) + 3.0f) * TESSELATION * size;
+ blades.lengthY = (random(5.5f) + 2.0f) * TESSELATION * size;
+ blades.hardness = (random(1.0f) + 0.2f) * TESSELATION;
+ blades.h = random(0.02f) + 0.2f;
+ blades.s = random(0.22f) + 0.78f;
+ blades.b = random(0.65f) + 0.35f;
+ blades.turbulencex = xpos * 0.006f;
}
private void loadTextures() {
final Type.Builder builder = new Type.Builder(mRS, A_8(mRS));
builder.add(Dimension.X, width);
builder.add(Dimension.Y, height);
+ builder.add(Dimension.LOD, 1);
final Allocation allocation = Allocation.createTyped(mRS, builder.create());
- allocation.data(data);
allocation.setName(name);
+
+ int[] grey1 = new int[] {0x3f3f3f3f};
+ int[] grey2 = new int[] {0x00000000};
+ Allocation.Adapter2D a = allocation.createAdapter2D();
+ a.setConstraint(Dimension.LOD, 0);
+ a.subData(0, 0, 4, 1, data);
+ a.setConstraint(Dimension.LOD, 1);
+ a.subData(0, 0, 2, 1, grey1);
+ a.setConstraint(Dimension.LOD, 2);
+ a.subData(0, 0, 1, 1, grey2);
+
return allocation;
}
private void createProgramFragment() {
Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
- samplerBuilder.setMin(LINEAR);
+ samplerBuilder.setMin(LINEAR_MIP_LINEAR);
samplerBuilder.setMag(LINEAR);
samplerBuilder.setWrapS(WRAP);
samplerBuilder.setWrapT(WRAP);
- mSampler = samplerBuilder.create();
-
- ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(REPLACE, 0);
+ Sampler sl = samplerBuilder.create();
+
+ samplerBuilder.setMin(NEAREST);
+ samplerBuilder.setMag(NEAREST);
+ Sampler sn = samplerBuilder.create();
+
+ ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.ALPHA, 0);
+ mPfGrass = builder.create();
+ mPfGrass.setName("PFGrass");
+ mPfGrass.bindSampler(sl, 0);
+
+ builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.RGB, 0);
mPfBackground = builder.create();
mPfBackground.setName("PFBackground");
- mPfBackground.bindSampler(mSampler, 0);
+ mPfBackground.bindSampler(sn, 0);
}
private void createProgramFragmentStore() {
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
- pvb.setTextureMatrixEnable(true);
mPvBackground = pvb.create();
mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");
import static android.renderscript.Element.RGBA_8888;
import static android.renderscript.Element.RGB_565;
-import static android.renderscript.ProgramFragment.EnvMode.MODULATE;
-import static android.renderscript.ProgramFragment.EnvMode.REPLACE;
import static android.renderscript.ProgramStore.DepthFunc.ALWAYS;
import static android.renderscript.Sampler.Value.LINEAR;
+import static android.renderscript.Sampler.Value.CLAMP;
import static android.renderscript.Sampler.Value.WRAP;
import com.android.wallpaper.R;
import com.android.wallpaper.RenderScriptScene;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
private ProgramFragment mPfTexture;
+ private ProgramFragment mPfTexture565;
private ProgramFragment mPfColor;
private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
- private Sampler mSampler;
+ private Sampler mClampSampler;
+ private Sampler mWrapSampler;
private Allocation mState;
public int rotate;
public int isPreview;
public float xOffset;
+ public int mode;
}
static class CommandState {
mWorldState.rotate = mWidth > mHeight ? 1 : 0;
mWorldState.isPreview = isPreview() ? 1 : 0;
+ try {
+ mWorldState.mode = mResources.getInteger(R.integer.nexus_mode);
+ } catch (Resources.NotFoundException exc) {
+ mWorldState.mode = 0; // standard nexus mode
+ }
+
mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
mState = Allocation.createTyped(mRS, mStateType);
mState.data(mWorldState);
}
private void createProgramFragment() {
+ // sampler and program fragment for pulses
Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
sampleBuilder.setMin(LINEAR);
sampleBuilder.setMag(LINEAR);
sampleBuilder.setWrapS(WRAP);
sampleBuilder.setWrapT(WRAP);
- mSampler = sampleBuilder.create();
-
- ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(MODULATE, 0);
+ mWrapSampler = sampleBuilder.create();
+ ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
+ ProgramFragment.Builder.Format.RGBA, 0);
mPfTexture = builder.create();
mPfTexture.setName("PFTexture");
- mPfTexture.bindSampler(mSampler, 0);
+ mPfTexture.bindSampler(mWrapSampler, 0);
- builder = new ProgramFragment.Builder(mRS, null, null);
- builder.setTexEnable(true, 0);
- builder.setTexEnvMode(REPLACE, 0);
+ builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.RGB, 0);
mPfColor = builder.create();
mPfColor.setName("PFColor");
- mPfColor.bindSampler(mSampler, 0);
+ mPfColor.bindSampler(mWrapSampler, 0);
+
+ // sampler and program fragment for background image
+ sampleBuilder.setWrapS(CLAMP);
+ sampleBuilder.setWrapT(CLAMP);
+ mClampSampler = sampleBuilder.create();
+ builder = new ProgramFragment.Builder(mRS);
+ builder.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
+ ProgramFragment.Builder.Format.RGB, 0);
+ mPfTexture565 = builder.create();
+ mPfTexture565.setName("PFTexture565");
+ mPfTexture565.bindSampler(mClampSampler, 0);
}
private void createProgramFragmentStore() {
mCommand.command = command;
mCommandAllocation.data(mCommand);
}
-}
\ No newline at end of file
+}