~ubuntu-branches/ubuntu/dapper/xscreensaver/dapper

« back to all changes in this revision

Viewing changes to hacks/glx/lament.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
 
/* xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
 
1
/* xscreensaver, Copyright (c) 1998-2004 Jamie Zawinski <jwz@jwz.org>
2
2
 *
3
3
 * Permission to use, copy, modify, distribute, and sell this software and its
4
4
 * documentation for any purpose is hereby granted without fee, provided that
67
67
 
68
68
     *  Needs music.  ("Hellraiser Themes" by Coil: TORSO CD161; also
69
69
        duplicated on the "Unnatural History 2" compilation, WORLN M04699.)
70
 
 
71
 
     *  I'm not totally happy with the spinning motion; I like the
72
 
        acceleration and deceleration, but it often feels like it's going too
73
 
        fast, or not naturally enough, or something.
74
 
 
75
 
     *  However, the motion is better than that used by gears, superquadrics,
76
 
        etc.; so maybe I should make them all share the same motion code.
77
70
 */
78
71
 
79
72
#include <X11/Intrinsic.h>
82
75
#define HACK_INIT       init_lament
83
76
#define HACK_DRAW       draw_lament
84
77
#define HACK_RESHAPE    reshape_lament
 
78
#define HACK_HANDLE_EVENT lament_handle_event
 
79
#define EVENT_MASK      PointerMotionMask
85
80
#define lament_opts     xlockmore_opts
86
 
#define DEFAULTS        "*delay:        10000   \n"     \
 
81
#define DEFAULTS        "*delay:        20000   \n"     \
87
82
                        "*showFPS:      False   \n"     \
88
83
                        "*wireframe:    False   \n"     \
89
 
                        "*texture:      True    \n"
 
84
 
90
85
#include "xlockmore.h"
91
86
 
92
87
#ifdef USE_GL /* whole file */
98
93
 
99
94
static int do_texture;
100
95
static XrmOptionDescRec opts[] = {
101
 
  {"-texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "true" },
102
 
  {"+texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "false" },
 
96
  {"-texture", ".lament.texture", XrmoptionNoArg, "true" },
 
97
  {"+texture", ".lament.texture", XrmoptionNoArg, "false" },
103
98
};
104
99
 
105
100
static argtype vars[] = {
106
 
  {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
 
101
  {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
107
102
};
108
103
 
109
104
ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL};
110
105
 
 
106
#include "normals.h"
111
107
#include "xpm-ximage.h"
 
108
#include "rotator.h"
 
109
#include "gltrackball.h"
112
110
#include "../images/lament.xpm"
113
111
 
114
112
#define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
154
152
 
155
153
typedef struct {
156
154
  GLXContext *glx_context;
 
155
  rotator *rot;
 
156
  double rotx, roty, rotz;
 
157
  trackball_state *trackball;
 
158
  Bool button_down_p;
157
159
 
158
160
  GLuint box;                      /* display list IDs */
159
161
  GLuint star1, star2;
161
163
  GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
162
164
  GLuint taser_base, taser_lifter, taser_slider;
163
165
 
164
 
  GLfloat rotx, roty, rotz;        /* current object rotation */
165
 
  GLfloat dx, dy, dz;              /* current rotational velocity */
166
 
  GLfloat ddx, ddy, ddz;           /* current rotational acceleration */
167
 
  GLfloat d_max;                   /* max velocity */
168
166
  XImage *texture;                 /* image bits */
169
167
  GLuint texids[6];                /* texture map IDs */
170
168
  lament_type type;                /* which mode of the object is current */
194
192
}
195
193
 
196
194
 
197
 
/* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
198
 
 */
199
 
 
200
 
typedef struct vector {
201
 
  GLfloat x, y, z;
202
 
} vector;
203
 
 
204
 
typedef struct plane {
205
 
  vector p1, p2, p3;
206
 
} plane;
207
 
 
208
 
static void
209
 
vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
210
 
{
211
 
  v->x = x;
212
 
  v->y = y;
213
 
  v->z = z;
214
 
}
215
 
 
216
 
static void
217
 
vector_cross(vector v1, vector v2, vector *v3)
218
 
{
219
 
  v3->x = (v1.y * v2.z) - (v1.z * v2.y);
220
 
  v3->y = (v1.z * v2.x) - (v1.x * v2.z);
221
 
  v3->z = (v1.x * v2.y) - (v1.y * v2.x);
222
 
}
223
 
 
224
 
static void
225
 
vector_subtract(vector v1, vector v2, vector *res)
226
 
{
227
 
  res->x = v1.x - v2.x;
228
 
  res->y = v1.y - v2.y;
229
 
  res->z = v1.z - v2.z;
230
 
}
231
 
 
232
 
static void
233
 
plane_normal(plane p, vector *n)
234
 
{
235
 
  vector v1, v2;
236
 
  vector_subtract(p.p1, p.p2, &v1);
237
 
  vector_subtract(p.p1, p.p3, &v2);
238
 
  vector_cross(v2, v1, n);
239
 
}
240
 
 
241
 
static void
242
 
do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
243
 
          GLfloat x2, GLfloat y2, GLfloat z2,
244
 
          GLfloat x3, GLfloat y3, GLfloat z3)
245
 
{
246
 
  plane plane;
247
 
  vector n;
248
 
  vector_set(&plane.p1, x1, y1, z1);
249
 
  vector_set(&plane.p2, x2, y2, z2);
250
 
  vector_set(&plane.p3, x3, y3, z3);
251
 
  plane_normal(plane, &n);
252
 
  n.x = -n.x; n.y = -n.y; n.z = -n.z;
253
 
 
254
 
  glNormal3f(n.x, n.y, n.z);
255
 
 
256
 
#ifdef DEBUG
257
 
  /* Draw a line in the direction of this face's normal. */
258
 
  {
259
 
    GLfloat ax = n.x > 0 ? n.x : -n.x;
260
 
    GLfloat ay = n.y > 0 ? n.y : -n.y;
261
 
    GLfloat az = n.z > 0 ? n.z : -n.z;
262
 
    GLfloat mx = (x1 + x2 + x3) / 3;
263
 
    GLfloat my = (y1 + y2 + y3) / 3;
264
 
    GLfloat mz = (z1 + z2 + z3) / 3;
265
 
    GLfloat xx, yy, zz;
266
 
 
267
 
    GLfloat max = ax > ay ? ax : ay;
268
 
    if (az > max) max = az;
269
 
    max *= 2;
270
 
    xx = n.x / max;
271
 
    yy = n.y / max;
272
 
    zz = n.z / max;
273
 
 
274
 
    glBegin(GL_LINE_LOOP);
275
 
    glVertex3f(mx, my, mz);
276
 
    glVertex3f(mx+xx, my+yy, mz+zz);
277
 
    glEnd();
278
 
  }
279
 
#endif /* DEBUG */
280
 
}
281
 
 
282
 
 
283
 
 
284
195
/* Shorthand utilities for making faces, with proper normals.
285
196
 */
286
197
 
1403
1314
/* Rendering and animating object models
1404
1315
 */
1405
1316
 
 
1317
Bool
 
1318
lament_handle_event (ModeInfo *mi, XEvent *event)
 
1319
{
 
1320
  lament_configuration *lc = &lcs[MI_SCREEN(mi)];
 
1321
 
 
1322
  if (event->xany.type == ButtonPress &&
 
1323
      event->xbutton.button == Button1)
 
1324
    {
 
1325
      lc->button_down_p = True;
 
1326
      gltrackball_start (lc->trackball,
 
1327
                         event->xbutton.x, event->xbutton.y,
 
1328
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
1329
      return True;
 
1330
    }
 
1331
  else if (event->xany.type == ButtonRelease &&
 
1332
           event->xbutton.button == Button1)
 
1333
    {
 
1334
      lc->button_down_p = False;
 
1335
      return True;
 
1336
    }
 
1337
  else if (event->xany.type == ButtonPress &&
 
1338
           (event->xbutton.button == Button4 ||
 
1339
            event->xbutton.button == Button5))
 
1340
    {
 
1341
      gltrackball_mousewheel (lc->trackball, event->xbutton.button, 5,
 
1342
                              !!event->xbutton.state);
 
1343
      return True;
 
1344
    }
 
1345
  else if (event->xany.type == MotionNotify &&
 
1346
           lc->button_down_p)
 
1347
    {
 
1348
      gltrackball_track (lc->trackball,
 
1349
                         event->xmotion.x, event->xmotion.y,
 
1350
                         MI_WIDTH (mi), MI_HEIGHT (mi));
 
1351
      return True;
 
1352
    }
 
1353
 
 
1354
  return False;
 
1355
}
 
1356
 
 
1357
 
1406
1358
static void
1407
1359
draw(ModeInfo *mi)
1408
1360
{
1415
1367
    glClear(GL_COLOR_BUFFER_BIT);
1416
1368
 
1417
1369
  glPushMatrix();
1418
 
  {
1419
 
    GLfloat x = lc->rotx;
1420
 
    GLfloat y = lc->roty;
1421
 
    GLfloat z = lc->rotz;
1422
 
 
1423
 
#if 0
1424
 
 x=0.75; y=0; z=0; 
1425
 
#endif
1426
 
 
1427
 
    if (x < 0) x = 1 - (x + 1);
1428
 
    if (y < 0) y = 1 - (y + 1);
1429
 
    if (z < 0) z = 1 - (z + 1);
1430
 
 
1431
 
    /* Make into the screen be +Y right be +X, and up be +Z. */
1432
 
    glRotatef(-90.0, 1.0, 0.0, 0.0);
1433
 
 
1434
 
    /* Scale it up. */
1435
 
    glScalef(4.0, 4.0, 4.0);
 
1370
 
 
1371
  gltrackball_rotate (lc->trackball);
 
1372
 
 
1373
  /* Make into the screen be +Y right be +X, and up be +Z. */
 
1374
  glRotatef(-90.0, 1.0, 0.0, 0.0);
 
1375
 
 
1376
  /* Scale it up. */
 
1377
  glScalef(4.0, 4.0, 4.0);
1436
1378
 
1437
1379
#ifdef DEBUG
1438
1380
    glPushMatrix();
1458
1400
    glPushMatrix();
1459
1401
    {
1460
1402
      /* Apply rotation to the object. */
1461
 
      glRotatef(x * 360, 1.0, 0.0, 0.0);
1462
 
      glRotatef(y * 360, 0.0, 1.0, 0.0);
1463
 
      glRotatef(z * 360, 0.0, 0.0, 1.0);
 
1403
      if (lc->type != LAMENT_LID_ZOOM)
 
1404
        get_rotation (lc->rot, &lc->rotx, &lc->roty, &lc->rotz,
 
1405
                      !lc->button_down_p);
 
1406
      glRotatef (lc->rotx * 360, 1.0, 0.0, 0.0);
 
1407
      glRotatef (lc->roty * 360, 0.0, 1.0, 0.0);
 
1408
      glRotatef (lc->rotz * 360, 0.0, 0.0, 1.0);
1464
1409
 
1465
1410
      switch (lc->type)
1466
1411
        {
1570
1515
    }
1571
1516
    glPopMatrix();
1572
1517
 
1573
 
  }
1574
1518
  glPopMatrix();
1575
1519
}
1576
1520
 
1764
1708
        {
1765
1709
          lc->anim_r = 0.0;
1766
1710
          lc->anim_z = 0.0;
1767
 
          lc->rotx = frand(1.0) * RANDSIGN();
1768
 
          lc->roty = frand(1.0) * RANDSIGN();
1769
 
          lc->rotz = frand(1.0) * RANDSIGN();
1770
1711
          lc->type = LAMENT_BOX;
1771
1712
        }
1772
1713
      break;
1820
1761
}
1821
1762
 
1822
1763
 
1823
 
static void
1824
 
rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1825
 
{
1826
 
  double ppos = *pos;
1827
 
 
1828
 
  /* tick position */
1829
 
  if (ppos < 0)
1830
 
    ppos = -(ppos + *v);
1831
 
  else
1832
 
    ppos += *v;
1833
 
 
1834
 
  if (ppos > 1.0)
1835
 
    ppos -= 1.0;
1836
 
  else if (ppos < 0)
1837
 
    ppos += 1.0;
1838
 
 
1839
 
  if (ppos < 0) abort();
1840
 
  if (ppos > 1.0) abort();
1841
 
  *pos = (*pos > 0 ? ppos : -ppos);
1842
 
 
1843
 
  /* accelerate */
1844
 
  *v += *dv;
1845
 
 
1846
 
  /* clamp velocity */
1847
 
  if (*v > max_v || *v < -max_v)
1848
 
    {
1849
 
      *dv = -*dv;
1850
 
    }
1851
 
  /* If it stops, start it going in the other direction. */
1852
 
  else if (*v < 0)
1853
 
    {
1854
 
      if (random() % 4)
1855
 
        {
1856
 
          *v = 0;
1857
 
 
1858
 
          /* keep going in the same direction */
1859
 
          if (random() % 2)
1860
 
            *dv = 0;
1861
 
          else if (*dv < 0)
1862
 
            *dv = -*dv;
1863
 
        }
1864
 
      else
1865
 
        {
1866
 
          /* reverse gears */
1867
 
          *v = -*v;
1868
 
          *dv = -*dv;
1869
 
          *pos = -*pos;
1870
 
        }
1871
 
    }
1872
 
 
1873
 
  /* Alter direction of rotational acceleration randomly. */
1874
 
  if (! (random() % 120))
1875
 
    *dv = -*dv;
1876
 
 
1877
 
  /* Change acceleration very occasionally. */
1878
 
  if (! (random() % 200))
1879
 
    {
1880
 
      if (*dv == 0)
1881
 
        *dv = 0.00001;
1882
 
      else if (random() & 1)
1883
 
        *dv *= 1.2;
1884
 
      else
1885
 
        *dv *= 0.8;
1886
 
    }
1887
 
}
1888
 
 
1889
 
 
1890
1764
 
1891
1765
/* Window management, etc
1892
1766
 */
1918
1792
     Note that the image-map bits we have are 128x128.  Therefore, if the
1919
1793
     image is magnified a lot, it looks pretty blocky.  So it's better to
1920
1794
     have a 128x128 animation on a 1280x1024 screen that looks good, than
1921
 
     a 1024x1024 animation that looks really pixellated.
 
1795
     a 1024x1024 animation that looks really pixelated.
1922
1796
   */
1923
1797
  if (win_size > target_size * 1.5)
1924
1798
    {
1993
1867
          clear_gl_error();
1994
1868
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1995
1869
                       lc->texture->width, height, 0,
1996
 
                       GL_RGBA, GL_UNSIGNED_BYTE,
 
1870
                       GL_RGBA,
 
1871
                       /* GL_UNSIGNED_BYTE, */
 
1872
                       GL_UNSIGNED_INT_8_8_8_8_REV,
1997
1873
                       (lc->texture->data +
1998
1874
                        (lc->texture->bytes_per_line * height * i)));
1999
1875
          check_gl_error("texture");
2099
1975
 
2100
1976
  lc = &lcs[MI_SCREEN(mi)];
2101
1977
 
2102
 
  lc->rotx = frand(1.0) * RANDSIGN();
2103
 
  lc->roty = frand(1.0) * RANDSIGN();
2104
 
  lc->rotz = frand(1.0) * RANDSIGN();
2105
 
 
2106
 
  /* bell curve from 0-1.5 degrees, avg 0.75 */
2107
 
  lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2108
 
  lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2109
 
  lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2110
 
 
2111
 
  lc->d_max = lc->dx * 2;
2112
 
 
2113
 
  lc->ddx = 0.00006 + frand(0.00003);
2114
 
  lc->ddy = 0.00006 + frand(0.00003);
2115
 
  lc->ddz = 0.00006 + frand(0.00003);
 
1978
  {
 
1979
    double rot_speed = 0.5;
 
1980
    lc->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
 
1981
    lc->trackball = gltrackball_init ();
 
1982
  }
2116
1983
 
2117
1984
  lc->type = LAMENT_BOX;
2118
1985
  lc->anim_pause = 300 + (random() % 100);
2148
2015
  glFinish();
2149
2016
  glXSwapBuffers(dpy, window);
2150
2017
 
2151
 
  if (lc->type != LAMENT_LID_ZOOM)
2152
 
    {
2153
 
      rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2154
 
      rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2155
 
      rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);
2156
 
    }
2157
 
 
2158
2018
  if (lc->anim_pause)
2159
2019
    lc->anim_pause--;
2160
2020
  else