From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/sballs.c | 823 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 823 insertions(+) create mode 100644 hacks/glx/sballs.c (limited to 'hacks/glx/sballs.c') diff --git a/hacks/glx/sballs.c b/hacks/glx/sballs.c new file mode 100644 index 0000000..6cd95f5 --- /dev/null +++ b/hacks/glx/sballs.c @@ -0,0 +1,823 @@ +/* sballs --- balls spinning like crazy in GL */ + +#if 0 +static const char sccsid[] = "@(#)sballs.c 5.02 2001/03/10 xlockmore"; +#endif + +/* Copyright (c) E. Lassauge, 2001. */ + +/* + * 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 + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * The original code for this mode was written by + * Mustata Bogdan (LoneRunner) + * and can be found at http://www.cfxweb.net/lonerunner/ + * + * Eric Lassauge (November-07-2000) + * http://lassauge.free.fr/linux.html + * + * REVISION HISTORY: + * + * E.Lassauge - 03-Oct-2001: + * - minor bugfixes - get ready for xscreensaver + * E.Lassauge - 09-Mar-2001: + * - get rid of my framerate options to use showfps + * E.Lassauge - 28-Nov-2000: + * - add handling of polyhedrons (like in ico) + * - modified release part to add freeing of GL objects + * E.Lassauge - 14-Nov-2000: + * - use new common xpm_to_ximage function + * + */ + +#ifdef STANDALONE /* xscreensaver mode */ +#define DEFAULTS "*delay: 30000 \n" \ + "*size: 0 \n" \ + "*cycles: 4 \n" \ + "*showFPS: False \n" \ + "*wireframe: False \n" \ + +# define release_sballs 0 +#define MODE_sballs +#include "xlockmore.h" /* from the xscreensaver distribution */ +#include "gltrackball.h" +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ +#include "visgl.h" +#endif /* !STANDALONE */ + +#define MINSIZE 32 /* minimal viewport size */ +#define FRAME 50 /* frame count interval */ +#define MAX_OBJ 8 /* number of 3D objects */ + +#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( STANDALONE ) +/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ +# include "ximage-loader.h" +# define I_HAVE_XPM + +# include "images/gen/sball_png.h" +# include "images/gen/sball-bg_png.h" + +/* Manage option vars */ +#define DEF_TEXTURE "True" +#define DEF_OBJECT "0" +static Bool do_texture; +static int object, object_arg; +static int spheres; + +static XrmOptionDescRec opts[] = { + {"-texture", ".sballs.texture", XrmoptionNoArg, "on"}, + {"+texture", ".sballs.texture", XrmoptionNoArg, "off"}, + {"-object", ".sballs.object", XrmoptionSepArg, 0}, + +}; + +static argtype vars[] = { + {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, + {&object_arg, "object", "Object", DEF_OBJECT, t_Int}, + +}; + +static OptionStruct desc[] = { + /*{"-count spheres", "set number of spheres"},*/ + /*{"-cycles speed", "set ball speed value"},*/ + {"-/+texture", "turn on/off texturing"}, + {"-object num", "number of the 3D object (0 means random)"}, +}; + +ENTRYPOINT ModeSpecOpt sballs_opts = + { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc }; + +#ifdef USE_MODULES +ModStruct sballs_description = + { "sballs", "init_sballs", "draw_sballs", NULL, + "draw_sballs", "change_sballs", "free_sballs", &sballs_opts, + /* + delay,count,cycles,size,ncolors,sat + */ + 10000, 0, 10, 400, 64, 1.0, "", + "balls spinning like crazy in GL", 0, NULL +}; +#endif /* USE_MODULES */ + +/* misc types and defines */ +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} +typedef float vec_t; +typedef vec_t vec3_t[3]; + +#define MAX_BALLS 20 + +/* the mode struct, contains all per screen variables */ +typedef struct { + GLint WIDTH, HEIGHT; /* display dimensions */ + GLXContext *glx_context; + + + XImage *btexture; /* back texture image bits */ + XImage *ftexture; /* face texture image bits */ + GLuint backid; /* back texture id: GL world */ + GLuint faceid; /* face texture id: GL world */ + + vec3_t eye; + vec3_t rotm; + int speed; + float radius[MAX_BALLS]; + + trackball_state *trackball; + Bool button_down_p; + +} sballsstruct; + +/* array of sballsstruct indexed by screen number */ +static sballsstruct *sballs = (sballsstruct *) NULL; + +/* lights */ +static const float LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +static const float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +static const float LightPosition[]= { 0.0f, 0.0f, 4.0f, 1.0f }; + +/* structure of the polyhedras */ +typedef struct { + const char *longname; /* long name of object */ + const char *shortname; /* short name of object */ + int numverts; /* number of vertices */ + float radius; /* radius */ + vec3_t v[MAX_BALLS];/* the vertices */ +} Polyinfo; + +static const Polyinfo polygons[] = +{ + +/* 0: objtetra - structure values for tetrahedron */ + { + "tetrahedron", "tetra", /* long and short names */ + 4, /* number of vertices */ + 0.8, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.0 + {T, T, T}, + {T, -T, -T}, + {-T, T, -T}, + {-T, -T, T}, +#undef T + } + }, + +/* 1: objcube - structure values for cube */ + + { + "hexahedron", "cube", /* long and short names */ + 8, /* number of vertices, edges, and faces */ + 0.6, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.0 + {T, T, T}, + {T, T, -T}, + {T, -T, -T}, + {T, -T, T}, + {-T, T, T}, + {-T, T, -T}, + {-T, -T, -T}, + {-T, -T, T}, +#undef T + } + }, + +/* 2: objocta - structure values for octahedron */ + + { + "octahedron", "octa", /* long and short names */ + 6, /* number of vertices */ + 0.6, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.5 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, + {0, 0, T}, + {0, 0, -T}, +#undef T + } + }, +/* 3: objdodec - structure values for dodecahedron */ + + { + "dodecahedron", "dodeca", /* long and short names */ + 20, /* number of vertices */ + 0.35, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ + {0.000000, 0.500000, 1.000000}, + {0.000000, -0.500000, 1.000000}, + {0.000000, -0.500000, -1.000000}, + {0.000000, 0.500000, -1.000000}, + {1.000000, 0.000000, 0.500000}, + {-1.000000, 0.000000, 0.500000}, + {-1.000000, 0.000000, -0.500000}, + {1.000000, 0.000000, -0.500000}, + {0.500000, 1.000000, 0.000000}, + {-0.500000, 1.000000, 0.000000}, + {-0.500000, -1.000000, 0.000000}, + {0.500000, -1.000000, 0.000000}, + {0.750000, 0.750000, 0.750000}, + {-0.750000, 0.750000, 0.750000}, + {-0.750000, -0.750000, 0.750000}, + {0.750000, -0.750000, 0.750000}, + {0.750000, -0.750000, -0.750000}, + {0.750000, 0.750000, -0.750000}, + {-0.750000, 0.750000, -0.750000}, + {-0.750000, -0.750000, -0.750000}, + } + }, + +/* 4: objicosa - structure values for icosahedron */ + + { + "icosahedron", "icosa", /* long and short names */ + 12, /* number of vertices */ + 0.4, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ + {0.00000000, 0.00000000, -0.95105650}, + {0.00000000, 0.85065080, -0.42532537}, + {0.80901698, 0.26286556, -0.42532537}, + {0.50000000, -0.68819095, -0.42532537}, + {-0.50000000, -0.68819095, -0.42532537}, + {-0.80901698, 0.26286556, -0.42532537}, + {0.50000000, 0.68819095, 0.42532537}, + {0.80901698, -0.26286556, 0.42532537}, + {0.00000000, -0.85065080, 0.42532537}, + {-0.80901698, -0.26286556, 0.42532537}, + {-0.50000000, 0.68819095, 0.42532537}, + {0.00000000, 0.00000000, 0.95105650} + } + }, + +/* 5: objplane - structure values for plane */ + + { + "plane", "plane", /* long and short names */ + 4, /* number of vertices */ + 0.7, + { /* vertices (x,y,z) */ + /* all points must be within radius 2 of the origin */ +#define T 1.1 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, +#undef T + } + }, + +/* 6: objpyr - structure values for pyramid */ + + { + "pyramid", "pyramid", /* long and short names */ + 5, /* number of vertices */ + 0.5, + { /* vertices (x,y,z) */ + /* all points must be within radius 1 of the origin */ +#define T 1.0 + {T, 0, 0}, + {-T, 0, 0}, + {0, T, 0}, + {0, -T, 0}, + {0, 0, T}, +#undef T + } + }, + +/* 7: objstar - structure values for octahedron star (stellated octahedron?) */ + { + "star", "star", /* long and short names */ + 8, /* number of vertices */ + 0.7, + { /* vertices (x,y,z) */ + /* all points must be within radius 1 of the origin */ +#define T 0.9 + {T, T, T}, + {T, -T, -T}, + {-T, T, -T}, + {-T, -T, T}, + {-T, -T, -T}, + {-T, T, T}, + {T, -T, T}, + {T, T, -T}, +#undef T + } + }, + +}; + + + + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Misc funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + + +/* initialise textures */ +static void inittextures(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + +#if defined( I_HAVE_XPM ) + if (do_texture) { + + glGenTextures(1, &sb->backid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->backid); +#endif /* HAVE_GLBINDTEXTURE */ + + sb->btexture = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), + sball_bg_png, + sizeof(sball_bg_png)); + if (!(sb->btexture)) { + (void) fprintf(stderr, "Error reading the background texture.\n"); + glDeleteTextures(1, &sb->backid); + do_texture = False; + sb->faceid = 0; /* default textures */ + sb->backid = 0; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + sb->btexture->width, sb->btexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sb->btexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + +/* + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + Let's pixellate it instead: +*/ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glGenTextures(1, &sb->faceid); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->faceid); +#endif /* HAVE_GLBINDTEXTURE */ + + sb->ftexture = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), + sball_png, sizeof(sball_png)); + if (!(sb->ftexture)) { + (void) fprintf(stderr, "Error reading the face texture.\n"); + glDeleteTextures(1, &sb->faceid); + sb->faceid = 0; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + clear_gl_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + sb->ftexture->width, sb->ftexture->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sb->ftexture->data); + check_gl_error("texture"); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + +/* + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + Let's pixellate it instead: +*/ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + { + sb->faceid = 0; /* default textures */ + sb->backid = 0; + } +#else /* !I_HAVE_XPM */ + do_texture = False; + sb->faceid = 0; /* default textures */ + sb->backid = 0; +#endif /* !I_HAVE_XPM */ +} + +static void drawSphere(ModeInfo * mi,int sphere_num) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + float x = polygons[object].v[sphere_num][0]; + float y = polygons[object].v[sphere_num][1]; + float z = polygons[object].v[sphere_num][2]; + int numMajor = 15; + int numMinor = 30; + float radius = sb->radius[sphere_num]; + double majorStep = (M_PI / numMajor); + double minorStep = (2.0 * M_PI / numMinor); + int i, j; + + glPushMatrix(); + glTranslatef(x, y, z); + + glColor4f(1, 1, 1, 1); + for (i = 0; i < numMajor; ++i) + { + double a = i * majorStep; + double b = a + majorStep; + double r0 = radius * sin(a); + double r1 = radius * sin(b); + GLfloat z0 = radius * cos(a); + GLfloat z1 = radius * cos(b); + + glBegin(MI_IS_WIREFRAME(mi) ? GL_LINE_STRIP: GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) + { + double c = j * minorStep; + GLfloat x = cos(c); + GLfloat y = sin(c); + + glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); + glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); + glVertex3f(x * r0, y * r0, z0); + + glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); + glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); + glVertex3f(x * r1, y * r1, z1); + + mi->polygon_count++; + } + glEnd(); + } + + glPopMatrix(); +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * GL funcs. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +#ifndef STANDALONE +static void Reshape(ModeInfo * mi) +#else +ENTRYPOINT void reshape_sballs(ModeInfo * mi, int width, int height) +#endif +{ + + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + int size = MI_SIZE(mi); + + /* Viewport is specified size if size >= MINSIZE && size < screensize */ + if (size <= 1) { + sb->WIDTH = MI_WIDTH(mi); + sb->HEIGHT = MI_HEIGHT(mi); + } else if (size < MINSIZE) { + sb->WIDTH = MINSIZE; + sb->HEIGHT = MINSIZE; + } else { + sb->WIDTH = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size; + sb->HEIGHT = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size; + } + + if (width > height * 5) { /* tiny window: show middle */ + sb->WIDTH = width; + sb->HEIGHT = sb->WIDTH*0.75; + } + + glViewport((MI_WIDTH(mi) - sb->WIDTH) / 2, (MI_HEIGHT(mi) - sb->HEIGHT) / 2, sb->WIDTH, sb->HEIGHT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(55.0, (float)sb->WIDTH / (float) sb->HEIGHT, 1.0, 300.0); + + glMatrixMode(GL_MODELVIEW); + +} + +static void Draw(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + int sphere; + + mi->polygon_count = 0; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glEnable(GL_DEPTH_TEST); + + /* move eyes */ + glTranslatef (-sb->eye[0], -sb->eye[1], -sb->eye[2]); + + /* draw background */ + if (do_texture) + { + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glColor3f(1, 1, 1); +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->backid); +#endif /* HAVE_GLBINDTEXTURE */ + } + else + { + glColor3f(0, 0, 0); + } + glBegin(GL_QUAD_STRIP); +#ifndef HAVE_MOBILE + /* Letterbox the background image */ + glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(8, 4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(8, -4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,0); glVertex3f(-8, 4.1, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,1); glVertex3f(-8, -4.1, -4); +#else + /* Fill the iPhone screen. Letterboxing looks dumb there. */ + glNormal3f(0, 0, 1); glTexCoord2f(0,0); glVertex3f(4, 5.2, -4); + glNormal3f(0, 0, 1); glTexCoord2f(0,1); glVertex3f(4, -5.2, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,0); glVertex3f(-4, 5.2, -4); + glNormal3f(0, 0, 1); glTexCoord2f(1,1); glVertex3f(-4, -5.2, -4); +#endif + glEnd(); + mi->polygon_count++; + + gltrackball_rotate (sb->trackball); + + /* rotate the balls */ + glRotatef(sb->rotm[0], 1.0f, 0.0f, 0.0f); + glRotatef(sb->rotm[1], 0.0f, 1.0f, 0.0f); + glRotatef(sb->rotm[2], 0.0f, 0.0f, 1.0f); + + if (! sb->button_down_p) { + sb->rotm[0] += sb->speed; + sb->rotm[1] += -(sb->speed); + sb->rotm[2] += 0; + } + + /* draw the balls */ + if (do_texture) +#ifdef HAVE_GLBINDTEXTURE + glBindTexture(GL_TEXTURE_2D, sb->faceid); + else +#endif /* HAVE_GLBINDTEXTURE */ + glEnable(GL_LIGHTING); + for (sphere=0;spherebtexture = (XImage*) NULL; + sb->ftexture = (XImage*) NULL; + } + + vinit(sb->eye ,0.0f, 0.0f, 6.0f); + vinit(sb->rotm ,0.0f, 0.0f, 0.0f); + sb->speed = MI_CYCLES(mi); + + /* initialise object number */ + object = object_arg-1; + if (object < 0 || object >= MAX_OBJ) + object = NRAND(MAX_OBJ); + + /* initialise sphere number */ + spheres = MI_COUNT(mi); + if (MI_COUNT(mi) > polygons[object].numverts) + spheres = polygons[object].numverts; + if (MI_COUNT(mi) < 1) + spheres = polygons[object].numverts; + /* initialise sphere radius */ + for(i=0; i < spheres;i++) + { +#if RANDOM_RADIUS + sb->radius[i] = ((float) LRAND() / (float) MAXRAND); + if (sb->radius[i] < 0.3) + sb->radius[i] = 0.3; + if (sb->radius[i] > 0.7) + sb->radius[i] = 0.7; +#else + sb->radius[i] = polygons[object].radius; +#endif + } + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tobject=%s\n\tspheres=%d\n\tspeed=%d\n\ttexture=%s\n", + MI_NAME(mi), + polygons[object].shortname, + spheres, + (int) MI_CYCLES(mi), + do_texture ? "on" : "off" + ); + } + + glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); + glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); + glEnable(GL_LIGHT1); +} + +/* + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + * Xlock hooks. + *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * Initialize sballs. Called each time the window changes. + *----------------------------------------------------------------------------- + */ + +ENTRYPOINT void init_sballs(ModeInfo * mi) +{ + sballsstruct *sb; + + MI_INIT(mi, sballs); + sb = &sballs[MI_SCREEN(mi)]; + + sb->trackball = gltrackball_init (True); + + if ((sb->glx_context = init_GL(mi)) != NULL) { + +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_sballs(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + glDrawBuffer(GL_BACK); + Init(mi); + + } else { + MI_CLEARWINDOW(mi); + } +} + +/* + *----------------------------------------------------------------------------- + * Called by the mainline code periodically to update the display. + *----------------------------------------------------------------------------- + */ +ENTRYPOINT void draw_sballs(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + sballsstruct *sb; + + if (sballs == NULL) + return; + sb = &sballs[MI_SCREEN(mi)]; + + MI_IS_DRAWN(mi) = True; + if (!sb->glx_context) + return; + + glXMakeCurrent(display, window, *(sb->glx_context)); + Draw(mi); +#ifndef STANDALONE + Reshape(mi); /* xlock mode */ +#else + reshape_sballs(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ +#endif + + glFinish(); + glXSwapBuffers(display, window); +} + + +/* + *----------------------------------------------------------------------------- + * The display is being taken away from us. Free up malloc'ed + * memory and X resources that we've alloc'ed. + *----------------------------------------------------------------------------- + */ + +ENTRYPOINT void free_sballs(ModeInfo * mi) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + if (sb->glx_context) + { + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sb->glx_context)); + if (sb->btexture) + { + glDeleteTextures(1,&sb->backid); + XDestroyImage(sb->btexture); + sb->btexture = 0; + } + if (sb->ftexture) + { + glDeleteTextures(1,&sb->faceid); + XDestroyImage(sb->ftexture); + sb->ftexture = 0; + } + } +} + +ENTRYPOINT Bool +sballs_handle_event (ModeInfo *mi, XEvent *event) +{ + sballsstruct *sb = &sballs[MI_SCREEN(mi)]; + + if (gltrackball_event_handler (event, sb->trackball, + MI_WIDTH (mi), MI_HEIGHT (mi), + &sb->button_down_p)) + return True; + + return False; +} + + +#ifndef STANDALONE +ENTRYPOINT void change_sballs(ModeInfo * mi) +{ + sballsstruct *sb; + + if (sballs == NULL) + return; + sb = &sballs[MI_SCREEN(mi)]; + + if (!sb->glx_context) + return; + + /* initialise object number */ + if ((object == 0) || (object > MAX_OBJ)) + object = NRAND(MAX_OBJ-1)+1; + object--; + + /* correct sphere number */ + spheres = MI_COUNT(mi); + if (MI_COUNT(mi) > polygons[object].numverts) + spheres = polygons[object].numverts; + if (MI_COUNT(mi) < 1) + spheres = polygons[object].numverts; + + if (MI_IS_DEBUG(mi)) { + (void) fprintf(stderr, + "%s:\n\tobject=%s\n\tspheres=%d\n\tspeed=%d\n\ttexture=%s\n", + MI_NAME(mi), + polygons[object].shortname, + spheres, + (int) MI_CYCLES(mi), + do_texture ? "on" : "off" + ); + } + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sb->glx_context)); + +} +#endif /* !STANDALONE */ + +XSCREENSAVER_MODULE ("SBalls", sballs) + +#endif /* MODE_sballs */ -- cgit v1.2.3-55-g7522