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.
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.
14 * Cubic Grid - a 3D lattice. The observer is located in the centre of
15 * a spinning finite lattice. As it rotates, various view-throughs appear and
16 * evolve. A simple idea with interesting results.
18 * Vasek Potocek (Dec-28-2007)
19 * vasek.potocek@post.cz
22 #define DEFAULTS "*delay: 20000 \n" \
23 "*showFPS: False \n" \
24 "*wireframe: False \n" \
25 "*suppressRotationAnimation: True\n" \
27 # define free_cubicgrid 0
28 # define release_cubicgrid 0
29 #include "xlockmore.h"
33 #define DEF_SPEED "1.0"
36 #define DEF_BIGDOTS "True"
39 #define countof(x) (sizeof((x))/sizeof((*x)))
42 #include "gltrackball.h"
44 /*************************************************************************/
51 static argtype vars[] = {
52 { &speed, "speed", "Speed", DEF_SPEED, t_Float },
53 { &size, "zoom", "Zoom", DEF_ZOOM, t_Float },
54 { &ticks, "ticks", "Ticks", DEF_DIV, t_Int },
55 { &bigdots, "bigdots", "BigDots", DEF_BIGDOTS, t_Bool },
58 static XrmOptionDescRec opts[] = {
59 { "-speed", ".speed", XrmoptionSepArg, 0 },
60 { "-zoom", ".zoom", XrmoptionSepArg, 0 },
61 { "-ticks", ".ticks", XrmoptionSepArg, 0 },
62 { "-bigdots", ".bigdots", XrmoptionNoArg, "True" },
63 { "+bigdots", ".bigdots", XrmoptionNoArg, "False" },
66 ENTRYPOINT ModeSpecOpt cubicgrid_opts = {countof(opts), opts, countof(vars), vars, NULL};
69 ModStruct cubicgrid_description =
70 { "cubicgrid", "init_cubicgrid", "draw_cubicgrid", NULL,
71 "draw_cubicgrid", "change_cubicgrid", NULL, &cubicgrid_opts,
72 25000, 1, 1, 1, 1.0, 4, "",
73 "Shows a rotating 3D lattice from inside", 0, NULL
78 GLXContext *glx_context;
83 trackball_state *trackball;
88 static cubicgrid_conf *cubicgrid = NULL;
90 static const GLfloat zpos = -18.0;
92 /*************************************************************************/
95 cubicgrid_handle_event (ModeInfo *mi, XEvent *event)
97 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
99 if (gltrackball_event_handler (event, cp->trackball,
100 MI_WIDTH (mi), MI_HEIGHT (mi),
108 static Bool draw_main(ModeInfo *mi)
110 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
113 glClear(GL_COLOR_BUFFER_BIT);
116 glRotatef (180, 1, 0, 0); /* Make trackball track the right way */
117 glRotatef (180, 0, 1, 0);
119 glTranslatef(0, 0, zpos);
121 glScalef(size/ticks, size/ticks, size/ticks);
124 # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
126 GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
127 int o = (int) current_device_rotation();
128 if (o != 0 && o != 180 && o != -180)
129 glScalef (1/h, 1/h, 1);
133 gltrackball_rotate (cp->trackball);
135 get_rotation (cp->rot, &x, &y, &z, !cp->button_down_p);
136 glRotatef (-x * 360, 1.0, 0.0, 0.0);
137 glRotatef (-y * 360, 0.0, 1.0, 0.0);
138 glRotatef (-z * 360, 0.0, 0.0, 1.0);
140 glTranslatef(-ticks/2.0, -ticks/2.0, -ticks/2.0);
141 glCallList(cp->list);
145 static void init_gl(ModeInfo *mi)
147 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
151 glDrawBuffer(GL_BACK);
155 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
156 glShadeModel(GL_FLAT);
158 cp->list = glGenLists(1);
159 glNewList(cp->list, GL_COMPILE);
161 glColor3f(1.0, 1.0, 1.0);
163 for(x = 0; x < ticks; x++) {
164 for(y = 0; y < ticks; y++) {
165 for(z = 0; z < ticks; z++) {
176 for(x = 0; x < ticks; x++) {
177 for(y = 0; y < ticks; y++) {
178 for(z = 0; z < ticks; z++) {
179 glColor3f(x/tf, y/tf, z/tf);
190 /*************************************************************************/
192 ENTRYPOINT void reshape_cubicgrid(ModeInfo *mi, int width, int height)
194 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
196 if(!height) height = 1;
197 cp->ratio = (GLfloat)width/(GLfloat)height;
199 if (width > height * 3) { /* tiny window: show middle */
202 cp->ratio = (GLfloat)width/(GLfloat)height;
205 glViewport(0, y, (GLint) width, (GLint) height);
206 glMatrixMode(GL_PROJECTION);
208 gluPerspective(30.0, cp->ratio, 1.0, 100.0);
209 glMatrixMode(GL_MODELVIEW);
210 glClear(GL_COLOR_BUFFER_BIT);
213 ENTRYPOINT void init_cubicgrid(ModeInfo *mi)
216 MI_INIT(mi, cubicgrid);
217 cp = &cubicgrid[MI_SCREEN(mi)];
219 if ((cp->glx_context = init_GL(mi)) != NULL) {
221 reshape_cubicgrid(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
227 double spin_speed = 0.045 * speed;
228 double spin_accel = 0.005 * speed;
230 cp->rot = make_rotator (spin_speed, spin_speed, spin_speed,
231 spin_accel, 0, True);
232 cp->trackball = gltrackball_init (True);
236 ENTRYPOINT void draw_cubicgrid(ModeInfo * mi)
238 Display *display = MI_DISPLAY(mi);
239 Window window = MI_WINDOW(mi);
241 if (!cubicgrid) return;
242 cp = &cubicgrid[MI_SCREEN(mi)];
243 MI_IS_DRAWN(mi) = True;
244 if (!cp->glx_context) return;
245 glXMakeCurrent(display, window, *(cp->glx_context));
246 if (!draw_main(mi)) {
250 mi->polygon_count = cp->npoints;
251 if (MI_IS_FPS(mi)) do_fps (mi);
253 glXSwapBuffers(display, window);
257 ENTRYPOINT void change_cubicgrid(ModeInfo * mi)
259 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
260 if (!cp->glx_context) return;
261 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(cp->glx_context));
264 #endif /* !STANDALONE */
267 XSCREENSAVER_MODULE ("CubicGrid", cubicgrid)