~ubuntu-branches/ubuntu/lucid/xscreensaver/lucid

« back to all changes in this revision

Viewing changes to hacks/glx/blocktube.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2007-12-06 09:53:12 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206095312-fkzcwe4vqm50z208
Tags: 5.04-1ubuntu1
* Merge from debian unstable, remaining changes:
  - split xscreensaver into xscreensaver, xscreensaver-data (hacks we ship),
    xscreensaver-data-extra (hacks in universe). split out gl hacks for
    universe to xscreensaver-gl-extra
  - use fridge for rss screensavers
  - create and install .desktop files for gnome-screensaver

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 * implied warranty.
12
12
 */
13
13
 
14
 
#include <X11/Intrinsic.h>
15
 
 
16
14
#define DEBUG 1
17
15
 
18
 
extern XtAppContext app;
19
 
 
20
 
#define PROGCLASS       "Blocktube"
21
 
#define HACK_INIT       init_blocktube
22
 
#define HACK_DRAW       draw_blocktube
23
 
#define HACK_RESHAPE    reshape_blocktube
24
 
#define EVENT_MASK      PointerMotionMask
25
 
#define blocktube_opts  xlockmore_opts
26
 
 
27
 
#define DEF_HOLDTIME    "1000"
28
 
#define DEF_CHANGETIME  "200"
29
 
#define MAX_ENTITIES     1000
30
 
#define DEF_TEXTURE     "True"
31
 
#define DEF_FOG         "True"
32
 
 
33
16
#define DEFAULTS        "*delay:        40000           \n" \
34
17
                        "*wireframe:    False           \n" \
35
18
                        "*showFPS:      False           \n" \
36
19
 
 
20
# define refresh_blocktube 0
 
21
# define blocktube_handle_event 0
37
22
#undef countof
38
23
#define countof(x) (sizeof((x))/sizeof((*x)))
39
24
 
44
29
 
45
30
#ifdef USE_GL /* whole file */
46
31
 
47
 
#include <GL/glu.h>
 
32
#define DEF_HOLDTIME    "1000"
 
33
#define DEF_CHANGETIME  "200"
 
34
#define MAX_ENTITIES     1000
 
35
#define DEF_TEXTURE     "True"
 
36
#define DEF_FOG         "True"
48
37
 
49
 
#if defined(USE_XPM) || defined(USE_XPMINC) || defined(HAVE_XPM) || defined (HAVE_GDK_PIXBUF)
 
38
#if defined(USE_XPM) || defined(USE_XPMINC) || defined(STANDALONE)
50
39
/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */
51
40
#include "xpm-ximage.h"
52
41
#define I_HAVE_XPM
55
44
#endif /* HAVE_XPM */
56
45
 
57
46
typedef struct {
58
 
    GLXContext *glx_context;
59
 
    GLuint  block_dlist;
60
 
} blocktube_configuration;
61
 
 
62
 
static int nextID = 1;
63
 
static blocktube_configuration *lps = NULL;
64
 
 
65
 
typedef struct {
66
47
    int id, r, g, b;
67
48
    GLfloat tVal;
68
49
    int age;
72
53
    GLfloat angularVelocity;
73
54
} entity;
74
55
 
75
 
static entity entities[MAX_ENTITIES];
76
 
static float targetR, targetG, targetB,
77
 
             currentR, currentG, currentB,
78
 
             deltaR, deltaG, deltaB;
 
56
typedef struct {
 
57
  GLXContext *glx_context;
 
58
  GLuint  block_dlist;
 
59
  int nextID;
 
60
 
 
61
  entity entities[MAX_ENTITIES];
 
62
  float targetR, targetG, targetB,
 
63
    currentR, currentG, currentB,
 
64
    deltaR, deltaG, deltaB;
 
65
  int counter;
 
66
  int changing;
 
67
  GLfloat zoom;
 
68
  GLfloat tilt;
 
69
  GLuint envTexture;
 
70
  XImage *texti;
 
71
 
 
72
  GLfloat tunnelLength;
 
73
  GLfloat tunnelWidth;
 
74
 
 
75
} blocktube_configuration;
 
76
 
 
77
static blocktube_configuration *lps = NULL;
 
78
 
79
79
static GLint holdtime;
80
80
static GLint changetime;
81
 
static int counter = 0;
82
 
static int changing = 0;
83
 
static GLfloat zoom = 30.0f;
84
 
static GLfloat tilt = 4.5f;
85
 
static GLuint loop;
86
 
static GLuint envTexture;
87
 
static XImage *texti;
88
81
static int do_texture;
89
82
static int do_fog;
90
83
 
91
 
GLfloat tunnelLength=200;
92
 
GLfloat tunnelWidth=5;
93
 
 
94
84
static XrmOptionDescRec opts[] = {
95
85
    { "-holdtime",  ".holdtime",  XrmoptionSepArg, 0 },
96
86
    { "-changetime",  ".changetime",  XrmoptionSepArg, 0 },
113
103
    {"-changetime", "how long it takes to fade to a new color"},
114
104
};
115
105
 
116
 
ModeSpecOpt blocktube_opts = {countof(opts), opts, countof(vars), vars, desc};
 
106
ENTRYPOINT ModeSpecOpt blocktube_opts = {countof(opts), opts, countof(vars), vars, desc};
117
107
 
118
108
#ifdef USE_MODULES
119
109
ModStruct blocktube_description =
126
116
#if defined( I_HAVE_XPM )
127
117
static Bool LoadGLTextures(ModeInfo *mi)
128
118
{
 
119
    blocktube_configuration *lp = &lps[MI_SCREEN(mi)];
129
120
    Bool status;
130
121
 
131
122
    status = True;
132
 
    glGenTextures(1, &envTexture);
133
 
    glBindTexture(GL_TEXTURE_2D, envTexture);
134
 
    texti = xpm_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), MI_COLORMAP(mi),
 
123
    glGenTextures(1, &lp->envTexture);
 
124
    glBindTexture(GL_TEXTURE_2D, lp->envTexture);
 
125
    lp->texti = xpm_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), MI_COLORMAP(mi),
135
126
                          blocktube_xpm);
136
 
    if (!texti) {
 
127
    if (!lp->texti) {
137
128
        status = False;
138
129
    } else {
139
130
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
140
 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texti->width, texti->height, 0,
141
 
            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, texti->data);
 
131
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lp->texti->width, lp->texti->height, 0,
 
132
            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, lp->texti->data);
142
133
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
143
134
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
144
135
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
148
139
}
149
140
#endif
150
141
 
151
 
static void newTargetColor(void)
 
142
static void newTargetColor(blocktube_configuration *lp)
152
143
{
153
144
    int luminance = 0;
154
145
 
155
146
    while (luminance <= 150) {
156
 
        targetR = random() % 256;
157
 
        targetG = random() % 256;
158
 
        targetB = random() % 256;
159
 
        deltaR = (targetR - currentR) / changetime;
160
 
        deltaG = (targetG - currentG) / changetime;
161
 
        deltaB = (targetB - currentB) / changetime;
162
 
        luminance = 0.3 * targetR + 0.59 * targetG + 0.11 * targetB;
 
147
        lp->targetR = random() % 256;
 
148
        lp->targetG = random() % 256;
 
149
        lp->targetB = random() % 256;
 
150
        lp->deltaR = (lp->targetR - lp->currentR) / changetime;
 
151
        lp->deltaG = (lp->targetG - lp->currentG) / changetime;
 
152
        lp->deltaB = (lp->targetB - lp->currentB) / changetime;
 
153
        luminance = 0.3 * lp->targetR + 0.59 * lp->targetG + 0.11 * lp->targetB;
163
154
    }
164
155
}
165
156
 
166
 
static void randomize_entity (entity *ent)
 
157
static void randomize_entity (blocktube_configuration *lp, entity *ent)
167
158
{
168
 
    ent->id = nextID++;
 
159
    ent->id = lp->nextID++;
169
160
    ent->tVal = 1 - ((float)random() / RAND_MAX / 1.5);
170
161
    ent->age = 0;
171
162
    ent->lifetime = 100;
172
163
    ent->angle = random() % 360;
173
164
    ent->angularVelocity = 0.5-((float)(random()) / RAND_MAX);
174
 
    ent->position[0] = (float)(random()) / RAND_MAX + tunnelWidth;
 
165
    ent->position[0] = (float)(random()) / RAND_MAX + lp->tunnelWidth;
175
166
    ent->position[1] = (float)(random()) / RAND_MAX * 2;
176
 
    ent->position[2] = -(float)(random()) / RAND_MAX * tunnelLength;
 
167
    ent->position[2] = -(float)(random()) / RAND_MAX * lp->tunnelLength;
177
168
}
178
169
 
179
 
static void entityTick(entity *ent)
 
170
static void entityTick(blocktube_configuration *lp, entity *ent)
180
171
{
181
172
    ent->angle += ent->angularVelocity;
182
173
    ent->position[2] += 0.1;
183
 
    if (ent->position[2] > zoom) {
184
 
        ent->position[2] = -tunnelLength + ((float)(random()) / RAND_MAX) * 20;
 
174
    if (ent->position[2] > lp->zoom) {
 
175
        ent->position[2] = -lp->tunnelLength + ((float)(random()) / RAND_MAX) * 20;
185
176
    }
186
177
    ent->age += 0.1;
187
178
}
188
179
 
189
 
static void tick(void)
 
180
static void tick(blocktube_configuration *lp)
190
181
{
191
 
    counter--;
192
 
    if (!counter) {
193
 
        if (!changing) {
194
 
            newTargetColor();
195
 
            counter = changetime;
 
182
    lp->counter--;
 
183
    if (!lp->counter) {
 
184
        if (!lp->changing) {
 
185
            newTargetColor(lp);
 
186
            lp->counter = changetime;
196
187
        } else {
197
 
            counter = holdtime;
 
188
            lp->counter = holdtime;
198
189
        }
199
 
        changing = (!changing);
 
190
        lp->changing = (!lp->changing);
200
191
    } else {
201
 
        if (changing) {
202
 
            currentR += deltaR;
203
 
            currentG += deltaG;
204
 
            currentB += deltaB;
 
192
        if (lp->changing) {
 
193
            lp->currentR += lp->deltaR;
 
194
            lp->currentG += lp->deltaG;
 
195
            lp->currentB += lp->deltaB;
205
196
        }
206
197
    }
207
198
}
208
199
 
209
200
static void cube_vertices(float x, float y, float z, int wire);
210
201
 
211
 
void init_blocktube (ModeInfo *mi)
 
202
ENTRYPOINT void reshape_blocktube (ModeInfo *mi, int width, int height);
 
203
 
 
204
ENTRYPOINT void init_blocktube (ModeInfo *mi)
212
205
{
 
206
    int loop;
213
207
    GLfloat fogColor[4] = {0,0,0,1};
214
208
    blocktube_configuration *lp;
215
209
    int wire = MI_IS_WIREFRAME(mi);
227
221
    lp = &lps[MI_SCREEN(mi)];
228
222
    lp->glx_context = init_GL(mi);
229
223
 
 
224
    lp->zoom = 30;
 
225
    lp->tilt = 4.5;
 
226
    lp->tunnelLength = 200;
 
227
    lp->tunnelWidth = 5;
 
228
 
230
229
    if (wire) {
231
230
      do_fog = False;
232
231
      do_texture = False;
254
253
      glFogi(GL_FOG_MODE, GL_LINEAR);
255
254
      glHint(GL_FOG_HINT, GL_NICEST);
256
255
      glFogf(GL_FOG_START, 0);
257
 
      glFogf(GL_FOG_END, tunnelLength/1.8);
 
256
      glFogf(GL_FOG_END, lp->tunnelLength/1.8);
258
257
      glFogfv(GL_FOG_COLOR, fogColor);
259
258
      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
260
259
    }
280
279
      glEnable(GL_LIGHT0);
281
280
    }
282
281
 
283
 
    counter = holdtime;
284
 
    currentR = random() % 256;
285
 
    currentG = random() % 256;
286
 
    currentB = random() % 256;
287
 
    newTargetColor();
 
282
    lp->counter = holdtime;
 
283
    lp->currentR = random() % 256;
 
284
    lp->currentG = random() % 256;
 
285
    lp->currentB = random() % 256;
 
286
    newTargetColor(lp);
288
287
    for (loop = 0; loop < MAX_ENTITIES; loop++)
289
288
    {
290
 
        randomize_entity(&entities[loop]);
 
289
        randomize_entity(lp, &lp->entities[loop]);
291
290
    }
292
291
    reshape_blocktube(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
293
292
    glFlush();
294
293
}
295
294
 
296
 
void release_blocktube (ModeInfo *mi)
 
295
ENTRYPOINT void release_blocktube (ModeInfo *mi)
297
296
{
298
 
#if defined ( I_HAVE_XPM )
299
 
    glDeleteTextures(1, &envTexture);
300
 
    XDestroyImage(texti);
301
 
#endif
 
297
  if (lps) {
 
298
    int screen;
 
299
    for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
 
300
      blocktube_configuration *lp = &lps[screen];
 
301
# if defined ( I_HAVE_XPM )
 
302
      if (lp->envTexture)
 
303
        glDeleteTextures(1, &lp->envTexture);
 
304
      if (lp->texti)
 
305
        XDestroyImage(lp->texti);
 
306
# endif
 
307
    }
 
308
    free (lps);
 
309
    lps = 0;
 
310
  }
 
311
  FreeAllGL(mi);
302
312
}
303
313
 
304
 
void reshape_blocktube (ModeInfo *mi, int width, int height)
 
314
ENTRYPOINT void reshape_blocktube (ModeInfo *mi, int width, int height)
305
315
{
306
316
    GLfloat h = (GLfloat) height / (GLfloat) width;
307
317
 
378
388
    glCallList (lp->block_dlist);
379
389
}
380
390
 
381
 
void
 
391
ENTRYPOINT void
382
392
draw_blocktube (ModeInfo *mi)
383
393
{
384
394
    blocktube_configuration *lp = &lps[MI_SCREEN(mi)];
390
400
    if (!lp->glx_context)
391
401
      return;
392
402
 
 
403
    glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(lp->glx_context));
 
404
 
393
405
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
394
406
 
395
407
    if (do_texture) {
396
408
      glEnable(GL_TEXTURE_GEN_S);
397
409
      glEnable(GL_TEXTURE_GEN_T);
398
 
      glBindTexture(GL_TEXTURE_2D, envTexture);
 
410
      glBindTexture(GL_TEXTURE_2D, lp->envTexture);
399
411
    }
400
412
 
401
413
    for (loop = 0; loop < MAX_ENTITIES; loop++) {
402
 
        cEnt = &entities[loop];
 
414
        cEnt = &lp->entities[loop];
403
415
 
404
416
        glLoadIdentity();
405
 
        glTranslatef(0.0f, 0.0f, zoom);
406
 
        glRotatef(tilt, 1.0f, 0.0f, 0.0f);
 
417
        glTranslatef(0.0f, 0.0f, lp->zoom);
 
418
        glRotatef(lp->tilt, 1.0f, 0.0f, 0.0f);
407
419
        glRotatef(cEnt->angle, 0.0f, 0.0f, 1.0f);
408
420
        glTranslatef(cEnt->position[0], cEnt->position[1], cEnt->position[2]);
409
 
        glColor4ub((int)(currentR * cEnt->tVal),
410
 
                   (int)(currentG * cEnt->tVal),
411
 
                   (int)(currentB * cEnt->tVal), 255);
 
421
        glColor4ub((int)(lp->currentR * cEnt->tVal),
 
422
                   (int)(lp->currentG * cEnt->tVal),
 
423
                   (int)(lp->currentB * cEnt->tVal), 255);
412
424
        draw_block(mi, cEnt);
413
 
        entityTick(cEnt);
 
425
        entityTick(lp, cEnt);
414
426
    }
415
 
    tick();
 
427
    tick(lp);
416
428
 
417
429
    if (mi->fps_p) do_fps (mi);
418
430
    glFinish();
419
431
    glXSwapBuffers(dpy, window);
420
432
}
421
433
 
 
434
XSCREENSAVER_MODULE ("BlockTube", blocktube)
 
435
 
422
436
#endif /* USE_GL */