2 #include <GL/freeglut.h>
10 #define CURVE_VS "sdr/curve_top.v.glsl"
11 #define CURVE_FS "sdr/curve_top.f.glsl"
12 #define BEAM_VS "sdr/beam.v.glsl"
13 #define BEAM_FS "sdr/beam.f.glsl"
15 #define BEAM_SHELLS 40
16 #define BEAM_RMIN 0.01
17 #define BEAM_RMAX 0.125
18 #define BEAM_ENERGY 0.02
21 #define BEAM_START_ANGLE 180
22 #define BEAM_STOP_ANGLE 359
32 static void cleanup();
37 static void backdrop();
40 static void update_anim();
42 static void display();
44 static void reshape(int x, int y);
45 static void keyboard(unsigned char c, int x, int y);
46 static void mbutton(int bn, int state, int x, int y);
47 static void mmotion(int x, int y);
49 static inline float smoothstep(float a, float b, float x);
51 static float cam_theta = 45, cam_phi, cam_dist = 10;
52 static unsigned int sdr_curve_top, sdr_beam, sdr_sky;
53 static long start_time;
54 static float anim_speed = 1.0;
55 static long anim_stop_time;
57 static float beam_speed = 0.1;
58 static float beam_angle;
59 static float prev_beam_angle;
62 static const float sil_color[] = {0.05, 0.02, 0.1, 1.0};
63 static const float beam_color[] = {0.5, 0.4, 0.2, 1.0};
65 int main(int argc, char **argv)
67 glutInit(&argc, argv);
68 glutInitWindowSize(800, 600);
69 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
71 glutCreateWindow("Faros");
73 glutDisplayFunc(display);
75 glutReshapeFunc(reshape);
76 glutKeyboardFunc(keyboard);
77 glutMouseFunc(mbutton);
78 glutMotionFunc(mmotion);
94 glEnable(GL_CULL_FACE);
95 glEnable(GL_DEPTH_TEST);
96 glEnable(GL_MULTISAMPLE);
98 // glEnable(GL_LIGHTING);
101 glEnable(GL_NORMALIZE);
103 if(!(sdr_curve_top = create_program_load(CURVE_VS, CURVE_FS)))
106 if(!(sdr_beam = create_program_load(BEAM_VS, BEAM_FS)))
109 if(!(sdr_sky = create_program_load("sdr/sky.v.glsl", "sdr/sky.f.glsl"))) {
113 start_time = glutGet(GLUT_ELAPSED_TIME);
117 static void cleanup()
123 glColor3fv(sil_color);
127 glScalef(1.1, 3, 1.1);
128 glTranslatef(0, 0.5, 0);
132 glShadeModel(GL_FLAT);
136 glRotatef(90, 1, 0, 0);
137 glTranslatef(0, -0.15, 0);
138 glutSolidCylinder(2, 0.3, 16, 1);
143 glTranslatef(0, 3, 0);
144 glRotatef(22.5, 0, 1, 0);
145 glRotatef(-90, 1, 0, 0);
146 glutSolidCylinder(0.5, 1.0, 8, 1);
149 // trim middle cylinder (mporntoura)
151 glTranslatef(0, 3.9, 0);
152 glRotatef(22.5, 0, 1, 0);
153 glRotatef(-90, 1, 0, 0);
154 glutSolidCylinder(0.55, 0.02, 8, 1);
157 // top smaller cylinder
159 glTranslatef(0, 4, 0);
160 glRotatef(22.5, 0, 1, 0);
161 glRotatef(-90, 1, 0, 0);
162 glutSolidCylinder(0.28, 0.5, 8, 1);
165 // top wire even smaller cylinder
167 glTranslatef(0, 4.5, 0);
168 glRotatef(22.5, 0, 1, 0);
169 glRotatef(-90, 1, 0, 0);
170 glutWireCylinder(0.18, 0.3, 9, 3);
173 glShadeModel(GL_SMOOTH);
177 glTranslatef(0, 4.8, 0);
178 glRotatef(22.5, 0, 1, 0);
179 glRotatef(-90, 1, 0, 0);
180 glutSolidCone(0.18, 0.2, 9, 1);
185 glTranslatef(-0.28, 4, 0);
187 glutSolidSphere(0.1, 16, 16);
190 //pyramid on top of kormos
191 bind_program(sdr_curve_top);
194 glTranslatef(0, 3, 0);
195 glRotatef(45, 0, 1, 0);
196 glRotatef(-90, 1, 0, 0);
197 glScalef(1, 1, 0.45);
198 glutSolidCylinder(1, 1, 4, 16);
206 glPushAttrib(GL_ENABLE_BIT);
207 glDisable(GL_CULL_FACE);
211 glTranslatef(0, 4.65, 0.2);
212 bind_program(sdr_beam);
213 set_uniform_float(sdr_beam, "beam_len", BEAM_LEN);
216 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
218 for(int i=0; i<BEAM_SHELLS; i++) {
219 float t = (float)i / (float)(BEAM_SHELLS - 1);
220 float rad = BEAM_RMIN + (BEAM_RMAX - BEAM_RMIN) * t;
221 float alpha = BEAM_ENERGY / (t * t);
223 glColor4f(beam_color[0], beam_color[1], beam_color[2], alpha);
225 glutSolidCylinder(rad, BEAM_LEN, 12, 1);
239 glTranslatef(0, -1.25, 0);
242 glColor3fv(sil_color);
243 glutSolidSphere(10, 32, 32);
248 static void backdrop()
251 bind_program(sdr_sky);
252 glutSolidSphere(200, 16, 32);
264 static void update_anim(long tmsec)
266 static float beam_start_time;
267 static float beam_stop_interval;
269 float tsec = (float)tmsec / 1000.0;
270 float tanim = tsec * anim_speed;
272 if(state == ST_CAM_WAIT) {
273 if(beam_angle >= BEAM_START_ANGLE && prev_beam_angle < BEAM_START_ANGLE) {
275 printf("func: %s\n", __func__);
276 printf("state from wait to stop (ba: %f)\n", beam_angle);
277 beam_start_time = tmsec;
278 beam_stop_interval = beam_angle / beam_speed; // 400 / beam_speed;
279 printf(" stop interval: %f\n", beam_stop_interval);
282 if(state == ST_CAM_STOP) {
283 float t = smoothstep(beam_start_time, beam_start_time + beam_stop_interval, tmsec);
284 prev_beam_angle = beam_angle;
285 beam_angle = BEAM_START_ANGLE + (BEAM_STOP_ANGLE - BEAM_START_ANGLE) * t;
288 printf("state from stop to xlogo\n");
291 } else if(state == ST_XLOGO) {
294 prev_beam_angle = beam_angle;
295 beam_angle = fmod(tanim * beam_speed * 360, 360.0);
299 static void display()
301 if(anim_stop_time > 0) {
302 tmsec = anim_stop_time - start_time;
304 tmsec = (long)glutGet(GLUT_ELAPSED_TIME) - start_time;
309 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
312 glMatrixMode(GL_MODELVIEW);
315 glTranslatef(0, -2, -cam_dist);
316 glRotatef(cam_phi, 1, 0, 0);
317 glRotatef(cam_theta, 0, 1, 0);
324 glRotatef(beam_angle, 0, 1, 0);
337 static void reshape(int x, int y)
339 glViewport(0, 0, x, y);
341 glMatrixMode(GL_PROJECTION);
344 gluPerspective(50, (float)x / (float)y, 0.5, 500);
347 static long calc_timeshift(float prev_speed, float speed)
349 long delta = tmsec * speed - tmsec * prev_speed;
350 return delta / speed;
353 #define ANIM_DELTA 0.5
355 static void keyboard(unsigned char c, int x, int y)
357 float prev_anim_speed;
364 if(anim_stop_time > 0) {
365 start_time += glutGet(GLUT_ELAPSED_TIME) - anim_stop_time;
368 anim_stop_time = glutGet(GLUT_ELAPSED_TIME);
373 start_time += calc_timeshift(anim_speed, anim_speed + ANIM_DELTA);
374 anim_speed += ANIM_DELTA;
378 prev_anim_speed = anim_speed;
379 anim_speed -= ANIM_DELTA;
382 start_time += calc_timeshift(prev_anim_speed, anim_speed);
390 prev_beam_angle = beam_angle;
391 printf("from default to cam_wait\n");
394 printf("from xlogo to default\n");
407 static int prev_x, prev_y;
409 static void mbutton(int bn, int state, int x, int y)
411 int button = bn - GLUT_LEFT_BUTTON;
412 bst[button] = state == GLUT_DOWN;
418 static void mmotion(int x, int y)
426 if (dx == 0 && dy == 0)
430 cam_theta += dx * 0.5;
441 cam_dist += dy * 0.1;
448 static inline float smoothstep(float a, float b, float x)
450 if(x < a) return 0.0f;
451 if(x >= b) return 1.0f;
453 x = (x - a) / (b - a);
454 return x * x * (3.0f - 2.0f * x);