1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* atunnel --- OpenGL Advanced Tunnel Screensaver */
5 static const char sccsid[] = "@(#)atunnel.c 5.13 2004/05/25 xlockmore";
8 /* Copyright (c) E. Lassauge, 2003-2004. */
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 (May-25-2004) <lassauge@users.sourceforge.net>
28 * http://lassauge.free.fr/linux.html
32 * E.Lassauge - 25-May-2004:
33 * - added more texture !
34 * E.Lassauge - 16-Mar-2002:
35 * - created based on the Roman demo.
36 * - deleted all external file stuff to use xpm textures and
37 * hardcoded path point values.
41 #ifdef STANDALONE /* xscreensaver mode */
42 #define DEFAULTS "*delay: 10000 \n" \
43 "*showFPS: False \n" \
44 "*suppressRotationAnimation: True\n" \
46 # define release_atunnel 0
47 # define atunnel_handle_event 0
49 # include "xlockmore.h" /* from the xscreensaver distribution */
50 #else /* !STANDALONE */
51 # include "xlock.h" /* from the xlockmore distribution */
52 #endif /* !STANDALONE */
54 #ifdef MODE_atunnel /* whole file */
59 #include "tunnel_draw.h"
61 #if defined( USE_XPM ) || defined( USE_XPMINC ) || defined(STANDALONE)
62 /* USE_XPM & USE_XPMINC in xlock mode ; STANDALONE in xscreensaver mode */
63 #include "ximage-loader.h"
66 #include "images/gen/tunnel0_png.h"
67 #include "images/gen/tunnel1_png.h"
68 #include "images/gen/tunnel2_png.h"
69 #include "images/gen/tunnel3_png.h"
70 #include "images/gen/tunnel4_png.h"
71 #include "images/gen/tunnel5_png.h"
76 #define countof(x) (sizeof((x))/sizeof((*x)))
78 #define DEF_LIGHT "True"
79 #define DEF_WIRE "False"
80 #define DEF_TEXTURE "True"
84 static Bool do_texture;
86 static XrmOptionDescRec opts[] = {
87 {"-light", ".atunnel.light", XrmoptionNoArg, "true" },
88 {"+light", ".atunnel.light", XrmoptionNoArg, "false" },
89 {"-wireframe",".atunnel.wire", XrmoptionNoArg, "true" },
90 {"+wireframe",".atunnel.wire", XrmoptionNoArg, "false" },
91 {"-texture", ".atunnel.texture", XrmoptionNoArg, "true" },
92 {"+texture", ".atunnel.texture", XrmoptionNoArg, "false" },
95 static argtype vars[] = {
96 {&do_light, "light", "Light", DEF_LIGHT, t_Bool},
97 {&do_wire, "wire", "Wire", DEF_WIRE, t_Bool},
98 {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
101 static OptionStruct desc[] =
103 {"-/+ light", "whether to do enable lighting (slower)"},
104 {"-/+ wire", "whether to do use wireframe instead of filled (faster)"},
105 {"-/+ texture", "whether to apply a texture (slower)"},
108 ENTRYPOINT ModeSpecOpt atunnel_opts = {countof(opts), opts, countof(vars), vars, desc};
111 ModStruct atunnel_description =
112 {"atunnel", "init_atunnel", "draw_atunnel", NULL,
113 "draw_atunnel", "init_atunnel", "free_atunnel", &atunnel_opts,
114 1000, 1, 2, 1, 4, 1.0, "",
115 "OpenGL advanced tunnel screensaver", 0, NULL};
118 /* structure for holding the screensaver data */
120 int screen_width, screen_height;
121 GLXContext *glx_context;
123 struct tunnel_state *ts;
124 GLuint texture[MAX_TEXTURE]; /* texture id: GL world */
127 static atunnelstruct *Atunnel = NULL;
129 /*=================== Load Texture =========================================*/
130 static void LoadTexture(ModeInfo * mi,
131 const unsigned char *data, unsigned long size,
134 #if defined( I_HAVE_XPM )
135 atunnelstruct *sa = &Atunnel[MI_SCREEN(mi)];
136 XImage *teximage; /* Texture data */
138 if ((teximage = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi),
141 (void) fprintf(stderr, "Error reading the texture.\n");
142 glDeleteTextures(1, &sa->texture[t_num]);
151 #ifdef HAVE_GLBINDTEXTURE
152 glBindTexture(GL_TEXTURE_2D, sa->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 atunnelstruct *sa = &Atunnel[MI_SCREEN(mi)];
174 GLfloat light_ambient[] = {1.0, 1.0, 1.0, 1.0};
175 GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
176 GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
177 GLfloat light_position[] = {0.0, 0.0, 1.0, 0.0};
178 GLfloat fogColor[4] = {0.8, 0.8, 0.8, 1.0};
182 glGenTextures(MAX_TEXTURE, sa->texture);
183 LoadTexture(mi, tunnel0_png, sizeof(tunnel0_png),0);
184 LoadTexture(mi, tunnel1_png, sizeof(tunnel1_png),1);
185 LoadTexture(mi, tunnel2_png, sizeof(tunnel2_png),2);
186 LoadTexture(mi, tunnel3_png, sizeof(tunnel3_png),3);
187 LoadTexture(mi, tunnel4_png, sizeof(tunnel4_png),4);
188 LoadTexture(mi, tunnel5_png, sizeof(tunnel5_png),5);
189 glEnable(GL_TEXTURE_2D);
191 sa->ts = atunnel_InitTunnel();
193 /* Set lighting parameters */
196 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
197 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
198 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
199 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
203 glDepthFunc(GL_LESS);
205 glEnable(GL_LIGHTING);
208 # ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
213 glDisable(GL_NORMALIZE);
214 glDisable(GL_CULL_FACE);
215 glDisable(GL_DEPTH_TEST);
216 glDisable(GL_TEXTURE_2D);
217 glPolygonMode(GL_FRONT,GL_LINE);
218 glPolygonMode(GL_BACK,GL_LINE);
222 glEnable(GL_DEPTH_TEST);
223 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
226 glFogi(GL_FOG_MODE, GL_EXP);
227 glFogfv(GL_FOG_COLOR, fogColor);
228 glFogf(GL_FOG_DENSITY, 0.3);
232 glCullFace(GL_FRONT);
233 glEnable(GL_CULL_FACE);
236 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
240 /* Standard reshape function */
242 reshape_atunnel(ModeInfo *mi, int width, int height)
244 double h = (GLfloat) height / (GLfloat) width;
247 if (width > height * 2) { /* tiny window: show middle */
250 h = height / (GLfloat) width;
253 glViewport(0, y, width, height);
254 glMatrixMode(GL_PROJECTION);
256 glFrustum(-0.1*(1/h), 0.1*(1/h), -0.1, 0.1, 0.1, 10);
257 glMatrixMode(GL_MODELVIEW);
260 /* draw the screensaver once */
261 ENTRYPOINT void draw_atunnel(ModeInfo * mi)
263 atunnelstruct *sa = &Atunnel[MI_SCREEN(mi)];
264 Display *display = MI_DISPLAY(mi);
265 Window window = MI_WINDOW(mi);
267 if (!sa->glx_context)
270 glXMakeCurrent(display, window, *(sa->glx_context));
272 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
276 atunnel_DrawTunnel(sa->ts, do_texture, do_light, sa->texture);
277 atunnel_SplashScreen(sa->ts, do_wire, do_texture, do_light);
280 /* manage framerate display */
281 if (MI_IS_FPS(mi)) do_fps (mi);
282 glXSwapBuffers(display, window);
287 /* xscreensaver initialization routine */
288 ENTRYPOINT void init_atunnel(ModeInfo * mi)
290 int screen = MI_SCREEN(mi);
293 MI_INIT(mi, Atunnel);
294 sa = &Atunnel[screen];
296 sa->window = MI_WINDOW(mi);
297 if ((sa->glx_context = init_GL(mi)) != NULL) {
298 reshape_atunnel(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
306 /* all sorts of nice cleanup code should go here! */
307 ENTRYPOINT void free_atunnel(ModeInfo * mi)
310 atunnelstruct *sa = &Atunnel[MI_SCREEN(mi)];
315 XSCREENSAVER_MODULE ("Atunnel", atunnel)