X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fextrusion.c;h=7e98f5e3bf924524049e5cf24b065702a6081a73;hp=1c63435680aa4413a60aa7d4f23c34fb415fe33d;hb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;hpb=e4fa2ac140f7bc56571373a7b7eb585fa4500e38 diff --git a/hacks/glx/extrusion.c b/hacks/glx/extrusion.c index 1c634356..7e98f5e3 100644 --- a/hacks/glx/extrusion.c +++ b/hacks/glx/extrusion.c @@ -22,34 +22,17 @@ * which can be obtained from http://www.linas.org/gle/index.html */ -/*- - * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock. - * otherwise caddr_t is not defined correctly - */ - -#include - #ifdef HAVE_CONFIG_H #include #endif #ifdef STANDALONE -# define PROGCLASS "Screensaver" -# define HACK_INIT init_screensaver -# define HACK_DRAW draw_screensaver -# define HACK_RESHAPE reshape_screensaver -# define HACK_HANDLE_EVENT screensaver_handle_event -# define EVENT_MASK PointerMotionMask -# define screensaver_opts xlockmore_opts -#define DEFAULTS "*delay: 10000 \n" \ - "*showFPS: False \n" \ - "*light: True \n" \ - "*wire: False \n" \ - "*texture: False \n" \ - "*image: BUILTIN \n" \ - "*name: RANDOM \n" \ - "*example: 0 \n" +#define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + "*wireframe: False \n" +# define refresh_extrusion 0 +# define release_extrusion 0 # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ # include "xlock.h" /* from the xlockmore distribution */ @@ -65,89 +48,57 @@ # endif /* VMS */ #endif -#include -#include -#include -#include -#include -#include -#ifdef HAVE_GLE3 -#include -#else -#include -#endif - #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) #include "xpm-ximage.h" #include "rotator.h" +#include "gltrackball.h" +#include "extrusion.h" #define checkImageWidth 64 #define checkImageHeight 64 -extern void InitStuff_helix2(void); -extern void DrawStuff_helix2(void); -extern void InitStuff_helix3(void); -extern void DrawStuff_helix3(void); -extern void InitStuff_helix4(void); -extern void DrawStuff_helix4(void); -extern void InitStuff_joinoffset(void); -extern void DrawStuff_joinoffset(void); -extern void InitStuff_screw(void); -extern void DrawStuff_screw(void); -extern void InitStuff_taper(void); -extern void DrawStuff_taper(void); -extern void InitStuff_twistoid(void); -extern void DrawStuff_twistoid(void); - - - #define WIDTH 640 #define HEIGHT 480 #define DEF_LIGHT "True" -#define DEF_WIRE "False" #define DEF_TEXTURE "False" -#define DEF_TEXTURE_QUALITY "False" +#define DEF_TEX_QUAL "False" #define DEF_MIPMAP "False" #define DEF_NAME "RANDOM" #define DEF_IMAGE "BUILTIN" static int do_light; -static int do_wire; static int do_texture; -static int do_texture_quality; +static int do_tex_qual; static int do_mipmap; static char *which_name; static char *which_image; static XrmOptionDescRec opts[] = { - {"-light", ".extrusion.light", XrmoptionNoArg, (caddr_t) "true" }, - {"+light", ".extrusion.light", XrmoptionNoArg, (caddr_t) "false" }, - {"-wire", ".extrusion.wire", XrmoptionNoArg, (caddr_t) "true" }, - {"+wire", ".extrusion.wire", XrmoptionNoArg, (caddr_t) "false" }, - {"-texture", ".extrusion.texture", XrmoptionNoArg, (caddr_t) "true" }, - {"+texture", ".extrusion.texture", XrmoptionNoArg, (caddr_t) "false" }, - {"-texture", ".extrusion.texture", XrmoptionNoArg, (caddr_t) "true" }, - {"+texture_quality", ".extrusion.texture", XrmoptionNoArg, (caddr_t) "false" }, - {"-texture_quality", ".extrusion.texture", XrmoptionNoArg, (caddr_t) "true" }, - {"+mipmap", ".extrusion.mipmap", XrmoptionNoArg, (caddr_t) "false" }, - {"-mipmap", ".extrusion.mipmap", XrmoptionNoArg, (caddr_t) "true" }, - {"-name", ".extrusion.name", XrmoptionSepArg, (caddr_t) NULL }, - {"-image", ".extrusion.image", XrmoptionSepArg, (caddr_t) NULL }, + {"-light", ".extrusion.light", XrmoptionNoArg, "true" }, + {"+light", ".extrusion.light", XrmoptionNoArg, "false" }, + {"-texture", ".extrusion.texture", XrmoptionNoArg, "true" }, + {"+texture", ".extrusion.texture", XrmoptionNoArg, "false" }, + {"-texture", ".extrusion.texture", XrmoptionNoArg, "true" }, + {"+texture_quality", ".extrusion.texture", XrmoptionNoArg, "false" }, + {"-texture_quality", ".extrusion.texture", XrmoptionNoArg, "true" }, + {"+mipmap", ".extrusion.mipmap", XrmoptionNoArg, "false" }, + {"-mipmap", ".extrusion.mipmap", XrmoptionNoArg, "true" }, + {"-name", ".extrusion.name", XrmoptionSepArg, 0 }, + {"-image", ".extrusion.image", XrmoptionSepArg, 0 }, }; static argtype vars[] = { - {&do_light, "light", "Light", DEF_LIGHT, t_Bool}, - {&do_wire, "wire", "Wire", DEF_WIRE, t_Bool}, - {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, - {&do_texture_quality, "texture_quality", "Texture_Quality", DEF_TEXTURE_QUALITY, t_Bool}, - {&do_mipmap, "mipmap", "Mipmap", DEF_MIPMAP, t_Bool}, - {&which_name, "name", "Name", DEF_NAME, t_String}, - {&which_image, "image", "Image", DEF_IMAGE, t_String}, + {&do_light, "light", "Light", DEF_LIGHT, t_Bool}, + {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, + {&do_tex_qual, "texture_quality", "Texture_Quality", DEF_TEX_QUAL, t_Bool}, + {&do_mipmap, "mipmap", "Mipmap", DEF_MIPMAP, t_Bool}, + {&which_name, "name", "Name", DEF_NAME, t_String}, + {&which_image, "image", "Image", DEF_IMAGE, t_String}, }; @@ -155,57 +106,56 @@ static OptionStruct desc[] = { {"-name num", "example 'name' to draw (helix2, helix3, helix4, joinoffset, screw, taper, twistoid)"}, {"-/+ light", "whether to do enable lighting (slower)"}, - {"-/+ wire", "whether to do use wireframe instead of filled (faster)"}, {"-/+ texture", "whether to apply a texture (slower)"}, {"-image ", "texture image to load"}, {"-/+ texture_quality", "whether to use texture smoothing (slower)"}, {"-/+ mipmap", "whether to use texture mipmap (slower)"}, }; -ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, desc}; +ENTRYPOINT ModeSpecOpt extrusion_opts = {countof(opts), opts, countof(vars), vars, desc}; #ifdef USE_MODULES -ModStruct screensaver_description = -{"screensaver", "init_screensaver", "draw_screensaver", "release_screensaver", - "draw_screensaver", "init_screensaver", NULL, &screensaver_opts, +ModStruct extrusion_description = +{"extrusion", "init_extrusion", "draw_extrusion", "release_extrusion", + "draw_extrusion", "init_extrusion", NULL, &extrusion_opts, 1000, 1, 2, 1, 4, 1.0, "", - "OpenGL screensaver", 0, NULL}; + "OpenGL extrusion", 0, NULL}; #endif -/* structure for holding the screensaver data */ +/* structure for holding the extrusion data */ typedef struct { int screen_width, screen_height; GLXContext *glx_context; rotator *rot; + trackball_state *trackball; Bool button_down_p; + Bool button2_down_p; + int mouse_start_x, mouse_start_y; int mouse_x, mouse_y; + int mouse_dx, mouse_dy; Window window; XColor fg, bg; -} screensaverstruct; -static screensaverstruct *Screensaver = NULL; - + int extrusion_number; +} extrusionstruct; +static extrusionstruct *Extrusion = NULL; -/* convenient access to the screen width */ -static int global_width=640, global_height=480; /* set up a light */ -static GLfloat lightOnePosition[] = {40.0, 40, 100.0, 0.0}; -static GLfloat lightOneColor[] = {0.99, 0.99, 0.99, 1.0}; +static const GLfloat lightOnePosition[] = {40.0, 40, 100.0, 0.0}; +static const GLfloat lightOneColor[] = {0.99, 0.99, 0.00, 1.0}; -static GLfloat lightTwoPosition[] = {-40.0, 40, 100.0, 0.0}; -static GLfloat lightTwoColor[] = {0.99, 0.99, 0.99, 1.0}; +static const GLfloat lightTwoPosition[] = {-40.0, 40, 100.0, 0.0}; +static const GLfloat lightTwoColor[] = {0.00, 0.99, 0.99, 1.0}; float rot_x=0, rot_y=0, rot_z=0; float lastx=0, lasty=0; -static float max_lastx=300, max_lasty=400; +static float max_lastx=400, max_lasty=400; static float min_lastx=-400, min_lasty=-400; -static int screensaver_number; - struct functions { void (*InitStuff)(void); void (*DrawStuff)(void); @@ -216,7 +166,7 @@ struct functions { like we're looking at them from the back or something */ -static struct functions funcs_ptr[] = { +static const struct functions funcs_ptr[] = { {InitStuff_helix2, DrawStuff_helix2, "helix2"}, {InitStuff_helix3, DrawStuff_helix3, "helix3"}, {InitStuff_helix4, DrawStuff_helix4, "helix4"}, @@ -226,13 +176,13 @@ static struct functions funcs_ptr[] = { {InitStuff_twistoid, DrawStuff_twistoid, "twistoid"}, }; -static int num_screensavers = countof(funcs_ptr); +static int num_extrusions = countof(funcs_ptr); /* BEGINNING OF FUNCTIONS */ -GLubyte * +static GLubyte * Generate_Image(int *width, int *height, int *format) { GLubyte *result; @@ -261,7 +211,7 @@ Generate_Image(int *width, int *height, int *format) /* Create a texture in OpenGL. First an image is loaded and stored in a raster buffer, then it's */ -void Create_Texture(ModeInfo *mi, const char *filename) +static void Create_Texture(ModeInfo *mi, const char *filename) { int height, width; GLubyte *image; @@ -287,7 +237,7 @@ void Create_Texture(ModeInfo *mi, const char *filename) /* perhaps we can edge a bit more speed at the expense of quality */ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - if (do_texture_quality) { + if (do_tex_qual) { /* with texture_quality, the min and mag filters look *much* nice but are *much* slower */ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); @@ -329,54 +279,85 @@ void Create_Texture(ModeInfo *mi, const char *filename) static void init_rotation (ModeInfo *mi) { - screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)]; - double spin_speed = 1.0; - gp->rot = make_rotator (spin_speed, spin_speed, spin_speed, 1.0, 0.0, True); + extrusionstruct *gp = &Extrusion[MI_SCREEN(mi)]; + double spin_speed = 0.5; + gp->rot = make_rotator (spin_speed, spin_speed, spin_speed, + 0.2, + 0.005, + True); + gp->trackball = gltrackball_init (); lastx = (random() % (int) (max_lastx - min_lastx)) + min_lastx; lasty = (random() % (int) (max_lasty - min_lasty)) + min_lasty; } -/* draw the screensaver once */ -void draw_screensaver(ModeInfo * mi) +/* draw the extrusion once */ +ENTRYPOINT void +draw_extrusion(ModeInfo * mi) { - screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)]; + extrusionstruct *gp = &Extrusion[MI_SCREEN(mi)]; Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); + static const GLfloat color[4] = {0.6, 0.6, 0.4, 1.0}; + /* static const GLfloat spec[4] = {0.6, 0.6, 0.6, 1.0}; */ + /* static const GLfloat shiny = 40.0; */ + + double x, y, z; + if (!gp->glx_context) return; - glXMakeCurrent(display, window, *(gp->glx_context)); + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(gp->glx_context)); + + glPushMatrix(); + + gltrackball_rotate (gp->trackball); + + get_rotation (gp->rot, &x, &y, &z, + !(gp->button_down_p || gp->button2_down_p)); + glRotatef (x * 360, 1.0, 0.0, 0.0); + glRotatef (y * 360, 0.0, 1.0, 0.0); + glRotatef (z * 360, 0.0, 0.0, 1.0); - funcs_ptr[screensaver_number].DrawStuff(); - /* track the mouse only if a button is down. */ - if (gp->button_down_p) + if (gp->button2_down_p) { - lastx = gp->mouse_x; - lasty = gp->mouse_y; - } - else - { - float scale = (max_lastx - min_lastx); - double x, y, z; - get_rotation (gp->rot, &x, &y, &z, True); - rot_x = x * 360; - rot_y = y * 360; - rot_z = z * 360; - lastx = x * scale + min_lastx; - lasty = y * scale + min_lasty; + gp->mouse_dx += gp->mouse_x - gp->mouse_start_x; + gp->mouse_dy += gp->mouse_y - gp->mouse_start_y; + gp->mouse_start_x = gp->mouse_x; + gp->mouse_start_y = gp->mouse_y; } + { + float scale = (max_lastx - min_lastx); + get_position (gp->rot, &x, &y, &z, + !(gp->button_down_p || gp->button2_down_p)); + lastx = x * scale + min_lastx + gp->mouse_dx; + lasty = y * scale + min_lasty + gp->mouse_dy; + } + + glScalef(0.5, 0.5, 0.5); + + /* glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); */ + /* glMateriali (GL_FRONT_AND_BACK, GL_SHININESS, shiny); */ + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glFrontFace(GL_CCW); + + funcs_ptr[gp->extrusion_number].DrawStuff(); + + glPopMatrix(); + if (mi->fps_p) do_fps (mi); glXSwapBuffers(display, window); } /* set up lighting conditions */ -static void SetupLight(void) +static void +SetupLight(void) { glLightfv (GL_LIGHT0, GL_POSITION, lightOnePosition); glLightfv (GL_LIGHT0, GL_DIFFUSE, lightOneColor); @@ -392,55 +373,60 @@ static void SetupLight(void) glEnable (GL_COLOR_MATERIAL); } -/* reset the projection matrix */ -static void resetProjection(void) { +/* Standard reshape function */ +ENTRYPOINT void +reshape_extrusion (ModeInfo *mi, int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport (0, 0, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum (-9, 9, -9, 9, 50, 150.0); + gluPerspective (30.0, 1/h, 1.0, 100.0); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); -} + gluLookAt( 0.0, 0.0, 30.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); -/* Standard reshape function */ -void -reshape_screensaver(ModeInfo *mi, int width, int height) -{ - global_width=width; - global_height=height; - glViewport( 0, 0, global_width, global_height ); - resetProjection(); + glClear(GL_COLOR_BUFFER_BIT); } -/* decide which screensaver example to run */ -static void chooseScreensaverExample(ModeInfo *mi) +/* decide which extrusion example to run */ +static void +chooseExtrusionExample (ModeInfo *mi) { + extrusionstruct *gp = &Extrusion[MI_SCREEN(mi)]; int i; /* call the extrusion init routine */ if (!strncmp(which_name, "RANDOM", strlen(which_name))) { - screensaver_number = random() % num_screensavers; + gp->extrusion_number = random() % num_extrusions; } else { - screensaver_number=-1; - for (i=0; i < num_screensavers; i++) { + gp->extrusion_number=-1; + for (i=0; i < num_extrusions; i++) { if (!strncmp(which_name, funcs_ptr[i].name, strlen(which_name))) { - screensaver_number = i; + gp->extrusion_number = i; } } } - if (screensaver_number < 0 || screensaver_number >= num_screensavers) { - fprintf(stderr, "%s: invalid screensaver example number!\n", progname); - fprintf(stderr, "%s: known screensavers:\n", progname); - for (i=0; i < num_screensavers; i++) + if (gp->extrusion_number < 0 || gp->extrusion_number >= num_extrusions) { + fprintf(stderr, "%s: invalid extrusion example number!\n", progname); + fprintf(stderr, "%s: known extrusions:\n", progname); + for (i=0; i < num_extrusions; i++) fprintf(stderr,"\t%s\n", funcs_ptr[i].name); exit(1); } init_rotation(mi); - funcs_ptr[screensaver_number].InitStuff(); + funcs_ptr[gp->extrusion_number].InitStuff(); } + /* main OpenGL initialization routine */ static void initializeGL(ModeInfo *mi, GLsizei width, GLsizei height) @@ -448,19 +434,18 @@ initializeGL(ModeInfo *mi, GLsizei width, GLsizei height) int style; int mode; - reshape_screensaver(mi, width, height); + reshape_extrusion(mi, width, height); glViewport( 0, 0, width, height ); glEnable(GL_DEPTH_TEST); glClearColor(0,0,0,0); -/* glCullFace(GL_BACK); */ -/* glEnable(GL_CULL_FACE); */ - glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, TRUE); + glDisable (GL_CULL_FACE); + glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, True); glShadeModel(GL_SMOOTH); if (do_light) SetupLight(); - if (do_wire) { + if (MI_IS_WIREFRAME(mi)) { glPolygonMode(GL_FRONT,GL_LINE); glPolygonMode(GL_BACK,GL_LINE); } @@ -485,29 +470,54 @@ initializeGL(ModeInfo *mi, GLsizei width, GLsizei height) } -Bool -screensaver_handle_event (ModeInfo *mi, XEvent *event) +ENTRYPOINT Bool +extrusion_handle_event (ModeInfo *mi, XEvent *event) { - screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)]; + extrusionstruct *gp = &Extrusion[MI_SCREEN(mi)]; if (event->xany.type == ButtonPress && - event->xbutton.button & Button1) + (event->xbutton.button == Button4 || + event->xbutton.button == Button5 || + event->xbutton.button == Button6 || + event->xbutton.button == Button7)) + { + gltrackball_mousewheel (gp->trackball, event->xbutton.button, 10, + !!event->xbutton.state); + return True; + } + else if (event->xany.type == ButtonPress && /* rotate with left button */ + !event->xbutton.state) /* if no modifier keys */ { gp->button_down_p = True; - gp->mouse_x = event->xbutton.x; - gp->mouse_y = event->xbutton.y; + gltrackball_start (gp->trackball, + event->xbutton.x, event->xbutton.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + else if (event->xany.type == ButtonPress) /* deform with other buttons */ + { /* or with modifier keys */ + gp->button2_down_p = True; + gp->mouse_start_x = gp->mouse_x = event->xbutton.x; + gp->mouse_start_y = gp->mouse_y = event->xbutton.y; return True; } - else if (event->xany.type == ButtonRelease && - event->xbutton.button & Button1) + else if (event->xany.type == ButtonRelease) { gp->button_down_p = False; + gp->button2_down_p = False; return True; } else if (event->xany.type == MotionNotify) { - gp->mouse_x = event->xmotion.x; - gp->mouse_y = event->xmotion.y; + if (gp->button_down_p) + gltrackball_track (gp->trackball, + event->xmotion.x, event->xmotion.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + if (gp->button2_down_p) + { + gp->mouse_x = event->xmotion.x; + gp->mouse_y = event->xmotion.y; + } return True; } @@ -515,42 +525,33 @@ screensaver_handle_event (ModeInfo *mi, XEvent *event) } - -/* xscreensaver initialization routine */ -void init_screensaver(ModeInfo * mi) +/* xextrusion initialization routine */ +ENTRYPOINT void +init_extrusion (ModeInfo * mi) { int screen = MI_SCREEN(mi); - screensaverstruct *gp; + extrusionstruct *gp; - if (Screensaver == NULL) { - if ((Screensaver = (screensaverstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (screensaverstruct))) == NULL) + if (MI_IS_WIREFRAME(mi)) do_light = 0; + + if (Extrusion == NULL) { + if ((Extrusion = (extrusionstruct *) + calloc(MI_NUM_SCREENS(mi), sizeof (extrusionstruct))) == NULL) return; } - gp = &Screensaver[screen]; + gp = &Extrusion[screen]; gp->window = MI_WINDOW(mi); if ((gp->glx_context = init_GL(mi)) != NULL) { - reshape_screensaver(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_extrusion(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); initializeGL(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - chooseScreensaverExample(mi); + chooseExtrusionExample(mi); } else { MI_CLEARWINDOW(mi); } } -/* all sorts of nice cleanup code should go here! */ -void release_screensaver(ModeInfo * mi) -{ - int screen; - if (Screensaver != NULL) { - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - /* screensaverstruct *gp = &Screensaver[screen];*/ - } - (void) free((void *) Screensaver); - Screensaver = NULL; - } - FreeAllGL(mi); -} -#endif +XSCREENSAVER_MODULE ("Extrusion", extrusion) +#endif /* USE_GL */