1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* atunnels --- OpenGL Advanced Tunnel Screensaver */
5 static const char sccsid[] = "@(#)atunnels.c 5.07 2003/02/12 xlockmore";
8 /* Copyright (c) E. Lassauge, 2003. */
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.
23 * The original code for this mode was written by Roman Podobedov
25 * WEB: http://romka.demonews.com
27 * Eric Lassauge (March-16-2002) <lassauge@mail.dotcom.fr>
28 * http://lassauge.free.fr/linux.html
32 * E.Lassauge - 16-Mar-2002:
33 * - created based on the Roman demo.
34 * - deleted all external file stuff to use xpm textures and
35 * hardcoded path point values.
39 #ifdef STANDALONE /* xscreensaver mode */
40 # define PROGCLASS "Atunnels"
41 # define HACK_INIT init_atunnels
42 # define HACK_DRAW draw_atunnels
43 # define HACK_RESHAPE reshape_atunnels
44 # define atunnels_opts xlockmore_opts
45 #define DEFAULTS "*delay: 10000 \n" \
46 "*showFPS: False \n" \
52 # include "xlockmore.h" /* from the xscreensaver distribution */
53 #else /* !STANDALONE */
54 # include "xlock.h" /* from the xlockmore distribution */
55 #endif /* !STANDALONE */
57 #ifdef MODE_atunnels /* whole file */
62 #include "tunnel_draw.h"
64 #if defined( USE_XPM ) || defined( USE_XPMINC ) || defined(STANDALONE)
65 /* USE_XPM & USE_XPMINC in xlock mode ; STANDALONE in xscreensaver mode */
66 #include "xpm-ximage.h"
70 #include "../images/tunnel0.xpm"
71 #include "../images/tunnel1.xpm"
72 #include "../images/tunnel2.xpm"
73 #else /* !STANDALONE */
74 #include "pixmaps/tunnel0.xpm"
75 #include "pixmaps/tunnel1.xpm"
76 #include "pixmaps/tunnel2.xpm"
77 #endif /* !STANDALONE */
81 #define countof(x) (sizeof((x))/sizeof((*x)))
83 #define DEF_LIGHT "True"
84 #define DEF_WIRE "False"
85 #define DEF_TEXTURE "True"
89 static Bool do_texture;
91 static XrmOptionDescRec opts[] = {
92 {(char *)"-light", (char *)".atunnels.light", XrmoptionNoArg, (caddr_t) "true" },
93 {(char *)"+light", (char *)".atunnels.light", XrmoptionNoArg, (caddr_t) "false" },
94 {(char *)"-wire", (char *)".atunnels.wire", XrmoptionNoArg, (caddr_t) "true" },
95 {(char *)"+wire", (char *)".atunnels.wire", XrmoptionNoArg, (caddr_t) "false" },
96 {(char *)"-texture", (char *)".atunnels.texture", XrmoptionNoArg, (caddr_t) "true" },
97 {(char *)"+texture", (char *)".atunnels.texture", XrmoptionNoArg, (caddr_t) "false" },
100 static argtype vars[] = {
101 {(caddr_t *) &do_light, (char *)"light", (char *)"Light", DEF_LIGHT, t_Bool},
102 {(caddr_t *) &do_wire, (char *)"wire", (char *)"Wire", DEF_WIRE, t_Bool},
103 {(caddr_t *) &do_texture, (char *)"texture",(char *)"Texture", DEF_TEXTURE, t_Bool},
106 static OptionStruct desc[] =
108 {(char *)"-/+ light", (char *)"whether to do enable lighting (slower)"},
109 {(char *)"-/+ wire", (char *)"whether to do use wireframe instead of filled (faster)"},
110 {(char *)"-/+ texture", (char *)"whether to apply a texture (slower)"},
113 ModeSpecOpt atunnels_opts = {countof(opts), opts, countof(vars), vars, desc};
116 ModStruct atunnels_description =
117 {"atunnels", "init_atunnels", "draw_atunnels", "release_atunnels",
118 "draw_atunnels", "init_atunnels", NULL, &atunnels_opts,
119 1000, 1, 2, 1, 4, 1.0, "",
120 "OpenGL advanced tunnel screensaver", 0, NULL};
123 /* structure for holding the screensaver data */
125 int screen_width, screen_height;
126 GLXContext *glx_context;
130 static atunnelsstruct *Atunnels = NULL;
131 static GLuint texture[3]; /* texture id: GL world */
133 /*=================== Load Texture =========================================*/
134 static void LoadTexture(ModeInfo * mi, char **fn, int t_num)
136 #if defined( I_HAVE_XPM )
137 XImage *teximage; /* Texture data */
139 if ((teximage = xpm_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi),
140 MI_COLORMAP(mi), fn)) == None) {
141 (void) fprintf(stderr, "Error reading the texture.\n");
142 glDeleteTextures(1, &texture[t_num]);
151 #ifdef HAVE_GLBINDTEXTURE
152 glBindTexture(GL_TEXTURE_2D, texture[t_num]);
153 #endif /* HAVE_GLBINDTEXTURE */
154 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
156 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, teximage->width, teximage->height,
157 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage->data);
158 check_gl_error("texture");
160 /* Texture parameters, LINEAR scaling for better texture quality */
161 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
162 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164 XDestroyImage(teximage);
165 #else /* !I_HAVE_XPM */
167 #endif /* !I_HAVE_XPM */
170 /*=================== Main Initialization ==================================*/
171 static void Init(ModeInfo * mi)
173 GLfloat light_ambient[] = {1.0, 1.0, 1.0, 1.0};
174 GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
175 GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
176 GLfloat light_position[] = {0.0, 0.0, 1.0, 0.0};
177 GLfloat fogColor[4] = {0.8, 0.8, 0.8, 1.0};
179 glClearColor(0, 0, 0, 0);
182 glGenTextures(3, texture);
183 LoadTexture(mi, texture0,0);
184 LoadTexture(mi, texture1,1);
185 LoadTexture(mi, texture2,2);
186 glEnable(GL_TEXTURE_2D);
190 /* Set lighting parameters */
193 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
194 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
195 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
196 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
200 glDepthFunc(GL_LESS);
202 glEnable(GL_LIGHTING);
205 glDisable(GL_NORMALIZE);
206 glDisable(GL_CULL_FACE);
207 glDisable(GL_DEPTH_TEST);
208 glDisable(GL_TEXTURE_2D);
209 glPolygonMode(GL_FRONT,GL_LINE);
210 glPolygonMode(GL_BACK,GL_LINE);
214 glEnable(GL_DEPTH_TEST);
215 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
218 glFogi(GL_FOG_MODE, GL_EXP);
219 glFogfv(GL_FOG_COLOR, fogColor);
220 glFogf(GL_FOG_DENSITY, 0.3);
224 glCullFace(GL_FRONT);
225 glEnable(GL_CULL_FACE);
228 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
232 /* Standard reshape function */
234 reshape_atunnels(ModeInfo *mi, int width, int height)
238 glViewport(0, 0, width, height);
239 glMatrixMode(GL_PROJECTION);
241 a = (float)width/(float)height;
242 glFrustum(-0.1*a, 0.1*a, -0.1, 0.1, 0.1, 10);
243 glMatrixMode(GL_MODELVIEW);
246 /* draw the screensaver once */
247 void draw_atunnels(ModeInfo * mi)
249 atunnelsstruct *sa = &Atunnels[MI_SCREEN(mi)];
250 Display *display = MI_DISPLAY(mi);
251 Window window = MI_WINDOW(mi);
253 if (!sa->glx_context)
256 glXMakeCurrent(display, window, *(sa->glx_context));
258 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
262 DrawTunnel(do_texture, do_light, texture);
263 SplashScreen(do_wire, do_texture, do_light);
266 /* manage framerate display */
267 if (MI_IS_FPS(mi)) do_fps (mi);
268 glXSwapBuffers(display, window);
273 /* xscreensaver initialization routine */
274 void init_atunnels(ModeInfo * mi)
276 int screen = MI_SCREEN(mi);
279 if (Atunnels == NULL) {
280 if ((Atunnels = (atunnelsstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (atunnelsstruct))) == NULL)
283 sa = &Atunnels[screen];
285 sa->window = MI_WINDOW(mi);
286 if ((sa->glx_context = init_GL(mi)) != NULL) {
287 reshape_atunnels(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
295 /* all sorts of nice cleanup code should go here! */
296 void release_atunnels(ModeInfo * mi)
299 if (Atunnels != NULL) {
300 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
301 /* atunnelsstruct *sa = &Atunnels[screen];*/
303 (void) free((void *) Atunnels);