~ubuntu-branches/ubuntu/breezy/xscreensaver/breezy

« back to all changes in this revision

Viewing changes to hacks/glx/moebius.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2005-10-11 21:00:42 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051011210042-u7q6zslgevdxspr3
Tags: 4.21-4ubuntu17
updated pt_BR again, fixed to UTF-8 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 4 -*- */
2
2
/* moebius --- Moebius Strip II, an Escher-like GL scene with ants. */
3
3
 
4
 
#if !defined( lint ) && !defined( SABER )
5
 
static const char sccsid[] = "@(#)moebius.c     4.08 97/01/04 xlockmore";
6
 
 
 
4
#if 0
 
5
static const char sccsid[] = "@(#)moebius.c     5.01 2001/03/01 xlockmore";
7
6
#endif
8
7
 
9
 
#undef DEBUG_LISTS
10
 
 
11
8
/*-
12
9
 * Permission to use, copy, modify, and distribute this software and its
13
10
 * documentation for any purpose and without fee is hereby granted,
22
19
 * other special, indirect and consequential damages.
23
20
 *
24
21
 * The RotateAroundU() routine was adapted from the book
25
 
 *    "Computer Graphics Principles and Practice 
 
22
 *    "Computer Graphics Principles and Practice
26
23
 *     Foley - vanDam - Feiner - Hughes
27
24
 *     Second Edition" Pag. 227, exercise 5.15.
28
 
 * 
 
25
 *
29
26
 * This mode shows some interesting scenes that are impossible OR very
30
27
 * wierd to build in the real universe. Much of the scenes are inspirated
31
28
 * on Mauritz Cornelis Escher's works which derivated the mode's name.
32
29
 * M.C. Escher (1898-1972) was a dutch artist and many people prefer to
33
30
 * say he was a mathematician.
34
31
 *
35
 
 * Thanks goes to Brian Paul for making it possible and inexpensive to use 
 
32
 * Thanks goes to Brian Paul for making it possible and inexpensive to use
36
33
 * OpenGL at home.
37
34
 *
38
35
 * Since I'm not a native English speaker, my apologies for any grammatical
39
 
 * mistake.
 
36
 * mistakes.
40
37
 *
41
38
 * My e-mail address is
42
 
 * m-vianna@usa.net
 
39
 * mfvianna@centroin.com.br
43
40
 *
44
41
 * Marcelo F. Vianna (Jun-01-1997)
45
42
 *
46
43
 * Revision History:
47
 
 * 01-Jan-98: Mode separated from escher and renamed
48
 
 * 08-Jun-97: New scene implemented: "Impossible Cage" based in a M.C. Escher's
49
 
 *            painting with the same name (quite similar). The first GL mode
50
 
 *            to use texture mapping.
51
 
 *            The "Impossible Cage" scene doesn't use DEPTH BUFFER, the 
52
 
 *            wood planks are drawn consistently using GL_CULL_FACE, and
53
 
 *            the painter's algorithm is used to sort the planks.
54
 
 *            Marcelo F. Vianna.
55
 
 * 07-Jun-97: Speed ups in Moebius Strip using GL_CULL_FACE.
56
 
 *            Marcelo F. Vianna.
57
 
 * 03-Jun-97: Initial Release (Only one scene: "Moebius Strip")
58
 
 *            The Moebius Strip scene was inspirated in a M.C. Escher's
59
 
 *            painting named Moebius Strip II in wich ants walk across a
60
 
 *            Moebius Strip path, sometimes meeting each other and sometimes
61
 
 *            being in "opposite faces" (note that the moebius strip has
62
 
 *            only one face and one edge).
63
 
 *            Marcelo F. Vianna.
64
 
 *
 
44
 * 05-Apr-2002: Removed all gllist uses (fix some bug with nvidia driver)
 
45
 * 01-Mar-2001: backported from xscreensaver by lassauge@mail.dotcom.fr
 
46
 *    Feb-2001: Made motion and rotation be smoother Jamie Zawinski
 
47
 *              <jwz@jwz.org>
 
48
 * 01-Nov-2000: Allocation checks
 
49
 * 01-Jan-1998: Mode separated from escher and renamed
 
50
 * 08-Jun-1997: New scene implemented: "Impossible Cage" based in a M.C.
 
51
 *              Escher's painting with the same name (quite similar). The
 
52
 *              first GL mode to use texture mapping.
 
53
 *              The "Impossible Cage" scene doesn't use DEPTH BUFFER, the
 
54
 *              wood planks are drawn consistently using GL_CULL_FACE, and
 
55
 *              the painter's algorithm is used to sort the planks.
 
56
 *              Marcelo F. Vianna.
 
57
 * 07-Jun-1997: Speed ups in Moebius Strip using GL_CULL_FACE.
 
58
 *              Marcelo F. Vianna.
 
59
 * 03-Jun-1997: Initial Release (Only one scene: "Moebius Strip")
 
60
 *              The Moebius Strip scene was inspirated in a M.C. Escher's
 
61
 *              painting named Moebius Strip II in wich ants walk across a
 
62
 *              Moebius Strip path, sometimes meeting each other and sometimes
 
63
 *              being in "opposite faces" (note that the moebius strip has
 
64
 *              only one face and one edge).
 
65
 *              Marcelo F. Vianna.
65
66
 */
66
67
 
67
68
/*-
76
77
 * In real OpenGL, PseudoColor DO NOT support texture map (as far as I know).
77
78
 */
78
79
 
 
80
#ifdef VMS
79
81
#include <X11/Intrinsic.h>
 
82
#endif
80
83
 
81
84
#ifdef STANDALONE
 
85
# define MODE_moebius
82
86
# define PROGCLASS                      "Moebius"
83
87
# define HACK_INIT                      init_moebius
84
88
# define HACK_DRAW                      draw_moebius
85
89
# define HACK_RESHAPE           reshape_moebius
 
90
# define HACK_HANDLE_EVENT      moebius_handle_event
 
91
# define EVENT_MASK                     PointerMotionMask
86
92
# define moebius_opts           xlockmore_opts
87
 
# define DEFAULTS                       "*cycles:               1       \n"                     \
88
 
                                                        "*delay:                20000   \n"                     \
 
93
# define DEFAULTS                       "*delay:                20000   \n"                     \
89
94
                                                        "*showFPS:      False   \n"                     \
90
95
                                                        "*wireframe:    False   \n"
91
96
# include "xlockmore.h"         /* from the xscreensaver distribution */
94
99
 
95
100
#endif /* !STANDALONE */
96
101
 
97
 
#ifdef USE_GL
 
102
#ifdef MODE_moebius
98
103
 
99
104
 
100
105
#include <GL/glu.h>
101
106
#include "e_textures.h"
 
107
#include "rotator.h"
 
108
#include "gltrackball.h"
102
109
 
103
110
#define DEF_SOLIDMOEBIUS  "False"
104
111
#define DEF_NOANTS  "False"
108
115
 
109
116
static XrmOptionDescRec opts[] =
110
117
{
111
 
  {"-solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "on"},
112
 
 {"+solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "off"},
113
 
        {"-noants", ".moebius.noants", XrmoptionNoArg, (caddr_t) "on"},
114
 
        {"+noants", ".moebius.noants", XrmoptionNoArg, (caddr_t) "off"}
 
118
  {"-solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "on"},
 
119
  {"+solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "off"},
 
120
  {"-noants", ".moebius.noants", XrmoptionNoArg, "on"},
 
121
  {"+noants", ".moebius.noants", XrmoptionNoArg, "off"}
115
122
};
116
123
static argtype vars[] =
117
124
{
118
 
        {(caddr_t *) & solidmoebius, "solidmoebius", "Solidmoebius", DEF_SOLIDMOEBIUS, t_Bool},
119
 
        {(caddr_t *) & noants, "noants", "Noants", DEF_NOANTS, t_Bool}
 
125
  {&solidmoebius, "solidmoebius", "Solidmoebius", DEF_SOLIDMOEBIUS, t_Bool},
 
126
  {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
 
127
 
120
128
};
121
129
static OptionStruct desc[] =
122
130
{
130
138
#ifdef USE_MODULES
131
139
ModStruct   moebius_description =
132
140
{"moebius", "init_moebius", "draw_moebius", "release_moebius",
133
 
 "draw_moebius", "change_moebius", NULL, &moebius_opts,
 
141
 "draw_moebius", "change_moebius", (char *) NULL, &moebius_opts,
134
142
 1000, 1, 1, 1, 4, 1.0, "",
135
143
 "Shows Moebius Strip II, an Escher-like GL scene with ants", 0, NULL};
136
144
 
145
153
#define Pi                         M_PI
146
154
#endif
147
155
 
 
156
#define ObjMoebiusStrip 0
 
157
#define ObjAntBody      1
 
158
#define MaxObj          2
 
159
 
148
160
/*************************************************************************/
149
161
 
150
162
typedef struct {
151
163
        GLint       WindH, WindW;
152
164
        GLfloat     step;
153
165
        GLfloat     ant_position;
154
 
        int         AreObjectsDefined[2];
155
166
        GLXContext *glx_context;
156
 
 
157
 
  GLfloat rotx, roty, rotz;        /* current object rotation */
158
 
  GLfloat dx, dy, dz;              /* current rotational velocity */
159
 
  GLfloat ddx, ddy, ddz;           /* current rotational acceleration */
160
 
  GLfloat d_max;                           /* max velocity */
161
 
 
 
167
    rotator    *rot;
 
168
    trackball_state *trackball;
 
169
    Bool        button_down_p;
162
170
} moebiusstruct;
163
171
 
164
172
static float front_shininess[] =
201
209
static float MaterialGray8[] =
202
210
{0.8, 0.8, 0.8, 1.0};
203
211
 
204
 
static moebiusstruct *moebius = NULL;
205
 
static GLuint objects;
 
212
static moebiusstruct *moebius = (moebiusstruct *) NULL;
206
213
 
207
214
#define NUM_SCENES      2
208
215
 
209
 
#define ObjMoebiusStrip 0
210
 
#define ObjAntBody      1
211
 
 
212
 
static void
 
216
static Bool
213
217
mySphere(float radius)
214
218
{
215
219
        GLUquadricObj *quadObj;
216
220
 
217
 
        quadObj = gluNewQuadric();
 
221
        if ((quadObj = gluNewQuadric()) == 0)
 
222
                return False;
218
223
        gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
219
224
        gluSphere(quadObj, radius, 16, 16);
220
225
        gluDeleteQuadric(quadObj);
 
226
        return True;
221
227
}
222
228
 
223
 
static void
 
229
static Bool
224
230
myCone(float radius)
225
231
{
226
232
        GLUquadricObj *quadObj;
227
233
 
228
 
        quadObj = gluNewQuadric();
 
234
        if ((quadObj = gluNewQuadric()) == 0)
 
235
                return False;
229
236
        gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
230
237
        gluCylinder(quadObj, radius, 0, radius * 3, 8, 1);
231
238
        gluDeleteQuadric(quadObj);
 
239
        return True;
232
240
}
233
241
 
234
 
static void
 
242
static Bool
235
243
draw_moebius_ant(moebiusstruct * mp, float *Material, int mono)
236
244
{
237
245
        static float ant_step = 0;
246
254
                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
247
255
        else
248
256
                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Material);
249
 
        if (!mp->AreObjectsDefined[ObjAntBody]) {
250
 
                glNewList(objects + ObjAntBody, GL_COMPILE_AND_EXECUTE);
251
 
                glEnable(GL_CULL_FACE);
252
 
                glPushMatrix();
253
 
                glScalef(1, 1.3, 1);
254
 
                mySphere(0.18);
255
 
                glScalef(1, 1 / 1.3, 1);
256
 
                glTranslatef(0.00, 0.30, 0.00);
257
 
                mySphere(0.2);
258
 
 
259
 
                glTranslatef(-0.05, 0.17, 0.05);
260
 
                glRotatef(-90, 1, 0, 0);
261
 
                glRotatef(-25, 0, 1, 0);
262
 
                myCone(0.05);
263
 
                glTranslatef(0.00, 0.10, 0.00);
264
 
                myCone(0.05);
265
 
                glRotatef(25, 0, 1, 0);
266
 
                glRotatef(90, 1, 0, 0);
267
 
 
268
 
                glScalef(1, 1.3, 1);
269
 
                glTranslatef(0.15, -0.65, 0.05);
270
 
                mySphere(0.25);
271
 
                glScalef(1, 1 / 1.3, 1);
272
 
                glPopMatrix();
273
 
                glDisable(GL_CULL_FACE);
274
 
                glEndList();
275
 
                mp->AreObjectsDefined[ObjAntBody] = 1;
276
 
#ifdef DEBUG_LISTS
277
 
                (void) printf("Ant drawn SLOWLY\n");
278
 
#endif
279
 
        } else {
280
 
                glCallList(objects + ObjAntBody);
281
 
#ifdef DEBUG_LISTS
282
 
                (void) printf("Ant drawn quickly\n");
283
 
#endif
284
 
        }
 
257
        glEnable(GL_CULL_FACE);
 
258
        glPushMatrix();
 
259
        glScalef(1, 1.3, 1);
 
260
        if (!mySphere(0.18))
 
261
                return False;
 
262
        glScalef(1, 1 / 1.3, 1);
 
263
        glTranslatef(0.00, 0.30, 0.00);
 
264
        if (!mySphere(0.2))
 
265
                return False;
 
266
 
 
267
        glTranslatef(-0.05, 0.17, 0.05);
 
268
        glRotatef(-90, 1, 0, 0);
 
269
        glRotatef(-25, 0, 1, 0);
 
270
        if (!myCone(0.05))
 
271
                return False;
 
272
        glTranslatef(0.00, 0.10, 0.00);
 
273
        if (!myCone(0.05))
 
274
                return False;
 
275
        glRotatef(25, 0, 1, 0);
 
276
        glRotatef(90, 1, 0, 0);
 
277
 
 
278
        glScalef(1, 1.3, 1);
 
279
        glTranslatef(0.15, -0.65, 0.05);
 
280
        if (!mySphere(0.25))
 
281
                return False;
 
282
        glScalef(1, 1 / 1.3, 1);
 
283
        glPopMatrix();
 
284
        glDisable(GL_CULL_FACE);
285
285
 
286
286
        glDisable(GL_LIGHTING);
287
287
        /* ANTENNAS */
398
398
        glEnable(GL_LIGHTING);
399
399
 
400
400
        ant_step += 0.3;
 
401
        return True;
401
402
}
402
403
 
403
404
static void
423
424
 
424
425
#define MoebiusDivisions 40
425
426
#define MoebiusTransversals 4
426
 
static void
 
427
static Bool
427
428
draw_moebius_strip(ModeInfo * mi)
428
429
{
429
430
        GLfloat     Phi, Theta;
434
435
 
435
436
        float       Cx, Cy, Cz;
436
437
 
437
 
        if (!mp->AreObjectsDefined[ObjMoebiusStrip]) {
438
 
                glNewList(objects + ObjMoebiusStrip, GL_COMPILE_AND_EXECUTE);
439
 
 
440
 
                if (solidmoebius) {
 
438
        if (solidmoebius) {
 
439
                glBegin(GL_QUAD_STRIP);
 
440
                Phi = 0;
 
441
                i = 0;
 
442
                while (i < (MoebiusDivisions * 2 + 1)) {
 
443
                        Theta = Phi / 2;
 
444
                        cPhi = cos(Phi);
 
445
                        sPhi = sin(Phi);
 
446
 
 
447
                        i++;
 
448
                        if (mono)
 
449
                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
 
450
                        else if (i % 2)
 
451
                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
 
452
                        else
 
453
                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
 
454
 
 
455
                        RotateAaroundU(cPhi, sPhi, 0, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
 
456
                        glNormal3f(Cx, Cy, Cz);
 
457
                        RotateAaroundU(0, 0, 1, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
 
458
                        glVertex3f(cPhi * 3 + Cx, sPhi * 3 + Cy, +Cz);
 
459
                        glVertex3f(cPhi * 3 - Cx, sPhi * 3 - Cy, -Cz);
 
460
 
 
461
                        Phi += Pi / MoebiusDivisions;
 
462
                }
 
463
                glEnd();
 
464
        } else {
 
465
                for (j = -MoebiusTransversals; j < MoebiusTransversals; j++) {
 
466
                        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
441
467
                        glBegin(GL_QUAD_STRIP);
442
468
                        Phi = 0;
443
469
                        i = 0;
446
472
                                cPhi = cos(Phi);
447
473
                                sPhi = sin(Phi);
448
474
 
449
 
                                i++;
450
 
                                if (mono)
451
 
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
452
 
                                else if (i % 2)
453
 
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
454
 
                                else
455
 
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
456
 
 
457
475
                                RotateAaroundU(cPhi, sPhi, 0, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
458
476
                                glNormal3f(Cx, Cy, Cz);
459
477
                                RotateAaroundU(0, 0, 1, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
460
 
                                glVertex3f(cPhi * 3 + Cx, sPhi * 3 + Cy, +Cz);
461
 
                                glVertex3f(cPhi * 3 - Cx, sPhi * 3 - Cy, -Cz);
 
478
                                j++;
 
479
                                if (j == MoebiusTransversals || mono)
 
480
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
 
481
                                else if (i % 2)
 
482
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
 
483
                                else
 
484
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
 
485
                                glVertex3f(cPhi * 3 + Cx / MoebiusTransversals * j, sPhi * 3 + Cy / MoebiusTransversals * j, +Cz / MoebiusTransversals * j);
 
486
                                j--;
 
487
                                if (j == -MoebiusTransversals || mono)
 
488
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
 
489
                                else if (i % 2)
 
490
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
 
491
                                else
 
492
                                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
 
493
                                glVertex3f(cPhi * 3 + Cx / MoebiusTransversals * j, sPhi * 3 + Cy / MoebiusTransversals * j, +Cz / MoebiusTransversals * j);
462
494
 
463
495
                                Phi += Pi / MoebiusDivisions;
 
496
                                i++;
464
497
                        }
465
498
                        glEnd();
466
 
                } else {
467
 
                        for (j = -MoebiusTransversals; j < MoebiusTransversals; j++) {
468
 
                                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
469
 
                                glBegin(GL_QUAD_STRIP);
470
 
                                Phi = 0;
471
 
                                i = 0;
472
 
                                while (i < (MoebiusDivisions * 2 + 1)) {
473
 
                                        Theta = Phi / 2;
474
 
                                        cPhi = cos(Phi);
475
 
                                        sPhi = sin(Phi);
476
 
 
477
 
                                        RotateAaroundU(cPhi, sPhi, 0, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
478
 
                                        glNormal3f(Cx, Cy, Cz);
479
 
                                        RotateAaroundU(0, 0, 1, -sPhi, cPhi, 0, &Cx, &Cy, &Cz, Theta);
480
 
                                        j++;
481
 
                                        if (j == MoebiusTransversals || mono)
482
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
483
 
                                        else if (i % 2)
484
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
485
 
                                        else
486
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
487
 
                                        glVertex3f(cPhi * 3 + Cx / MoebiusTransversals * j, sPhi * 3 + Cy / MoebiusTransversals * j, +Cz / MoebiusTransversals * j);
488
 
                                        j--;
489
 
                                        if (j == -MoebiusTransversals || mono)
490
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
491
 
                                        else if (i % 2)
492
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
493
 
                                        else
494
 
                                                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
495
 
                                        glVertex3f(cPhi * 3 + Cx / MoebiusTransversals * j, sPhi * 3 + Cy / MoebiusTransversals * j, +Cz / MoebiusTransversals * j);
496
 
 
497
 
                                        Phi += Pi / MoebiusDivisions;
498
 
                                        i++;
499
 
                                }
500
 
                                glEnd();
501
 
                        }
502
 
                        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
503
499
                }
504
 
 
505
 
                glEndList();
506
 
                mp->AreObjectsDefined[ObjMoebiusStrip] = 1;
507
 
#ifdef DEBUG_LISTS
508
 
                (void) printf("Strip drawn SLOWLY\n");
509
 
#endif
510
 
        } else {
511
 
                glCallList(objects + ObjMoebiusStrip);
512
 
#ifdef DEBUG_LISTS
513
 
                (void) printf("Strip drawn quickly\n");
514
 
#endif
 
500
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
515
501
        }
516
502
 
517
503
        if (!noants) {
521
507
                glTranslatef(3, 0, 0);
522
508
                glRotatef(mp->ant_position / 2 + 90, 0, 1, 0);
523
509
                glTranslatef(0.28, 0, -0.45);
524
 
                draw_moebius_ant(mp, MaterialYellow, mono);
 
510
                if (!draw_moebius_ant(mp, MaterialYellow, mono))
 
511
                        return False;
525
512
                glPopMatrix();
526
513
 
527
514
                /* DRAW YELLOW ANT */
530
517
                glTranslatef(3, 0, 0);
531
518
                glRotatef(mp->ant_position / 2, 0, 1, 0);
532
519
                glTranslatef(0.28, 0, -0.45);
533
 
                draw_moebius_ant(mp, MaterialBlue, mono);
 
520
                if (!draw_moebius_ant(mp, MaterialBlue, mono))
 
521
                        return False;
534
522
                glPopMatrix();
535
523
 
536
524
                /* DRAW GREEN ANT */
540
528
                glRotatef(-mp->ant_position / 2, 0, 1, 0);
541
529
                glTranslatef(0.28, 0, 0.45);
542
530
                glRotatef(180, 1, 0, 0);
543
 
                draw_moebius_ant(mp, MaterialGreen, mono);
 
531
                if (!draw_moebius_ant(mp, MaterialGreen, mono))
 
532
                        return False;
544
533
                glPopMatrix();
545
534
 
546
535
                /* DRAW CYAN ANT */
550
539
                glRotatef(-mp->ant_position / 2 + 90, 0, 1, 0);
551
540
                glTranslatef(0.28, 0, 0.45);
552
541
                glRotatef(180, 1, 0, 0);
553
 
                draw_moebius_ant(mp, MaterialCyan, mono);
 
542
                if (!draw_moebius_ant(mp, MaterialCyan, mono))
 
543
                        return False;
554
544
                glPopMatrix();
555
545
        }
556
546
        mp->ant_position += 1;
 
547
        return True;
557
548
}
558
549
#undef MoebiusDivisions
559
550
#undef MoebiusTransversals
578
569
                glLineWidth(1);
579
570
                glPointSize(1);
580
571
        }
581
 
        mp->AreObjectsDefined[ObjMoebiusStrip] = 0;
582
 
        mp->AreObjectsDefined[ObjAntBody] = 0;
583
572
}
584
573
 
585
574
static void
586
575
pinit(void)
587
576
{
 
577
    int status;
588
578
        glClearDepth(1.0);
589
579
        glClearColor(0.0, 0.0, 0.0, 1.0);
590
580
 
610
600
        glDisable(GL_CULL_FACE);
611
601
 
612
602
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
613
 
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, WoodTextureWidth, WoodTextureHeight,
614
 
                          GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData);
 
603
 
 
604
    clear_gl_error();
 
605
        status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
 
606
                               WoodTextureWidth, WoodTextureHeight,
 
607
                               GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData);
 
608
    if (status)
 
609
      {
 
610
        const char *s = (char *) gluErrorString (status);
 
611
        fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
 
612
                 progname, WoodTextureWidth, WoodTextureHeight,
 
613
                 (s ? s : "(unknown)"));
 
614
        exit (1);
 
615
      }
 
616
    check_gl_error("mipmapping");
 
617
 
615
618
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
616
619
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
617
620
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
624
627
 
625
628
 
626
629
 
627
 
/* lifted from lament.c */
628
 
#define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
629
 
#define RANDSIGN() ((random() & 1) ? 1 : -1)
630
 
 
631
 
static void
632
 
rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
633
 
{
634
 
  double ppos = *pos;
635
 
 
636
 
  /* tick position */
637
 
  if (ppos < 0)
638
 
    ppos = -(ppos + *v);
639
 
  else
640
 
    ppos += *v;
641
 
 
642
 
  if (ppos > 1.0)
643
 
    ppos -= 1.0;
644
 
  else if (ppos < 0)
645
 
    ppos += 1.0;
646
 
 
647
 
  if (ppos < 0) abort();
648
 
  if (ppos > 1.0) abort();
649
 
  *pos = (*pos > 0 ? ppos : -ppos);
650
 
 
651
 
  /* accelerate */
652
 
  *v += *dv;
653
 
 
654
 
  /* clamp velocity */
655
 
  if (*v > max_v || *v < -max_v)
656
 
    {
657
 
      *dv = -*dv;
658
 
    }
659
 
  /* If it stops, start it going in the other direction. */
660
 
  else if (*v < 0)
661
 
    {
662
 
      if (random() % 4)
663
 
        {
664
 
          *v = 0;
665
 
 
666
 
          /* keep going in the same direction */
667
 
          if (random() % 2)
668
 
            *dv = 0;
669
 
          else if (*dv < 0)
670
 
            *dv = -*dv;
671
 
        }
672
 
      else
673
 
        {
674
 
          /* reverse gears */
675
 
          *v = -*v;
676
 
          *dv = -*dv;
677
 
          *pos = -*pos;
678
 
        }
679
 
    }
680
 
 
681
 
  /* Alter direction of rotational acceleration randomly. */
682
 
  if (! (random() % 120))
683
 
    *dv = -*dv;
684
 
 
685
 
  /* Change acceleration very occasionally. */
686
 
  if (! (random() % 200))
687
 
    {
688
 
      if (*dv == 0)
689
 
        *dv = 0.00001;
690
 
      else if (random() & 1)
691
 
        *dv *= 1.2;
692
 
      else
693
 
        *dv *= 0.8;
694
 
    }
 
630
void
 
631
release_moebius(ModeInfo * mi)
 
632
{
 
633
        if (moebius != NULL) {
 
634
                (void) free((void *) moebius);
 
635
                moebius = (moebiusstruct *) NULL;
 
636
        }
 
637
        FreeAllGL(mi);
 
638
}
 
639
 
 
640
Bool
 
641
moebius_handle_event (ModeInfo *mi, XEvent *event)
 
642
{
 
643
  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
644
 
 
645
  if (event->xany.type == ButtonPress &&
 
646
      event->xbutton.button == Button1)
 
647
    {
 
648
      mp->button_down_p = True;
 
649
      gltrackball_start (mp->trackball,
 
650
                         event->xbutton.x, event->xbutton.y,
 
651
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
652
      return True;
 
653
    }
 
654
  else if (event->xany.type == ButtonRelease &&
 
655
           event->xbutton.button == Button1)
 
656
    {
 
657
      mp->button_down_p = False;
 
658
      return True;
 
659
    }
 
660
  else if (event->xany.type == ButtonPress &&
 
661
           (event->xbutton.button == Button4 ||
 
662
            event->xbutton.button == Button5))
 
663
    {
 
664
      gltrackball_mousewheel (mp->trackball, event->xbutton.button, 10,
 
665
                              !!event->xbutton.state);
 
666
      return True;
 
667
    }
 
668
  else if (event->xany.type == MotionNotify &&
 
669
           mp->button_down_p)
 
670
    {
 
671
      gltrackball_track (mp->trackball,
 
672
                         event->xmotion.x, event->xmotion.y,
 
673
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
674
      return True;
 
675
    }
 
676
 
 
677
  return False;
695
678
}
696
679
 
697
680
 
698
681
void
699
682
init_moebius(ModeInfo * mi)
700
683
{
701
 
        int         screen = MI_SCREEN(mi);
702
684
        moebiusstruct *mp;
703
685
 
704
686
        if (moebius == NULL) {
706
688
                                            sizeof (moebiusstruct))) == NULL)
707
689
                        return;
708
690
        }
709
 
        mp = &moebius[screen];
 
691
        mp = &moebius[MI_SCREEN(mi)];
710
692
        mp->step = NRAND(90);
711
693
        mp->ant_position = NRAND(90);
712
694
 
713
 
    mp->rotx = frand(1.0) * RANDSIGN();
714
 
    mp->roty = frand(1.0) * RANDSIGN();
715
 
    mp->rotz = frand(1.0) * RANDSIGN();
716
 
 
717
 
    /* bell curve from 0-1.5 degrees, avg 0.75 */
718
 
    mp->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
719
 
    mp->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
720
 
    mp->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
721
 
 
722
 
    mp->d_max = mp->dx * 2;
723
 
 
724
 
    mp->ddx = 0.00006 + frand(0.00003);
725
 
    mp->ddy = 0.00006 + frand(0.00003);
726
 
    mp->ddz = 0.00006 + frand(0.00003);
 
695
    {
 
696
      double rot_speed = 0.3;
 
697
      mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
 
698
      mp->trackball = gltrackball_init ();
 
699
    }
727
700
 
728
701
        if ((mp->glx_context = init_GL(mi)) != NULL) {
729
702
 
730
703
                reshape_moebius(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
731
704
                glDrawBuffer(GL_BACK);
732
 
                if (!glIsList(objects))
733
 
                        objects = glGenLists(3);
734
705
                pinit();
735
706
        } else {
736
707
                MI_CLEARWINDOW(mi);
740
711
void
741
712
draw_moebius(ModeInfo * mi)
742
713
{
743
 
        moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
714
        moebiusstruct *mp;
744
715
 
745
716
        Display    *display = MI_DISPLAY(mi);
746
717
        Window      window = MI_WINDOW(mi);
747
718
 
 
719
        if (moebius == NULL)
 
720
            return;
 
721
        mp = &moebius[MI_SCREEN(mi)];
 
722
 
 
723
        MI_IS_DRAWN(mi) = True;
 
724
 
748
725
        if (!mp->glx_context)
749
726
                return;
750
727
 
756
733
 
757
734
        glTranslatef(0.0, 0.0, -10.0);
758
735
 
 
736
    gltrackball_rotate (mp->trackball);
 
737
 
759
738
        if (!MI_IS_ICONIC(mi)) {
760
739
                glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
761
740
        } else {
763
742
        }
764
743
 
765
744
    {
766
 
      GLfloat x = mp->rotx;
767
 
      GLfloat y = mp->roty;
768
 
      GLfloat z = mp->rotz;
769
 
      if (x < 0) x = 1 - (x + 1);
770
 
      if (y < 0) y = 1 - (y + 1);
771
 
      if (z < 0) z = 1 - (z + 1);
772
 
      glRotatef(x * 360, 1.0, 0.0, 0.0);
773
 
      glRotatef(y * 360, 0.0, 1.0, 0.0);
774
 
      glRotatef(z * 360, 0.0, 0.0, 1.0);
 
745
      double x, y, z;
 
746
      get_rotation (mp->rot, &x, &y, &z, !mp->button_down_p);
 
747
      glRotatef (x * 360, 1.0, 0.0, 0.0);
 
748
      glRotatef (y * 360, 0.0, 1.0, 0.0);
 
749
      glRotatef (z * 360, 0.0, 0.0, 1.0);
775
750
    }
776
751
 
777
752
        /* moebius */
778
 
        draw_moebius_strip(mi);
 
753
        if (!draw_moebius_strip(mi)) {
 
754
                release_moebius(mi);
 
755
                return;
 
756
        }
779
757
 
780
758
        glPopMatrix();
781
759
 
782
 
    rotate(&mp->rotx, &mp->dx, &mp->ddx, mp->d_max);
783
 
    rotate(&mp->roty, &mp->dy, &mp->ddy, mp->d_max);
784
 
    rotate(&mp->rotz, &mp->dz, &mp->ddz, mp->d_max);
785
 
 
786
 
    if (mi->fps_p) do_fps (mi);
 
760
    if (MI_IS_FPS(mi)) do_fps (mi);
787
761
        glFlush();
788
762
 
789
763
        glXSwapBuffers(display, window);
803
777
        pinit();
804
778
}
805
779
 
806
 
void
807
 
release_moebius(ModeInfo * mi)
808
 
{
809
 
        if (moebius != NULL) {
810
 
                (void) free((void *) moebius);
811
 
                moebius = NULL;
812
 
        }
813
 
        if (glIsList(objects)) {
814
 
                glDeleteLists(objects, 3);
815
 
        }
816
 
        FreeAllGL(mi);
817
 
}
818
 
 
819
780
#endif