From: John Tsiombikas Date: Thu, 3 Dec 2020 17:03:14 +0000 (+0200) Subject: part system X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=demo_prior;a=commitdiff_plain;h=6a752049e496c93a61e0130348f71888583d743c part system --- diff --git a/src/demo.c b/src/demo.c index 8653aa4..d0b1127 100644 --- a/src/demo.c +++ b/src/demo.c @@ -1,12 +1,19 @@ +#include #include "opengl.h" #include "demo.h" +#include "part.h" + +void reg_whitted(void); int win_width, win_height; +float win_aspect; long time_msec; int demo_init(void) { + int i; + if(init_opengl() == -1) { return -1; } @@ -16,54 +23,98 @@ int demo_init(void) glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_MULTISAMPLE); + reg_whitted(); + + for(i=0; iinit() == -1) { + fprintf(stderr, "part %s init failed\n", parts[i]->name); + return -1; + } + } + + switch_part(parts[0]); return 0; } void demo_cleanup(void) { + int i; + + for(i=0; idestroy(); + } } void demo_display(void) { - glClearColor(0.05, 0.05, 0.05, 1); + long part_time; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, 0, -8); + if(!cur_part) return; + + part_time = time_msec - cur_part->start_time; + if(part_time < cur_part->in_time) { + float t = (float)part_time / cur_part->in_time; - glFrontFace(GL_CW); - glutSolidTeapot(1.0); - glFrontFace(GL_CCW); + if(prev_part) { + long prev_part_time = time_msec - prev_part->start_time; + if(prev_part->draw_out) { + prev_part->draw_out(prev_part_time, t); + } else { + prev_part->draw(prev_part_time); + } + } + + if(cur_part->draw_in) { + cur_part->draw_in(part_time, t); + } else { + cur_part->draw(part_time); + } + } else { + prev_part = 0; + cur_part->draw(part_time); + } } void demo_reshape(int x, int y) { + win_width = x; + win_height = y; + win_aspect = (float)x / (float)y; + glViewport(0, 0, x, y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); + gluPerspective(50.0, win_aspect, 0.5, 500.0); } void demo_keyboard(int key, int st) { - if(st) { - switch(key) { - case 27: - demo_quit(); - break; - } + if(st && key == 27) { + demo_quit(); + return; + } + + if(cur_part && cur_part->keyboard) { + cur_part->keyboard(key, st); } } void demo_mbutton(int bn, int st, int x, int y) { + if(cur_part && cur_part->mbutton) { + cur_part->mbutton(bn, st, x, y); + } } void demo_mmotion(int x, int y) { + if(cur_part && cur_part->mmotion) { + cur_part->mmotion(x, y); + } } void demo_sball_motion(int x, int y, int z) diff --git a/src/demo.h b/src/demo.h index 381fbe9..6ede328 100644 --- a/src/demo.h +++ b/src/demo.h @@ -2,6 +2,7 @@ #define DEMO_H_ extern int win_width, win_height; +extern float win_aspect; extern long time_msec; diff --git a/src/part.c b/src/part.c new file mode 100644 index 0000000..8067a1e --- /dev/null +++ b/src/part.c @@ -0,0 +1,24 @@ +#include "part.h" +#include "demo.h" + +struct demo_part *cur_part, *prev_part; + +struct demo_part *parts[MAX_DEMO_PARTS]; +int num_parts; + +void add_part(struct demo_part *part) +{ + parts[num_parts++] = part; +} + +void switch_part(struct demo_part *part) +{ + part->start_time = time_msec; + + if(cur_part) { + prev_part = cur_part; + cur_part = part; + } else { + cur_part = part; + } +} diff --git a/src/part.h b/src/part.h new file mode 100644 index 0000000..8d0fbdf --- /dev/null +++ b/src/part.h @@ -0,0 +1,42 @@ +#ifndef PART_H_ +#define PART_H_ + +struct demo_part { + const char *name; + long start_time; + long in_time; /* transition overlap with previous part */ + + int (*init)(void); + void (*destroy)(void); + + void (*start)(void); + void (*stop)(void); + + /* tm is the time from the start of this part in milliseconds */ + void (*draw)(long tm); + + /* optional: transition draw functions. if null, the regular draw will be + * called for the duration of the transition instead + */ + void (*draw_in)(long tm, float t); + void (*draw_out)(long tm, float t); + + /* optional, will be called only when active */ + void (*reshape)(int x, int y); + void (*keyboard)(int key, int st); + void (*mbutton)(int bn, int st, int x, int y); + void (*mmotion)(int x, int y); +}; + +#define MAX_DEMO_PARTS 64 +extern struct demo_part *parts[MAX_DEMO_PARTS]; +extern int num_parts; + +extern struct demo_part *cur_part, *prev_part; + +void add_part(struct demo_part *part); +void switch_part(struct demo_part *part); + +struct demo_part *find_part(const char *name); + +#endif /* PART_H_ */ diff --git a/src/part_whitted.c b/src/part_whitted.c new file mode 100644 index 0000000..7154abf --- /dev/null +++ b/src/part_whitted.c @@ -0,0 +1,94 @@ +#include "opengl.h" +#include "demo.h" +#include "part.h" + +static int init(void); +static void destroy(void); +static void start(void); +static void stop(void); +static void draw(long tm); +static void mbutton(int bn, int st, int x, int y); +static void mmotion(int x, int y); + +static float cam_theta, cam_phi, cam_dist = 8; + +static int bnstate[8]; +static int mouse_x, mouse_y; + +static struct demo_part part = { + "whitted", + 0, 0, + init, destroy, + start, stop, + draw, + 0, 0, + 0, 0, + mbutton, mmotion +}; + +void reg_whitted(void) +{ + add_part(&part); +} + + +static int init(void) +{ + return 0; +} + +static void destroy(void) +{ +} + +static void start(void) +{ +} + +static void stop(void) +{ +} + +static void draw(long tm) +{ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glFrontFace(GL_CW); + glutSolidTeapot(1.0); + glFrontFace(GL_CCW); +} + +static void mbutton(int bn, int st, int x, int y) +{ + bnstate[bn] = st; + mouse_x = x; + mouse_y = y; +} + +static void mmotion(int x, int y) +{ + int dx = x - mouse_x; + int dy = y - mouse_y; + mouse_x = x; + mouse_y = y; + + if(!(dx | dy)) return; + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; + } + if(bnstate[2]) { + cam_dist += dy * 0.1; + if(cam_dist < 0) cam_dist = 0; + } +}