1#pragma version(1)
2
3#pragma rs java_package_name(com.android.galaxy4)
4#include "rs_graphics.rsh"
5#pragma stateVertex(parent);
6#pragma stateStore(parent);
7
8typedef struct __attribute__((packed, aligned(4))) Particle {
9    float3 position;
10    float pointSize;
11} Particle_t;
12
13typedef struct VpConsts {
14    rs_matrix4x4 MVP;
15    float scaleSize;
16} VpConsts_t;
17VpConsts_t *vpConstants;
18
19Particle_t *spaceClouds;
20Particle_t *bgStars;
21Particle_t *staticStars;
22
23rs_mesh spaceCloudsMesh;
24rs_mesh bgStarsMesh;
25rs_mesh staticStarsMesh;
26
27rs_program_vertex vertSpaceClouds;
28rs_program_vertex vertBgStars;
29rs_program_vertex vertStaticStars;
30rs_program_fragment fragSpaceClouds;
31rs_program_fragment fragBgStars;
32rs_program_fragment fragStaticStars;
33rs_program_vertex vertBg;
34rs_program_fragment fragBg;
35
36rs_allocation textureSpaceCloud;
37rs_allocation textureStaticStar;
38rs_allocation textureStaticStar2;
39rs_allocation textureBg;
40
41float densityDPI;
42
43static int gGalaxyRadius = 300;
44static float screenWidth;
45static float screenHeight;
46
47static int numBgStars;
48static int numClouds;
49static int numStaticStars;
50
51#define PI 3.1415f
52#define TWO_PI 6.283f
53
54/**
55 * Helper function to generate the stars.
56 */
57static float randomGauss() {
58    float x1;
59    float x2;
60    float w = 2.f;
61
62    while (w >= 1.0f) {
63        x1 = rsRand(2.0f) - 1.0f;
64        x2 = rsRand(2.0f) - 1.0f;
65        w = x1 * x1 + x2 * x2;
66    }
67
68    w = sqrt(-2.0f * log(w) / w);
69    return x1 * w;
70}
71
72static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) {
73    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
74}
75
76void positionParticles() {
77    screenWidth = rsgGetWidth();
78    screenHeight = rsgGetHeight();
79
80    float wRatio = 1.0f;
81    float hRatio = 1.0f;
82
83    if (screenWidth > screenHeight) {
84        wRatio = screenWidth/screenHeight;
85        screenHeight = screenWidth;
86    } else {
87        hRatio = screenHeight/screenWidth;
88        screenWidth = screenHeight;
89    }
90
91    float scale = gGalaxyRadius / (screenWidth * 0.5f);
92
93    // clouds
94    Particle_t* particle = spaceClouds;
95    numClouds = rsAllocationGetDimX(rsGetAllocation(spaceClouds));
96    for (int i=0; i<numClouds; i++) {
97        float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
98        d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
99        float id = d / gGalaxyRadius;
100        float z = randomGauss() * 0.4f * (1.0f - id);
101        if (d > gGalaxyRadius * 0.15f) {
102            z *= 0.6f * (1.0f - id);
103        } else {
104            z *= 0.72f;
105        }
106        particle->position.x = rsRand(TWO_PI);
107        particle->position.y = d;
108        particle->pointSize = 1.0f;
109        particle->position.z = z/5.0f;
110        particle++;
111    }
112
113    // bg stars
114    numBgStars = rsAllocationGetDimX(rsGetAllocation(bgStars));
115    particle = bgStars;
116    for (int i=0; i<numBgStars; i++) {
117        float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
118        d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d);
119        float id = d / gGalaxyRadius;
120        float z = randomGauss() * 0.4f * (1.0f - id);
121        if (d > gGalaxyRadius * 0.15f) {
122            z *= 0.6f * (1.0f - id);
123        } else {
124            z *= 0.72f;
125        }
126        particle->position.x = rsRand(TWO_PI);
127        particle->position.y = d;
128        particle->pointSize = 1.0f;
129        particle->position.z = z/5.0f;
130        particle++;
131    }
132
133    // static stars
134    numStaticStars = rsAllocationGetDimX(rsGetAllocation(staticStars));
135    particle = staticStars;
136    for (int i=0; i<numStaticStars; i++) {
137        particle->position.x = rsRand(-wRatio, wRatio);
138        particle->position.y = rsRand(-hRatio, hRatio);
139        particle->pointSize = rsRand(1.0f, 10.0f);
140        particle++;
141    }
142}
143
144int root() {
145    float xpos = 0.0f;
146    float ypos = 0.0f;
147    xpos = -(screenWidth-rsgGetWidth())/2.0f;
148    ypos = -(screenHeight-rsgGetHeight())/2.0f;
149
150    rsgClearColor(0.0f, 0.f, 0.f, 0.5f);
151
152    // bg
153    rsgBindProgramVertex(vertBg);
154    rsgBindProgramFragment(fragBg);
155    rsgBindTexture(fragBg, 0, textureBg);
156    rsgDrawRect(xpos, ypos, screenWidth+xpos, screenHeight+ypos, 0.0f);
157
158    // space cloud
159    rsgBindProgramVertex(vertSpaceClouds);
160    Particle_t *particle = spaceClouds;
161    for (int i=0; i<numClouds; i++) {
162        particle->position.x -= .065;
163        particle++;
164    }
165    rsgBindProgramFragment(fragSpaceClouds);
166    rsgBindTexture(fragSpaceClouds, 0, textureSpaceCloud);
167    rsgDrawMesh(spaceCloudsMesh);
168
169    // bg stars
170    rsgBindProgramVertex(vertBgStars);
171    particle = bgStars;
172    for (int i=0; i<numBgStars; i++) {
173        particle->position.x -= .007;
174        particle++;
175    }
176    rsgBindProgramFragment(fragBgStars);
177    rsgDrawMesh(bgStarsMesh);
178
179    // static stars
180    rsgBindTexture(fragStaticStars, 0, textureStaticStar);
181    rsgBindTexture(fragStaticStars, 1, textureStaticStar2);
182    rsgBindProgramVertex(vertStaticStars);
183    rsgBindProgramFragment(fragStaticStars);
184    rsgDrawMesh(staticStarsMesh);
185
186    return 40;
187}