diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/spheremonics.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/spheremonics.c')
| -rw-r--r-- | hacks/glx/spheremonics.c | 925 |
1 files changed, 0 insertions, 925 deletions
diff --git a/hacks/glx/spheremonics.c b/hacks/glx/spheremonics.c deleted file mode 100644 index 13eed8a..0000000 --- a/hacks/glx/spheremonics.c +++ /dev/null @@ -1,925 +0,0 @@ -/* xscreensaver, Copyright (c) 2002-2014 Jamie Zawinski <jwz@jwz.org> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * Algorithm by Paul Bourke <pbourke@swin.edu.au> - * http://astronomy.swin.edu.au/~pbourke/geometry/sphericalh/ - * Screensaver veneer and parameter selection by jwz. - * - * Paul says: - * - * These closed objects are commonly called spherical harmonics, - * although they are only remotely related to the mathematical - * definition found in the solution to certain wave functions, most - * notable the eigenfunctions of angular momentum operators. - * - * The formula is quite simple: the form used here is based upon - * spherical (polar) coordinates (radius, theta, phi). - * - * r = sin(m0 phi) ^ m1 + - * cos(m2 phi) ^ m3 + - * sin(m4 theta) ^ m5 + - * cos(m6 theta) ^ m7 - * - * Where phi ranges from 0 to pi (lines of latitude), and theta ranges - * from 0 to 2 pi (lines of longitude), and r is the radius. The - * parameters m0, m1, m2, m3, m4, m5, m6, and m7 are all integers - * greater than or equal to 0. - * - * As the degree increases, the objects become increasingly "pointed" - * and a large number of polygons are required to represent the surface - * faithfully. - * - * jwz adds: - * - * The eight parameters live in the `cc->m' array. - * Each time we permute the image, we alter *one* of those eight parameters. - * Each time we alter a parameter, we move it in the same direction (either - * toward larger or smaller values) in the range [0, 3]. - * - * By altering only one parameter at a time, and only by small amounts, - * we tend to produce successive objects that are pretty similar to each - * other, so you can see a progression. - * - * It'd be nice if they were even closer together, so that it looked more - * like a morph, but, well, that's not how it works. - * - * There tends to be a dark stripe in the colormaps. I don't know why. - * Perhaps utils/colors.c is at fault? - * - * Note that this equation sometimes generates faces that are inside out: - * -parameters 01210111 - * To make this work, we need to render back-faces with two-sided lighting: - * figuring out how to correct the winding and normals on those inside out - * surfaces would be too hard. - */ - -#define DEFAULTS "*delay: 30000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - "*labelfont: sans-serif 18\n" \ - "*suppressRotationAnimation: True\n" \ - -# define release_spheremonics 0 - -#include "xlockmore.h" -#include "texfont.h" -#include "normals.h" -#include "colors.h" -#include "rotator.h" -#include "gltrackball.h" -#include <ctype.h> - -#ifdef USE_GL /* whole file */ - -#define DEF_DURATION "200" -#define DEF_SPIN "XYZ" -#define DEF_WANDER "False" -#define DEF_RESOLUTION "64" -#define DEF_BBOX "False" -#define DEF_GRID "True" -#define DEF_SMOOTH "True" -#define DEF_PARMS "(default)" - -typedef struct { - GLXContext *glx_context; - rotator *rot; - trackball_state *trackball; - Bool button_down_p; - - GLuint dlist, dlist2, grid_dlist; - GLfloat scale; - XYZ bbox[2]; - - int resolution; - int ncolors; - XColor *colors; - - int m[8]; - int dm[8]; - int m_max; - - int tracer; - int mesher; - int polys1, polys2; /* polygon counts */ - - texture_font_data *font_data; - - int change_tick; - int done_once; - double fade; - -} spheremonics_configuration; - -static spheremonics_configuration *ccs = NULL; - -static char *do_spin; -static Bool do_wander; -static Bool do_bbox; -static Bool do_grid; -static int smooth_p; -static char *static_parms; -static int res; -static int duration; - -static XrmOptionDescRec opts[] = { - { "-spin", ".spin", XrmoptionSepArg, 0 }, - { "+spin", ".spin", XrmoptionNoArg, "" }, - { "-wander", ".wander", XrmoptionNoArg, "True" }, - { "+wander", ".wander", XrmoptionNoArg, "False" }, - { "-resolution", ".resolution", XrmoptionSepArg, 0 }, - { "-duration", ".duration", XrmoptionSepArg, 0 }, - { "-bbox", ".bbox", XrmoptionNoArg, "True" }, - { "+bbox", ".bbox", XrmoptionNoArg, "False" }, - { "-grid", ".grid", XrmoptionNoArg, "True" }, - { "+grid", ".grid", XrmoptionNoArg, "False" }, - {"-smooth", ".smooth", XrmoptionNoArg, "True" }, - {"+smooth", ".smooth", XrmoptionNoArg, "False" }, - { "-parameters", ".parameters", XrmoptionSepArg, 0 }, -}; - -static argtype vars[] = { - {&do_spin, "spin", "Spin", DEF_SPIN, t_String}, - {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, - {&res, "resolution", "Resolution", DEF_RESOLUTION, t_Int}, - {&duration, "duration", "Duration", DEF_DURATION, t_Int}, - {&do_bbox, "bbox", "BBox", DEF_BBOX, t_Bool}, - {&do_grid, "grid", "Grid", DEF_GRID, t_Bool}, - {&smooth_p, "smooth", "Smooth", DEF_SMOOTH, t_Bool}, - {&static_parms, "parameters", "Parameters", DEF_PARMS, t_String}, -}; - -ENTRYPOINT ModeSpecOpt spheremonics_opts = {countof(opts), opts, countof(vars), vars, NULL}; - - -/* Window management, etc - */ -ENTRYPOINT void -reshape_spheremonics (ModeInfo *mi, int width, int height) -{ - GLfloat h = (GLfloat) height / (GLfloat) width; - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width * 9/16; - y = -height/2; - h = height / (GLfloat) width; - } - - glViewport (0, y, (GLint) width, (GLint) height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - 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); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - glClear(GL_COLOR_BUFFER_BIT); -} - - -static void -gl_init (ModeInfo *mi) -{ -/* spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; */ - int wire = MI_IS_WIREFRAME(mi); - - static const GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0}; - - glEnable(GL_NORMALIZE); - - if (!wire) - { - glLightfv(GL_LIGHT0, GL_POSITION, pos); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); - - /* With objects that have proper winding and normals set up on all - their faces, one can cull back-faces; however, these equations - generate objects that are sometimes "inside out", and determining - whether a facet has been inverted like that is really hard. - So we render both front and back faces, at a probable performance - penalty on non-accelerated systems. - - When rendering back faces, we also need to do two-sided lighting, - or the fact that the normals are flipped gives us too-dark surfaces - on the inside-out surfaces. - - This isn't generally something you'd want, because you end up - with half the lighting dynamic range (kind of.) So if you had - a sphere with correctly pointing normals, and a single light - source, it would be illuminated from two sides. In this case, - though, it saves us from a difficult and time consuming - inside/outside test. And we don't really care about a precise - lighting effect. - */ - glDisable(GL_CULL_FACE); - glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, True); - } - - if (smooth_p) - { - glEnable (GL_LINE_SMOOTH); - glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable (GL_BLEND); - } -} - - - -/* generate the object */ - -static XYZ -sphere_eval (double theta, double phi, int *m) -{ - double r = 0; - XYZ p; - - r += pow (sin(m[0] * phi), (double)m[1]); - r += pow (cos(m[2] * phi), (double)m[3]); - r += pow (sin(m[4] * theta),(double)m[5]); - r += pow (cos(m[6] * theta),(double)m[7]); - - p.x = r * sin(phi) * cos(theta); - p.y = r * cos(phi); - p.z = r * sin(phi) * sin(theta); - - return (p); -} - - -static void -do_color (int i, XColor *colors) -{ - GLfloat c[4]; - c[0] = colors[i].red / 65535.0; - c[1] = colors[i].green / 65535.0; - c[2] = colors[i].blue / 65535.0; - c[3] = 1.0; - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c); - glColor3f (c[0], c[1], c[2]); -} - - -static void -draw_circle (ModeInfo *mi, Bool teeth_p) -{ - GLfloat th; - int tick = 0; - GLfloat x, y; - GLfloat step = (M_PI / 180); - - glBegin(GL_LINE_LOOP); - for (th = 0; th < M_PI*2; th += step*5) - { - GLfloat r1 = 0.5; - x = cos (th); - y = sin (th); - glVertex3f(x*r1, y*r1, 0); - } - glEnd(); - - if (!teeth_p) return; - - glBegin(GL_LINES); - for (th = 0; th < M_PI*2; th += step) - { - GLfloat r1 = 0.5; - GLfloat r2 = r1 - 0.01; - if (! (tick % 10)) - r2 -= 0.02; - else if (! (tick % 5)) - r2 -= 0.01; - tick++; - - x = cos (th); - y = sin (th); - glVertex3f(x*r1, y*r1, 0); - glVertex3f(x*r2, y*r2, 0); - } - glEnd(); -} - - -static void -draw_bounding_box (ModeInfo *mi) -{ - /* spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; */ - - static const GLfloat c1[4] = { 0.2, 0.2, 0.6, 1.0 }; - int wire = MI_IS_WIREFRAME(mi); - - GLfloat x1,y1,z1,x2,y2,z2; - -# if 0 - x1 = cc->bbox[0].x; - y1 = cc->bbox[0].y; - z1 = cc->bbox[0].z; - x2 = cc->bbox[1].x; - y2 = cc->bbox[1].y; - z2 = cc->bbox[1].z; -# else - x1 = y1 = z1 = -0.5; - x2 = y2 = z2 = 0.5; -# endif - - if (do_bbox && !wire) - { - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c1); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(0, 1, 0); - glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z2); - glVertex3f(x2, y1, z2); glVertex3f(x2, y1, z1); - glEnd(); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(0, -1, 0); - glVertex3f(x2, y2, z1); glVertex3f(x2, y2, z2); - glVertex3f(x1, y2, z2); glVertex3f(x1, y2, z1); - glEnd(); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(0, 0, 1); - glVertex3f(x1, y1, z1); glVertex3f(x2, y1, z1); - glVertex3f(x2, y2, z1); glVertex3f(x1, y2, z1); - glEnd(); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(0, 0, -1); - glVertex3f(x1, y2, z2); glVertex3f(x2, y2, z2); - glVertex3f(x2, y1, z2); glVertex3f(x1, y1, z2); - glEnd(); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(1, 0, 0); - glVertex3f(x1, y2, z1); glVertex3f(x1, y2, z2); - glVertex3f(x1, y1, z2); glVertex3f(x1, y1, z1); - glEnd(); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(-1, 0, 0); - glVertex3f(x2, y1, z1); glVertex3f(x2, y1, z2); - glVertex3f(x2, y2, z2); glVertex3f(x2, y2, z1); - glEnd(); - glDisable(GL_CULL_FACE); - } -} - - -static void -do_tracer (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - - if (cc->tracer == -1 && - cc->mesher == -1 && - !(random() % (duration * 4))) - { - if (random() & 1) - cc->tracer = ((random() & 1) ? 0 : 180); - else - cc->mesher = ((random() % ((duration / 3) + 1)) + - (random() % ((duration / 3) + 1))); - } - - if (cc->tracer >= 0) - { - int d = (90 - cc->tracer); - GLfloat th = d * (M_PI / 180); - GLfloat x = cos (th); - GLfloat y = sin (th); - GLfloat s = 1.5 / cc->scale; - - if (s > 0.001) - { - static const GLfloat c[4] = { 0.6, 0.5, 1.0, 1.0 }; - - glDisable (GL_LIGHTING); - - glPushMatrix(); - glRotatef (90, 1, 0, 0); - glTranslatef (0, 0, y*s/2); - s *= x; - glScalef(s, s, s); - glColor3f (c[0], c[1], c[2]); - draw_circle (mi, False); - glPopMatrix(); - - if (! MI_IS_WIREFRAME(mi)) glEnable (GL_LIGHTING); - } - - cc->tracer += 5; - if (cc->tracer == 180 || cc->tracer == 360) - cc->tracer = -1; - } -} - - -static int -unit_spheremonics (ModeInfo *mi, - int resolution, Bool wire, int *m, XColor *colors) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - int polys = 0; - int i, j; - double du, dv; - XYZ q[4]; - XYZ n[4]; - int res = (wire == 2 - ? resolution / 2 - : resolution); - - cc->bbox[0].x = cc->bbox[0].y = cc->bbox[0].z = 0; - cc->bbox[1].x = cc->bbox[1].y = cc->bbox[1].z = 0; - - du = (M_PI+M_PI) / (double)res; /* Theta */ - dv = M_PI / (double)res; /* Phi */ - - if (wire) - glColor3f (1, 1, 1); - - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - - for (i = 0; i < res; i++) { - double u = i * du; - for (j = 0; j < res; j++) { - double v = j * dv; - q[0] = sphere_eval (u, v, m); - n[0] = calc_normal(q[0], - sphere_eval (u+du/10, v, m), - sphere_eval (u, v+dv/10, m)); - glNormal3f(n[0].x,n[0].y,n[0].z); - if (!wire) do_color (i, colors); - glVertex3f(q[0].x,q[0].y,q[0].z); - - q[1] = sphere_eval (u+du, v, m); - n[1] = calc_normal(q[1], - sphere_eval (u+du+du/10, v, m), - sphere_eval (u+du, v+dv/10, m)); - glNormal3f(n[1].x,n[1].y,n[1].z); - if (!wire) do_color ((i+1)%res, colors); - glVertex3f(q[1].x,q[1].y,q[1].z); - - q[2] = sphere_eval (u+du, v+dv, m); - n[2] = calc_normal(q[2], - sphere_eval (u+du+du/10, v+dv, m), - sphere_eval (u+du, v+dv+dv/10, m)); - glNormal3f(n[2].x,n[2].y,n[2].z); - if (!wire) do_color ((i+1)%res, colors); - glVertex3f(q[2].x,q[2].y,q[2].z); - - q[3] = sphere_eval (u,v+dv, m); - n[3] = calc_normal(q[3], - sphere_eval (u+du/10, v+dv, m), - sphere_eval (u, v+dv+dv/10, m)); - glNormal3f(n[3].x,n[3].y,n[3].z); - if (!wire) do_color (i, colors); - glVertex3f(q[3].x,q[3].y,q[3].z); - - polys++; - -# define CHECK_BBOX(N) \ - if (q[(N)].x < cc->bbox[0].x) cc->bbox[0].x = q[(N)].x; \ - if (q[(N)].y < cc->bbox[0].y) cc->bbox[0].y = q[(N)].y; \ - if (q[(N)].z < cc->bbox[0].z) cc->bbox[0].z = q[(N)].z; \ - if (q[(N)].x > cc->bbox[1].x) cc->bbox[1].x = q[(N)].x; \ - if (q[(N)].y > cc->bbox[1].y) cc->bbox[1].y = q[(N)].y; \ - if (q[(N)].z > cc->bbox[1].z) cc->bbox[1].z = q[(N)].z - - CHECK_BBOX(0); - CHECK_BBOX(1); - CHECK_BBOX(2); - CHECK_BBOX(3); -# undef CHECK_BBOX - } - } - glEnd(); - - { - GLfloat w = cc->bbox[1].x - cc->bbox[0].x; - GLfloat h = cc->bbox[1].y - cc->bbox[0].y; - GLfloat d = cc->bbox[1].z - cc->bbox[0].z; - GLfloat wh = (w > h ? w : h); - GLfloat hd = (h > d ? h : d); - GLfloat scale = (wh > hd ? wh : hd); - - cc->scale = 1/scale; - - if (wire < 2 && (do_bbox || do_grid)) - { - GLfloat s = scale * 1.5; - glPushMatrix(); - glScalef(s, s, s); - draw_bounding_box (mi); - glPopMatrix(); - } - } - return polys; -} - - -static void -init_colors (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - int i; - cc->ncolors = cc->resolution; - cc->colors = (XColor *) calloc(cc->ncolors, sizeof(XColor)); - make_smooth_colormap (0, 0, 0, - cc->colors, &cc->ncolors, - False, 0, False); - - /* brighter colors, please... */ - for (i = 0; i < cc->ncolors; i++) - { - cc->colors[i].red = (cc->colors[i].red / 2) + 32767; - cc->colors[i].green = (cc->colors[i].green / 2) + 32767; - cc->colors[i].blue = (cc->colors[i].blue / 2) + 32767; - } -} - - -/* Pick one of the parameters to the function and tweak it up or down. - */ -static void -tweak_parameters (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - - /* If the -parameters command line option was specified, just use that - all the time. - */ - if (static_parms && - *static_parms && - !!strcasecmp (static_parms, "(default)")) - { - unsigned long n; - char dummy; - if (8 == sscanf (static_parms, "%d %d %d %d %d %d %d %d %c", - &cc->m[0], &cc->m[1], &cc->m[2], &cc->m[3], - &cc->m[4], &cc->m[5], &cc->m[6], &cc->m[7], - &dummy)) - return; - else if (strlen (static_parms) == 8 && - 1 == sscanf (static_parms, "%lu %c", &n, &dummy)) - { - const char *s = static_parms; - int i = 0; - while (*s) - cc->m[i++] = (*s++)-'0'; - return; - } - fprintf (stderr, - "%s: -parameters must be a string of 8 ints (not \"%s\")\n", - progname, static_parms); - exit (1); - } - - static_parms = 0; - - -# define SHIFT(N) do { \ - int n = (N); \ - cc->m[n] += cc->dm[n]; \ - if (cc->m[n] <= 0) \ - cc->m[n] = 0, cc->dm[n] = -cc->dm[n]; \ - else if (cc->m[n] >= cc->m_max) \ - cc->m[n] = cc->m_max, cc->dm[n] = -cc->dm[n]; \ - } while(0) - -/* else if (cc->m[n] >= cc->m_max/2 && (! (random() % 3))) \ - cc->m[n] = cc->m_max/2, cc->dm[n] = -cc->dm[n]; \ -*/ - - switch(random() % 8) - { - case 0: SHIFT(0); break; - case 1: SHIFT(1); break; - case 2: SHIFT(2); break; - case 3: SHIFT(3); break; - case 4: SHIFT(4); break; - case 5: SHIFT(5); break; - case 6: SHIFT(6); break; - case 7: SHIFT(7); break; - default: abort(); break; - } -# undef SHIFT - -#if 0 - printf ("%s: state: %d %d %d %d %d %d %d %d\n", - progname, - cc->m[0], cc->m[1], cc->m[2], cc->m[3], - cc->m[4], cc->m[5], cc->m[6], cc->m[7]); -#endif - -} - - -static void -generate_spheremonics (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - - tweak_parameters (mi); - - if (!cc->done_once || (0 == (random() % 20))) - init_colors (mi); - - glNewList(cc->dlist, GL_COMPILE); - cc->polys1 = unit_spheremonics (mi, cc->resolution, wire,cc->m,cc->colors); - glEndList(); - - glNewList(cc->dlist2, GL_COMPILE); - glPushMatrix(); - glScalef (1.05, 1.05, 1.05); - cc->polys2 = unit_spheremonics (mi, cc->resolution, 2, cc->m, cc->colors); - glPopMatrix(); - glEndList(); - - if (! cc->done_once) - { - glNewList(cc->grid_dlist, GL_COMPILE); - if (do_grid) - { - static const GLfloat c2[4] = { 1.0, 0.0, 0.0, 1.0 }; - glPushMatrix(); - glColor3f (c2[0], c2[1], c2[2]); - glBegin(GL_LINES); - glVertex3f(0, -0.66, 0); - glVertex3f(0, 0.66, 0); - glEnd(); - draw_circle (mi, True); - glRotatef(90, 1, 0, 0); - draw_circle (mi, True); - glRotatef(90, 0, 1, 0); - draw_circle (mi, True); - glPopMatrix(); - } - glEndList(); - } - - cc->done_once = True; -} - - - - -ENTRYPOINT void -init_spheremonics (ModeInfo *mi) -{ - spheremonics_configuration *cc; - - MI_INIT (mi, ccs); - - cc = &ccs[MI_SCREEN(mi)]; - - if ((cc->glx_context = init_GL(mi)) != NULL) { - gl_init(mi); - reshape_spheremonics (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - - { - Bool spinx=False, spiny=False, spinz=False; - double spin_speed = 1.0; - double wander_speed = 0.03; - - char *s = do_spin; - while (*s) - { - if (*s == 'x' || *s == 'X') spinx = True; - else if (*s == 'y' || *s == 'Y') spiny = True; - else if (*s == 'z' || *s == 'Z') spinz = True; - else if (*s == '0') ; - else - { - fprintf (stderr, - "%s: spin must contain only the characters X, Y, or Z (not \"%s\")\n", - progname, do_spin); - exit (1); - } - s++; - } - - cc->rot = make_rotator (spinx ? spin_speed : 0, - spinz ? spin_speed : 0, - spiny ? spin_speed : 0, - 1.0, - do_wander ? wander_speed : 0, - (spinx && spiny && spinz)); - cc->trackball = gltrackball_init (True); - } - - cc->tracer = -1; - cc->mesher = -1; - - cc->resolution = res; - - cc->font_data = load_texture_font (mi->dpy, "labelfont"); - - cc->dlist = glGenLists(1); - cc->dlist2 = glGenLists(1); - cc->grid_dlist = glGenLists(1); - - cc->m_max = 4; /* 9? */ - { - unsigned int i; - for (i = 0; i < countof(cc->dm); i++) - cc->dm[i] = 1; /* going up! */ - - /* Generate a few more times so we don't always start off with a sphere */ - for (i = 0; i < 5; i++) - tweak_parameters (mi); - } - - generate_spheremonics(mi); -} - - -ENTRYPOINT Bool -spheremonics_handle_event (ModeInfo *mi, XEvent *event) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, cc->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &cc->button_down_p)) - return True; - else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) - { - cc->change_tick = duration; - return True; - } - - return False; -} - - -ENTRYPOINT void -draw_spheremonics (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - if (!cc->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cc->glx_context); - - gl_init(mi); - - glShadeModel(GL_SMOOTH); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix (); - - glScalef(1.1, 1.1, 1.1); - - { - double x, y, z; - get_position (cc->rot, &x, &y, &z, !cc->button_down_p); - glTranslatef((x - 0.5) * 8, - (y - 0.5) * 6, - (z - 0.5) * 8); - - gltrackball_rotate (cc->trackball); - - get_rotation (cc->rot, &x, &y, &z, !cc->button_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); - } - - glScalef(7,7,7); - - mi->polygon_count = 0; - - if (do_grid) - { - GLfloat s = 1.5; - glDisable (GL_LIGHTING); - glPushMatrix(); - glScalef (s, s, s); - glCallList (cc->grid_dlist); - glPopMatrix(); - if (! MI_IS_WIREFRAME(mi)) - glEnable (GL_LIGHTING); - } - - glScalef (cc->scale, cc->scale, cc->scale); - glPushMatrix(); - { - double fade_speed = 0.15; - GLfloat s; - if (cc->fade == 0) - s = 1; - else if (cc->fade > 0) - { - s = cc->fade; - cc->fade -= fade_speed; - cc->change_tick = 0; - if (cc->fade <= 0) - { - cc->fade = -1.0; - generate_spheremonics (mi); - } - } - else - { - s = 1 + cc->fade; - cc->fade += fade_speed; - cc->change_tick = 0; - if (cc->fade >= 0) cc->fade = 0; - } - - glScalef (s, s, s); - glCallList (cc->dlist); - } - glPopMatrix(); - mi->polygon_count += cc->polys1; - - if (cc->mesher >= 0 /* || cc->button_down_p */) - { - glDisable (GL_LIGHTING); - glCallList (cc->dlist2); - mi->polygon_count += cc->polys2; - if (cc->mesher >= 0) - cc->mesher--; - } - - if (cc->fade == 0) - do_tracer(mi); - - if (cc->button_down_p) - { - char buf[200]; - sprintf (buf, - ((cc->m[0]<10 && cc->m[1]<10 && cc->m[2]<10 && cc->m[3]<10 && - cc->m[4]<10 && cc->m[5]<10 && cc->m[6]<10 && cc->m[7]<10) - ? "%d%d%d%d%d%d%d%d" - : "%d %d %d %d %d %d %d %d"), - cc->m[0], cc->m[1], cc->m[2], cc->m[3], - cc->m[4], cc->m[5], cc->m[6], cc->m[7]); - - glColor3f(1.0, 1.0, 0.0); - print_texture_label (mi->dpy, cc->font_data, - mi->xgwa.width, mi->xgwa.height, - 1, buf); - } - - if (!static_parms) - { - if (cc->change_tick++ >= duration && !cc->button_down_p) - { - cc->change_tick = 0; - cc->fade = 1.0; - cc->mesher = -1; /* turn off the mesh when switching objects */ - } - } - - glPopMatrix(); - - if (mi->fps_p) do_fps (mi); - glFinish(); - - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_spheremonics (ModeInfo *mi) -{ - spheremonics_configuration *cc = &ccs[MI_SCREEN(mi)]; - if (!cc->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *cc->glx_context); - if (cc->colors) free (cc->colors); - if (cc->trackball) gltrackball_free (cc->trackball); - if (cc->rot) free_rotator (cc->rot); - if (cc->font_data) free_texture_font (cc->font_data); - if (glIsList(cc->dlist)) glDeleteLists(cc->dlist, 1); - if (glIsList(cc->dlist2)) glDeleteLists(cc->dlist2, 1); - if (glIsList(cc->grid_dlist)) glDeleteLists(cc->grid_dlist, 1); -} - -XSCREENSAVER_MODULE ("Spheremonics", spheremonics) - -#endif /* USE_GL */ |
