2 #include <GL/freeglut.h>
14 #define BEAM_SHELLS 40
15 #define BEAM_RMIN 0.01
16 #define BEAM_RMAX 0.125
17 #define BEAM_ENERGY 0.01
19 #define BEAM_DEF_SPEED 0.1
28 static void cleanup();
30 static void display();
32 static void backdrop();
36 static void reshape(int x, int y);
37 static void keyboard(unsigned char c, int x, int y);
38 static void keyb_special(int key, int x, int y);
39 static void mbutton(int bn, int state, int x, int y);
40 static void mmotion(int x, int y);
42 int win_width, win_height;
43 static bool freecam = true;
45 static Camera cam = {0, 0, 0, 0, 0, 10};
46 static unsigned int sdr_beam, sdr_sky;
47 static long start_time;
48 static long anim_stop_time;
49 long tmsec, prev_tmsec, anim_time;
52 static const float sil_color[] = {0.05, 0.02, 0.1, 1.0};
53 static const float beam_color[] = {0.5, 0.4, 0.2, 1.0};
55 static float beam_angle, beam_speed;
56 static float beam_len;
57 static float xlogo_alpha;
59 static bool show_help, show_ui = true;
61 int main(int argc, char **argv)
63 glutInit(&argc, argv);
64 glutInitWindowSize(800, 600);
65 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
67 glutCreateWindow("Faros (press F1 for controls help)");
69 glutDisplayFunc(display);
71 glutReshapeFunc(reshape);
72 glutKeyboardFunc(keyboard);
73 glutSpecialFunc(keyb_special);
74 glutMouseFunc(mbutton);
75 glutMotionFunc(mmotion);
91 glEnable(GL_CULL_FACE);
92 glEnable(GL_DEPTH_TEST);
93 glEnable(GL_MULTISAMPLE);
95 // glEnable(GL_LIGHTING);
98 glEnable(GL_NORMALIZE);
103 if(!(sdr_beam = create_program_load("sdr/beam.v.glsl", "sdr/beam.f.glsl")))
106 if(!(sdr_sky = create_program_load("sdr/sky.v.glsl", "sdr/sky.f.glsl"))) {
113 add_seq_track("beam-speed", INTERP_SIGMOID, EXTRAP_CLAMP, BEAM_DEF_SPEED);
114 add_seq_track("beam-len", INTERP_SIGMOID, EXTRAP_CLAMP, BEAM_LEN);
115 add_seq_track("cam-dist", INTERP_SIGMOID, EXTRAP_CLAMP, 10);
116 add_seq_track("cam-phi", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
117 add_seq_track("cam-theta", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
118 add_seq_track("cam-x", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
119 add_seq_track("cam-y", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
120 add_seq_track("cam-z", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
121 add_seq_track("xlogo", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
122 add_seq_track("xcircle", INTERP_SIGMOID, EXTRAP_CLAMP, 1);
125 freecam = seq_track_empty("cam-theta");
127 start_time = glutGet(GLUT_ELAPSED_TIME);
128 prev_tmsec = start_time;
132 static void cleanup()
136 free_program(sdr_beam);
137 free_program(sdr_sky);
140 static void display()
142 tmsec = (long)glutGet(GLUT_ELAPSED_TIME) - start_time;
143 float dt = (tmsec - prev_tmsec) / 1000.0f;
149 anim_time = anim_stop_time - start_time;
152 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
155 glMatrixMode(GL_MODELVIEW);
159 cam.dist = get_seq_value("cam-dist", anim_time);
160 cam.phi = get_seq_value("cam-phi", anim_time);
161 cam.theta = get_seq_value("cam-theta", anim_time);
162 cam.x = get_seq_value("cam-x", anim_time);
163 cam.y = get_seq_value("cam-y", anim_time);
164 cam.z = get_seq_value("cam-z", anim_time);
167 glTranslatef(0, -2, -cam.dist);
168 glRotatef(cam.phi, 1, 0, 0);
169 glRotatef(cam.theta, 0, 1, 0);
170 glTranslatef(-cam.x, -cam.y, -cam.z);
172 glColor3fv(sil_color);
176 beam_len = get_seq_value("beam-len", anim_time);
177 beam_speed = get_seq_value("beam-speed", anim_time);
178 beam_angle += beam_speed * 360.0f * dt;
180 xlogo_alpha = get_seq_value("xlogo", anim_time);
181 float xcircle = get_seq_value("xcircle", anim_time);
183 if(xlogo_alpha > 0.0) {
185 float beam_angle_rad = beam_angle / 180.0 * M_PI;
186 float xlogo_dist = beam_len;
187 float xlogo_pos[3] = {sin(beam_angle_rad), 0, cos(beam_angle_rad)};
188 glTranslatef(xlogo_pos[0] * xlogo_dist, xlogo_pos[1] * xlogo_dist + 4.7, xlogo_pos[2] * xlogo_dist);
189 xlogo(0.5, xlogo_alpha, xcircle);
194 glRotatef(beam_angle, 0, 1, 0);
211 glPushAttrib(GL_ENABLE_BIT);
212 glDisable(GL_CULL_FACE);
216 glTranslatef(0, 4.65, 0.2);
217 bind_program(sdr_beam);
218 set_uniform_float(sdr_beam, "beam_len", beam_len);
221 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
224 for(int i=0; i<BEAM_SHELLS; i++) {
225 float t = (float)i / (float)(BEAM_SHELLS - 1);
226 float rad = BEAM_RMIN + (BEAM_RMAX - BEAM_RMIN) * t;
228 float alpha = BEAM_ENERGY / (t * t);
231 glColor4f(beam_color[0], beam_color[1], beam_color[2], alpha);
233 glutSolidCylinder(rad, beam_len, 12, 1);
245 static void backdrop()
248 bind_program(sdr_sky);
249 glutSolidSphere(200, 16, 32);
256 static const char *help_lines[] = {
258 " LMB drag ....... rotate",
259 " MMB drag ....... pan",
260 " RMB drag/wheel . zoom",
261 " c .............. toggle free/animated camera",
262 " v .............. print current view parameters",
265 " <space> ........ pause time",
266 " <backspace> .... restart time",
267 " +/- ............ change beam rotation speed and set keyframe",
268 " 0 .............. clear beam rotation keyframes",
269 " [/] ............ change beam length and set keyframe",
270 " \\ .............. clear beam length keyframes",
271 " <enter> ........ record automatic beam start/stop transition",
272 " K .............. set camera keyframe",
273 " <shift>-L ...... clear all camera keyframes",
274 " X .............. toggle X logo and set keyframe",
275 " <shift>-X ...... clear logo keyframes",
276 " ~ .............. dump all animation keyframes to seq_dump",
280 glPushAttrib(GL_ENABLE_BIT);
281 glDisable(GL_DEPTH_TEST);
283 glMatrixMode(GL_MODELVIEW);
286 glMatrixMode(GL_PROJECTION);
289 glOrtho(0, win_width, win_height, 0, -1, 1);
292 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
294 glColor4f(0, 0, 0, 0.5);
296 glVertex2f(0, win_height);
297 glVertex2f(win_width, win_height);
298 glVertex2f(win_width, 0);
304 for(int i=0; help_lines[i]; i++) {
305 glColor3f(0.05, 0.05, 0.05);
306 glRasterPos2i(xpos + 1, ypos + 2);
307 const char *s = help_lines[i];
309 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *s++);
311 glColor3f(0.7, 1, 0.6);
312 glRasterPos2i(xpos, ypos);
315 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *s++);
322 glMatrixMode(GL_MODELVIEW);
333 static void reshape(int x, int y)
337 glViewport(0, 0, x, y);
339 glMatrixMode(GL_PROJECTION);
342 gluPerspective(50, (float)x / (float)y, 0.5, 500);
345 static void keyboard(unsigned char c, int x, int y)
348 static float orig_beam_speed;
349 static Camera orig_cam;
350 long anim_time = anim_stopped ? anim_stop_time - start_time : tmsec;
357 start_time = glutGet(GLUT_ELAPSED_TIME);
359 anim_stop_time = anim_stopped ? start_time : 0;
365 long msec = glutGet(GLUT_ELAPSED_TIME);
366 start_time += msec - anim_stop_time;
367 prev_tmsec = msec - start_time;
369 anim_stopped = false;
371 anim_stop_time = glutGet(GLUT_ELAPSED_TIME);
377 beam_speed = get_seq_value("beam-speed", anim_time);
378 set_seq_value("beam-speed", anim_time, beam_speed + 0.1);
382 beam_speed = get_seq_value("beam-speed", anim_time) - 0.1;
383 if(beam_speed < 0) beam_speed = 0;
384 set_seq_value("beam-speed", anim_time, beam_speed);
388 clear_seq_track("beam-speed");
392 beam_len = get_seq_value("beam-len", anim_time) - 0.5;
393 if(beam_len < 0) beam_len = 0;
394 set_seq_value("beam-len", anim_time, beam_len);
398 beam_len = get_seq_value("beam-len", anim_time);
399 set_seq_value("beam-len", anim_time, beam_len + 0.5);
403 clear_seq_track("beam-len");
408 idx = find_seq_track("beam-speed");
410 if(get_seq_value(idx, anim_time) > 0.0) {
411 clear_seq_track(idx);
412 set_seq_value(idx, anim_time, beam_speed);
413 set_seq_value(idx, anim_time + 3000, 0);
414 orig_beam_speed = beam_speed;
416 clear_seq_track(idx);
417 set_seq_value(idx, anim_time, 0);
418 set_seq_value(idx, anim_time + 3000, orig_beam_speed);
424 printf("camera mode: %s\n", freecam ? "free" : "animated");
433 printf("current view\n");
434 printf(" pos: %f %f %f\n", cam.x, cam.y, cam.z);
435 printf(" theta: %f, phi: %f\n", cam.theta, cam.phi);
436 printf(" dist: %f\n", cam.dist);
440 printf("clearing camera keyframes\n");
441 clear_seq_track("cam-x");
442 clear_seq_track("cam-y");
443 clear_seq_track("cam-z");
444 clear_seq_track("cam-theta");
445 clear_seq_track("cam-phi");
446 clear_seq_track("cam-dist");
450 printf("setting camera keyframe for time: %ld\n", anim_time);
451 set_seq_value("cam-x", anim_time, cam.x);
452 set_seq_value("cam-y", anim_time, cam.y);
453 set_seq_value("cam-z", anim_time, cam.z);
454 set_seq_value("cam-theta", anim_time, cam.theta);
455 set_seq_value("cam-phi", anim_time, cam.phi);
456 set_seq_value("cam-dist", anim_time, cam.dist);
460 set_seq_value("xlogo", anim_time, xlogo_alpha < 0.5 ? 1.0 : 0.0);
464 printf("clearing logo keyframes\n");
465 clear_seq_track("xlogo");
469 printf("dumping animation data to: seq_dump\n");
470 if(!dump_seq("seq_dump")) {
471 fprintf(stderr, "dump failed\n");
480 static void keyb_special(int key, int x, int y)
484 show_help = !show_help;
496 static int prev_x, prev_y;
498 static void mbutton(int bn, int state, int x, int y)
500 int button = bn - GLUT_LEFT_BUTTON;
501 bool pressed = state == GLUT_DOWN;
502 bst[button] = pressed;
511 if(cam.dist < 0) cam.dist = 0;
524 static void mmotion(int x, int y)
532 if (dx == 0 && dy == 0)
536 cam.theta += dx * 0.5;
547 cam.dist += dy * 0.1;
554 float theta = cam.theta / 180.0f * M_PI;
555 float phi = cam.phi / 180.0f * M_PI;
557 float pan_u[3], pan_v[3];
559 pan_u[0] = cos(theta);
561 pan_u[2] = sin(theta);
563 pan_v[0] = sin(phi) * sin(theta);
565 pan_v[2] = -sin(phi) * cos(theta);
567 float pan_x = -dx * 0.002 * cam.dist;
568 float pan_y = dy * 0.002 * cam.dist;
570 cam.x += pan_u[0] * pan_x + pan_v[0] * pan_y;
571 cam.y += pan_u[1] * pan_x + pan_v[1] * pan_y;
572 cam.z += pan_u[2] * pan_x + pan_v[2] * pan_y;