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

« back to all changes in this revision

Viewing changes to hacks/glx/providence.c

  • Committer: Bazaar Package Importer
  • Author(s): Ralf Hildebrandt
  • Date: 2005-04-09 00:06:43 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050409000643-z0abtifbt9s20pcc
Tags: 4.21-3
Patch by Joachim Breitner to check more frequently if DPMS kicked in (closes: #303374, #286664).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Permission to use, copy, modify, and distribute this software and its
 
3
 * documentation for any purpose and without fee is hereby granted,
 
4
 * provided that the above copyright notice appear in all copies and that
 
5
 * both that copyright notice and this permission notice appear in
 
6
 * supporting documentation.
 
7
 *
 
8
 * This file is provided AS IS with no warranties of any kind.  The author
 
9
 * shall have no liability with respect to the infringement of copyrights,
 
10
 * trade secrets or any patents by this file or any part thereof.  In no
 
11
 * event will the author be liable for any lost revenue or profits or
 
12
 * other special, indirect and consequential damages.
 
13
 *
 
14
 * Copyright 2004 Blair Tennessy
 
15
 */
 
16
 
 
17
#include <X11/Intrinsic.h>
 
18
 
 
19
#ifdef STANDALONE
 
20
#define PROGCLASS           "Providence"
 
21
#define HACK_INIT           init_providence
 
22
#define HACK_DRAW           draw_providence
 
23
#define HACK_RESHAPE        reshape_providence
 
24
#define HACK_HANDLE_EVENT   providence_handle_event
 
25
#define EVENT_MASK          PointerMotionMask
 
26
#define providence_opts     xlockmore_opts
 
27
#define DEFAULTS            "*delay:   20000   \n" \
 
28
                            "*showFPS: False   \n" \
 
29
                            "*wireframe: False \n"
 
30
 
 
31
#include "xlockmore.h"
 
32
#else
 
33
#include "xlock.h"
 
34
#endif
 
35
 
 
36
#include <GL/glu.h>
 
37
#include "gltrackball.h"
 
38
 
 
39
#define DEF_SOLIDPROVIDENCE  "False"
 
40
#define DEF_EYE  "True"
 
41
 
 
42
static int eye;
 
43
 
 
44
static XrmOptionDescRec opts[] = {
 
45
  {"-eye", ".providence.eye", XrmoptionNoArg, "on"},
 
46
  {"+eye", ".providence.eye", XrmoptionNoArg, "off"}
 
47
};
 
48
 
 
49
static argtype vars[] = {
 
50
  {&eye, "eye", "Eye", DEF_EYE, t_Bool}
 
51
};
 
52
 
 
53
static OptionStruct desc[] = {
 
54
  {"-/+eye", "turn on/off eye of providence"}
 
55
};
 
56
 
 
57
ModeSpecOpt providence_opts = {
 
58
  sizeof opts / sizeof opts[0], opts, 
 
59
  sizeof vars / sizeof vars[0], vars, desc
 
60
};
 
61
 
 
62
#ifdef USE_MODULES
 
63
ModStruct   providence_description = {
 
64
  "providence", "init_providence", "draw_providence", 
 
65
  "release_providence", "draw_providence", "change_providence", 
 
66
  (char *) NULL, &providence_opts, 1000, 1, 1, 1, 4, 1.0, "",
 
67
  "draws pyramid with glory", 0, NULL
 
68
};
 
69
#endif
 
70
 
 
71
#define Scale4Window               0.3
 
72
#define Scale4Iconic               0.4
 
73
 
 
74
#define sqr(A)                     ((A)*(A))
 
75
 
 
76
#ifndef Pi
 
77
#define Pi M_PI
 
78
#endif
 
79
 
 
80
int mono = 0, wire = 0;
 
81
double camera_velocity = 0.0;
 
82
double camera_z = -8.0;
 
83
int camera_mode = 0;
 
84
 
 
85
typedef struct {
 
86
  GLint       WindH, WindW;
 
87
  GLXContext *glx_context;
 
88
  trackball_state *trackball;
 
89
  Bool        button_down_p;
 
90
} providencestruct;
 
91
 
 
92
/* lighting variables */
 
93
GLfloat front_shininess[] = {60.0};
 
94
GLfloat front_specular[] = {0.2, 0.2, 0.2, 1.0};
 
95
GLfloat ambient[] = {0.8, 0.8, 0.8, 1.0};
 
96
GLfloat ambient2[] = {0.25, 0.25, 0.25, 1.0};
 
97
GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
 
98
GLfloat position0[] = {1.0, 5.0, 1.0, 1.0};
 
99
GLfloat position1[] = {-1.0, -5.0, 1.0, 1.0};
 
100
GLfloat lmodel_ambient[] = {0.5, 0.5, 0.5, 1.0};
 
101
GLfloat lmodel_twoside[] = {GL_TRUE};
 
102
 
 
103
/* gray-gray */
 
104
 
 
105
GLfloat MaterialGlory[] = {0.04, 0.30, 0.22, 0.7};
 
106
GLfloat MaterialGloryB[] = {0.07, 0.50, 0.36, 0.6};
 
107
 
 
108
GLfloat MaterialGloryF[] = {0.07, 0.50, 0.36, 1.0};
 
109
/* GLfloat MaterialGloryF[] = {0.06, 0.38, 0.27, 1.0}; */
 
110
GLfloat MaterialGloryE[] = {0.06, 0.38, 0.27, 0.3};
 
111
GLfloat MaterialGloryM[] = {0.5, 0.5, 0.5, 0.5};
 
112
GLfloat MaterialGloryMB[] = {0.36, 0.36, 0.36, 0.4};
 
113
GLfloat MaterialGreenback[4] = {0.04, 0.30, 0.22, 1.0};
 
114
GLfloat MaterialBlack[4] = {0.0, 0.0, 0.0, 1.0};
 
115
 
 
116
GLfloat MaterialGray5[] = {0.5, 0.5, 0.5, 1.0};
 
117
GLfloat MaterialGray6[] = {0.6, 0.6, 0.6, 1.0};
 
118
 
 
119
double currenttime;
 
120
 
 
121
static providencestruct *providence = (providencestruct *) NULL;
 
122
 
 
123
#define NUM_SCENES      2
 
124
 
 
125
/* brick texture */
 
126
#define checkImageWidth 64
 
127
#define checkImageHeight 64
 
128
GLubyte checkImage[checkImageWidth][checkImageHeight][3];
 
129
GLuint bricktexture;
 
130
 
 
131
/* build brick texture */
 
132
void make_brick(void) {
 
133
  int i, j, c;
 
134
 
 
135
  for (i = 0; i < checkImageWidth; i++) {
 
136
    for (j = 0; j < checkImageHeight; j++) {
 
137
      c = i % 16 == 15 ? 255 : (j + 48*(i / 16))%64 == 0 ? 255 : 
 
138
        102 + random() % 102;
 
139
      checkImage[i][j][0] = (GLubyte) c;
 
140
      checkImage[i][j][1] = (GLubyte) c;
 
141
      checkImage[i][j][2] = (GLubyte) c;
 
142
    }
 
143
  }
 
144
 
 
145
  glGenTextures(1, &bricktexture);
 
146
  glBindTexture(GL_TEXTURE_2D, bricktexture);
 
147
 
 
148
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 
149
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
150
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
 
151
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
 
152
  glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
 
153
               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
 
154
               &checkImage[0][0]);
 
155
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
156
}
 
157
 
 
158
/* int min */
 
159
int mini(int a, int b) { return a < b ? a : b; }
 
160
 
 
161
/* eye particles */
 
162
#define EYE_PARTICLE_COUNT 2000
 
163
int eyeparticles[EYE_PARTICLE_COUNT][2];
 
164
 
 
165
/* lookup table for the eye */
 
166
#define LOOKUPSIZE 3600
 
167
#define EYELENGTH 300
 
168
double lookup[LOOKUPSIZE][EYELENGTH][2];
 
169
double lookup2[LOOKUPSIZE][EYELENGTH][2];
 
170
 
 
171
/* build eye lookup table */
 
172
void build_eye(void) {
 
173
  int i, j;
 
174
  double x;
 
175
  double inc = 0.1 / EYELENGTH;
 
176
  double inc2 = 2.4*Pi / EYELENGTH;
 
177
 
 
178
  /* describe all values tangentially out from pupil */
 
179
  for(i = 0; i < LOOKUPSIZE; ++i) {
 
180
    double r = i * 2*Pi / LOOKUPSIZE;/*x + inc;*/
 
181
    double sr = sin(r);
 
182
    double cr = cos(r);
 
183
    x = 0.07;
 
184
 
 
185
    for(j = 0; j < EYELENGTH; ++j) {
 
186
      lookup[i][j][0] = x*sr;
 
187
      lookup[i][j][1] = x*cr;
 
188
      x += inc;
 
189
    }
 
190
  }
 
191
 
 
192
  /* lookup2: dollar sign */
 
193
  for(i = 0; i < LOOKUPSIZE; ++i) {
 
194
    double y = -1.2*Pi;
 
195
    
 
196
    for(j = 0; j < EYELENGTH; ++j) {
 
197
      if(i % 2) {
 
198
        lookup2[i][j][0] = sin(y)/6.0 + i/36000.0 - 0.05;
 
199
        lookup2[i][j][1] = i%4 ? y/12.0 - 0.05 : 1.2*Pi-y/12.0 + 0.05;
 
200
      }
 
201
      else {
 
202
        lookup2[i][j][0] = i/36000.0 - 0.05;
 
203
        lookup2[i][j][1] = y/9.0 - 0.05;
 
204
      }
 
205
      y += inc2;
 
206
    }
 
207
  }
 
208
}
 
209
 
 
210
int pyramidlist;
 
211
#define EPSILON 0.0001
 
212
 
 
213
double min(double a, double b) {
 
214
  return a < b ? a : b;
 
215
}
 
216
 
 
217
double max(double a, double b) {
 
218
  return a > b ? a : b;
 
219
}
 
220
 
 
221
#define PARTICLE_COUNT 2000
 
222
double particles[PARTICLE_COUNT][5];
 
223
 
 
224
void init_particle(double particle[5]) {
 
225
  /* position along glory */
 
226
  double p = (random() % 485410) / 100000.0;
 
227
 
 
228
  /* on a plane */
 
229
  particle[2] = 0.0;
 
230
  
 
231
  if(p < 1.5) {
 
232
    particle[0] = p - 0.75;
 
233
    particle[1] = -0.75001;
 
234
  }
 
235
  else if(p < 1.5 + sqrt(45)/4.0) {
 
236
    double d = p - 1.5;
 
237
    particle[0] = 0.75 - d*cos(atan(2.0));
 
238
    particle[1] = d*sin(atan(2.0)) - 0.75;
 
239
  }
 
240
  else {
 
241
    double d = 4.8541 - p;
 
242
    particle[0] = -0.75 + d*cos(atan(2.0));
 
243
    particle[1] = d*sin(atan(2.0)) - 0.75;
 
244
  }
 
245
 
 
246
  particle[3] = currenttime;
 
247
  particle[4] = 1.25 + (random()%10)/10.0;
 
248
}
 
249
 
 
250
/* init glory particles */
 
251
void init_particles(void) {
 
252
  int i;
 
253
  for(i = 0; i < PARTICLE_COUNT; ++i) {
 
254
    init_particle(particles[i]);
 
255
 
 
256
    /* set initial time */
 
257
    particles[i][3] = currenttime - (random()%1250)/1000.0;
 
258
  }
 
259
 
 
260
  /* init eye particles */
 
261
  for(i = 0; i < EYE_PARTICLE_COUNT; ++i) {
 
262
    eyeparticles[i][0] = random()%LOOKUPSIZE;
 
263
    eyeparticles[i][1] = random()%EYELENGTH;
 
264
  }
 
265
}
 
266
 
 
267
#define FPS 50
 
268
double theta = 0.0;
 
269
 
 
270
/* ugg, should be a priority queue if next event times known */
 
271
void update_particles(void) {
 
272
  int i;
 
273
 
 
274
  for(i = 0; i < PARTICLE_COUNT; ++i) {
 
275
    /* check for time elapse */
 
276
    if(currenttime > particles[i][3] + particles[i][4])
 
277
      init_particle(particles[i]);
 
278
  }
 
279
 
 
280
  /* now update eye particles */
 
281
  for(i = 0; i < EYE_PARTICLE_COUNT; ++i) {
 
282
/*     int x = eyeparticles[i][1] + random()%16; */
 
283
    int x = eyeparticles[i][1] + random()%(cos(theta) < 0.0 ? 8 : 16);
 
284
 
 
285
    /* reset if dead */
 
286
    if(x > EYELENGTH || random()%(cos(theta) < 0.0 ? 40 : 10) == 0) {
 
287
 
 
288
/*     if(x > EYELENGTH || (x > EYELENGTH/(2/3.0) && random()%7 == 0)) { */
 
289
      eyeparticles[i][0] = random()%LOOKUPSIZE;
 
290
      eyeparticles[i][1] = random()%40;
 
291
    }
 
292
    else {
 
293
      eyeparticles[i][1] = x;
 
294
    }    
 
295
  }
 
296
}
 
297
 
 
298
/* draw the pyramid */
 
299
void draw_seal(void) {
 
300
  int i;
 
301
  double base = sqrt(2.0);
 
302
  double top = 1.0 / sqrt(2.0);
 
303
  double tmod = 7.0/6.0;
 
304
 
 
305
  glPushMatrix();
 
306
 
 
307
  /* set options for mono, wireframe */
 
308
  if(wire) {
 
309
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
310
    glDisable(GL_LIGHTING);
 
311
    glDisable(GL_TEXTURE_2D);
 
312
  }
 
313
  else {
 
314
    glEnable(GL_TEXTURE_2D);
 
315
    glBindTexture(GL_TEXTURE_2D, bricktexture);
 
316
 
 
317
    glEnable(GL_LIGHTING);
 
318
 
 
319
    glColor4fv(mono ? MaterialGray5 : MaterialGloryF);
 
320
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
321
                 mono ? MaterialGray5 : MaterialGloryF);
 
322
  }
 
323
 
 
324
  glRotatef(45.0, 0.0, 1.0, 0.0);
 
325
  glTranslatef(0.0, -3.25, 0.0);
 
326
 
 
327
  for(i = 0; i < 4; ++i) {
 
328
    glRotatef(i*90.0, 0.0, 1.0, 0.0);
 
329
 
 
330
    glBegin(GL_QUADS);
 
331
    glNormal3f(1 / sqrt(6.0), 2 / sqrt(6.0), 1 / sqrt(6.0));
 
332
    glTexCoord2f(-base, 0.0);
 
333
    glVertex3f(-base, 0.0, base);
 
334
    glTexCoord2f(base, 0.0);
 
335
    glVertex3f(base, 0.0, base);
 
336
    glTexCoord2f(top, 13.0/4.0);
 
337
    glVertex3f(top, 2.0, top);
 
338
    glTexCoord2f(-top, 13.0/4.0);
 
339
    glVertex3f(-top, 2.0, top);
 
340
    glEnd();
 
341
  }
 
342
 
 
343
  glBegin(GL_QUADS);
 
344
 
 
345
  /* top */
 
346
  glNormal3f(0.0, 1.0, 0.0);
 
347
  glTexCoord2f(0.02, 0.0);
 
348
  glVertex3f(-top, 2.0, top);
 
349
  glTexCoord2f(2.0*top, 0.0);
 
350
  glVertex3f(top, 2.0, top);
 
351
  glTexCoord2f(2.0*top, tmod*2.1*top);
 
352
  glVertex3f(top, 2.0, -top);
 
353
  glTexCoord2f(0.02, tmod*2.1*top);
 
354
  glVertex3f(-top, 2.0, -top);
 
355
 
 
356
  /* base */
 
357
  glNormal3f(0.0, -1.0, 0.0);
 
358
  glTexCoord2f(-base, 0.0);
 
359
  glVertex3f(-base, 0.0, -base);
 
360
  glTexCoord2f(top, 0.0);
 
361
  glVertex3f(base, 0.0, -base);
 
362
  glTexCoord2f(top, top*13.0/4.0);
 
363
  glVertex3f(base, 0.0, base);
 
364
  glTexCoord2f(-top, top*13.0/4.0);
 
365
  glVertex3f(-base, 0.0, base);
 
366
 
 
367
  glEnd();
 
368
 
 
369
  glPopMatrix();
 
370
  glDisable(GL_TEXTURE_2D);
 
371
}
 
372
 
 
373
/* draw glory */
 
374
void draw_glory(void) {
 
375
  int i;
 
376
 
 
377
  if(wire) {
 
378
    glBegin(GL_TRIANGLES);
 
379
    glVertex3f(-0.75, -0.75, 0.0);
 
380
    glVertex3f(0.75, -0.75, 0.0);
 
381
    glVertex3f(0.0, 0.75, 0.0);
 
382
    glEnd();
 
383
    return;
 
384
  }
 
385
 
 
386
  /* draw particles */
 
387
  glDisable(GL_LIGHTING);
 
388
  glPushMatrix();
 
389
  glEnable(GL_BLEND);
 
390
 
 
391
  /* glory colour lines */
 
392
  glColor4fv(mono ? MaterialGloryM : MaterialGlory);
 
393
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
394
               mono ? MaterialGloryM : MaterialGlory);
 
395
 
 
396
  glBegin(GL_LINES);
 
397
  for(i = 0; i < PARTICLE_COUNT/2; ++i) {
 
398
    double t = currenttime - particles[i][3];
 
399
    double th = atan(particles[i][1] / particles[i][0]);
 
400
    if(particles[i][0] < 0.0)
 
401
      th += Pi;
 
402
 
 
403
    glVertex3f(particles[i][0], particles[i][1], particles[i][2]);
 
404
    glVertex3f(particles[i][0] + 0.2*cos(th)*t,
 
405
               particles[i][1] + 0.2*sin(th)*t,
 
406
               particles[i][2]);
 
407
  }
 
408
  glEnd();
 
409
  
 
410
  /* gloryb colour lines */
 
411
  glColor4fv(mono ? MaterialGloryMB : MaterialGloryB);
 
412
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
413
               mono ? MaterialGloryMB : MaterialGloryB);
 
414
  glBegin(GL_LINES);
 
415
  for(; i < PARTICLE_COUNT; ++i) {
 
416
    double t = currenttime - particles[i][3];
 
417
    double th = atan(particles[i][1] / particles[i][0]);
 
418
    if(particles[i][0] < 0.0)
 
419
      th += Pi;
 
420
 
 
421
    glVertex3f(particles[i][0], particles[i][1], particles[i][2]);
 
422
    glVertex3f(particles[i][0] + 0.2*cos(th)*t,
 
423
               particles[i][1] + 0.2*sin(th)*t,
 
424
               particles[i][2]);
 
425
  }
 
426
  glEnd();
 
427
 
 
428
  glPopMatrix();
 
429
  glEnable(GL_LIGHTING);
 
430
}
 
431
 
 
432
/* draw eye of providence */
 
433
void draw_eye(void) {
 
434
  int i;
 
435
 
 
436
  /* draw wireeye */
 
437
  if(wire) {
 
438
    glBegin(GL_TRIANGLES);
 
439
    glVertex3f(-0.25, -0.25, 0.0);
 
440
    glVertex3f(0.25, -0.25, 0.0);
 
441
    glVertex3f(0.0, 0.25, 0.0);
 
442
    glEnd();
 
443
    return;
 
444
  }
 
445
 
 
446
  /* draw particles */
 
447
  glDisable(GL_LIGHTING);
 
448
  glPushMatrix();
 
449
  glEnable(GL_BLEND);
 
450
 
 
451
  /* eye */
 
452
  glColor4fv(mono ? MaterialGloryM : MaterialGlory);
 
453
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
454
               mono ? MaterialGloryM : MaterialGlory);
 
455
 
 
456
  /* draw eye particles on z = 0 plane */
 
457
  glBegin(GL_POINTS);
 
458
  for(i = 0; i < EYE_PARTICLE_COUNT/2; ++i) {
 
459
    glVertex3f(lookup[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
460
               lookup[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
461
               0.0);
 
462
  }
 
463
  glEnd();
 
464
 
 
465
  /* eye */
 
466
  glColor4fv(mono ? MaterialGloryMB : MaterialGloryB);
 
467
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
468
               mono ? MaterialGloryMB : MaterialGloryB);
 
469
 
 
470
  /* draw eye particles on z = 0 plane */
 
471
  glBegin(GL_POINTS);
 
472
  for(; i < EYE_PARTICLE_COUNT; ++i) {
 
473
    glVertex3f(lookup[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
474
               lookup[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
475
               0.0);
 
476
  }
 
477
  glEnd();
 
478
 
 
479
 
 
480
  /* draw scaled particles */
 
481
  glPushMatrix();
 
482
  glScalef(3.3, 2.2, 3.3);
 
483
 
 
484
  /* eye */
 
485
  glColor4fv(mono ? MaterialGloryMB : MaterialGloryB);
 
486
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
487
               mono ? MaterialGloryMB : MaterialGloryB);
 
488
 
 
489
  /* draw eye particles on z = 0 plane */
 
490
  glBegin(GL_POINTS);
 
491
  for(i = 0; i < EYE_PARTICLE_COUNT/2; ++i) {
 
492
    glVertex3f(lookup[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
493
               lookup[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
494
               0.0);
 
495
  }
 
496
  glEnd();
 
497
 
 
498
  glColor4fv(mono ? MaterialGloryM : MaterialGlory);
 
499
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
500
               mono ? MaterialGloryM : MaterialGlory);
 
501
 
 
502
  /* draw eye particles on z = 0 plane */
 
503
  glBegin(GL_POINTS);
 
504
  for(; i < EYE_PARTICLE_COUNT; ++i) {
 
505
    glVertex3f(lookup[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
506
               lookup[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
507
               0.0);
 
508
  }
 
509
  glEnd();
 
510
 
 
511
  glPopMatrix();
 
512
 
 
513
  glPopMatrix();
 
514
  glEnable(GL_LIGHTING);
 
515
}
 
516
 
 
517
/* draw eye of providence */
 
518
void draw_eye2(void) {
 
519
  int i;
 
520
 
 
521
  /* draw wireeye */
 
522
  if(wire) {
 
523
    glBegin(GL_TRIANGLES);
 
524
    glVertex3f(-0.25, -0.25, 0.0);
 
525
    glVertex3f(0.25, -0.25, 0.0);
 
526
    glVertex3f(0.0, 0.25, 0.0);
 
527
    glEnd();
 
528
    return;
 
529
  }
 
530
 
 
531
  /* draw particles */
 
532
  glDisable(GL_LIGHTING);
 
533
  glPushMatrix();
 
534
  glEnable(GL_BLEND);
 
535
 
 
536
  /* eye */
 
537
  glColor4fv(mono ? MaterialGloryM : MaterialGlory);
 
538
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
539
               mono ? MaterialGloryM : MaterialGlory);
 
540
 
 
541
  /* draw eye particles on z = 0 plane */
 
542
  glBegin(GL_POINTS);
 
543
  for(i = 0; i < EYE_PARTICLE_COUNT/2; ++i) {
 
544
    glVertex3f(lookup2[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
545
               lookup2[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
546
               0.0);
 
547
  }
 
548
  glEnd();
 
549
 
 
550
  /* eye */
 
551
  glColor4fv(mono ? MaterialGloryMB : MaterialGloryB);
 
552
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
 
553
               mono ? MaterialGloryMB : MaterialGloryB);
 
554
 
 
555
  /* draw eye particles on z = 0 plane */
 
556
  glBegin(GL_POINTS);
 
557
  for(; i < EYE_PARTICLE_COUNT; ++i) {
 
558
    glVertex3f(lookup2[eyeparticles[i][0]][eyeparticles[i][1]][0], 
 
559
               lookup2[eyeparticles[i][0]][eyeparticles[i][1]][1],
 
560
               0.0);
 
561
  }
 
562
  glEnd();
 
563
 
 
564
  glPopMatrix();
 
565
  glEnable(GL_LIGHTING);
 
566
}
 
567
 
 
568
/* draw the scene */
 
569
void draw_providence_strip(ModeInfo *mi) {
 
570
  glTranslatef(0.0, 1.414, 0.0);
 
571
 
 
572
  position0[0] = 1.6*sin(theta);
 
573
  position0[1] = 1.2;
 
574
  position0[2] = 1.6*cos(theta);
 
575
  position0[3] = 0.0;
 
576
  glLightfv(GL_LIGHT0, GL_POSITION, position0);
 
577
  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient2);
 
578
  glEnable(GL_LIGHTING);
 
579
  glEnable(GL_LIGHT0);
 
580
 
 
581
  /* draw pyramid, glory */
 
582
  glDisable(GL_BLEND);
 
583
  glCallList(pyramidlist);
 
584
  draw_glory();
 
585
  if(eye) {
 
586
    if(cos(theta) < 0.0)
 
587
      draw_eye2();
 
588
    else
 
589
      draw_eye();
 
590
  }
 
591
 
 
592
  return;
 
593
}
 
594
 
 
595
void reshape_providence(ModeInfo * mi, int width, int height) {
 
596
  double h = (GLfloat) height / (GLfloat) width;  
 
597
  providencestruct *mp = &providence[MI_SCREEN(mi)];
 
598
 
 
599
  glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
 
600
  glMatrixMode(GL_PROJECTION);
 
601
  glLoadIdentity();
 
602
 
 
603
  gluPerspective(45, 1/h, 0.001, 25.0);
 
604
 
 
605
  glMatrixMode(GL_MODELVIEW);
 
606
  glLineWidth(2.0);
 
607
  glPointSize(2.0);
 
608
}
 
609
 
 
610
static void pinit(void) {
 
611
  glClearDepth(1.0);
 
612
  glClearColor(0.0, 0.0, 0.0, 1.0);
 
613
  
 
614
  /* setup twoside lighting */
 
615
  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient2);
 
616
  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
 
617
  glLightfv(GL_LIGHT0, GL_POSITION, position0);
 
618
 
 
619
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
 
620
  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
 
621
  glEnable(GL_LIGHTING);
 
622
  glEnable(GL_LIGHT0);
 
623
 
 
624
  currenttime = 0.0;
 
625
  init_particles();
 
626
  make_brick();
 
627
  build_eye();
 
628
 
 
629
  glEnable(GL_NORMALIZE);
 
630
  glFrontFace(GL_CCW);
 
631
/*   glDisable(GL_CULL_FACE); */
 
632
  glEnable(GL_CULL_FACE);
 
633
  glCullFace(GL_BACK);
 
634
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
635
 
 
636
  glShadeModel(GL_SMOOTH);
 
637
  glEnable(GL_DEPTH_TEST);
 
638
  glDepthFunc(GL_LEQUAL);
 
639
 
 
640
  /* build pyramid list */
 
641
  pyramidlist = glGenLists(1);
 
642
  glNewList(pyramidlist, GL_COMPILE);
 
643
  draw_seal();
 
644
  glEndList();
 
645
}
 
646
 
 
647
/* cleanup routine */
 
648
void release_providence(ModeInfo * mi) {
 
649
 
 
650
  if(providence) {
 
651
    free((void *) providence);
 
652
    providence = (providencestruct *) NULL;
 
653
  }
 
654
 
 
655
  FreeAllGL(mi);
 
656
}
 
657
 
 
658
/* event handling */
 
659
Bool providence_handle_event(ModeInfo *mi, XEvent *event) {
 
660
  providencestruct *mp = &providence[MI_SCREEN(mi)];
 
661
 
 
662
  switch(event->xany.type) {
 
663
  case ButtonPress:
 
664
 
 
665
    switch(event->xbutton.button) {
 
666
 
 
667
    case Button1:
 
668
      mp->button_down_p = True;
 
669
      gltrackball_start(mp->trackball, 
 
670
                        event->xbutton.x, event->xbutton.y,
 
671
                        MI_WIDTH (mi), MI_HEIGHT (mi));
 
672
      break;
 
673
      
 
674
    case Button4:
 
675
      camera_velocity += 1.0;
 
676
      break;
 
677
 
 
678
    case Button5:
 
679
      camera_velocity -= 1.0;
 
680
      break;
 
681
    }
 
682
 
 
683
    break;
 
684
    
 
685
  case ButtonRelease:
 
686
 
 
687
    switch(event->xbutton.button) {
 
688
    case Button1:
 
689
      mp->button_down_p = False;
 
690
      break;
 
691
    }
 
692
 
 
693
    break;
 
694
 
 
695
  case MotionNotify:
 
696
    if(mp->button_down_p)
 
697
      gltrackball_track(mp->trackball,
 
698
                        event->xmotion.x, event->xmotion.y,
 
699
                        MI_WIDTH (mi), MI_HEIGHT (mi));
 
700
    break;
 
701
    
 
702
  default:
 
703
    return False;
 
704
  }
 
705
 
 
706
  return True;
 
707
}
 
708
 
 
709
void init_providence(ModeInfo *mi) {
 
710
  providencestruct *mp;
 
711
  
 
712
  if(!providence) {
 
713
    if((providence = (providencestruct *) 
 
714
        calloc(MI_NUM_SCREENS(mi), sizeof (providencestruct))) == NULL)
 
715
      return;
 
716
  }
 
717
  mp = &providence[MI_SCREEN(mi)];
 
718
  mp->trackball = gltrackball_init ();
 
719
 
 
720
  mono = MI_IS_MONO(mi);
 
721
  wire = MI_IS_WIREFRAME(mi);
 
722
 
 
723
  if((mp->glx_context = init_GL(mi)) != NULL) {
 
724
    reshape_providence(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
 
725
    glDrawBuffer(GL_BACK);
 
726
    pinit();
 
727
  }
 
728
  else
 
729
    MI_CLEARWINDOW(mi);
 
730
}
 
731
 
 
732
void draw_providence(ModeInfo * mi) {
 
733
  providencestruct *mp;
 
734
  
 
735
  Display    *display = MI_DISPLAY(mi);
 
736
  Window      window = MI_WINDOW(mi);
 
737
  
 
738
  if(!providence)
 
739
    return;
 
740
  mp = &providence[MI_SCREEN(mi)];
 
741
  
 
742
  MI_IS_DRAWN(mi) = True;
 
743
  
 
744
  if(!mp->glx_context)
 
745
    return;
 
746
  
 
747
  glXMakeCurrent(display, window, *(mp->glx_context));
 
748
  
 
749
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
750
 
 
751
  glPushMatrix();
 
752
 
 
753
  /* modify camera */
 
754
  if(fabs(camera_velocity) > EPSILON) {
 
755
    camera_z = max(min(camera_z + 0.1*camera_velocity, -4.0), -12.0);
 
756
    camera_velocity = 0.95*camera_velocity;
 
757
  }
 
758
  
 
759
  /* rotate providence */
 
760
  glTranslatef(0.0, 0.0, camera_z + sin(theta/4.0));
 
761
  glRotatef(10.0+20.0*sin(theta/2.0), 1.0, 0.0, 0.0);
 
762
  gltrackball_rotate(mp->trackball);
 
763
  glRotatef(theta * 180.0 / Pi, 0.0, -1.0, 0.0);
 
764
 
 
765
  /* draw providence */
 
766
  draw_providence_strip(mi);
 
767
  glPopMatrix();
 
768
  
 
769
  if(MI_IS_FPS(mi)) do_fps (mi);
 
770
  glFlush();
 
771
  
 
772
  glXSwapBuffers(display, window);
 
773
 
 
774
  /* update */
 
775
  currenttime += 1.0 / FPS;
 
776
  theta = currenttime / 2.0;
 
777
  update_particles();
 
778
}
 
779
 
 
780
void change_providence(ModeInfo * mi) {
 
781
  providencestruct *mp = &providence[MI_SCREEN(mi)];
 
782
  
 
783
  if (!mp->glx_context)
 
784
        return;
 
785
  
 
786
  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
 
787
  pinit();
 
788
}