X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fglplanet.c;h=20632b9a56b0b792aba4f530c4213512d49029f4;hb=cccbddbc4140cf9a06d7d95cc5c0ca36eb5d6e28;hp=39ae21bb05cb8e23f709b83e00250790afc6655a;hpb=df7adbee81405e2849728a24b498ad2117784b1f;p=xscreensaver diff --git a/hacks/glx/glplanet.c b/hacks/glx/glplanet.c index 39ae21bb..20632b9a 100644 --- a/hacks/glx/glplanet.c +++ b/hacks/glx/glplanet.c @@ -1,12 +1,6 @@ /* -*- Mode: C; tab-width: 4 -*- */ -/* glplanet --- 3D rotating planet, e.g., Earth. */ - -#if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; - -#endif - -/*- +/* glplanet --- 3D rotating planet, e.g., Earth. + * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that @@ -20,6 +14,10 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; * other special, indirect and consequential damages. * * Revision History: + * + * 16-Jan-02: jwz@jwz.org gdk_pixbuf support. + * 21-Mar-01: jwz@jwz.org Broke sphere routine out into its own file. + * * 9-Oct-98: dek@cgl.ucsf.edu Added stars. * * 8-Oct-98: jwz@jwz.org Made the 512x512x1 xearth image be built in. @@ -32,18 +30,8 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; * BUGS: * -bounce is broken * - * For even more spectacular results, grab the images from the "SSysten" - * package (http://www.msu.edu/user/kamelkev/) and do this: - * - * cd ssystem-1.4/hires/ - * foreach f ( *.jpg ) - * djpeg $f | ppmquant 254 | ppmtoxpm > /tmp/$f:r.xpm - * end - * - * cd /tmp - * foreach f ( *.xpm ) - * glplanet -image $f - * end + * For even more spectacular results, grab the images from the "SSystem" + * package (http://www.msu.edu/user/kamelkev/) and use its JPEGs! */ @@ -58,11 +46,13 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; # define PROGCLASS "Planet" # define HACK_INIT init_planet # define HACK_DRAW draw_planet +# define HACK_RESHAPE reshape_planet # define planet_opts xlockmore_opts #define DEFAULTS "*delay: 15000 \n" \ + "*showFPS: False \n" \ "*rotate: True \n" \ "*roll: True \n" \ - "*bounce: True \n" \ + "*wander: True \n" \ "*wireframe: False \n" \ "*light: True \n" \ "*texture: True \n" \ @@ -78,12 +68,7 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; #ifdef USE_GL /* whole file */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif +#include "sphere.h" #ifdef HAVE_XMU # ifndef VMS @@ -98,9 +83,9 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; #define DEF_ROTATE "True" #define DEF_ROLL "True" -#define DEF_BOUNCE "True" +#define DEF_WANDER "True" #define DEF_TEXTURE "True" -#define DEF_STARS "True" +#define DEF_STARS "True" #define DEF_LIGHT "True" #define DEF_IMAGE "BUILTIN" @@ -109,7 +94,7 @@ static const char sccsid[] = "@(#)plate.c 4.07 97/11/24 xlockmore"; static int do_rotate; static int do_roll; -static int do_bounce; +static int do_wander; static int do_texture; static int do_stars; static int do_light; @@ -119,8 +104,8 @@ static XrmOptionDescRec opts[] = { {"+rotate", ".glplanet.rotate", XrmoptionNoArg, (caddr_t) "false" }, {"-roll", ".glplanet.roll", XrmoptionNoArg, (caddr_t) "true" }, {"+roll", ".glplanet.roll", XrmoptionNoArg, (caddr_t) "false" }, - {"-bounce", ".glplanet.bounce", XrmoptionNoArg, (caddr_t) "true" }, - {"+bounce", ".glplanet.bounce", XrmoptionNoArg, (caddr_t) "false" }, + {"-wander", ".glplanet.wander", XrmoptionNoArg, (caddr_t) "true" }, + {"+wander", ".glplanet.wander", XrmoptionNoArg, (caddr_t) "false" }, {"-texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "true" }, {"+texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "false" }, {"-stars", ".glplanet.stars", XrmoptionNoArg, (caddr_t) "true" }, @@ -133,7 +118,7 @@ static XrmOptionDescRec opts[] = { static argtype vars[] = { {(caddr_t *) &do_rotate, "rotate", "Rotate", DEF_ROTATE, t_Bool}, {(caddr_t *) &do_roll, "roll", "Roll", DEF_ROLL, t_Bool}, - {(caddr_t *) &do_bounce, "bounce", "Bounce", DEF_BOUNCE, t_Bool}, + {(caddr_t *) &do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, {(caddr_t *) &do_stars, "stars", "Stars", DEF_STARS, t_Bool}, {(caddr_t *) &do_light, "light", "Light", DEF_LIGHT, t_Bool}, @@ -150,7 +135,7 @@ ModStruct planet_description = "Animates texture mapped sphere (planet)", 0, NULL}; #endif -#include "../images/earth.xbm" +#include "../images/earth.xpm" #include "xpm-ximage.h" @@ -161,8 +146,8 @@ ModStruct planet_description = */ #define NUM_STARS 1000 -#define SLICES 15 -#define STACKS 15 +#define SLICES 32 +#define STACKS 32 /* radius of the sphere- fairly arbitrary */ #define RADIUS 4 @@ -188,6 +173,8 @@ typedef struct { GLfloat dx, dy, dz; GLfloat box_width, box_height, box_depth; + GLfloat sunpos[4]; + } planetstruct; @@ -197,48 +184,33 @@ static planetstruct *planets = NULL; static inline void normalize(GLfloat v[3]) { - GLfloat d = (GLfloat) sqrt((double) (v[0] * v[0] + v[1] * v[1] + v[2] * v[2])); - - if (d != 0) { - v[0] /= d; - v[1] /= d; - v[2] /= d; - } else { - v[0] = v[1] = v[2] = 0; + GLfloat d = (GLfloat) sqrt((double) (v[0] * v[0] + + v[1] * v[1] + + v[2] * v[2])); + if (d != 0) + { + v[0] /= d; + v[1] /= d; + v[2] /= d; + } + else + { + v[0] = v[1] = v[2] = 0; } } /* Set up and enable texturing on our object */ static void -setup_xbm_texture (char *bits, int width, int height, - XColor *fgc, XColor *bgc) +setup_xpm_texture (ModeInfo *mi, char **xpm_data) { - unsigned int fg = (((fgc->red >> 8) << 16) | - ((fgc->green >> 8) << 8) | - ((fgc->blue >> 8))); - unsigned int bg = (((bgc->red >> 8) << 16) | - ((bgc->green >> 8) << 8) | - ((bgc->blue >> 8))); - - unsigned char *data = (unsigned char *) - malloc ((width * height * 24) / 8); - unsigned char *out = data; - int x, y; - - for (y = 0; y < height; y++) - for (x = 0; x < width; x++) - { - unsigned char byte = bits [(y * (width / 8) + (x / 8))]; - unsigned char bit = (byte & (1 << (x % 8))) >> (x % 8); - unsigned int word = (bit ? bg : fg); - *out++ = (word & 0xFF0000) >> 16; - *out++ = (word & 0x00FF00) >> 8; - *out++ = (word & 0x0000FF); - } - - glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, - GL_RGB, GL_UNSIGNED_BYTE, data); + XImage *image = xpm_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi), + MI_COLORMAP (mi), xpm_data); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + image->width, image->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image->data); + check_gl_error("texture"); /* setup parameters for texturing */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -255,312 +227,192 @@ setup_file_texture (ModeInfo *mi, char *filename) { Display *dpy = mi->dpy; Visual *visual = mi->xgwa.visual; + Colormap cmap = mi->xgwa.colormap; + XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename); -#ifdef HAVE_XPM - { - char **xpm_data = 0; - int result = XpmReadFileToData (filename, &xpm_data); - switch (result) { - case XpmSuccess: - { - XImage *image = xpm_to_ximage (dpy, visual, cmap, xpm_data); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - image->width, image->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image->data); - - /* setup parameters for texturing */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - return; - } - break; - - case XpmOpenFailed: - fprintf (stderr, "%s: file %s doesn't exist.\n", progname, filename); - exit (-1); - break; - - case XpmFileInvalid: - /* Fall through and try it as an XBM. */ - break; - - case XpmNoMemory: - fprintf (stderr, "%s: XPM: out of memory\n", progname); - exit (-1); - break; - - default: - fprintf (stderr, "%s: XPM: unknown error code %d\n", progname, result); - exit (-1); - break; - } - } -#endif /* HAVE_XPM */ + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + image->width, image->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image->data); + check_gl_error("texture"); -#ifdef HAVE_XMU - { - planetstruct *gp = &planets[MI_SCREEN(mi)]; - unsigned int width = 0; - unsigned int height = 0; - unsigned char *data = 0; - int xhot, yhot; - int status = XmuReadBitmapDataFromFile (filename, &width, &height, &data, - &xhot, &yhot); - if (status != Success) - { -# ifdef HAVE_XPM - fprintf (stderr, "%s: not an XPM file: %s\n", progname, filename); -# endif - fprintf (stderr, "%s: not an XBM file: %s\n", progname, filename); - exit (1); - } + /* setup parameters for texturing */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width); - setup_xbm_texture ((char *) data, width, height, &gp->fg, &gp->bg); - } -#else /* !XMU */ - -# ifdef HAVE_XPM - fprintf (stderr, "%s: not an XPM file: %s\n", progname, filename); -# endif - fprintf (stderr, "%s: your vendor doesn't ship the standard Xmu library.\n", - progname); - fprintf (stderr, "%s: we can't load XBM files without it.\n",progname); - exit (1); -#endif /* !XMU */ + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } static void setup_texture(ModeInfo * mi) { - planetstruct *gp = &planets[MI_SCREEN(mi)]; +/* planetstruct *gp = &planets[MI_SCREEN(mi)];*/ + + glEnable(GL_TEXTURE_2D); + if (!which_image || !*which_image || !strcmp(which_image, "BUILTIN")) - setup_xbm_texture (earth_bits, earth_width, earth_height, - &gp->fg, &gp->bg); + setup_xpm_texture (mi, earth_xpm); else setup_file_texture (mi, which_image); -} - -/* Set up and enable lighting */ -static void -setup_light(void) -{ - /* set a number of parameters which make the scene look much nicer */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glShadeModel(GL_SMOOTH); + check_gl_error("texture initialization"); } -/* Set up and enable face culling so we don't see the inside of the sphere */ -static void -setup_face(void) +void +init_stars (ModeInfo *mi) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); -} + int i, j; + GLfloat max_size = 3; + GLfloat inc = 0.5; + int steps = max_size / inc; + int width = MI_WIDTH(mi); + int height = MI_HEIGHT(mi); + planetstruct *gp = &planets[MI_SCREEN(mi)]; + Bool wire = MI_IS_WIREFRAME(mi); + + if (!wire) + glEnable (GL_POINT_SMOOTH); -/* Function for determining points on the surface of the sphere */ -static void inline ParametricSphere(float theta, float rho, GLfloat *vector) -{ - vector[0] = -sin(theta) * sin(rho); - vector[1] = cos(theta) * sin(rho); - vector[2] = cos(rho); + gp->starlist = glGenLists(1); + glNewList(gp->starlist, GL_COMPILE); -#if DO_HELIX - vector[0] = -(1- cos(theta)) * cos(rho); - vector[1] = -(1- cos(theta)) * sin(rho); - vector[2] = -(sin(theta) + rho); -#endif /* DO_HELIX */ + glScalef (1.0/width, 1.0/height, 1); + + for (j = 1; j <= steps; j++) + { + glPointSize(inc * j); + glBegin(GL_POINTS); + for (i = 0 ; i < NUM_STARS / steps; i++) + { + glColor3f (0.6 + frand(0.3), + 0.6 + frand(0.3), + 0.6 + frand(0.3)); + glVertex2f ((GLfloat) (random() % width), + (GLfloat) (random() % height)); + } + glEnd(); + } + glEndList(); - return; + check_gl_error("stars initialization"); } -/* lame way to generate some random stars */ -void generate_stars(int width, int height) +void +draw_stars (ModeInfo * mi) { - int i; -/* GLfloat size_range[2], size;*/ - GLfloat x, y; + int width = MI_WIDTH(mi); + int height = MI_HEIGHT(mi); planetstruct *gp = &planets[MI_SCREEN(mi)]; -/* glGetFloatv(GL_POINT_SIZE_RANGE, size_range); */ - -/* printf("size range: %f\t%f\n", size_range[0], size_range[1]); */ - gp->starlist = glGenLists(1); - glNewList(gp->starlist, GL_COMPILE); - - /* this hackery makes the viewport map one-to-one with Vertex arguments */ - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0, width, 0, height); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + /* Sadly, this causes a stall of the graphics pipeline (as would the + equivalent calls to glGet*.) But there's no way around this, short + of having each caller set up the specific display matrix we need + here, which would kind of defeat the purpose of centralizing this + code in one file. + */ + glPushAttrib(GL_TRANSFORM_BIT | /* for matrix contents */ + GL_ENABLE_BIT | /* for various glDisable calls */ + GL_CURRENT_BIT | /* for glColor3f() */ + GL_LIST_BIT); /* for glListBase() */ + { + check_gl_error ("glPushAttrib"); + + /* disable lighting and texturing when drawing stars! + (glPopAttrib() restores these.) + */ + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + /* glPopAttrib() does not restore matrix changes, so we must + push/pop the matrix stacks to be non-intrusive there. + */ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + { + check_gl_error ("glPushMatrix"); + glLoadIdentity(); + + /* Each matrix mode has its own stack, so we need to push/pop + them separately. */ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + { + check_gl_error ("glPushMatrix"); + glLoadIdentity(); - /* disable depth testing for the stars, so they don't obscure the planet */ - glDisable(GL_DEPTH_TEST); - glEnable(GL_POINT_SMOOTH); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glBegin(GL_POINTS); - for(i = 0 ; i < NUM_STARS ; i++) - { -/* size = (drand48()+size_range[0]) * size_range[1]/2.; */ -/* glPointSize(size); */ - x = drand48()*width; - y = drand48()*height; - glVertex2f(x,y); - } - glEnd(); + gluOrtho2D (0, width, 0, height); + check_gl_error ("gluOrtho2D"); - /* return to original PROJECT and MODELVIEW */ - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); + /* Draw the stars */ + glScalef (width, height, 1); + glCallList(gp->starlist); + check_gl_error ("drawing stars"); + } + glPopMatrix(); + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + } + /* clean up after our state changes */ + glPopAttrib(); + check_gl_error ("glPopAttrib"); +} - glEndList(); -} -/* Initialization function for screen saver */ +/* Set up lighting */ static void -pinit(ModeInfo * mi) +init_sun (ModeInfo * mi) { - Bool wire = MI_IS_WIREFRAME(mi); planetstruct *gp = &planets[MI_SCREEN(mi)]; - int i, j; - int stacks=STACKS, slices=SLICES; - float radius=RADIUS; - float drho, dtheta; - float rho, theta; - GLfloat vector[3]; - GLfloat ds, dt, t, s;; + GLfloat lamb[4] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat ldif[4] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat spec[4] = { 1.0, 1.0, 1.0, 1.0 }; - if (wire) { - glEnable(GL_LINE_SMOOTH); - do_texture = False; - } + GLfloat mamb[4] = { 0.5, 0.5, 0.5, 1.0 }; + GLfloat mdif[4] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mpec[4] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat shiny = .4; - /* turn on various options we like */ - if (do_texture) - setup_texture(mi); - if (do_light) - setup_light(); + gp->sunpos[0] = 1.00 - frand(2.00); + gp->sunpos[1] = 0.25 - frand(0.50); + gp->sunpos[2] = -1.00; + gp->sunpos[3] = 0.00; - setup_face(); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); - if (do_stars) { - glEnable(GL_POINT_SMOOTH); - generate_stars(MI_WIDTH(mi), MI_HEIGHT(mi)); - } + glLightfv (GL_LIGHT0, GL_POSITION, gp->sunpos); + glLightfv (GL_LIGHT0, GL_AMBIENT, lamb); + glLightfv (GL_LIGHT0, GL_DIFFUSE, ldif); + glLightfv (GL_LIGHT0, GL_SPECULAR, spec); + glMaterialfv (GL_FRONT, GL_AMBIENT, mamb); + glMaterialfv (GL_FRONT, GL_DIFFUSE, mdif); + glMaterialfv (GL_FRONT, GL_SPECULAR, mpec); + glMaterialf (GL_FRONT, GL_SHININESS, shiny); - /*- - * Generate a sphere with quadrilaterals. - * Quad vertices are determined using a parametric sphere function. - * For fun, you could generate practically any parameteric surface and - * map an image onto it. - */ - - drho = M_PI / stacks; - dtheta = 2.0 * M_PI / slices; - ds = 1.0 / slices; - dt = 1.0 / stacks; - - - gp->platelist=glGenLists(1); - glNewList(gp->platelist, GL_COMPILE); - - glColor3f(1,1,1); - glBegin( wire ? GL_LINE_LOOP : GL_QUADS ); - - t = 0.0; - for(i=0; iplatelist); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_SMOOTH); + check_gl_error("lighting"); } @@ -612,44 +464,24 @@ rotate_and_move (ModeInfo * mi) while (gp->tz > 360) gp->tz -= 360; } - if (do_bounce) + if (do_wander) { - /* Move in the direction we had been moving in. */ - gp->xpos += gp->dx; - gp->ypos += gp->dy; - gp->zpos += gp->dz; - - /* Bounce. */ - if (gp->xpos > gp->box_depth) - gp->xpos = gp->box_depth, gp->dx = -gp->dx; - else if (gp->xpos < 0) - gp->xpos = 0, gp->dx = -gp->dx; - - if (gp->ypos > gp->box_width/2) - gp->ypos = gp->box_width/2, gp->dy = -gp->dy; - else if (gp->ypos < -gp->box_width/2) - gp->ypos = -gp->box_width/2, gp->dy = -gp->dy; - - if (gp->zpos > gp->box_height/2) - gp->zpos = gp->box_height/2, gp->dz = -gp->dz; - else if (gp->zpos < -gp->box_height/2) - gp->zpos = -gp->box_height/2, gp->dz = -gp->dz; + static int frame = 0; +# define SINOID(SCALE,SIZE) \ + ((((1 + sin((frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2) + gp->xpos = SINOID(0.031, gp->box_width); + gp->ypos = SINOID(0.023, gp->box_height); + gp->zpos = SINOID(0.017, gp->box_depth); + frame++; } } -/* Standard reshape function */ -static void -reshape(int width, int height) +void +reshape_planet (ModeInfo *mi, int width, int height) { - GLfloat light[4]; GLfloat h = (GLfloat) height / (GLfloat) width; - light[0] = -1; - light[1] = (int) (((random() % 3) & 0xFF) - 1); - light[2] = (int) (((random() % 3) & 0xFF) - 1); - light[3] = 0; - glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -657,18 +489,17 @@ reshape(int width, int height) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -DIST); - glLightfv(GL_LIGHT0, GL_POSITION, light); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void -init_planet(ModeInfo * mi) +init_planet (ModeInfo * mi) { - int screen = MI_SCREEN(mi); - planetstruct *gp; + int screen = MI_SCREEN(mi); + Bool wire = MI_IS_WIREFRAME(mi); if (planets == NULL) { if ((planets = (planetstruct *) calloc(MI_NUM_SCREENS(mi), @@ -679,6 +510,10 @@ init_planet(ModeInfo * mi) pick_velocity (mi); + if ((gp->glx_context = init_GL(mi)) != NULL) { + reshape_planet(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + } + { char *f = get_string_resource("imageForeground", "Foreground"); char *b = get_string_resource("imageBackground", "Background"); @@ -708,18 +543,38 @@ init_planet(ModeInfo * mi) free (b); } + if (wire) + { + do_texture = False; + do_light = False; + glEnable (GL_LINE_SMOOTH); + } - gp->window = MI_WINDOW(mi); - if ((gp->glx_context = init_GL(mi)) != NULL) { - reshape(MI_WIDTH(mi), MI_HEIGHT(mi)); - pinit(mi); - } else { - MI_CLEARWINDOW(mi); - } + if (do_texture) + setup_texture (mi); + + if (do_light) + init_sun (mi); + + if (do_stars) + init_stars (mi); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + gp->platelist = glGenLists(1); + glNewList (gp->platelist, GL_COMPILE); + glColor3f (1,1,1); + glPushMatrix (); + glScalef (RADIUS, RADIUS, RADIUS); + unit_sphere (STACKS, SLICES, wire); + glPopMatrix (); + glEndList(); } void -draw_planet(ModeInfo * mi) +draw_planet (ModeInfo * mi) { planetstruct *gp = &planets[MI_SCREEN(mi)]; Display *display = MI_DISPLAY(mi); @@ -731,54 +586,37 @@ draw_planet(ModeInfo * mi) glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glXMakeCurrent(display, window, *(gp->glx_context)); - - - if (do_stars) { - /* protect our modelview matrix and attributes */ - glPushMatrix(); - glPushAttrib(GL_ALL_ATTRIB_BITS); - { - glColor3f(1,1,1); - /* draw the star field. */ - glCallList(gp->starlist); + glXMakeCurrent (display, window, *(gp->glx_context)); - } - glPopMatrix(); - glPopAttrib(); - } + if (do_stars) + draw_stars (mi); - /* protect our modelview matrix and attributes */ glPushMatrix(); - glPushAttrib(GL_ALL_ATTRIB_BITS); - { - /* this pair of rotations seem to be necessary to orient the earth correctly */ - glRotatef(90,0,0,1); - glRotatef(90,0,1,0); - - glTranslatef(gp->xpos, gp->ypos, gp->zpos); - glRotatef(gp->tx, 1, 0, 0); - glRotatef(gp->ty, 0, 1, 0); - glRotatef(gp->tz, 0, 0, 1); - /* draw the sphere */ - draw_sphere(mi); - } - glPopMatrix(); - glPopAttrib(); + glRotatef (90,1,0,0); + glTranslatef (gp->xpos, gp->ypos, gp->zpos); + + glRotatef (gp->tx, 1, 0, 0); + glRotatef (gp->ty, 0, 1, 0); + glRotatef (gp->tz, 0, 0, 1); + glLightfv (GL_LIGHT0, GL_POSITION, gp->sunpos); + glCallList (gp->platelist); + glPopMatrix(); + if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(display, window); rotate_and_move (mi); } + void -release_planet(ModeInfo * mi) +release_planet (ModeInfo * mi) { if (planets != NULL) { - int screen; + int screen; for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { planetstruct *gp = &planets[screen];