X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fpulsar.c;h=a7695027e983fc84de1c834fcc352122f1bb26a0;hb=3c58fb6311db49c46f1670922933b27c6ea0c065;hp=b7a8e43346b096abc4c50e3a6bcea23d36c09ca2;hpb=551b3de3f619c04c2dd1971ee9b3f02e270c28c9;p=xscreensaver diff --git a/hacks/glx/pulsar.c b/hacks/glx/pulsar.c index b7a8e433..a7695027 100644 --- a/hacks/glx/pulsar.c +++ b/hacks/glx/pulsar.c @@ -15,7 +15,25 @@ * Revision History: * 4-Apr-1999: dek@cgl.ucsf.edu Created module "pulsar" + * 27-Apr-1999: dek@cgl.ucsf.edu Submitted module "pulsar" + * 4-May-1999: jwz@jwz.org Added module "pulsar" + * 4-May-1999: dek@cgl.ucsf.edu Submitted module "pulsar" updates * + * Notes: + * The pulsar screensaver draws a number of rotating, pulsing rectangles + * on your screen. Depending on the options you choose, you can set a number + * of interesting OpenGL parameters, including alpha blending, depth testing, fog, + * lighting, texturing, mipmapping, bilinear filtering, and line antialiasing. + * Additionally, there is a "frames per second" meter which gives an estimate of + * the speed of your graphics card. + * + * Example command-line switches: + * Only draw a single quad, and don't fill it (boring but fast) + * pulsar -wire -quads 1 -fps + * + * Only try this with hardware graphics acceleration (PPro 200 w/ a Voodoo 2 runs great) + * pulsar -quads 10 -texture -mipmap -texture_quality -light -fog -fps + * */ #include @@ -33,17 +51,21 @@ # define PROGCLASS "Screensaver" # define HACK_INIT init_screensaver # define HACK_DRAW draw_screensaver +# define HACK_RESHAPE reshape_screensaver # define screensaver_opts xlockmore_opts -#define DEFAULTS "*light: False \n" \ +#define DEFAULTS "*delay: 10000 \n" \ + "*showFPS: False \n" \ + "*light: False \n" \ "*wire: False \n" \ + "*quads: 5 \n" \ "*blend: True \n" \ "*fog: False \n" \ "*antialias: False \n" \ "*texture: False \n" \ "*texture_quality: False \n" \ "*mipmap: False \n" \ - "*fps: False \n" \ "*doDepth: False \n" \ + "*image: BUILTIN \n" # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ @@ -80,59 +102,43 @@ #define checkImageWidth 64 #define checkImageHeight 64 -char *Textures[] = { - "./test.ppm4", -}; - -typedef struct { - int sizeX, sizeY; - GLubyte *data; -} PPMImage; - /* Functions for handling the frames per second timer */ #include "GL/glx.h" -#ifndef SAMPLE_FRAMES -#define SAMPLE_FRAMES 10 -#endif - -static GLint base; -static int FrameCounter = 0; -static double oldtime=-1., newtime=-1.; -static char FPSstring[1024]="FPS: NONE"; - -static float x_pos=0, y_pos=0; - -#define FONT "-*-courier-medium-r-normal-*-240-*" - - - -#define NUM_TRIANGLES 5 -static float scale_x=1, scale_y=1, scale_z=1; -static int frame = 0; -struct triangle -{ - GLfloat tx, ty, tz; - GLfloat rx, ry, rz; - - GLfloat dtx, dty, dtz; - GLfloat drx, dry, drz; - -}; -struct triangle triangles[NUM_TRIANGLES]; -GLint tri_list; - - #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) #define WIDTH 800 #define HEIGHT 600 -int global_width=WIDTH, global_height=HEIGHT; +#define NUM_QUADS 5 +#define DEF_NUM_QUADS "5" +#define DEF_LIGHT "False" +#define DEF_WIRE "False" +#define DEF_BLEND "True" +#define DEF_FOG "False" +#define DEF_ANTIALIAS "False" +#define DEF_TEXTURE "False" +#define DEF_TEXTURE_QUALITY "False" +#define DEF_MIPMAP "False" +#define DEF_DO_DEPTH "False" +#define DEF_IMAGE "BUILTIN" + +static int num_quads; +static int do_light; +static int do_wire; +static int do_blend; +static int do_fog; +static int do_antialias; +static int do_texture; +static int do_texture_quality; +static int do_mipmap; +static int do_depth; +static char *which_image; static XrmOptionDescRec opts[] = { + {"-quads", ".pulsar.quads", XrmoptionSepArg, (caddr_t) NULL }, {"-light", ".pulsar.light", XrmoptionNoArg, (caddr_t) "true" }, {"+light", ".pulsar.light", XrmoptionNoArg, (caddr_t) "false" }, {"-wire", ".pulsar.wire", XrmoptionNoArg, (caddr_t) "true" }, @@ -149,35 +155,14 @@ static XrmOptionDescRec opts[] = { {"+texture_quality", ".pulsar.texture_quality", XrmoptionNoArg, (caddr_t) "false" }, {"-mipmap", ".pulsar.mipmap", XrmoptionNoArg, (caddr_t) "true" }, {"+mipmap", ".pulsar.mipmap", XrmoptionNoArg, (caddr_t) "false" }, - {"-fps", ".pulsar.fps", XrmoptionNoArg, (caddr_t) "true" }, - {"+fps", ".pulsar.fps", XrmoptionNoArg, (caddr_t) "false" }, {"-do_depth", ".pulsar.doDepth", XrmoptionNoArg, (caddr_t) "true" }, {"+do_depth", ".pulsar.doDepth", XrmoptionNoArg, (caddr_t) "false" }, + {"-image", ".pulsar.image", XrmoptionSepArg, (caddr_t) NULL }, }; -#define DEF_LIGHT "False" -#define DEF_WIRE "False" -#define DEF_BLEND "True" -#define DEF_FOG "False" -#define DEF_ANTIALIAS "False" -#define DEF_TEXTURE "False" -#define DEF_TEXTURE_QUALITY "False" -#define DEF_MIPMAP "False" -#define DEF_FPS "False" -#define DEF_DO_DEPTH "False" - -static int do_light; -static int do_wire; -static int do_blend; -static int do_fog; -static int do_antialias; -static int do_texture; -static int do_texture_quality; -static int do_mipmap; -static int do_fps; -static int do_depth; static argtype vars[] = { + {(caddr_t *) &num_quads, "quads", "Quads", DEF_NUM_QUADS, t_Int}, {(caddr_t *) &do_light, "light", "Light", DEF_LIGHT, t_Bool}, {(caddr_t *) &do_wire, "wire", "Wire", DEF_WIRE, t_Bool}, {(caddr_t *) &do_blend, "blend", "Blend", DEF_BLEND, t_Bool}, @@ -186,12 +171,27 @@ static argtype vars[] = { {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, {(caddr_t *) &do_texture_quality, "texture_quality", "Texture_quality", DEF_TEXTURE_QUALITY, t_Bool}, {(caddr_t *) &do_mipmap, "mipmap", "Mipmap", DEF_MIPMAP, t_Bool}, - {(caddr_t *) &do_fps, "fps", "fps", DEF_FPS, t_Bool}, {(caddr_t *) &do_depth, "doDepth", "DoDepth", DEF_DO_DEPTH, t_Bool}, + {(caddr_t *) &which_image, "image", "Image", DEF_IMAGE, t_String}, }; -ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, NULL}; +static OptionStruct desc[] = +{ + {"-quads num", "how many quads to draw"}, + {"-/+ light", "whether to do enable lighting (slower)"}, + {"-/+ wire", "whether to do use wireframe instead of filled (faster)"}, + {"-/+ blend", "whether to do enable blending (slower)"}, + {"-/+ fog", "whether to do enable fog (?)"}, + {"-/+ antialias", "whether to do enable antialiased lines (slower)"}, + {"-/+ texture", "whether to do enable texturing (much slower)"}, + {"-/+ texture_quality", "whether to do enable linear/mipmap filtering (much much slower)"}, + {"-/+ mipmap", "whether to do enable mipmaps (much slower)"}, + {"-/+ depth", "whether to do enable depth buffer checking (slower)"}, + {"-image ", "texture image to load (PPM, PPM4, TIFF(?), XPM(?))"}, +}; + +ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, desc}; #ifdef USE_MODULES ModStruct screensaver_description = @@ -212,93 +212,23 @@ typedef struct { static screensaverstruct *Screensaver = NULL; - -void FPS_Setup(void) -{ - Display *Dpy; - XFontStruct *fontInfo; - Font id; - int first=0, last=255; - - Dpy = XOpenDisplay(NULL); - fontInfo = XLoadQueryFont(Dpy, FONT); - if (fontInfo == NULL) - { - fprintf(stderr, "Failed to load font %s\n", FONT); - exit(1); - } - - id = fontInfo->fid; - first = fontInfo->min_char_or_byte2; - last = fontInfo->max_char_or_byte2; - - base = glGenLists((GLuint) last+1); - if (base == 0) { - fprintf (stderr, "out of display lists\n"); - exit(1); - } - glXUseXFont(id, first, last-first+1, base+first); - -} - -void PrintString(float x, float y, char *string) +struct quad { - int len, i; - - /* save the current state */ - /* note: could be expensive! */ - glPushAttrib(GL_ALL_ATTRIB_BITS); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0, global_width, 0, global_height); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - /* disable lighting and texturing when drawing bitmaps! */ - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - - /* draw a black background */ + GLfloat tx, ty, tz; + GLfloat rx, ry, rz; - /* draw the text */ - glColor3f(1,1,1); - glRasterPos2f( x, y); - len = (int) strlen(string); - for (i = 0; i < len; i++) { - glCallList(base+string[i]); - } + GLfloat dtx, dty, dtz; + GLfloat drx, dry, drz; - /* clean up after our state changes */ - glPopAttrib(); -} +}; -double gettime(void) -{ - struct timeval now; -#ifdef GETTIMEOFDAY_TWO_ARGS - struct timezone tzp; - gettimeofday(&now, &tzp); -#else - gettimeofday(&now); -#endif - return (double) (now.tv_sec + (((double) now.tv_usec) * 0.000001)); -} -void DoFPS(void) -{ - /* every SAMPLE_FRAMES frames, get the time and use it to get the - frames per second */ - if (!(FrameCounter % SAMPLE_FRAMES)) { - oldtime = newtime; - newtime = gettime(); - sprintf(FPSstring, "FPS: %.02f", SAMPLE_FRAMES/(newtime-oldtime)); - } +GLint quad_list; - PrintString(x_pos,y_pos,FPSstring); +static float scale_x=1, scale_y=1, scale_z=1; +static int frame = 0; - FrameCounter++; -} +struct quad *quads; GLubyte *Generate_Image(int *width, int *height, int *format) { @@ -367,12 +297,12 @@ uint32 *LoadTIFF(char *filename, int *width, int *height, int *format) } #endif - /* Load a modified version of PPM format with an extra byte for alpha */ GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format) { char buff[1024]; - PPMImage *result; + GLubyte *data; + int sizeX, sizeY; FILE *fp; int maxval; @@ -385,7 +315,7 @@ GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format) if (!fgets(buff, sizeof(buff), fp)) { - perror(filename); + perror("Unable to read header filename\n"); return Generate_Image(width, height, format); } @@ -395,20 +325,13 @@ GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format) return Generate_Image(width, height, format); } - result = malloc(sizeof(PPMImage)); - if (!result) - { - fprintf(stderr, "Unable to allocate memory\n"); - return Generate_Image(width, height, format); - } - do { fgets(buff, sizeof(buff), fp); } while (buff[0] == '#'); - if (sscanf(buff, "%d %d", &result->sizeX, &result->sizeY) != 2) + if (sscanf(buff, "%d %d", &sizeX, &sizeY) != 2) { fprintf(stderr, "Error loading image `%s'\n", filename); return Generate_Image(width, height, format); @@ -423,14 +346,14 @@ GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format) while (fgetc(fp) != '\n') ; - result->data = (GLubyte *)malloc(4 * result->sizeX * result->sizeY); - if (!result) + data = (GLubyte *)malloc(4 * sizeX * sizeY); + if (data == NULL) { fprintf(stderr, "Unable to allocate memory\n"); - exit(1); + exit(1); } - if (fread(result->data, 4 * result->sizeX, result->sizeY, fp) != result->sizeY) + if (fread(data, 4 * sizeX, sizeY, fp) != sizeY) { fprintf(stderr, "Error loading image `%s'\n", filename); return Generate_Image(width, height, format); @@ -438,17 +361,18 @@ GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format) fclose(fp); - *width = result->sizeX; - *height = result->sizeY; + *width = sizeX; + *height = sizeY; *format = GL_RGBA; - return result->data; + return data; } /* Load a plain PPM image */ GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format) { char buff[1024]; - PPMImage *result; + GLubyte *data; + GLint sizeX, sizeY; FILE *fp; int maxval; @@ -471,20 +395,13 @@ GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format) return Generate_Image(width, height, format); } - result = malloc(sizeof(PPMImage)); - if (!result) - { - fprintf(stderr, "Unable to allocate memory\n"); - return Generate_Image(width, height, format); - } - do { fgets(buff, sizeof(buff), fp); } while (buff[0] == '#'); - if (sscanf(buff, "%d %d", &result->sizeX, &result->sizeY) != 2) + if (sscanf(buff, "%d %d", &sizeX, &sizeY) != 2) { fprintf(stderr, "Error loading image `%s'\n", filename); return Generate_Image(width, height, format); @@ -499,14 +416,14 @@ GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format) while (fgetc(fp) != '\n') ; - result->data = (GLubyte *)malloc(3 * result->sizeX * result->sizeY); - if (!result) + data = (GLubyte *)malloc(3 * sizeX * sizeY); + if (data == NULL) { fprintf(stderr, "Unable to allocate memory\n"); - return Generate_Image(width, height, format); + exit(1); } - if (fread(result->data, 3 * result->sizeX, result->sizeY, fp) != result->sizeY) + if (fread(data, 3 * sizeX, sizeY, fp) != sizeY) { fprintf(stderr, "Error loading image `%s'\n", filename); return Generate_Image(width, height, format); @@ -514,10 +431,10 @@ GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format) fclose(fp); - *width = result->sizeX; - *height = result->sizeY; + *width = sizeX; + *height = sizeY; *format = GL_RGB; - return result->data; + return data; } /* Create a texture in OpenGL. First an image is loaded @@ -529,9 +446,9 @@ void Create_Texture(char *filename) GLint a; int format; - fprintf(stdout, "Loading texture '%s'\n", filename); - - if ( !strncmp((filename+strlen(filename)-3), "ppm", 3)) + if ( !strncmp(filename, "BUILTIN", 7)) + image = Generate_Image(&width, &height, &format); + else if ( !strncmp((filename+strlen(filename)-3), "ppm", 3)) image = LoadPPM(filename, &width, &height, &format); else if ( !strncmp((filename+strlen(filename)-4), "ppm4", 4)) image = LoadPPM4(filename, &width, &height, &format); @@ -549,23 +466,31 @@ void Create_Texture(char *filename) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + /* perhaps we can edge a bit more speed at the expense of quality */ + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); if (do_texture_quality) { + /* 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); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } else { + /* default is to do it quick and dirty */ + /* if you have mipmaps turned on, but not texture quality, nothing will happen! */ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); } + /* mipmaps make the image look much nicer */ if (do_mipmap) a=gluBuild2DMipmaps(GL_TEXTURE_2D, format, width, height, format, GL_UNSIGNED_BYTE, image); - else - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, - format, GL_UNSIGNED_BYTE, image); + else + { + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, + format, GL_UNSIGNED_BYTE, image); + check_gl_error("texture"); + } free(image); } @@ -579,33 +504,41 @@ void resetProjection(void) { } -void GenerateTriangle(void) +void GenerateQuad(void) { int i; - tri_list = glGenLists(1); - glNewList(tri_list,GL_COMPILE); -/* glBegin(GL_TRIANGLES); */ + quad_list = glGenLists(1); + glNewList(quad_list,GL_COMPILE); +#if 1 glBegin(GL_QUADS); glColor4f(1,0,0,.4); glNormal3f(0,0,1); glTexCoord2f(0,0); glVertex2f(-1, -1); glColor4f(0,1,0,.4); glNormal3f(0,0,1); glTexCoord2f(0,1); glVertex2f(-1, 1); glColor4f(0,0,1,.4); glNormal3f(0,0,1); glTexCoord2f(1,1); glVertex2f( 1, 1); glColor4f(1,1,1,1); glNormal3f(0,0,1); glTexCoord2f(1,0); glVertex2f( 1, -1); +#else + glBegin(GL_TRIANGLE_STRIP); + glColor4f(0,1,0,.4); glNormal3f(0,0,1); glTexCoord2f(0,1); glVertex2f(-1, 1); + glColor4f(1,0,0,.4); glNormal3f(0,0,1); glTexCoord2f(0,0); glVertex2f(-1, -1); + glColor4f(0,0,1,.4); glNormal3f(0,0,1); glTexCoord2f(1,1); glVertex2f( 1, 1); + glColor4f(1,1,1,.4); glNormal3f(0,0,1); glTexCoord2f(1,0); glVertex2f( 1, -1); +#endif glEnd(); glEndList(); - for (i=0; i < NUM_TRIANGLES; i++) + quads = (struct quad *) malloc(sizeof(struct quad) * num_quads); + for (i=0; i < num_quads; i++) { - triangles[i].rx = 0.; - triangles[i].ry = 0.; - triangles[i].rz = 0.; - triangles[i].tx = 0.; - triangles[i].ty = 0.; - triangles[i].tz = -10; - - triangles[i].drx = drand48() * 5.; - triangles[i].dry = drand48() * 5.; - triangles[i].drz = 0; + quads[i].rx = 0.; + quads[i].ry = 0.; + quads[i].rz = 0.; + quads[i].tx = 0.; + quads[i].ty = 0.; + quads[i].tz = -10; + + quads[i].drx = frand(5.0); + quads[i].dry = frand(5.0); + quads[i].drz = 0; } } @@ -613,18 +546,12 @@ void initializeGL(GLsizei width, GLsizei height) { GLfloat fogColor[4] = { 0.1, 0.1, 0.1, 0.1 }; - global_width=width; - global_height=height; - glViewport( 0, 0, width, height ); resetProjection(); if (do_depth) glEnable(GL_DEPTH_TEST); - if (do_fps) - FPS_Setup(); - if (do_antialias) { do_blend = 1; glEnable(GL_LINE_SMOOTH); @@ -659,36 +586,34 @@ void initializeGL(GLsizei width, GLsizei height) if (do_texture) - { - Create_Texture(Textures[0]); - } + Create_Texture(which_image); - GenerateTriangle(); + GenerateQuad(); } -void drawTriangles(void) { +void drawQuads(void) { int i; - for (i=0; i < NUM_TRIANGLES; i++) + for (i=0; i < num_quads; i++) { glPushMatrix(); - glTranslatef(triangles[i].tx,0,0); - glTranslatef(0,triangles[i].ty,0); - glTranslatef(0,0,triangles[i].tz); - glRotatef(triangles[i].rx, 1,0,0); - glRotatef(triangles[i].ry, 0,1,0); - glRotatef(triangles[i].rz, 0,0,1); - glCallList(tri_list); + glTranslatef(quads[i].tx,0,0); + glTranslatef(0,quads[i].ty,0); + glTranslatef(0,0,quads[i].tz); + glRotatef(quads[i].rx, 1,0,0); + glRotatef(quads[i].ry, 0,1,0); + glRotatef(quads[i].rz, 0,0,1); + glCallList(quad_list); glPopMatrix(); - triangles[i].rx += triangles[i].drx; - triangles[i].ry += triangles[i].dry; - triangles[i].rz += triangles[i].drz; + quads[i].rx += quads[i].drx; + quads[i].ry += quads[i].dry; + quads[i].rz += quads[i].drz; } } -GLvoid drawScene(GLvoid) +GLvoid drawScene(ModeInfo * mi) { - +/* check_gl_error ("drawScene"); */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* we have to do this here because the FPS meter turns these 3 features off!! */ @@ -709,15 +634,20 @@ GLvoid drawScene(GLvoid) } resetProjection(); + + /* use XYZ scaling factors to change the size of the pulsar */ glScalef(scale_x, scale_y, scale_z); - drawTriangles(); - + drawQuads(); + + /* update the scaling factors- cyclic */ scale_x = cos(frame/360.)*10.; scale_y = sin(frame/360.)*10.; scale_z = 1; + /* increment frame-counter */ frame++; - DoFPS(); + +/* check_gl_error ("drawScene"); */ } @@ -731,15 +661,16 @@ void draw_screensaver(ModeInfo * mi) return; glXMakeCurrent(display, window, *(gp->glx_context)); - drawScene(); + drawScene(mi); + if (mi->fps_p) do_fps (mi); glXSwapBuffers(display, window); } /* Standard reshape function */ -static void -reshape(int width, int height) +void +reshape_screensaver(ModeInfo *mi, int width, int height) { - glViewport( 0, 0, global_width, global_height ); + glViewport( 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi) ); resetProjection(); } @@ -758,7 +689,7 @@ init_screensaver(ModeInfo * mi) gp->window = MI_WINDOW(mi); if ((gp->glx_context = init_GL(mi)) != NULL) { - reshape(MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_screensaver(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); initializeGL(MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); @@ -777,7 +708,7 @@ void release_screensaver(ModeInfo * mi) (void) free((void *) Screensaver); Screensaver = NULL; } + free(quads); FreeAllGL(mi); } #endif -