sequencer load/save with treestore
[faros-demo] / src / main.cc
index 669ede3..cef9fda 100644 (file)
@@ -3,28 +3,26 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <assert.h>
 
 #include "sdr.h"
-
-#define CURVE_VS "sdr/curve_top.v.glsl"
-#define CURVE_FS "sdr/curve_top.f.glsl"
-#define BEAM_VS "sdr/beam.v.glsl"
-#define BEAM_FS "sdr/beam.f.glsl"
+#include "geom.h"
+#include "seq.h"
 
 #define BEAM_SHELLS 40
 #define BEAM_RMIN 0.01
 #define BEAM_RMAX 0.125
 #define BEAM_ENERGY 0.02
+#define BEAM_LEN 16.0
+#define BEAM_DEF_SPEED 0.1
 
 static bool init();
 static void cleanup();
 
-static void faros();
+static void display();
 static void light();
-static void ground();
 static void backdrop();
 
-static void display();
 static void idle();
 static void reshape(int x, int y);
 static void keyboard(unsigned char c, int x, int y);
@@ -32,9 +30,15 @@ static void mbutton(int bn, int state, int x, int y);
 static void mmotion(int x, int y);
 
 static float cam_theta = 45, cam_phi, cam_dist = 10;
-static unsigned int sdr_curve_top, sdr_beam, sdr_sky;
-static unsigned int start_time;
-static float beam_rot_speed = 0.1;
+static unsigned int sdr_beam, sdr_sky;
+static long start_time;
+static long anim_stop_time;
+static long tmsec, prev_tmsec;
+
+static const float sil_color[] = {0.05, 0.02, 0.1, 1.0};
+static const float beam_color[] = {0.5, 0.4, 0.2, 1.0};
+
+static float beam_angle, beam_speed;
 
 int main(int argc, char **argv)
 {
@@ -74,105 +78,67 @@ static bool init()
 
        glEnable(GL_NORMALIZE);
 
-       if(!(sdr_curve_top = create_program_load(CURVE_VS, CURVE_FS)))
+       if(!init_geom()) {
                return false;
-
-       if(!(sdr_beam = create_program_load(BEAM_VS, BEAM_FS)))
+       }
+       if(!(sdr_beam = create_program_load("sdr/beam.v.glsl", "sdr/beam.f.glsl")))
                return false;
 
        if(!(sdr_sky = create_program_load("sdr/sky.v.glsl", "sdr/sky.f.glsl"))) {
                return false;
        }
 
+       if(!init_seq()) {
+               return false;
+       }
+       add_seq_track("beam-speed", INTERP_SIGMOID, EXTRAP_CLAMP, BEAM_DEF_SPEED);
+       load_seq("seq");
+
        start_time = glutGet(GLUT_ELAPSED_TIME);
+       prev_tmsec = start_time;
        return true;
 }
 
 static void cleanup()
 {
+       destroy_seq();
+       destroy_geom();
+       free_program(sdr_beam);
+       free_program(sdr_sky);
 }
 
-static void faros()
+static void display()
 {
-       glColor3f(0, 0, 0);
+       tmsec = (long)glutGet(GLUT_ELAPSED_TIME) - start_time;
+       float dt = (tmsec - prev_tmsec) / 1000.0f;
+       prev_tmsec = tmsec;
 
-       // kormos
-       glPushMatrix();
-       glScalef(1.1, 3, 1.1);
-       glTranslatef(0, 0.5, 0);
-       glutSolidCube(1.0);
-       glPopMatrix();
-
-       glShadeModel(GL_FLAT);
+       if(anim_stop_time) dt = 0.0f;
 
-       // base
-       glPushMatrix();
-       glRotatef(90, 1, 0, 0);
-       glTranslatef(0, -0.15, 0);
-       glutSolidCylinder(2, 0.3, 16, 1);
-       glPopMatrix();
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       backdrop();
 
-       // middle cylinder
-       glPushMatrix();
-       glTranslatef(0, 3, 0);
-       glRotatef(22.5, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glutSolidCylinder(0.5, 1.0, 8, 1);
-       glPopMatrix();
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
 
-       // trim middle cylinder (mporntoura)
-       glPushMatrix();
-       glTranslatef(0, 3.9, 0);
-       glRotatef(22.5, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glutSolidCylinder(0.55, 0.02, 8, 1);
-       glPopMatrix();
+       glTranslatef(0, -2, -cam_dist);
+       glRotatef(cam_phi, 1, 0, 0);
+       glRotatef(cam_theta, 0, 1, 0);
 
-       // top smaller cylinder
-       glPushMatrix();
-       glTranslatef(0, 4, 0);
-       glRotatef(22.5, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glutSolidCylinder(0.28, 0.5, 8, 1);
-       glPopMatrix();
+       glColor3fv(sil_color);
+       ground();
+       faros();
 
-       // top wire even smaller cylinder
        glPushMatrix();
-       glTranslatef(0, 4.5, 0);
-       glRotatef(22.5, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glutWireCylinder(0.18, 0.3, 9, 3);
-       glPopMatrix();
 
-       glShadeModel(GL_SMOOTH);
-
-       // top troulos
-       glPushMatrix();
-       glTranslatef(0, 4.8, 0);
-       glRotatef(22.5, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glutSolidCone(0.18, 0.2, 9, 1);
-       glPopMatrix();
+       beam_speed = get_seq_value("beam-speed", tmsec);
+       beam_angle += beam_speed * 360.0f * dt;
+       glRotatef(beam_angle, 0, 1, 0);
+       light();
 
-       // tsamploukano
-       glPushMatrix();
-       glTranslatef(-0.28, 4, 0);
-       glScalef(1, 13, 1);
-       glutSolidSphere(0.1, 16, 16);
        glPopMatrix();
 
-       //pyramid on top of kormos
-       bind_program(sdr_curve_top);
-
-       glPushMatrix();
-       glTranslatef(0, 3, 0);
-       glRotatef(45, 0, 1, 0);
-       glRotatef(-90, 1, 0, 0);
-       glScalef(1, 1, 0.45);
-       glutSolidCylinder(1, 1, 4, 16);
-       glPopMatrix();
-       
-       bind_program(0);
+       glutSwapBuffers();
 }
 
 static void light()
@@ -184,6 +150,7 @@ static void light()
 
        glTranslatef(0, 4.65, 0.2);
        bind_program(sdr_beam);
+       set_uniform_float(sdr_beam, "beam_len", BEAM_LEN);
 
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -191,11 +158,11 @@ static void light()
        for(int i=0; i<BEAM_SHELLS; i++) {
                float t = (float)i / (float)(BEAM_SHELLS - 1);
                float rad = BEAM_RMIN + (BEAM_RMAX - BEAM_RMIN) * t;
-               float alpha = BEAM_ENERGY / t;
+               float alpha = BEAM_ENERGY / (t * t);
 
-               glColor4f(0.8, 0.8, 0.2, alpha);
+               glColor4f(beam_color[0], beam_color[1], beam_color[2], alpha);
 
-               glutSolidCylinder(rad, 6, 10, 1);
+               glutSolidCylinder(rad, BEAM_LEN, 12, 1);
        }
 
        bind_program(0);
@@ -205,19 +172,6 @@ static void light()
        glPopAttrib();
 }
 
-static void ground()
-{
-       glPushMatrix();
-
-       glTranslatef(0, -1.25, 0);
-       glScalef(1, 0.1, 1);
-
-       glColor3f(0, 0, 0);
-       glutSolidSphere(10, 32, 32);
-
-       glPopMatrix();
-}
-
 static void backdrop()
 {
        glFrontFace(GL_CW);
@@ -227,35 +181,7 @@ static void backdrop()
        glFrontFace(GL_CCW);
 }
 
-static void display()
-{
-       unsigned int tmsec = glutGet(GLUT_ELAPSED_TIME) - start_time;
-       float tsec = (float)tmsec / 1000.0;
-
-       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-       backdrop();
 
-       glMatrixMode(GL_MODELVIEW);
-       glLoadIdentity();
-
-       glTranslatef(0, -2, -cam_dist);
-       glRotatef(cam_phi, 1, 0, 0);
-       glRotatef(cam_theta, 0, 1, 0);
-
-       ground();
-       faros();
-
-       glPushMatrix();
-
-       float beam_angle = tsec * beam_rot_speed * 360;
-
-       glRotatef(beam_angle, 0, 1, 0);
-       light();
-
-       glPopMatrix();
-
-       glutSwapBuffers();
-}
 
 static void idle()
 {
@@ -272,11 +198,69 @@ static void reshape(int x, int y)
        gluPerspective(50, (float)x / (float)y, 0.5, 500);
 }
 
+#define ANIM_DELTA     0.5
+
 static void keyboard(unsigned char c, int x, int y)
 {
+       int idx;
+       static float orig_beam_speed;
+
        switch(c) {
        case 27:
                exit(0);
+
+       case '\b':
+               start_time = glutGet(GLUT_ELAPSED_TIME);
+               prev_tmsec = 0;
+               anim_stop_time = 0;
+               beam_angle = 0;
+               break;
+
+       case ' ':
+               if(anim_stop_time > 0) {
+                       long msec = glutGet(GLUT_ELAPSED_TIME);
+                       start_time += msec - anim_stop_time;
+                       prev_tmsec = msec - start_time;
+                       anim_stop_time = 0;
+               } else {
+                       anim_stop_time = glutGet(GLUT_ELAPSED_TIME);
+               }
+               break;
+
+       case '=':
+               beam_speed = get_seq_value("beam-speed", tmsec);
+               clear_seq_track("beam-speed");
+               set_seq_value("beam-speed", tmsec, beam_speed + ANIM_DELTA);
+               break;
+
+       case '-':
+               beam_speed = get_seq_value("beam-speed", tmsec) - ANIM_DELTA;
+               if(beam_speed < 0)
+                       beam_speed = 0;
+               clear_seq_track("beam-speed");
+               set_seq_value("beam-speed", tmsec, beam_speed);
+               break;
+
+       case '\r':
+       case '\n':
+               idx = find_seq_track("beam-speed");
+               assert(idx >= 0);
+               if(get_seq_value(idx, tmsec) > 0.0) {
+                       clear_seq_track(idx);
+                       set_seq_value(idx, tmsec, beam_speed);
+                       set_seq_value(idx, tmsec + 3000, 0);
+                       orig_beam_speed = beam_speed;
+               } else {
+                       clear_seq_track(idx);
+                       set_seq_value(idx, tmsec, 0);
+                       set_seq_value(idx, tmsec + 3000, orig_beam_speed);
+               }
+               break;
+
+       case '`':
+               dump_seq("seq_dump");
+               break;
+
        default:
                break;
        }