+#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "geom.h"
#include "sdr.h"
static unsigned int sdr_curve_top;
+static unsigned int tex_xcircle;
+
+static const unsigned char tex_xcircle_pixels[] = {
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 64, 255, 255, 255, 255, 64, 0,
+
+ 0, 64, 255, 255, 255, 255, 64, 0,
+ 0, 0, 255, 255, 255, 255, 0, 0,
+ 0, 0, 128, 255, 255, 128, 0, 0,
+ 0, 0, 0, 64, 64, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
bool init_geom()
{
if(!(sdr_curve_top = create_program_load("sdr/curve_top.v.glsl", "sdr/curve_top.f.glsl"))) {
return false;
}
+
+ glGenTextures(1, &tex_xcircle);
+ glBindTexture(GL_TEXTURE_2D, tex_xcircle);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 8, 16, 0,
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, tex_xcircle_pixels);
return true;
}
void destroy_geom()
{
+ glDeleteTextures(1, &tex_xcircle);
free_program(sdr_curve_top);
}
glPopMatrix();
}
-void xlogo()
+void xlogo(float sz, float alpha, float xcircle)
{
static const float xlogo_varr[] = {
-0.500, 0.407, -0.113, -0.109, 0.059, -0.006, -0.251, 0.407,
/* billboarding */
float mv[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
- mv[0] = mv[5] = mv[10] = 1.0f;
+ mv[0] = mv[5] = mv[10] = sz;
mv[1] = mv[2] = mv[4] = mv[6] = mv[8] = mv[9] = 0.0f;
glPushMatrix();
glLoadMatrixf(mv);
+ glTranslatef(0, 0.15, 0);
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
+ glColor4f(0, 0, 0, alpha);
const float *vptr = xlogo_varr;
for(int i=0; i<(int)(sizeof xlogo_varr / sizeof *xlogo_varr) / 2; i++) {
glVertex2fv(vptr);
vptr += 2;
}
glEnd();
+ glTranslatef(0, -0.15, 0);
+ glDisable(GL_BLEND);
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex_xcircle);
+
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_ALPHA_TEST);
+ float aref = 1.0f - xcircle;
+ glAlphaFunc(GL_GREATER, aref > 0.0f ? aref : 0.0f);
+
+ glScalef(1.4, 1, 1);
+
+#define XLOGO_CIRCLE_SEG 64
+ // circle thingy
+ glBegin(GL_QUAD_STRIP);
+ for(int i=0; i<XLOGO_CIRCLE_SEG; i++) {
+ float t = (float)i / (float)(XLOGO_CIRCLE_SEG - 1);
+ float tcol = fmod(t + 0.075f, 1.0f);
+
+ float theta = t * M_PI * 2.0f;
+ float rad = 0.4f;
+ float width = 0.05f * tcol;
+ float z = -cos(theta) * 0.1;
+
+ glColor4f(0.9, 0.9, 0.9, tcol);
+ glTexCoord2f(0, 1.0f - tcol);
+ glVertex3f(sin(theta) * (rad + width), cos(theta) * (rad + width), z);
+ glTexCoord2f(1, 1.0f - tcol);
+ glVertex3f(sin(theta) * (rad - width), cos(theta) * (rad - width), z);
+ }
+ glEnd();
glPopAttrib();
glPopMatrix();
void faros();
void ground();
-void xlogo();
+void xlogo(float sz, float alpha, float xcircle);
#endif /* GEOM_H_ */
#include "sdr.h"
#include "geom.h"
#include "seq.h"
+#include "ui.h"
#define BEAM_SHELLS 40
#define BEAM_RMIN 0.01
static void mbutton(int bn, int state, int x, int y);
static void mmotion(int x, int y);
-static int win_width, win_height;
+int win_width, win_height;
static bool freecam = true;
static Camera cam = {0, 0, 0, 0, 0, 10};
static unsigned int sdr_beam, sdr_sky;
static long start_time;
static long anim_stop_time;
-static long tmsec, prev_tmsec;
+long tmsec, prev_tmsec, anim_time;
+bool anim_stopped;
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_len;
static float xlogo_alpha;
-static bool show_help;
+static bool show_help, show_ui = true;
int main(int argc, char **argv)
{
add_seq_track("cam-y", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
add_seq_track("cam-z", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
add_seq_track("xlogo", INTERP_SIGMOID, EXTRAP_CLAMP, 0);
+ add_seq_track("xcircle", INTERP_SIGMOID, EXTRAP_CLAMP, 1);
load_seq("seq");
+ freecam = seq_track_empty("cam-theta");
+
start_time = glutGet(GLUT_ELAPSED_TIME);
prev_tmsec = start_time;
return true;
float dt = (tmsec - prev_tmsec) / 1000.0f;
prev_tmsec = tmsec;
- if(anim_stop_time) dt = 0.0f;
+ anim_time = tmsec;
+ if(anim_stopped) {
+ dt = 0.0f;
+ anim_time = anim_stop_time - start_time;
+ }
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
backdrop();
glLoadIdentity();
if(!freecam) {
- cam.dist = get_seq_value("cam-dist", tmsec);
- cam.phi = get_seq_value("cam-phi", tmsec);
- cam.theta = get_seq_value("cam-theta", tmsec);
- cam.x = get_seq_value("cam-x", tmsec);
- cam.y = get_seq_value("cam-y", tmsec);
- cam.z = get_seq_value("cam-z", tmsec);
+ cam.dist = get_seq_value("cam-dist", anim_time);
+ cam.phi = get_seq_value("cam-phi", anim_time);
+ cam.theta = get_seq_value("cam-theta", anim_time);
+ cam.x = get_seq_value("cam-x", anim_time);
+ cam.y = get_seq_value("cam-y", anim_time);
+ cam.z = get_seq_value("cam-z", anim_time);
}
glTranslatef(0, -2, -cam.dist);
ground();
faros();
- beam_len = get_seq_value("beam-len", tmsec);
- beam_speed = get_seq_value("beam-speed", tmsec);
+ beam_len = get_seq_value("beam-len", anim_time);
+ beam_speed = get_seq_value("beam-speed", anim_time);
beam_angle += beam_speed * 360.0f * dt;
- xlogo_alpha = get_seq_value("xlogo", tmsec);
+ xlogo_alpha = get_seq_value("xlogo", anim_time);
+ float xcircle = get_seq_value("xcircle", anim_time);
+
if(xlogo_alpha > 0.0) {
glPushMatrix();
float beam_angle_rad = beam_angle / 180.0 * M_PI;
float xlogo_dist = beam_len;
float xlogo_pos[3] = {sin(beam_angle_rad), 0, cos(beam_angle_rad)};
- glTranslatef(xlogo_pos[0] * xlogo_dist, xlogo_pos[1] * xlogo_dist + 5, xlogo_pos[2] * xlogo_dist);
- glColor4f(0, 0, 0, xlogo_alpha);
- xlogo();
+ glTranslatef(xlogo_pos[0] * xlogo_dist, xlogo_pos[1] * xlogo_dist + 4.7, xlogo_pos[2] * xlogo_dist);
+ xlogo(0.5, xlogo_alpha, xcircle);
glPopMatrix();
}
light();
glPopMatrix();
+ if(show_ui) {
+ ui();
+ }
+
if(show_help) {
help();
}
{
static const char *help_lines[] = {
"Camera control",
- " LMB ............ rotate",
+ " LMB drag ....... rotate",
" MMB drag ....... pan",
" RMB drag/wheel . zoom",
" c .............. toggle free/animated camera",
int idx;
static float orig_beam_speed;
static Camera orig_cam;
- long anim_time = anim_stop_time ? anim_stop_time - start_time : tmsec;
+ long anim_time = anim_stopped ? anim_stop_time - start_time : tmsec;
switch(c) {
case 27:
case '\b':
start_time = glutGet(GLUT_ELAPSED_TIME);
prev_tmsec = 0;
- anim_stop_time = 0;
+ anim_stop_time = anim_stopped ? start_time : 0;
beam_angle = 0;
break;
case ' ':
- if(anim_stop_time > 0) {
+ if(anim_stopped) {
long msec = glutGet(GLUT_ELAPSED_TIME);
start_time += msec - anim_stop_time;
prev_tmsec = msec - start_time;
anim_stop_time = 0;
+ anim_stopped = false;
} else {
anim_stop_time = glutGet(GLUT_ELAPSED_TIME);
+ anim_stopped = true;
}
break;
show_help = !show_help;
break;
+ case GLUT_KEY_F5:
+ show_ui = !show_ui;
+ break;
+
default:
break;
}
}
}
+bool seq_track_empty(int idx)
+{
+ return tracks[idx].track->empty();
+}
+
+bool seq_track_empty(const char *name)
+{
+ int idx = find_seq_track(name);
+ if(idx >= 0) {
+ return tracks[idx].track->empty();
+ }
+ return true;
+}
+
void set_seq_value(int idx, long tm, float val)
{
tracks[idx].track->set_value(tm, val);
+ printf("track(%d): set keyframe %ld -> %f\n", idx, tm, val);
}
void set_seq_value(const char *name, long tm, float val)
{
int idx = find_seq_track(name);
if(idx >= 0) {
- tracks[idx].track->set_value(tm, val);
+ set_seq_value(idx, tm, val);
}
}
int nkeys = tracks[i].track->get_num_keys();
if(!nkeys) continue;
- fprintf(fp, " track {\n");
- fprintf(fp, " name = \"%s\"\n", tracks[i].name);
+ fprintf(fp, "\ttrack {\n");
+ fprintf(fp, "\t\tname = \"%s\"\n", tracks[i].name);
for(int j=0; j<nkeys; j++) {
TrackKey key = (*tracks[i].track)[j];
- fprintf(fp, " key {\n");
- fprintf(fp, " time = %ld\n", key.time);
- fprintf(fp, " value = %g\n", key.value);
- fprintf(fp, " }\n");
+ fprintf(fp, "\t\tkey {\n");
+ fprintf(fp, "\t\t\ttime = %ld\n", key.time);
+ fprintf(fp, "\t\t\tvalue = %g\n", key.value);
+ fprintf(fp, "\t\t}\n");
}
- fprintf(fp, " }\n\n");
+ fprintf(fp, "\t}\n\n");
}
fprintf(fp, "}\n");
fclose(fp);
void clear_seq_track(int idx);
void clear_seq_track(const char *name);
+bool seq_track_empty(int idx);
+bool seq_track_empty(const char *name);
+
void set_seq_value(int idx, long tm, float val);
void set_seq_value(const char *name, long tm, float val);
float get_seq_value(int idx, long tm);
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+#include <alloca.h>
+#include <GL/glut.h>
+#include "ui.h"
+
+extern int win_width, win_height;
+
+extern bool anim_stopped;
+extern long anim_time;
+
+
+bool init_ui()
+{
+ return true;
+}
+
+void destroy_ui()
+{
+}
+
+void ui()
+{
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, win_width, win_height, 0, -1, 1);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ if(anim_stopped) {
+ glBegin(GL_QUADS);
+ glColor3f(1, 1, 1);
+ glVertex2f(10, 10);
+ glVertex2f(10, 50);
+ glVertex2f(22, 50);
+ glVertex2f(22, 10);
+ glVertex2f(30, 10);
+ glVertex2f(30, 50);
+ glVertex2f(42, 50);
+ glVertex2f(42, 10);
+ glEnd();
+ }
+
+ glColor3f(1, 0.9, 0.5);
+ gl_printf(win_width - 100, 20, "%4ld.%03ld", anim_time / 1000, anim_time % 1000);
+
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glPopAttrib();
+}
+
+void gl_printf(int x, int y, const char *fmt, ...)
+{
+ va_list ap;
+ int buf_size, curx, cury;
+ char *buf, tmp;
+
+ va_start(ap, fmt);
+ buf_size = vsnprintf(&tmp, 0, fmt, ap);
+ va_end(ap);
+
+ if(buf_size == -1) {
+ buf_size = 512;
+ }
+
+ buf = (char*)alloca(buf_size + 1);
+ va_start(ap, fmt);
+ vsnprintf(buf, buf_size + 1, fmt, ap);
+ va_end(ap);
+
+ static const float tabstop = 4;
+ static const float line_spacing = 18;
+
+ curx = x;
+ cury = y;
+ glRasterPos2i(x, y);
+
+ while(*buf) {
+ char c = *buf++;
+
+ switch(c) {
+ case '\r':
+ if(*buf == '\n') ++buf;
+ case '\n':
+ cury += line_spacing;
+ curx = x;
+ glRasterPos2i(curx, cury);
+ break;
+
+ case '\t':
+ curx = (curx / tabstop) * tabstop + tabstop;
+ glRasterPos2i(curx, cury);
+ break;
+
+ default:
+ glutBitmapCharacter(GLUT_BITMAP_9_BY_15, c);
+ }
+ }
+}
--- /dev/null
+#ifndef UI_H_
+#define UI_H_
+
+bool init_ui();
+void destroy_ui();
+
+void ui();
+
+void gl_printf(int x, int y, const char *fmt, ...);
+
+#endif /* UI_H_ */