OSDN Git Service

48ed78367ffcf0806046b0cba84a819fa1bd9eb4
[android-x86/packages-wallpapers-Basic.git] / res / raw / grass.rs
1 // Copyright (C) 2009 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma version(1)
16 #pragma stateVertex(PVBackground)
17 #pragma stateFragment(PFBackground)
18 #pragma stateStore(PFSBackground)
19
20 #define RSID_BLADES_BUFFER 2
21
22 #define TESSELATION 0.5f
23 #define HALF_TESSELATION 0.25f
24
25 #define MAX_BEND 0.09f
26
27 #define SECONDS_IN_DAY 86400.0f
28
29 #define PI 3.1415926f
30 #define HALF_PI 1.570796326f
31
32 #define REAL_TIME 1
33
34 void updateBlades()
35 {
36     int bladesCount = State->bladesCount;
37     struct Blades_s *bladeStruct = Blades;
38
39     int i;
40     for (i = 0; i < bladesCount; i ++) {
41         float xpos = randf2(-State->width, State->width);
42         bladeStruct->xPos = xpos;
43         bladeStruct->turbulencex = xpos * 0.006f;
44         bladeStruct->yPos = State->height;
45         bladeStruct++;
46     }
47 }
48
49 float time(int isPreview) {
50     if (REAL_TIME && !isPreview) {
51         return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY;
52     }
53     float t = uptimeMillis() / 30000.0f;
54     return t - (int) t;
55 }
56
57 void alpha(float a) {
58     color(1.0f, 1.0f, 1.0f, a);
59 }
60
61 void drawNight(int width, int height) {
62     bindTexture(NAMED_PFBackground, 0, NAMED_TNight);
63     drawQuadTexCoords(
64             0.0f, -32.0f, 0.0f,
65             0.0f, 1.0f,
66             width, -32.0f, 0.0f,
67             2.0f, 1.0f,
68             width, 1024.0f - 32.0f, 0.0f,
69             2.0f, 0.0f,
70             0.0f, 1024.0f - 32.0f, 0.0f,
71             0.0f, 0.0f);
72 }
73
74 void drawSunrise(int width, int height) {
75     bindTexture(NAMED_PFBackground, 0, NAMED_TSunrise);
76     drawRect(0.0f, 0.0f, width, height, 0.0f);
77 }
78
79 void drawNoon(int width, int height) {
80     bindTexture(NAMED_PFBackground, 0, NAMED_TSky);
81     drawRect(0.0f, 0.0f, width, height, 0.0f);
82 }
83
84 void drawSunset(int width, int height) {
85     bindTexture(NAMED_PFBackground, 0, NAMED_TSunset);
86     drawRect(0.0f, 0.0f, width, height, 0.0f);
87 }
88
89 int drawBlade(struct Blades_s *bladeStruct, float *bladeBuffer, int *bladeColor,
90         float brightness, float xOffset, float now) {
91
92     float scale = bladeStruct->scale;
93     float angle = bladeStruct->angle;
94     float xpos = bladeStruct->xPos + xOffset;
95     int size = bladeStruct->size;
96
97     int color = hsbToAbgr(bladeStruct->h, bladeStruct->s,
98                           lerpf(0, bladeStruct->b, brightness), 1.0f);
99
100     float newAngle = (turbulencef2(bladeStruct->turbulencex, now, 4.0f) - 0.5f) * 0.5f;
101     angle = clampf(angle + (newAngle + bladeStruct->offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
102
103     float currentAngle = HALF_PI;
104
105     float bottomX = xpos;
106     float bottomY = bladeStruct->yPos;
107
108     float d = angle * bladeStruct->hardness;
109
110     int triangles = size * 2;
111
112     for ( ; size > 0; size -= 1) {
113         float topX = bottomX - cosf_fast(currentAngle) * bladeStruct->lengthX;
114         float topY = bottomY - sinf_fast(currentAngle) * bladeStruct->lengthY;
115
116         float si = size * scale;
117         float spi = si - scale;
118
119         float bottomLeft = bottomX - si;
120         float bottomRight = bottomX + si;
121         float topLeft = topX - spi;
122         float topRight = topX + spi;
123         float bottom = bottomY + HALF_TESSELATION;
124
125         // First triangle
126         bladeColor[0] = color;                          // V1.ABGR
127
128         bladeBuffer[1] = bottomLeft;                    // V1.X
129         bladeBuffer[2] = bottom;                        // V1.Y
130
131         bladeColor[5] = color;                          // V1.ABGR
132
133         bladeBuffer[6] = topLeft;                       // V2.X
134         bladeBuffer[7] = topY;                          // V2.Y
135
136         bladeColor[10] = color;                         // V3.ABGR
137
138         bladeBuffer[11] = topRight;                     // V3.X
139         bladeBuffer[12] = topY;                         // V3.Y
140
141         // Second triangle
142         bladeBuffer += 15;
143         bladeColor += 15;
144
145         bladeColor[0] = color;                          // V1.ABGR
146
147         bladeBuffer[1] = bottomLeft;                    // V1.X
148         bladeBuffer[2] = bottom;                        // V1.Y
149
150         bladeColor[5] = color;                          // V2.ABGR
151
152         bladeBuffer[6] = topRight;                      // V2.X
153         bladeBuffer[7] = topY;                          // V2.Y
154
155         bladeColor[10] = color;                         // V3.ABGR
156
157         bladeBuffer[11] = bottomRight;                  // V3.X
158         bladeBuffer[12] = bottom;                       // V3.Y
159
160         bladeBuffer += 15;
161         bladeColor += 15;
162
163         bottomX = topX;
164         bottomY = topY;
165
166         currentAngle += d;
167     }
168
169     bladeStruct->angle = angle;
170
171     // 3 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
172     return triangles * 15;
173 }
174
175 void drawBlades(float brightness, float xOffset) {
176     // For anti-aliasing
177     bindTexture(NAMED_PFGrass, 0, NAMED_TAa);
178
179     int bladesCount = State->bladesCount;
180     int trianglesCount = State->trianglesCount;
181
182     int i = 0;
183     struct Blades_s *bladeStruct = Blades;
184     float *bladeBuffer = loadArrayF(RSID_BLADES_BUFFER, 0);
185     int *bladeColor = loadArrayI32(RSID_BLADES_BUFFER, 0);
186
187     float now = uptimeMillis() * 0.00004f;
188
189     for ( ; i < bladesCount; i += 1) {
190         int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, brightness, xOffset, now);
191         bladeBuffer += offset;
192         bladeColor += offset;
193         bladeStruct ++;
194     }
195
196     uploadToBufferObject(NAMED_BladesBuffer);
197     drawSimpleMeshRange(NAMED_BladesMesh, 0, trianglesCount * 3);
198 }
199
200 int main(int launchID) {
201     int width = State->width;
202     int height = State->height;
203
204     float x = lerpf(width, 0, State->xOffset);
205
206     float now = time(State->isPreview);
207     alpha(1.0f);
208
209     float newB = 1.0f;
210     float dawn = State->dawn;
211     float morning = State->morning;
212     float afternoon = State->afternoon;
213     float dusk = State->dusk;
214
215     if (now >= 0.0f && now < dawn) {                    // Draw night
216         drawNight(width, height);
217         newB = 0.0f;
218     } else if (now >= dawn && now <= morning) {         // Draw sunrise
219         float half = dawn + (morning - dawn) * 0.5f;
220         if (now <= half) {                              // Draw night->sunrise
221             drawNight(width, height);
222             newB = normf(dawn, half, now);
223             alpha(newB);
224             drawSunrise(width, height);
225         } else {                                        // Draw sunrise->day
226             drawSunrise(width, height);
227             alpha(normf(half, morning, now));
228             drawNoon(width, height);
229         }
230     } else if (now > morning && now < afternoon) {      // Draw day
231         drawNoon(width, height);
232     } else if (now >= afternoon && now <= dusk) {       // Draw sunset
233         float half = afternoon + (dusk - afternoon) * 0.5f;
234         if (now <= half) {                              // Draw day->sunset
235             drawNoon(width, height);
236             newB = normf(afternoon, half, now);
237             alpha(newB);
238             newB = 1.0f - newB;
239             drawSunset(width, height);
240         } else {                                        // Draw sunset->night
241             drawSunset(width, height);
242             alpha(normf(half, dusk, now));
243             drawNight(width, height);
244             newB = 0.0f;
245         }
246     } else if (now > dusk) {                            // Draw night
247         drawNight(width, height);
248         newB = 0.0f;
249     }
250
251     bindProgramFragment(NAMED_PFGrass);
252     drawBlades(newB, x);
253
254     return 30;
255 }