blob: 696ef7524a32e234b0876f185f33982b050e9502 [file] [log] [blame]
Romain Guy55a384c2009-08-12 10:58:02 -07001// 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 stateFragmentStore(PFSBackground)
19
20#define RSID_STATE 0
Romain Guy55a384c2009-08-12 10:58:02 -070021#define RSID_BLADES 1
Romain Guyb7d22522009-08-20 12:08:50 -070022#define RSID_BLADES_BUFFER 2
23
24#define BLADE_STRUCT_FIELDS_COUNT 13
Romain Guy55a384c2009-08-12 10:58:02 -070025#define BLADE_STRUCT_ANGLE 0
26#define BLADE_STRUCT_SIZE 1
27#define BLADE_STRUCT_XPOS 2
28#define BLADE_STRUCT_YPOS 3
29#define BLADE_STRUCT_OFFSET 4
30#define BLADE_STRUCT_SCALE 5
31#define BLADE_STRUCT_LENGTHX 6
32#define BLADE_STRUCT_LENGTHY 7
33#define BLADE_STRUCT_HARDNESS 8
34#define BLADE_STRUCT_H 9
35#define BLADE_STRUCT_S 10
36#define BLADE_STRUCT_B 11
Romain Guyb7d22522009-08-20 12:08:50 -070037#define BLADE_STRUCT_TURBULENCEX 12
Romain Guy55a384c2009-08-12 10:58:02 -070038
Romain Guy78b54da2009-08-19 18:11:33 -070039#define TESSELATION 0.5f
Romain Guyb7d22522009-08-20 12:08:50 -070040#define HALF_TESSELATION 0.25f
Romain Guy55a384c2009-08-12 10:58:02 -070041
42#define MAX_BEND 0.09f
43
44#define MIDNIGHT 0.0f
45#define MORNING 0.375f
46#define AFTERNOON 0.6f
47#define DUSK 0.8f
48
Romain Guyb7d22522009-08-20 12:08:50 -070049#define SECONDS_IN_DAY 86400.0f
Romain Guy55a384c2009-08-12 10:58:02 -070050
51#define PI 3.1415926f
Romain Guyb7d22522009-08-20 12:08:50 -070052#define HALF_PI 1.570796326f
Romain Guy55a384c2009-08-12 10:58:02 -070053
54#define REAL_TIME 0
55
Romain Guy44da1782009-08-28 11:03:21 -070056float time() {
Romain Guy55a384c2009-08-12 10:58:02 -070057 if (REAL_TIME) {
58 return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY;
59 }
Romain Guy44da1782009-08-28 11:03:21 -070060 float t = uptimeMillis() / 20000.0f;
61 return t - (int) t;
Romain Guy55a384c2009-08-12 10:58:02 -070062}
63
64void alpha(float a) {
65 color(1.0f, 1.0f, 1.0f, a);
66}
67
68void drawNight(int width, int height) {
Romain Guyb7d22522009-08-20 12:08:50 -070069 bindTexture(NAMED_PFBackground, 0, NAMED_TNight);
Romain Guy55a384c2009-08-12 10:58:02 -070070 drawQuadTexCoords(
71 0.0f, -32.0f, 0.0f,
72 0.0f, 1.0f,
73 width, -32.0f, 0.0f,
74 2.0f, 1.0f,
75 width, 1024.0f - 32.0f, 0.0f,
76 2.0f, 0.0f,
77 0.0f, 1024.0f - 32.0f, 0.0f,
78 0.0f, 0.0f);
Romain Guy55a384c2009-08-12 10:58:02 -070079}
80
81void drawSunrise(int width, int height) {
82 bindTexture(NAMED_PFBackground, 0, NAMED_TSunrise);
83 drawRect(0.0f, 0.0f, width, height, 0.0f);
84}
85
86void drawNoon(int width, int height) {
87 bindTexture(NAMED_PFBackground, 0, NAMED_TSky);
88 drawRect(0.0f, 0.0f, width, height, 0.0f);
89}
90
91void drawSunset(int width, int height) {
92 bindTexture(NAMED_PFBackground, 0, NAMED_TSunset);
93 drawRect(0.0f, 0.0f, width, height, 0.0f);
94}
95
Romain Guy44da1782009-08-28 11:03:21 -070096int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now, float xOffset) {
Romain Guy55a384c2009-08-12 10:58:02 -070097 float offset = bladeStruct[BLADE_STRUCT_OFFSET];
98 float scale = bladeStruct[BLADE_STRUCT_SCALE];
99 float angle = bladeStruct[BLADE_STRUCT_ANGLE];
100 float hardness = bladeStruct[BLADE_STRUCT_HARDNESS];
Romain Guyb7d22522009-08-20 12:08:50 -0700101 float turbulenceX = bladeStruct[BLADE_STRUCT_TURBULENCEX];
102
Romain Guy44da1782009-08-28 11:03:21 -0700103 float xpos = bladeStruct[BLADE_STRUCT_XPOS] + xOffset;
Romain Guy55a384c2009-08-12 10:58:02 -0700104 float ypos = bladeStruct[BLADE_STRUCT_YPOS];
105
106 float lengthX = bladeStruct[BLADE_STRUCT_LENGTHX];
107 float lengthY = bladeStruct[BLADE_STRUCT_LENGTHY];
108
109 int size = bladeStruct[BLADE_STRUCT_SIZE];
110
111 float h = bladeStruct[BLADE_STRUCT_H];
112 float s = bladeStruct[BLADE_STRUCT_S];
113 float b = bladeStruct[BLADE_STRUCT_B];
114
115 float newB = 1.0f;
116 if (now >= MIDNIGHT && now < MORNING) {
117 newB = now / MORNING;
118 }
119
120 if (now >= AFTERNOON && now < DUSK) {
121 newB = 1.0f - normf(AFTERNOON, DUSK, now);
122 }
123
124 if (now >= DUSK) {
125 newB = 0.0f;
126 }
127
Romain Guyb7d22522009-08-20 12:08:50 -0700128 int color = hsbToAbgr(h, s, lerpf(0, b, newB), 1.0f);
Romain Guy55a384c2009-08-12 10:58:02 -0700129
Romain Guy44da1782009-08-28 11:03:21 -0700130 float newAngle = turbulencef2(turbulenceX, uptimeMillis() * 0.00004f, 4.0f) - 0.5f;
Romain Guy78b54da2009-08-19 18:11:33 -0700131 newAngle *= 0.5f;
Romain Guy55a384c2009-08-12 10:58:02 -0700132 angle = clampf(angle + (newAngle + offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
133
Romain Guyb7d22522009-08-20 12:08:50 -0700134 float currentAngle = HALF_PI;
Romain Guy55a384c2009-08-12 10:58:02 -0700135
136 float bottomX = xpos;
137 float bottomY = ypos;
138
Romain Guyb7d22522009-08-20 12:08:50 -0700139 float d = angle * hardness;
Romain Guy55a384c2009-08-12 10:58:02 -0700140
Romain Guyb7d22522009-08-20 12:08:50 -0700141 int triangles = size * 2;
Romain Guy55a384c2009-08-12 10:58:02 -0700142
Romain Guyb7d22522009-08-20 12:08:50 -0700143 for ( ; size > 0; size -= 1) {
144 float topX = bottomX - cosf_fast(currentAngle) * lengthX;
145 float topY = bottomY - sinf_fast(currentAngle) * lengthY;
Romain Guy55a384c2009-08-12 10:58:02 -0700146
Romain Guyb7d22522009-08-20 12:08:50 -0700147 float si = size * scale;
148 float spi = si - scale;
149
150 float bottomLeft = bottomX - si;
151 float bottomRight = bottomX + si;
152 float topLeft = topX - spi;
153 float topRight = topX + spi;
154 float bottom = bottomY + HALF_TESSELATION;
155
156 // First triangle
157 bladeColor[0] = color; // V1.ABGR
158
159 bladeBuffer[1] = bottomLeft; // V1.X
160 bladeBuffer[2] = bottom; // V1.Y
161
162 bladeColor[5] = color; // V1.ABGR
163
164 bladeBuffer[6] = topLeft; // V2.X
165 bladeBuffer[7] = topY; // V2.Y
166
167 bladeColor[10] = color; // V3.ABGR
168
169 bladeBuffer[11] = topRight; // V3.X
170 bladeBuffer[12] = topY; // V3.Y
171
172 // Second triangle
173 bladeBuffer += 15;
174 bladeColor += 15;
175
176 bladeColor[0] = color; // V1.ABGR
177
178 bladeBuffer[1] = bottomLeft; // V1.X
179 bladeBuffer[2] = bottom; // V1.Y
180
181 bladeColor[5] = color; // V2.ABGR
182
183 bladeBuffer[6] = topRight; // V2.X
184 bladeBuffer[7] = topY; // V2.Y
185
186 bladeColor[10] = color; // V3.ABGR
187
188 bladeBuffer[11] = bottomRight; // V3.X
189 bladeBuffer[12] = bottom; // V3.Y
190
191 bladeBuffer += 15;
192 bladeColor += 15;
Romain Guy55a384c2009-08-12 10:58:02 -0700193
194 bottomX = topX;
195 bottomY = topY;
Romain Guyb7d22522009-08-20 12:08:50 -0700196
197 currentAngle += d;
Romain Guy55a384c2009-08-12 10:58:02 -0700198 }
199
Romain Guyb7d22522009-08-20 12:08:50 -0700200 bladeStruct[BLADE_STRUCT_ANGLE] = angle;
201
202 // 3 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
203 return triangles * 15;
Romain Guy55a384c2009-08-12 10:58:02 -0700204}
205
Romain Guy44da1782009-08-28 11:03:21 -0700206void drawBlades(float now, float xOffset) {
Romain Guy55a384c2009-08-12 10:58:02 -0700207 // For anti-aliasing
208 bindTexture(NAMED_PFBackground, 0, NAMED_TAa);
209
Romain Guyb7d22522009-08-20 12:08:50 -0700210 int bladesCount = State_bladesCount;
211 int trianglesCount = State_trianglesCount;
Romain Guy55a384c2009-08-12 10:58:02 -0700212
213 int i = 0;
Romain Guyb7d22522009-08-20 12:08:50 -0700214 float *bladeStruct = loadArrayF(RSID_BLADES, 0);
215 float *bladeBuffer = loadArrayF(RSID_BLADES_BUFFER, 0);
216 int *bladeColor = loadArrayI32(RSID_BLADES_BUFFER, 0);
217
218 for ( ; i < bladesCount; i += 1) {
Romain Guy44da1782009-08-28 11:03:21 -0700219 int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, now, xOffset);
Romain Guyb7d22522009-08-20 12:08:50 -0700220 bladeBuffer += offset;
221 bladeColor += offset;
222 bladeStruct += BLADE_STRUCT_FIELDS_COUNT;
Romain Guy55a384c2009-08-12 10:58:02 -0700223 }
Romain Guyb7d22522009-08-20 12:08:50 -0700224
225 uploadToBufferObject(NAMED_BladesBuffer);
226 drawSimpleMeshRange(NAMED_BladesMesh, 0, trianglesCount * 3);
Romain Guy55a384c2009-08-12 10:58:02 -0700227}
228
229int main(int launchID) {
Romain Guyb7d22522009-08-20 12:08:50 -0700230 int width = State_width;
231 int height = State_height;
Romain Guy55a384c2009-08-12 10:58:02 -0700232
Romain Guy44da1782009-08-28 11:03:21 -0700233 float x = lerpf(width, 0, State_xOffset);
234
235 float now = time();
Romain Guy55a384c2009-08-12 10:58:02 -0700236 alpha(1.0f);
237
238 if (now >= MIDNIGHT && now < MORNING) {
239 drawNight(width, height);
240 alpha(normf(MIDNIGHT, MORNING, now));
241 drawSunrise(width, height);
242 } else if (now >= MORNING && now < AFTERNOON) {
243 drawSunrise(width, height);
244 alpha(normf(MORNING, AFTERNOON, now));
245 drawNoon(width, height);
246 } else if (now >= AFTERNOON && now < DUSK) {
247 drawNoon(width, height);
248 alpha(normf(AFTERNOON, DUSK, now));
249 drawSunset(width, height);
250 } else if (now >= DUSK) {
251 drawNight(width, height);
252 alpha(1.0f - normf(DUSK, 1.0f, now));
253 drawSunset(width, height);
254 }
255
Romain Guy44da1782009-08-28 11:03:21 -0700256 drawBlades(now, x);
Romain Guy55a384c2009-08-12 10:58:02 -0700257
258 return 1;
259}