Home | History | Annotate | Download | only in noisefield
      1 #pragma version(1)
      2 
      3 #pragma rs java_package_name(com.android.noisefield)
      4 
      5 #include "rs_graphics.rsh"
      6 #pragma stateVertex(parent);
      7 #pragma stateStore(parent);
      8 
      9 
     10 rs_allocation textureDot;
     11 rs_allocation textureVignette;
     12 
     13 rs_program_vertex vertBg;
     14 rs_program_fragment fragBg;
     15 
     16 rs_program_vertex vertDots;
     17 rs_program_fragment fragDots;
     18 
     19 rs_program_store storeAlpha;
     20 rs_program_store storeAdd;
     21 
     22 typedef struct VpConsts {
     23     rs_matrix4x4 MVP;
     24     float scaleSize;
     25 } VpConsts_t;
     26 VpConsts_t *vpConstants;
     27 
     28 typedef struct Particle {
     29     float3 position;
     30     float speed;
     31     float wander;
     32     float alphaStart;
     33     float alpha;
     34     int life;
     35     int death;
     36 } Particle_t;
     37 Particle_t *dotParticles;
     38 
     39 
     40 typedef struct VertexColor_s {
     41     float3 position;
     42     float4 color;
     43     float offsetX;
     44 
     45 } VertexColor;
     46 VertexColor* vertexColors;
     47 
     48 rs_mesh dotMesh;
     49 rs_mesh gBackgroundMesh;
     50 
     51 float densityDPI;
     52 bool touchDown = false;
     53 
     54 #define B 0x100
     55 #define BM 0xff
     56 #define N 0x1000
     57 
     58 static int p[B + B + 2];
     59 static float g3[B + B + 2][3];
     60 static float g2[B + B + 2][2];
     61 static float g1[B + B + 2];
     62 
     63 // used for motion easing from touch to non-touch state
     64 static float touchInfluence = 0;
     65 
     66 static float touchX = 0;
     67 static float touchY = 0;
     68 
     69 static float noise_sCurve(float t) {
     70     return t * t * (3.0f - 2.0f * t);
     71 }
     72 
     73 static void normalizef2(float v[]) {
     74     float s = (float)sqrt(v[0] * v[0] + v[1] * v[1]);
     75     v[0] = v[0] / s;
     76     v[1] = v[1] / s;
     77 }
     78 
     79 static void normalizef3(float v[]) {
     80     float s = (float)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
     81     v[0] = v[0] / s;
     82     v[1] = v[1] / s;
     83     v[2] = v[2] / s;
     84 }
     85 
     86 void init() {
     87     int i, j, k;
     88     for (i = 0; i < B; i++) {
     89         p[i] = i;
     90 
     91         g1[i] = (float)(rsRand(B * 2) - B) / B;
     92 
     93         for (j = 0; j < 2; j++)
     94             g2[i][j] = (float)(rsRand(B * 2) - B) / B;
     95         normalizef2(g2[i]);
     96 
     97         for (j = 0; j < 3; j++)
     98             g3[i][j] = (float)(rsRand(B * 2) - B) / B;
     99         normalizef3(g3[i]);
    100     }
    101 
    102     for (i = B-1; i >= 0; i--) {
    103         k = p[i];
    104         p[i] = p[j = rsRand(B)];
    105         p[j] = k;
    106     }
    107 
    108     for (i = 0; i < B + 2; i++) {
    109         p[B + i] = p[i];
    110         g1[B + i] = g1[i];
    111         for (j = 0; j < 2; j++)
    112             g2[B + i][j] = g2[i][j];
    113         for (j = 0; j < 3; j++)
    114             g3[B + i][j] = g3[i][j];
    115     }
    116 }
    117 
    118 static float noisef2(float x, float y) {
    119     int bx0, bx1, by0, by1, b00, b10, b01, b11;
    120     float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
    121     float *q;
    122     int i, j;
    123 
    124     t = x + N;
    125     bx0 = ((int)t) & BM;
    126     bx1 = (bx0+1) & BM;
    127     rx0 = t - (int)t;
    128     rx1 = rx0 - 1.0f;
    129 
    130     t = y + N;
    131     by0 = ((int)t) & BM;
    132     by1 = (by0+1) & BM;
    133     ry0 = t - (int)t;
    134     ry1 = ry0 - 1.0f;
    135 
    136     i = p[bx0];
    137     j = p[bx1];
    138 
    139     b00 = p[i + by0];
    140     b10 = p[j + by0];
    141     b01 = p[i + by1];
    142     b11 = p[j + by1];
    143 
    144     sx = noise_sCurve(rx0);
    145     sy = noise_sCurve(ry0);
    146 
    147     q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
    148     q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
    149     a = mix(u, v, sx);
    150 
    151     q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
    152     q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
    153     b = mix(u, v, sx);
    154 
    155     return 1.5f * mix(a, b, sy);
    156 }
    157 
    158 void positionParticles() {
    159     Particle_t* particle = dotParticles;
    160     int size = rsAllocationGetDimX(rsGetAllocation(dotParticles));
    161     for(int i=0; i<size; i++) {
    162         particle->position.x = rsRand(-1.0f, 1.0f);
    163         particle->position.y = rsRand(-1.0f, 1.0f);
    164         particle->speed = rsRand(0.0002f, 0.02f);
    165         particle->wander = rsRand(0.50f, 1.5f);
    166         particle->death = 0;
    167         particle->life = rsRand(300, 800);
    168         particle->alphaStart = rsRand(0.01f, 1.0f);
    169         particle->alpha = particle->alphaStart;
    170         particle++;
    171     }
    172 }
    173 
    174 void touch(float x, float y) {
    175     bool landscape = rsgGetWidth() > rsgGetHeight();
    176     float wRatio;
    177     float hRatio;
    178     if(!landscape){
    179         wRatio = 1.0;
    180         hRatio = rsgGetHeight()/rsgGetWidth();
    181     } else {
    182         hRatio = 1.0;
    183         wRatio = rsgGetWidth()/rsgGetHeight();
    184     }
    185 
    186     touchInfluence = 1.0;
    187     touchX = x/rsgGetWidth() * wRatio * 2 - wRatio;
    188     touchY = -(y/rsgGetHeight() * hRatio * 2 - hRatio);
    189 }
    190 
    191 int root() {
    192     rsgClearColor(0.0, 0.0, 0.0, 1.0f);
    193     int size = rsAllocationGetDimX(rsGetAllocation(vertexColors));
    194     rsgBindProgramVertex(vertDots);
    195     rsgBindProgramFragment(fragDots);
    196     rsgBindTexture(fragDots, 0, textureDot);
    197     rsgDrawMesh(dotMesh);
    198 
    199     // bg
    200     rsgBindProgramVertex(vertBg);
    201     rsgBindProgramFragment(fragBg);
    202     rsgDrawMesh(gBackgroundMesh);
    203 
    204     // dots
    205     Particle_t* particle = dotParticles;
    206     size = rsAllocationGetDimX(rsGetAllocation(dotParticles));
    207     float rads;
    208     float speed;
    209 
    210     for(int i=0; i<size; i++) {
    211         if(particle->life < 0 || particle->position.x < -1.2 ||
    212            particle->position.x >1.2 || particle->position.y < -1.7 ||
    213            particle->position.y >1.7) {
    214             particle->position.x = rsRand(-1.0f, 1.0f);
    215             particle->position.y = rsRand(-1.0f, 1.0f);
    216             particle->speed = rsRand(0.0002f, 0.02f);
    217             particle->wander = rsRand(0.50f, 1.5f);
    218             particle->death = 0;
    219             particle->life = rsRand(300, 800);
    220             particle->alphaStart = rsRand(0.01f, 1.0f);
    221             particle->alpha = particle->alphaStart;
    222         }
    223 
    224         float touchDist = sqrt(pow(touchX - particle->position.x, 2) +
    225                                pow(touchY - particle->position.y, 2));
    226 
    227         float noiseval = noisef2(particle->position.x, particle->position.y);
    228         if(touchDown || touchInfluence > 0.0) {
    229             if(touchDown){
    230                 touchInfluence = 1.0;
    231             }
    232             rads = atan2(touchX - particle->position.x + noiseval,
    233                          touchY - particle->position.y + noiseval);
    234             if(touchDist != 0){
    235                 speed = ( (0.25 + (noiseval * particle->speed + 0.01)) / touchDist * 0.3 );
    236                 speed = speed * touchInfluence;
    237             } else {
    238                 speed = .3;
    239             }
    240             particle->position.x += cos(rads) * speed * 0.2;
    241             particle->position.y += sin(rads) * speed * 0.2;
    242         }
    243 
    244         float angle = 360 * noiseval * particle->wander;
    245         speed = noiseval * particle->speed + 0.01;
    246         rads = angle * 3.14159265 / 180.0;
    247 
    248         particle->position.x += cos(rads) * speed * 0.33;
    249         particle->position.y += sin(rads) * speed * 0.33;
    250 
    251         particle->life--;
    252         particle->death++;
    253 
    254         float dist = sqrt(particle->position.x*particle->position.x +
    255                           particle->position.y*particle->position.y);
    256         if(dist < 0.95) {
    257             dist = 0;
    258             particle->alphaStart *= (1-dist);
    259         } else {
    260             dist = dist-0.95;
    261             if(particle->alphaStart < 1.0f) {
    262                 particle->alphaStart +=0.01;
    263                 particle->alphaStart *= (1-dist);
    264             }
    265         }
    266 
    267         if(particle->death < 101) {
    268             particle->alpha = (particle->alphaStart)*(particle->death)/100.0;
    269         } else if(particle->life < 101) {
    270             particle->alpha = particle->alpha*particle->life/100.0;
    271         } else {
    272             particle->alpha = particle->alphaStart;
    273         }
    274 
    275         particle++;
    276     }
    277 
    278     if(touchInfluence > 0) {
    279         touchInfluence-=0.01;
    280     }
    281     return 35;
    282 }