1
/* -*- Mode: C; tab-width: 4 -*- */
3
#if !defined( lint ) && !defined( SABER )
4
/*static const char sccsid[] = "@(#)gleidescope.c 1.0 03/06/27 xlockmore";*/
7
/* enable -grab switch */
11
* Permission to use, copy, modify, and distribute this software and its
12
* documentation for any purpose and without fee is hereby granted,
13
* provided that the above copyright notice appear in all copies and that
14
* both that copyright notice and this permission notice appear in
15
* supporting documentation.
17
* This file is provided AS IS with no warranties of any kind. The author
18
* shall have no liability with respect to the infringement of copyrights,
19
* trade secrets or any patents by this file or any part thereof. In no
20
* event will the author be liable for any lost revenue or profits or
21
* other special, indirect and consequential damages.
25
* 20030627 1.0 acd First Release.
26
* Texture loading code from 'glplanet'
27
* by Jamie Zawinski <jwz@jwz.org>
28
* 20030810 1.1 acd Added size flag.
29
* Now grabs screen / video / picture
30
* (uses code from 'glslideshow' by
31
* Mike Oliphant, Ben Buxton, Jamie Zawinski).
34
* Added fade code (also from glslideshow).
35
* 20031013 1.2 acd Migrated to compile without warnings under
37
* 20031023 1.3 acd Better code to limit twisting speeds.
38
* Tweaked initial rotation values.
39
* Move, Rotate, Zoom now chosen at random if
40
* no preference is given.
41
* Made grid slightly bigger so you can't see
42
* the edge when zooming and moving.
45
#include <X11/Intrinsic.h>
48
#include "xpm-ximage.h"
51
**----------------------------------------------------------------------------
53
**----------------------------------------------------------------------------
57
# define PROGCLASS "gleidescope"
58
# define HACK_INIT init_gleidescope
59
# define HACK_DRAW draw_gleidescope
60
# define HACK_RESHAPE reshape_gleidescope
61
# define HACK_HANDLE_EVENT gleidescope_handle_event
62
# define EVENT_MASK PointerMotionMask
63
# define gleidescope_opts xlockmore_opts
66
"*showFPS: False \n" \
70
# include "xlockmore.h" /* from the xscreensaver distribution */
71
#else /* !STANDALONE */
72
# include "xlock.h" /* from the xlockmore distribution */
73
#endif /* !STANDALONE */
79
/* acd TODO should all these be in gleidestruct? */
81
static Bool grab; /* grab images */
83
static Bool move; /* moving camera */
84
static Bool nomove; /* no moving camera */
85
static Bool rotate; /* rotate in place */
86
static Bool norotate; /* no rotate in place */
87
static int size = -1; /* size */
88
static Bool zoom; /* zooming camera */
89
static Bool nozoom; /* no zooming camera */
90
static char *image; /* name of texture to load */
91
static int duration; /* length of time to display grabbed image */
93
#define MAX_TANGLE_VEL 2.0
95
static float tangle = 0; /* texture angle */
96
static float tangle_vel = 0.0; /* texture velocity */
97
static float tangle_acc = 0.0; /* texture acceleration */
99
#define MAX_RANGLE_VEL 1.5
101
static float rangle = 0; /* rotate angle */
102
static float rangle_vel = 0.0; /* rotate velocity */
103
static float rangle_acc = 0.0; /* rotate acceleration */
105
static XrmOptionDescRec opts[] =
108
{"-grab", ".gleidescope.grab", XrmoptionNoArg, "true"},
110
{"-move", ".gleidescope.move", XrmoptionNoArg, "true"},
111
{"-no-move", ".gleidescope.nomove", XrmoptionNoArg, "true"},
112
{"-rotate", ".gleidescope.rotate", XrmoptionNoArg, "true"},
113
{"-no-rotate", ".gleidescope.norotate", XrmoptionNoArg, "true"},
114
/*{"-size", ".gleidescope.size", XrmoptionNoArg, "-1"},*/
115
{"-zoom", ".gleidescope.zoom", XrmoptionNoArg, "true"},
116
{"-no-zoom", ".gleidescope.nozoom", XrmoptionNoArg, "true"},
117
{"-image", ".gleidescope.image", XrmoptionSepArg, "DEFAULT"},
118
{"-duration", ".gleidescope.duration", XrmoptionSepArg, "30"},
122
static argtype vars[] = {
124
{&grab, "grab", "Grab", "False", t_Bool},
126
{&move, "move", "Move", "False", t_Bool},
127
{&nomove, "nomove", "noMove", "False", t_Bool},
128
{&rotate, "rotate", "Rotate", "False", t_Bool},
129
{&norotate, "norotate", "noRotate", "False", t_Bool},
130
/*{&size, "size", "Size", "-1", t_Int},*/
131
{&zoom, "zoom", "Zoom", "False", t_Bool},
132
{&nozoom, "nozoom", "noZoom", "False", t_Bool},
133
{&image, "image", "Image", "DEFAULT", t_String},
134
{&duration, "duration", "Duration", "30", t_Int},
137
static OptionStruct desc[] = {
139
{"-grab", "grab images to create animation"},
141
{"-move", "camera will move"},
142
{"-no-move", "camera won't move"},
143
{"-rotate", "camera will rotate"},
144
{"-no-rotate", "camera won't rotate"},
145
/*{"-size", "size of the hexagons (1-10)"},*/
146
{"-zoom", "camera will zoom"},
147
{"-no-zoom", "camera won't zoom"},
148
{"-image", "xpm / xbm image file to use for texture"},
149
{"-duration", "length of time texture will be used"},
152
ModeSpecOpt gleidescope_opts = {
153
sizeof opts / sizeof opts[0], opts,
154
sizeof vars / sizeof vars[0], vars,
159
ModStruct gleidescope_description = {
160
"gleidescope", "init_gleidescope", "draw_gleidescope", "release_gleidescope",
161
"draw_gleidescope", "init_gleidescope", NULL, &gleidescope_opts,
162
1000, 1, 2, 1, 4, 1.0, "",
163
"GL Kaleidescope", 0, NULL};
167
**-----------------------------------------------------------------------------
169
**-----------------------------------------------------------------------------
172
typedef struct hex_s {
173
GLfloat x, y, z; /* position */
182
#define MAX_FADE 500 /* number of fade cycles */
185
float cam_x_speed, cam_z_speed, cam_y_speed;
186
int cam_x_phase, cam_z_phase, cam_y_phase;
188
GLXContext *glx_context;
190
GLfloat max_tx, max_ty; /* maximum texture sizes */
191
GLuint textures[2]; /* texture handles */
192
GLuint visible; /* texture handle for new texture */
198
#define XOFFSET (0.8660254f) /* sin 60' */
199
#define YOFFSET (1.5000000f) /* cos 60' + 1 */
205
/* generates a grid with edges of given size */
206
/* acd TODO - replace hex[] with this and allow size and distance as parameters */
209
generate_grid(int size)
216
for (y = -size ; y <= size ; y++) {
217
for (x = -i ; x <= i ; x += 2) {
218
printf("{XOFFSET * %d, YOFFSET * %d, 0},\n", x, y);
232
/* edges of size 7 */
233
/* number of hexagons required to cover screen depends on camera distance */
234
/* at a distance of 10 this is just about enough. */
235
{XOFFSET * -6, YOFFSET * -6, 0},
236
{XOFFSET * -4, YOFFSET * -6, 0},
237
{XOFFSET * -2, YOFFSET * -6, 0},
238
{XOFFSET * 0, YOFFSET * -6, 0},
239
{XOFFSET * 2, YOFFSET * -6, 0},
240
{XOFFSET * 4, YOFFSET * -6, 0},
241
{XOFFSET * 6, YOFFSET * -6, 0},
243
{XOFFSET * -7, YOFFSET * -5, 0},
244
{XOFFSET * -5, YOFFSET * -5, 0},
245
{XOFFSET * -3, YOFFSET * -5, 0},
246
{XOFFSET * -1, YOFFSET * -5, 0},
247
{XOFFSET * 1, YOFFSET * -5, 0},
248
{XOFFSET * 3, YOFFSET * -5, 0},
249
{XOFFSET * 5, YOFFSET * -5, 0},
250
{XOFFSET * 7, YOFFSET * -5, 0},
252
{XOFFSET * -8, YOFFSET * -4, 0},
253
{XOFFSET * -6, YOFFSET * -4, 0},
254
{XOFFSET * -4, YOFFSET * -4, 0},
255
{XOFFSET * -2, YOFFSET * -4, 0},
256
{XOFFSET * 0, YOFFSET * -4, 0},
257
{XOFFSET * 2, YOFFSET * -4, 0},
258
{XOFFSET * 4, YOFFSET * -4, 0},
259
{XOFFSET * 6, YOFFSET * -4, 0},
260
{XOFFSET * 8, YOFFSET * -4, 0},
262
{XOFFSET * -9, YOFFSET * -3, 0},
263
{XOFFSET * -7, YOFFSET * -3, 0},
264
{XOFFSET * -5, YOFFSET * -3, 0},
265
{XOFFSET * -3, YOFFSET * -3, 0},
266
{XOFFSET * -1, YOFFSET * -3, 0},
267
{XOFFSET * 1, YOFFSET * -3, 0},
268
{XOFFSET * 3, YOFFSET * -3, 0},
269
{XOFFSET * 5, YOFFSET * -3, 0},
270
{XOFFSET * 7, YOFFSET * -3, 0},
271
{XOFFSET * 9, YOFFSET * -3, 0},
273
{XOFFSET * -10, YOFFSET * -2, 0},
274
{XOFFSET * -8, YOFFSET * -2, 0},
275
{XOFFSET * -6, YOFFSET * -2, 0},
276
{XOFFSET * -4, YOFFSET * -2, 0},
277
{XOFFSET * -2, YOFFSET * -2, 0},
278
{XOFFSET * 0, YOFFSET * -2, 0},
279
{XOFFSET * 2, YOFFSET * -2, 0},
280
{XOFFSET * 4, YOFFSET * -2, 0},
281
{XOFFSET * 6, YOFFSET * -2, 0},
282
{XOFFSET * 8, YOFFSET * -2, 0},
283
{XOFFSET * 10, YOFFSET * -2, 0},
285
{XOFFSET * -11, YOFFSET * -1, 0},
286
{XOFFSET * -9, YOFFSET * -1, 0},
287
{XOFFSET * -7, YOFFSET * -1, 0},
288
{XOFFSET * -5, YOFFSET * -1, 0},
289
{XOFFSET * -3, YOFFSET * -1, 0},
290
{XOFFSET * -1, YOFFSET * -1, 0},
291
{XOFFSET * 1, YOFFSET * -1, 0},
292
{XOFFSET * 3, YOFFSET * -1, 0},
293
{XOFFSET * 5, YOFFSET * -1, 0},
294
{XOFFSET * 7, YOFFSET * -1, 0},
295
{XOFFSET * 9, YOFFSET * -1, 0},
296
{XOFFSET * 11, YOFFSET * -1, 0},
298
{XOFFSET * -12, YOFFSET * 0, 0},
299
{XOFFSET * -10, YOFFSET * 0, 0},
300
{XOFFSET * -8, YOFFSET * 0, 0},
301
{XOFFSET * -6, YOFFSET * 0, 0},
302
{XOFFSET * -4, YOFFSET * 0, 0},
303
{XOFFSET * -2, YOFFSET * 0, 0},
304
{XOFFSET * 0, YOFFSET * 0, 0},
305
{XOFFSET * 2, YOFFSET * 0, 0},
306
{XOFFSET * 4, YOFFSET * 0, 0},
307
{XOFFSET * 6, YOFFSET * 0, 0},
308
{XOFFSET * 8, YOFFSET * 0, 0},
309
{XOFFSET * 10, YOFFSET * 0, 0},
310
{XOFFSET * 12, YOFFSET * 0, 0},
312
{XOFFSET * -11, YOFFSET * 1, 0},
313
{XOFFSET * -9, YOFFSET * 1, 0},
314
{XOFFSET * -7, YOFFSET * 1, 0},
315
{XOFFSET * -5, YOFFSET * 1, 0},
316
{XOFFSET * -3, YOFFSET * 1, 0},
317
{XOFFSET * -1, YOFFSET * 1, 0},
318
{XOFFSET * 1, YOFFSET * 1, 0},
319
{XOFFSET * 3, YOFFSET * 1, 0},
320
{XOFFSET * 5, YOFFSET * 1, 0},
321
{XOFFSET * 7, YOFFSET * 1, 0},
322
{XOFFSET * 9, YOFFSET * 1, 0},
323
{XOFFSET * 11, YOFFSET * 1, 0},
325
{XOFFSET * -10, YOFFSET * 2, 0},
326
{XOFFSET * -8, YOFFSET * 2, 0},
327
{XOFFSET * -6, YOFFSET * 2, 0},
328
{XOFFSET * -4, YOFFSET * 2, 0},
329
{XOFFSET * -2, YOFFSET * 2, 0},
330
{XOFFSET * 0, YOFFSET * 2, 0},
331
{XOFFSET * 2, YOFFSET * 2, 0},
332
{XOFFSET * 4, YOFFSET * 2, 0},
333
{XOFFSET * 6, YOFFSET * 2, 0},
334
{XOFFSET * 8, YOFFSET * 2, 0},
335
{XOFFSET * 10, YOFFSET * 2, 0},
337
{XOFFSET * -9, YOFFSET * 3, 0},
338
{XOFFSET * -7, YOFFSET * 3, 0},
339
{XOFFSET * -5, YOFFSET * 3, 0},
340
{XOFFSET * -3, YOFFSET * 3, 0},
341
{XOFFSET * -1, YOFFSET * 3, 0},
342
{XOFFSET * 1, YOFFSET * 3, 0},
343
{XOFFSET * 3, YOFFSET * 3, 0},
344
{XOFFSET * 5, YOFFSET * 3, 0},
345
{XOFFSET * 7, YOFFSET * 3, 0},
346
{XOFFSET * 9, YOFFSET * 3, 0},
348
{XOFFSET * -8, YOFFSET * 4, 0},
349
{XOFFSET * -6, YOFFSET * 4, 0},
350
{XOFFSET * -4, YOFFSET * 4, 0},
351
{XOFFSET * -2, YOFFSET * 4, 0},
352
{XOFFSET * 0, YOFFSET * 4, 0},
353
{XOFFSET * 2, YOFFSET * 4, 0},
354
{XOFFSET * 4, YOFFSET * 4, 0},
355
{XOFFSET * 6, YOFFSET * 4, 0},
356
{XOFFSET * 8, YOFFSET * 4, 0},
358
{XOFFSET * -7, YOFFSET * 5, 0},
359
{XOFFSET * -5, YOFFSET * 5, 0},
360
{XOFFSET * -3, YOFFSET * 5, 0},
361
{XOFFSET * -1, YOFFSET * 5, 0},
362
{XOFFSET * 1, YOFFSET * 5, 0},
363
{XOFFSET * 3, YOFFSET * 5, 0},
364
{XOFFSET * 5, YOFFSET * 5, 0},
365
{XOFFSET * 7, YOFFSET * 5, 0},
367
{XOFFSET * -6, YOFFSET * 6, 0},
368
{XOFFSET * -4, YOFFSET * 6, 0},
369
{XOFFSET * -2, YOFFSET * 6, 0},
370
{XOFFSET * 0, YOFFSET * 6, 0},
371
{XOFFSET * 2, YOFFSET * 6, 0},
372
{XOFFSET * 4, YOFFSET * 6, 0},
373
{XOFFSET * 6, YOFFSET * 6, 0},
377
**----------------------------------------------------------------------------
379
**----------------------------------------------------------------------------
382
static gleidestruct *gleidescope = NULL;
385
*load defaults in config structure
387
void setdefaultconfig(void)
400
static double xmouse = 0.0;
401
static double ymouse = 0.0;
404
gleidescope_handle_event(ModeInfo *mi, XEvent *event)
406
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
409
printf("event:%d\n", event->xany.type);
410
printf("button:%d\n", event->xbutton.button);
412
switch(event->xany.type)
416
if (event->xbutton.button == Button1 ||
417
event->xbutton.button == Button3)
419
/* store initial values of mouse */
420
xstart = event->xbutton.x;
421
ystart = event->xbutton.y;
424
gp->button_down_p = True;
428
else if (event->xbutton.button == Button4)
433
else if (event->xbutton.button == Button5)
443
if (event->xbutton.button == Button1 ||
444
event->xbutton.button == Button3)
447
gp->button_down_p = False;
454
if (gp->button_down_p)
456
/* update mouse position */
457
xmouse += (double)(event->xmotion.x - xstart) / MI_WIDTH(mi);
458
ymouse += (double)(event->xmotion.y - ystart) / MI_HEIGHT(mi);
459
xstart = event->xmotion.x;
460
ystart = event->xmotion.y;
470
#include "grab-ximage.h"
473
getSnapshot(ModeInfo *mi, GLuint name)
475
Bool mipmap_p = True;
477
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
479
if (MI_IS_WIREFRAME(mi))
482
glBindTexture (GL_TEXTURE_2D, name);
483
if (! screen_to_texture (mi->xgwa.screen, mi->window, 0, 0,
484
mipmap_p, NULL, NULL, &iw, &ih, &tw, &th))
487
gp->max_tx = (GLfloat) iw / tw;
488
gp->max_ty = (GLfloat) ih / th;
490
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
491
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
492
(mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
494
/* remember time of last image change */
495
gp->start_time = time ((time_t *) 0);
499
setup_file_texture (ModeInfo *mi, char *filename, GLuint name)
501
Display *dpy = mi->dpy;
502
Visual *visual = mi->xgwa.visual;
505
Colormap cmap = mi->xgwa.colormap;
506
XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
508
/* use this texture */
509
glBindTexture(GL_TEXTURE_2D, name);
512
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
513
image->width, image->height, 0,
514
GL_RGBA, GL_UNSIGNED_BYTE, image->data);
515
sprintf (buf, "texture: %.100s (%dx%d)",
516
filename, image->width, image->height);
519
/* setup parameters for texturing */
520
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
521
glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
523
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
524
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
525
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
526
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
527
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
531
setup_texture(ModeInfo * mi, GLuint id)
533
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
535
if (!image || !*image || !strcmp(image, "DEFAULT")) {
536
/* no image specified - grab screen */
538
/* max_tx and max_ty set in getSnapshot() */
540
/* use supplied image file */
541
setup_file_texture(mi, image, id);
543
/* set tx params to use whole image */
548
check_gl_error("texture initialization");
550
/* Need to flip the texture top for bottom for some reason. */
551
glMatrixMode (GL_TEXTURE);
553
glMatrixMode (GL_MODELVIEW);
556
#define VERTEX0 glVertex3f( 0.0000f, 0.000f, 0.0f);
557
#define VERTEX1 glVertex3f( 0.0000f, 1.000f, 0.0f);
558
#define VERTEX2 glVertex3f( XOFFSET, 0.500f, 0.0f);
559
#define VERTEX3 glVertex3f( XOFFSET, -0.500f, 0.0f);
560
#define VERTEX4 glVertex3f( 0.0000f, -1.000f, 0.0f);
561
#define VERTEX5 glVertex3f(-XOFFSET, -0.500f, 0.0f);
562
#define VERTEX6 glVertex3f(-XOFFSET, 0.500f, 0.0f);
565
draw_hexagons(ModeInfo *mi, int translucency, GLuint texture)
569
GLfloat t1x, t1y, t2x, t2y, t3x, t3y;
570
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
576
col[3] = (float)translucency / MAX_FADE;
578
/* calculate vertices of equilateral triangle within image. */
579
/* t1 is always in centre */
580
t1x = gp->max_tx / 2;
581
t1y = gp->max_ty / 2;
583
t2x = (gp->max_tx / 2) * (1 + cos((ymouse * 2 * M_PI) + (tangle * M_PI / 180)));
584
t2y = (gp->max_ty / 2) * (1 + sin((ymouse * 2 * M_PI) + (tangle * M_PI / 180)));
585
/* t3 is always 60' further around than t2 */
586
tangle2 = (ymouse * 2 * M_PI) + (tangle * M_PI / 180) + (M_PI * 2 / 6);
587
t3x = (gp->max_tx / 2) * (1 + (cos(tangle2)));
588
t3y = (gp->max_ty / 2) * (1 + (sin(tangle2)));
589
/* NB image is flipped vertically hence: */
593
/*printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t1x, t1y, t2x, t2y, gp->max_tx, gp->max_ty);*/
595
glColor4f(1.0, 1.0, 1.0, (float)translucency / MAX_FADE);
596
glEnable(GL_TEXTURE_2D);
598
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
599
glDepthMask(GL_FALSE);
600
glBindTexture(GL_TEXTURE_2D, gp->textures[texture]);
602
for (i = 0 ; i < sizeof(hex) / sizeof(hex[0]) ; i++) {
606
glTranslatef(hex[i].x, hex[i].y, 0.0);
608
glBegin(GL_TRIANGLES);
611
** six triangles to each hexagon
614
glTexCoord2f(t1x, t1y);
616
glTexCoord2f(t2x, t2y);
618
glTexCoord2f(t3x, t3y);
621
glTexCoord2f(t1x, t1y);
623
glTexCoord2f(t3x, t3y);
625
glTexCoord2f(t2x, t2y);
628
glTexCoord2f(t1x, t1y);
630
glTexCoord2f(t2x, t2y);
632
glTexCoord2f(t3x, t3y);
635
glTexCoord2f(t1x, t1y);
637
glTexCoord2f(t3x, t3y);
639
glTexCoord2f(t2x, t2y);
642
glTexCoord2f(t1x, t1y);
644
glTexCoord2f(t2x, t2y);
646
glTexCoord2f(t3x, t3y);
649
glTexCoord2f(t1x, t1y);
651
glTexCoord2f(t3x, t3y);
653
glTexCoord2f(t2x, t2y);
661
#ifdef DISPLAY_TEXTURE
663
/* acd debug - display (bigger, centred) texture */
664
glScalef(2.0, 2.0, 2.0);
665
glTranslatef(-0.5, -0.5, 0.0);
667
glTexCoord2f(0.0, 0.0);
668
glVertex3f(0.0, 0.0, -0.1);
669
glTexCoord2f(1.0, 0.0);
670
glVertex3f(1.0, 0.0, -0.1);
671
glTexCoord2f(1.0, 1.0);
672
glVertex3f(1.0, 1.0, -0.1);
673
glTexCoord2f(0.0, 1.0);
674
glVertex3f(0.0, 1.0, -0.1);
676
/* acd debug - display texture triangle */
677
glColor4f(1.0, 1.0, 1.0, 1.0);
678
glBegin(GL_LINE_LOOP);
679
glVertex3f(t1x, t1y, -0.11);
680
glVertex3f(t2x, t2y, -0.11);
681
glVertex3f(t3x, t3y, -0.11);
686
glDisable(GL_TEXTURE_2D);
687
glDepthMask(GL_TRUE);
692
* main rendering loop
697
GLfloat x_angle, y_angle, z_angle;
698
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
702
glClearColor(0.5, 0.5, 0.5, 1.0);
703
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
708
x_angle = gp->cam_x_phase + gp->tic * gp->cam_x_speed;
709
y_angle = gp->cam_y_phase + gp->tic * gp->cam_y_speed;
710
z_angle = gp->cam_z_phase + gp->tic * gp->cam_z_speed;
713
v1.x = 2 * sin(x_angle);
714
v1.y = 2 * sin(y_angle);
720
/* size is changed in pinit() to be distance from plane */
729
/* user defined size */
732
/* max distance given by adding the constant and the multiplier */
733
v1.z = 5.0 + 4.0 * sin(z_angle);
739
/* update rotation angle (but not if mouse button down) */
740
if (rotate && !gp->button_down_p)
742
float new_rangle_vel = 0.0;
744
/* update camera rotation angle and velocity */
745
rangle += rangle_vel;
746
new_rangle_vel = rangle_vel + rangle_acc;
747
if (new_rangle_vel > -MAX_RANGLE_VEL && new_rangle_vel < MAX_RANGLE_VEL)
749
/* new velocity is within limits */
750
rangle_vel = new_rangle_vel;
753
/* randomly change twisting speed */
754
if ((random() % 1000) < 1)
756
rangle_acc = frand(0.002) - 0.001;
761
/* this makes the image wobble - requires -move and a larger grid */
762
gluLookAt(0, 0, v1.z, v1.x, v1.y, 0.0, 0.0, 1.0, 0.0);
764
/* no wobble - camera always perpendicular to grid */
766
/* rotating camera rather than entire space - smoother */
770
sin((xmouse * M_PI * 2) + rangle * M_PI / 180),
771
cos((xmouse * M_PI * 2) + rangle * M_PI / 180),
775
/* light position same as camera */
784
draw_hexagons(mi, MAX_FADE, gp->visible);
788
/* fading - show both textures with alpha */
789
draw_hexagons(mi, MAX_FADE - gp->fade, gp->visible);
790
draw_hexagons(mi, gp->fade, 1 - gp->visible);
795
/* have we faded enough? */
796
if (gp->fade > MAX_FADE)
800
gp->visible = 1 - gp->visible;
804
/* increment texture angle based on time, velocity etc */
805
/* but only if button is not down */
806
if (!gp->button_down_p)
808
float new_tangle_vel = 0.0;
810
tangle += tangle_vel;
812
/* work out new texture angle velocity */
813
new_tangle_vel = tangle_vel + tangle_acc;
814
if (new_tangle_vel > -MAX_TANGLE_VEL && new_tangle_vel < MAX_TANGLE_VEL)
816
/* new velocity is inside limits */
817
tangle_vel = new_tangle_vel;
820
/* randomly change texture angle acceleration */
821
if ((random() % 1000) < 1)
823
tangle_acc = frand(0.002) - 0.001;
831
* new window size or exposure
833
void reshape_gleidescope(ModeInfo *mi, int width, int height)
835
GLfloat h = (GLfloat) height / (GLfloat) width;
837
glViewport(0, 0, (GLint) width, (GLint) height);
838
glMatrixMode(GL_PROJECTION);
840
gluPerspective(50.0, 1/h, 0.1, 2000.0);
841
glMatrixMode (GL_MODELVIEW);
850
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
852
/* set start time - star_time = 0 implies non-dynamic texture */
853
gp->start_time = (time_t)0;
855
/* set the texture size to default */
862
glShadeModel(GL_SMOOTH);
863
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
864
glEnable(GL_DEPTH_TEST);
865
glEnable(GL_CULL_FACE);
866
glDisable(GL_LIGHTING);
868
/* space for textures */
869
glGenTextures(1, &gp->textures[0]);
870
glGenTextures(1, &gp->textures[1]);
873
setup_texture(mi, gp->textures[gp->visible]);
876
** want to choose a value for arg randomly if neither -arg nor -no-arg
877
** is specified. xscreensaver libraries don't seem to let you do this -
878
** if something isn't true then it is false (pesky two-state boolean values).
879
** so, i've defined both -arg and -no-arg to arguments and added the
881
** (btw if both -arg and -no-arg are defined then arg is set to False)
883
if (zoom == False && nozoom == False)
885
/* no zoom preference - randomise */
886
zoom = (((random() & 0x1) == 0x1) ? True : False);
888
else if (nozoom == True)
890
/* definately no zoom */
894
if (move == False && nomove == False)
896
/* no move preference - randomise */
897
move = (((random() & 0x1) == 0x1) ? True : False);
899
else if (nomove == True)
901
/* definately no move */
905
if (rotate == False && norotate == False)
907
/* no rotate preference - randomise */
908
rotate = (((random() & 0x1) == 0x1) ? True : False);
910
else if (norotate == True)
912
/* definately no rotate */
916
/* define cam variables */
917
gp->cam_x_speed = frand(3.0) - 1.5;
918
gp->cam_x_phase = random() % 360;
919
gp->cam_y_speed = frand(3.0) - 1.5;
920
gp->cam_y_phase = random() % 360;
921
gp->cam_z_speed = frand(3.0) - 1.5;
922
gp->cam_z_phase = random() % 360;
924
/* initial angular speeds */
925
rangle_vel = frand(0.2) - 0.1;
926
tangle_vel = frand(0.2) - 0.1;
927
rangle_acc = frand(0.002) - 0.001;
928
tangle_acc = frand(0.002) - 0.001;
939
/* distance is 11 - size */
942
fprintf(stderr, "-size given. ignoring -zoom.\n");
947
} else if (size >= 10) {
954
printf("phases [%d, %d, %d]\n", gp->cam_x_phase, gp->cam_y_phase, gp->cam_z_phase);
959
init_gleidescope(ModeInfo * mi)
962
int screen = MI_SCREEN(mi);
965
if (gleidescope == NULL) {
966
gleidescope = (gleidestruct *) calloc(MI_NUM_SCREENS(mi), sizeof (gleidestruct));
967
if (gleidescope == NULL) {
971
gp = &gleidescope[screen];
972
gp->window = MI_WINDOW(mi);
974
if ((gp->glx_context = init_GL(mi)) != NULL) {
976
reshape_gleidescope(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
978
glDrawBuffer(GL_BACK);
980
/* do initialisation */
989
draw_gleidescope(ModeInfo * mi)
991
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
992
Display *display = MI_DISPLAY(mi);
993
Window window = MI_WINDOW(mi);
996
if (!gp->glx_context)
999
glDrawBuffer(GL_BACK);
1001
glXMakeCurrent(display, window, *(gp->glx_context));
1009
glXSwapBuffers(display, window);
1017
/* need to change texture? */
1018
if ((gp->start_time != 0) && (duration != -1) && gp->fade == 0) {
1019
if (gp->start_time + duration <= time((time_t *)0)) {
1020
/* get new snapshot (into back buffer) and start fade count */
1021
getSnapshot(mi, gp->textures[1 - gp->visible]);
1028
release_gleidescope(ModeInfo * mi)
1030
if (gleidescope != NULL) {
1033
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
1034
gleidestruct *gp = &gleidescope[screen];
1036
/* acd - is this needed? */
1037
if (gp->glx_context) {
1038
/* Display lists MUST be freed while their glXContext is current. */
1039
glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
1041
/* acd - was code here for freeing things that are no longer in struct */
1044
(void) free((void *) gleidescope);