capture feature
[censuslogo] / src / app.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <GL/gl.h>
6 #include "app.h"
7 #include "logo.h"
8
9 #ifndef GL_MULTISAMPLE
10 #define GL_MULTISAMPLE  0x809d
11 #endif
12
13 int nverts = 256;
14 int msaa = 1;
15 int fullscr = 0;
16
17
18 static void draw_disc(float x, float y, float rad, int sub);
19 static void draw_line(float x0, float y0, float x1, float y1, float rad);
20 static void print_usage(const char *argv0);
21
22 int app_init(void)
23 {
24         if(init_logo("data/census.curves") == -1) {
25                 return -1;
26         }
27
28 #ifdef MSAA
29         if(msaa) {
30                 glEnable(GL_MULTISAMPLE);
31         }
32 #endif
33
34         return 0;
35 }
36
37 #define LOOPTIME        1.45f
38
39 void app_display(void)
40 {
41         int i;
42         float t = (float)msec / 1000.0f;
43         float a[2], b[2], dt;
44         float anim, alpha;
45
46         glClear(GL_COLOR_BUFFER_BIT);
47
48         glLineWidth(5.0);
49
50         anim = fmod(t / 6.0f, LOOPTIME);
51
52         if(nloops > 0 && (anim < t / 6.0f)) {
53                 app_quit();
54                 return;
55         }
56
57         alpha = 1.0f - ((anim - (LOOPTIME - 0.075)) / 0.06f);
58         if(alpha < 0.0f) alpha = 0.0f;
59         if(alpha > 1.0f) alpha = 1.0f;
60
61         dt = (anim > 1.0f ? 1.0f : anim) / (float)(nverts - 1);
62
63         glColor4f(1, 1, 1, alpha);
64         for(i=0; i<nverts-1; i++) {
65                 float t0 = (float)i * dt;
66                 float t1 = (float)(i + 1) * dt;
67                 eval_logo(a, t0);
68                 eval_logo(b, t1);
69                 draw_line(a[0], a[1], b[0], b[1], 0.02);
70         }
71
72         if(anim > 0.0f) {
73                 eval_logo(a, 0);
74                 draw_disc(a[0], a[1], 0.05, 22);
75         }
76         if(anim >= 1.0f) {
77                 eval_logo(b, 1);
78                 draw_disc(b[0], b[1], 0.05, 22);
79         }
80
81         glEnable(GL_BLEND);
82         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
83
84         glColor4f(0.8, 0, 0, 2.0 * (anim - 1.0f) / (LOOPTIME - 1.0f));
85         draw_disc(0, 0, 0.14, 30);
86
87         if(alpha < 1.0f) {
88                 glBegin(GL_QUADS);
89                 glColor4f(0, 0, 0, 1.0f - alpha);
90                 glVertex2f(-1, -1);
91                 glVertex2f(1, -1);
92                 glVertex2f(1, 1);
93                 glVertex2f(-1, 1);
94                 glEnd();
95         }
96
97         glDisable(GL_BLEND);
98 }
99
100 static void draw_disc(float x, float y, float rad, int sub)
101 {
102         int i;
103         glBegin(GL_TRIANGLE_FAN);
104         glVertex2f(x, y);
105         for(i=0; i<sub; i++) {
106                 float t = (float)i / (float)(sub - 1);
107                 float theta = t * M_PI * 2.0;
108                 glVertex2f(cos(theta) * rad + x, sin(theta) * rad + y);
109         }
110         glEnd();
111 }
112
113 static void draw_line(float x0, float y0, float x1, float y1, float rad)
114 {
115         float dx, dy, rx, ry, len;
116
117         dx = x1 - x0;
118         dy = y1 - y0;
119         len = sqrt(dx * dx + dy * dy);
120
121         rx = rad * dy / len;
122         ry = -rad * dx / len;
123
124         draw_disc(x0, y0, rad, 12);
125         draw_disc(x1, y1, rad, 12);
126
127         glBegin(GL_QUADS);
128         glVertex2f(x0 + rx, y0 + ry);
129         glVertex2f(x1 + rx, y1 + ry);
130         glVertex2f(x1 - rx, y1 - ry);
131         glVertex2f(x0 - rx, y0 - ry);
132         glEnd();
133 }
134
135
136 void app_reshape(int x, int y)
137 {
138         float aspect = (float)x / (float)y;
139         glViewport(0, 0, x, y);
140         glMatrixMode(GL_PROJECTION);
141         glLoadIdentity();
142         glScalef(1.0f / aspect, 1.0f, 1.0f);
143 }
144
145 void app_keyboard(int key, int pressed)
146 {
147         switch(key) {
148         case 27:
149                 app_quit();
150
151         case '-':
152                 nverts -= 8;
153                 printf("nverts: %d\n", nverts);
154                 break;
155
156         case '=':
157                 nverts += 8;
158                 printf("nverts: %d\n", nverts);
159                 break;
160
161         case 'f':
162                 fullscr = !fullscr;
163                 if(fullscr) {
164                         app_fullscreen();
165                 } else {
166                         app_windowed();
167                 }
168                 break;
169         }
170 }
171
172
173 int app_parse_args(int argc, char **argv)
174 {
175         int i;
176
177         for(i=1; i<argc; i++) {
178                 if(argv[i][0] == '-') {
179                         if(strcmp(argv[i], "-fs") == 0) {
180                                 fullscr = 1;
181                         } else if(strcmp(argv[i], "-noaa") == 0) {
182                                 msaa = 0;
183                         } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
184                                 print_usage(argv[0]);
185                                 exit(0);
186                         } else {
187                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
188                                 return -1;
189                         }
190                 } else {
191                         fprintf(stderr, "unexpected argument: %s\n", argv[i]);
192                         return -1;
193                 }
194         }
195         return 0;
196 }
197
198 static void print_usage(const char *argv0)
199 {
200         printf("Usage: %s [options]\n", argv0);
201         printf("Options:\n");
202         printf(" -fs: fullscreen\n");
203         printf(" -noaa: disable anti-aliasing\n");
204         printf(" -h,-help: print usage and exit\n");
205 }