blob: e183178c22a791bb5af7c2b0be3896eeb752e2b4 [file] [log] [blame]
Romain Guy59206df2009-09-09 13:07:58 -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(PVSky)
17#pragma stateFragment(PFBackground)
Jason Samscc924472009-10-05 14:37:53 -070018#pragma stateStore(PFSBackground)
Romain Guy59206df2009-09-09 13:07:58 -070019
Mike Cleron70ebeb82009-11-12 07:49:08 -080020#define LEAVES_TEXTURES_COUNT 8
Romain Guy59206df2009-09-09 13:07:58 -070021#define LEAF_SIZE 0.55f
Mike Cleron5b219fc2009-11-19 23:23:13 -080022#define LEAVES_COUNT 14
Romain Guy59206df2009-09-09 13:07:58 -070023
Romain Guyf0bb9562009-10-07 12:25:24 -070024float skyOffsetX;
25float skyOffsetY;
Jason Sams756f9742009-11-15 10:16:07 -080026float g_DT;
27int g_LastTime;
Romain Guy59206df2009-09-09 13:07:58 -070028
Jason Sams2cfcc6d2009-10-21 17:51:46 -070029struct drop_s {
Jason Samsb344cf42009-11-06 11:50:42 -080030 float ampS;
31 float ampE;
Jason Sams2cfcc6d2009-10-21 17:51:46 -070032 float spread;
Jason Sams2cfcc6d2009-10-21 17:51:46 -070033 float x;
34 float y;
35};
36struct drop_s gDrops[10];
Jason Sams2cfcc6d2009-10-21 17:51:46 -070037int gMaxDrops;
38
Mike Cleron5b219fc2009-11-19 23:23:13 -080039struct Leaves_s {
40 float x;
41 float y;
42 float scale;
43 float angle;
44 float spin;
45 float u1;
46 float u2;
47 float altitude;
48 float rippled;
49 float deltaX;
50 float deltaY;
51 int newLeaf;
52};
53
54struct Leaves_s gLeavesStore[LEAVES_COUNT];
Mike Cleron5b219fc2009-11-19 23:23:13 -080055struct Leaves_s* gLeaves[LEAVES_COUNT];
Mike Cleron5b219fc2009-11-19 23:23:13 -080056struct Leaves_s* gNextLeaves[LEAVES_COUNT];
57
Jason Sams2cfcc6d2009-10-21 17:51:46 -070058void init() {
59 int ct;
60 gMaxDrops = 10;
61 for (ct=0; ct<gMaxDrops; ct++) {
Jason Samsb344cf42009-11-06 11:50:42 -080062 gDrops[ct].ampS = 0;
63 gDrops[ct].ampE = 0;
Jason Sams2cfcc6d2009-10-21 17:51:46 -070064 gDrops[ct].spread = 1;
Jason Sams2cfcc6d2009-10-21 17:51:46 -070065 }
Romain Guy59206df2009-09-09 13:07:58 -070066}
67
Romain Guy59014c62009-10-09 12:27:18 -070068void initLeaves() {
Mike Cleron5b219fc2009-11-19 23:23:13 -080069 struct Leaves_s *leaf = gLeavesStore;
Jason Sams873e9932009-10-22 14:03:52 -070070 float width = State->glWidth * 2;
Romain Guy59014c62009-10-09 12:27:18 -070071 float height = State->glHeight;
72
73 int i;
Mike Cleron5b219fc2009-11-19 23:23:13 -080074 for (i = 0; i < LEAVES_COUNT; i ++) {
75 gLeaves[i] = leaf;
Romain Guy59014c62009-10-09 12:27:18 -070076 int sprite = randf(LEAVES_TEXTURES_COUNT);
Romain Guy2d427942009-10-14 15:43:27 -070077 leaf->x = randf2(-width * 0.5f, width * 0.5f);
78 leaf->y = randf2(-height * 0.5f, height * 0.5f);
Romain Guy59014c62009-10-09 12:27:18 -070079 leaf->scale = randf2(0.4f, 0.5f);
80 leaf->angle = randf2(0.0f, 360.0f);
Romain Guy2d427942009-10-14 15:43:27 -070081 leaf->spin = degf(randf2(-0.02f, 0.02f)) * 0.25f;
Romain Guy59014c62009-10-09 12:27:18 -070082 leaf->u1 = sprite / (float) LEAVES_TEXTURES_COUNT;
83 leaf->u2 = (sprite + 1) / (float) LEAVES_TEXTURES_COUNT;
84 leaf->altitude = -1.0f;
85 leaf->rippled = 1.0f;
Jason Sams756f9742009-11-15 10:16:07 -080086 leaf->deltaX = randf2(-0.02f, 0.02f) / 2.0f;
87 leaf->deltaY = -0.08f * randf2(0.9f, 1.1f) / 2.0f;
Romain Guy59014c62009-10-09 12:27:18 -070088 leaf++;
89 }
90}
91
Jason Samsb344cf42009-11-06 11:50:42 -080092void updateDrop(int ct) {
Jason Sams756f9742009-11-15 10:16:07 -080093 gDrops[ct].spread += 30.f * g_DT;
Jason Sams16bf60c2010-01-26 12:40:07 -080094 gDrops[ct].ampE = gDrops[ct].ampS / gDrops[ct].spread;
Jason Samsb344cf42009-11-06 11:50:42 -080095}
96
Jason Sams2cfcc6d2009-10-21 17:51:46 -070097void drop(int x, int y, float s) {
Jason Sams6eec5982009-10-23 17:47:12 -070098 int ct;
99 int iMin = 0;
100 float minAmp = 10000.f;
101 for (ct = 0; ct < gMaxDrops; ct++) {
Jason Samsb344cf42009-11-06 11:50:42 -0800102 if (gDrops[ct].ampE < minAmp) {
Jason Sams6eec5982009-10-23 17:47:12 -0700103 iMin = ct;
Jason Samsb344cf42009-11-06 11:50:42 -0800104 minAmp = gDrops[ct].ampE;
Jason Sams6eec5982009-10-23 17:47:12 -0700105 }
106 }
Jason Samsb344cf42009-11-06 11:50:42 -0800107 gDrops[iMin].ampS = s;
108 gDrops[iMin].spread = 0;
Jason Sams6eec5982009-10-23 17:47:12 -0700109 gDrops[iMin].x = x;
110 gDrops[iMin].y = State->meshHeight - y - 1;
Jason Samsb344cf42009-11-06 11:50:42 -0800111 updateDrop(iMin);
Romain Guy59206df2009-09-09 13:07:58 -0700112}
113
114void generateRipples() {
Jason Sams16bf60c2010-01-26 12:40:07 -0800115 int ct;
116 for (ct = 0; ct < gMaxDrops; ct++) {
117 struct drop_s * d = &gDrops[ct];
118 vecF32_4_t *v = &Constants->Drop01;
119 v += ct;
120 v->x = d->x;
121 v->y = d->y;
122 v->z = d->ampE * 0.12f;
123 v->w = d->spread;
Romain Guy59206df2009-09-09 13:07:58 -0700124 }
Jason Sams16bf60c2010-01-26 12:40:07 -0800125 Constants->Offset.x = State->xOffset;
126
Jason Sams73f2f5f2009-11-10 16:13:23 -0800127 for (ct = 0; ct < gMaxDrops; ct++) {
128 updateDrop(ct);
129 }
Romain Guy59206df2009-09-09 13:07:58 -0700130}
131
Jason Sams6eec5982009-10-23 17:47:12 -0700132void genLeafDrop(struct Leaves_s *leaf, float amp) {
133 float nx = (leaf->x + State->glWidth * 0.5f) / State->glWidth;
134 float ny = (leaf->y + State->glHeight * 0.5f) / State->glHeight;
135 drop(nx * State->meshWidth, State->meshHeight - ny * State->meshHeight, amp);
136
137}
138
Mike Cleron5b219fc2009-11-19 23:23:13 -0800139int drawLeaf(struct Leaves_s *leaf) {
Romain Guya6d4d982009-10-15 12:37:13 -0700140
Romain Guy59014c62009-10-09 12:27:18 -0700141 float x = leaf->x;
Romain Guy59014c62009-10-09 12:27:18 -0700142 float y = leaf->y;
Romain Guy59206df2009-09-09 13:07:58 -0700143
Romain Guy59014c62009-10-09 12:27:18 -0700144 float u1 = leaf->u1;
145 float u2 = leaf->u2;
Romain Guy59206df2009-09-09 13:07:58 -0700146
Romain Guy59014c62009-10-09 12:27:18 -0700147 float a = leaf->altitude;
148 float s = leaf->scale;
149 float r = leaf->angle;
Romain Guy59206df2009-09-09 13:07:58 -0700150
151 float tz = 0.0f;
152 if (a > 0.0f) {
153 tz = -a;
Romain Guy59206df2009-09-09 13:07:58 -0700154 }
155
Jason Sams2cfcc6d2009-10-21 17:51:46 -0700156 float matrix[16];
Romain Guy59014c62009-10-09 12:27:18 -0700157 if (a > 0.0f) {
Jason Sams73f2f5f2009-11-10 16:13:23 -0800158
Mike Cleronfc6bdef2009-11-10 13:31:30 -0800159 float alpha = 1.0f;
Mike Cleron701a47f2009-11-10 12:55:26 -0800160 if (a >= 0.4f) alpha = 1.0f - (a - 0.4f) / 0.1f;
Jason Sams73f2f5f2009-11-10 16:13:23 -0800161
Mike Cleron701a47f2009-11-10 12:55:26 -0800162 color(0.0f, 0.0f, 0.0f, alpha * 0.15f);
Romain Guya6d4d982009-10-15 12:37:13 -0700163
Jason Sams6eec5982009-10-23 17:47:12 -0700164 if (State->rotate) {
Romain Guya6d4d982009-10-15 12:37:13 -0700165 matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
166 } else {
167 matrixLoadIdentity(matrix);
168 }
Jason Sams73f2f5f2009-11-10 16:13:23 -0800169
Mike Cleron701a47f2009-11-10 12:55:26 -0800170 float shadowOffet = a / 5;
Jason Sams73f2f5f2009-11-10 16:13:23 -0800171
Mike Cleron701a47f2009-11-10 12:55:26 -0800172 matrixTranslate(matrix, (x - State->xOffset * 2) + (shadowOffet / 2), y - shadowOffet, tz);
Romain Guy59014c62009-10-09 12:27:18 -0700173 matrixScale(matrix, s, s, 1.0f);
174 matrixRotate(matrix, r, 0.0f, 0.0f, 1.0f);
175 vpLoadModelMatrix(matrix);
176
Jason Sams873e9932009-10-22 14:03:52 -0700177 drawQuadTexCoords(-LEAF_SIZE, -LEAF_SIZE, 0, u1, 1.0f,
178 LEAF_SIZE, -LEAF_SIZE, 0, u2, 1.0f,
179 LEAF_SIZE, LEAF_SIZE, 0, u2, 0.0f,
180 -LEAF_SIZE, LEAF_SIZE, 0, u1, 0.0f);
Romain Guy59014c62009-10-09 12:27:18 -0700181
Romain Guy59014c62009-10-09 12:27:18 -0700182 color(1.0f, 1.0f, 1.0f, alpha);
183 } else {
184 color(1.0f, 1.0f, 1.0f, 1.0f);
185 }
186
Jason Sams6eec5982009-10-23 17:47:12 -0700187 if (State->rotate) {
Romain Guya6d4d982009-10-15 12:37:13 -0700188 matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
189 } else {
190 matrixLoadIdentity(matrix);
191 }
Jason Sams873e9932009-10-22 14:03:52 -0700192 matrixTranslate(matrix, x - State->xOffset * 2, y, tz);
Romain Guy59206df2009-09-09 13:07:58 -0700193 matrixScale(matrix, s, s, 1.0f);
194 matrixRotate(matrix, r, 0.0f, 0.0f, 1.0f);
195 vpLoadModelMatrix(matrix);
196
Jason Sams873e9932009-10-22 14:03:52 -0700197 drawQuadTexCoords(-LEAF_SIZE, -LEAF_SIZE, 0, u1, 1.0f,
198 LEAF_SIZE, -LEAF_SIZE, 0, u2, 1.0f,
199 LEAF_SIZE, LEAF_SIZE, 0, u2, 0.0f,
200 -LEAF_SIZE, LEAF_SIZE, 0, u1, 0.0f);
Romain Guy59206df2009-09-09 13:07:58 -0700201
Romain Guy59014c62009-10-09 12:27:18 -0700202 float spin = leaf->spin;
Romain Guy59206df2009-09-09 13:07:58 -0700203 if (a <= 0.0f) {
Romain Guy59014c62009-10-09 12:27:18 -0700204 float rippled = leaf->rippled;
Romain Guy59206df2009-09-09 13:07:58 -0700205 if (rippled < 0.0f) {
Jason Sams6eec5982009-10-23 17:47:12 -0700206 genLeafDrop(leaf, 1.5f);
207 //drop(((x + State->glWidth * 0.5f) / State->glWidth) * meshWidth,
208 // meshHeight - ((y + State->glHeight * 0.5f) / State->glHeight) * meshHeight, 1);
Romain Guy59206df2009-09-09 13:07:58 -0700209 spin /= 4.0f;
Romain Guy59014c62009-10-09 12:27:18 -0700210 leaf->spin = spin;
211 leaf->rippled = 1.0f;
Romain Guy59206df2009-09-09 13:07:58 -0700212 }
Jason Sams756f9742009-11-15 10:16:07 -0800213 leaf->x = x + leaf->deltaX * g_DT;
214 leaf->y = y + leaf->deltaY * g_DT;
Romain Guy59206df2009-09-09 13:07:58 -0700215 r += spin;
Romain Guy59014c62009-10-09 12:27:18 -0700216 leaf->angle = r;
Romain Guy59206df2009-09-09 13:07:58 -0700217 } else {
Jason Sams756f9742009-11-15 10:16:07 -0800218 a -= 0.15f * g_DT;
Romain Guy59014c62009-10-09 12:27:18 -0700219 leaf->altitude = a;
Romain Guy59206df2009-09-09 13:07:58 -0700220 r += spin * 2.0f;
Romain Guy59014c62009-10-09 12:27:18 -0700221 leaf->angle = r;
Romain Guy59206df2009-09-09 13:07:58 -0700222 }
223
Mike Cleron5b219fc2009-11-19 23:23:13 -0800224 int newLeaf = 0;
Jason Sams6eec5982009-10-23 17:47:12 -0700225 if (-LEAF_SIZE * s + x > State->glWidth || LEAF_SIZE * s + x < -State->glWidth ||
226 LEAF_SIZE * s + y < -State->glHeight / 2.0f) {
Romain Guy59206df2009-09-09 13:07:58 -0700227
228 int sprite = randf(LEAVES_TEXTURES_COUNT);
Jason Sams6eec5982009-10-23 17:47:12 -0700229 leaf->x = randf2(-State->glWidth, State->glWidth);
230 leaf->y = randf2(-State->glHeight * 0.5f, State->glHeight * 0.5f);
Jason Sams756f9742009-11-15 10:16:07 -0800231
Romain Guy59014c62009-10-09 12:27:18 -0700232 leaf->scale = randf2(0.4f, 0.5f);
Mike Cleron70ebeb82009-11-12 07:49:08 -0800233 leaf->spin = degf(randf2(-0.02f, 0.02f)) * 0.35f;
Romain Guy59014c62009-10-09 12:27:18 -0700234 leaf->u1 = sprite / (float) LEAVES_TEXTURES_COUNT;
235 leaf->u2 = (sprite + 1) / (float) LEAVES_TEXTURES_COUNT;
Mike Cleron70ebeb82009-11-12 07:49:08 -0800236 leaf->altitude = 0.7f;
Romain Guy59014c62009-10-09 12:27:18 -0700237 leaf->rippled = -1.0f;
Jason Sams756f9742009-11-15 10:16:07 -0800238 leaf->deltaX = randf2(-0.02f, 0.02f) / 2.0f;
239 leaf->deltaY = -0.08f * randf2(0.9f, 1.1f) / 2.0f;
Mike Cleron5b219fc2009-11-19 23:23:13 -0800240 leaf->newLeaf = 1;
241 newLeaf = 1;
Romain Guy59206df2009-09-09 13:07:58 -0700242 }
Mike Cleron5b219fc2009-11-19 23:23:13 -0800243 return newLeaf;
Romain Guy59206df2009-09-09 13:07:58 -0700244}
245
246void drawLeaves() {
Romain Guy59014c62009-10-09 12:27:18 -0700247 bindProgramFragment(NAMED_PFSky);
Romain Guy59206df2009-09-09 13:07:58 -0700248 bindProgramFragmentStore(NAMED_PFSLeaf);
249 bindProgramVertex(NAMED_PVSky);
Romain Guy59014c62009-10-09 12:27:18 -0700250 bindTexture(NAMED_PFSky, 0, NAMED_TLeaves);
251
252 color(1.0f, 1.0f, 1.0f, 1.0f);
Romain Guy59206df2009-09-09 13:07:58 -0700253
Mike Cleron5b219fc2009-11-19 23:23:13 -0800254 int newLeaves = 0;
Romain Guy59206df2009-09-09 13:07:58 -0700255 int i = 0;
Mike Cleron5b219fc2009-11-19 23:23:13 -0800256 for ( ; i < LEAVES_COUNT; i += 1) {
257 if (drawLeaf(gLeaves[i])) {
258 newLeaves = 1;
Jason Sams0cd53062009-12-08 15:46:00 -0800259
Mike Cleron5b219fc2009-11-19 23:23:13 -0800260 }
261 }
Jason Sams0cd53062009-12-08 15:46:00 -0800262
263 if (newLeaves > 0) {
Mike Cleron5b219fc2009-11-19 23:23:13 -0800264 int index = 0;
Jason Sams0cd53062009-12-08 15:46:00 -0800265
Mike Cleron5b219fc2009-11-19 23:23:13 -0800266 // Copy all the old leaves to the beginning of gNextLeaves
267 for (i=0; i < LEAVES_COUNT; i++) {
268 if (gLeaves[i]->newLeaf == 0) {
269 gNextLeaves[index] = gLeaves[i];
270 index++;
271 }
272 }
Jason Sams0cd53062009-12-08 15:46:00 -0800273
Mike Cleron5b219fc2009-11-19 23:23:13 -0800274 // Now copy all the newly falling leaves to the end of gNextLeaves
275 for (i=0; i < LEAVES_COUNT; i++) {
276 if (gLeaves[i]->newLeaf > 0) {
277 gNextLeaves[index] = gLeaves[i];
278 gNextLeaves[index]->newLeaf = 0;
279 index++;
280 }
281 }
Jason Sams0cd53062009-12-08 15:46:00 -0800282
Mike Cleron5b219fc2009-11-19 23:23:13 -0800283 // And move everything in gNextLeaves back to gLeaves
284 for (i=0; i < LEAVES_COUNT; i++) {
285 gLeaves[i] = gNextLeaves[i];
286 }
Romain Guy59206df2009-09-09 13:07:58 -0700287 }
288
289 float matrix[16];
290 matrixLoadIdentity(matrix);
291 vpLoadModelMatrix(matrix);
292}
293
294void drawRiverbed() {
295 bindTexture(NAMED_PFBackground, 0, NAMED_TRiverbed);
Jason Sams2430b672009-09-24 13:01:52 -0700296 drawSimpleMesh(NAMED_WaterMesh);
Romain Guy59206df2009-09-09 13:07:58 -0700297}
298
Romain Guy59206df2009-09-09 13:07:58 -0700299int main(int index) {
Jason Sams756f9742009-11-15 10:16:07 -0800300 // Compute dt in seconds.
301 int newTime = uptimeMillis();
302 g_DT = (newTime - g_LastTime) / 1000.f;
303 g_LastTime = newTime;
304 g_DT = minf(g_DT, 0.2f);
305
306
Romain Guy59206df2009-09-09 13:07:58 -0700307 if (Drop->dropX != -1) {
Jason Sams73f2f5f2009-11-10 16:13:23 -0800308 drop(Drop->dropX, Drop->dropY, 2);
Romain Guy59206df2009-09-09 13:07:58 -0700309 Drop->dropX = -1;
310 Drop->dropY = -1;
311 }
Romain Guy2d427942009-10-14 15:43:27 -0700312
Jason Sams2cfcc6d2009-10-21 17:51:46 -0700313 int ct;
Jason Sams6eec5982009-10-23 17:47:12 -0700314 int add = 0;
Jason Sams2cfcc6d2009-10-21 17:51:46 -0700315 for (ct = 0; ct < gMaxDrops; ct++) {
Jason Samsb344cf42009-11-06 11:50:42 -0800316 if (gDrops[ct].ampE < 0.005f) {
Jason Sams6eec5982009-10-23 17:47:12 -0700317 add = 1;
318 }
Jason Sams2cfcc6d2009-10-21 17:51:46 -0700319 }
Romain Guy2d427942009-10-14 15:43:27 -0700320
Jason Sams6eec5982009-10-23 17:47:12 -0700321 if (add) {
Mike Cleron5b219fc2009-11-19 23:23:13 -0800322 int i = (int)randf(LEAVES_COUNT);
323 genLeafDrop(gLeaves[i], randf(0.3f) + 0.1f);
Romain Guya454eca2009-10-14 18:22:20 -0700324 }
Romain Guy59206df2009-09-09 13:07:58 -0700325
Romain Guya6d4d982009-10-15 12:37:13 -0700326 if (State->rotate) {
327 float matrix[16];
328 matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
329 vpLoadModelMatrix(matrix);
330 }
331
Jason Sams16bf60c2010-01-26 12:40:07 -0800332 bindProgramVertex(NAMED_PVWater);
333 generateRipples();
Romain Guy59206df2009-09-09 13:07:58 -0700334 drawRiverbed();
Jason Sams16bf60c2010-01-26 12:40:07 -0800335
336 bindProgramVertex(NAMED_PVSky);
Romain Guy59206df2009-09-09 13:07:58 -0700337 drawLeaves();
Romain Guy59206df2009-09-09 13:07:58 -0700338
Jason Sams0cd53062009-12-08 15:46:00 -0800339 return 30;
Romain Guy59206df2009-09-09 13:07:58 -0700340}