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"
26 # define refresh_cubicgrid 0
27 #include "xlockmore.h"
31 #define DEF_SPEED "1.0"
34 #define DEF_BIGDOTS "True"
37 #define countof(x) (sizeof((x))/sizeof((*x)))
40 #include "gltrackball.h"
42 /*************************************************************************/
49 static argtype vars[] = {
50 { &speed, "speed", "Speed", DEF_SPEED, t_Float },
51 { &size, "zoom", "Zoom", DEF_ZOOM, t_Float },
52 { &ticks, "ticks", "Ticks", DEF_DIV, t_Int },
53 { &bigdots, "bigdots", "BigDots", DEF_BIGDOTS, t_Bool },
56 static XrmOptionDescRec opts[] = {
57 { "-speed", ".speed", XrmoptionSepArg, 0 },
58 { "-zoom", ".zoom", XrmoptionSepArg, 0 },
59 { "-ticks", ".ticks", XrmoptionSepArg, 0 },
60 { "-bigdots", ".bigdots", XrmoptionNoArg, "True" },
61 { "+bigdots", ".bigdots", XrmoptionNoArg, "False" },
64 ENTRYPOINT ModeSpecOpt cubicgrid_opts = {countof(opts), opts, countof(vars), vars, NULL};
67 ModStruct cubicgrid_description =
68 { "cubicgrid", "init_cubicgrid", "draw_cubicgrid", "release_cubicgrid",
69 "draw_cubicgrid", "change_cubicgrid", NULL, &cubicgrid_opts,
70 25000, 1, 1, 1, 1.0, 4, "",
71 "Shows a rotating 3D lattice from inside", 0, NULL
76 GLXContext *glx_context;
81 trackball_state *trackball;
86 static cubicgrid_conf *cubicgrid = NULL;
88 static const GLfloat zpos = -18.0;
90 /*************************************************************************/
93 cubicgrid_handle_event (ModeInfo *mi, XEvent *event)
95 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
97 if (event->xany.type == ButtonPress &&
98 event->xbutton.button == Button1)
100 cp->button_down_p = True;
101 gltrackball_start (cp->trackball,
102 event->xbutton.x, event->xbutton.y,
103 MI_WIDTH (mi), MI_HEIGHT (mi));
106 else if (event->xany.type == ButtonRelease &&
107 event->xbutton.button == Button1)
109 cp->button_down_p = False;
112 else if (event->xany.type == ButtonPress &&
113 (event->xbutton.button == Button4 ||
114 event->xbutton.button == Button5 ||
115 event->xbutton.button == Button6 ||
116 event->xbutton.button == Button7))
118 gltrackball_mousewheel (cp->trackball, event->xbutton.button, 2,
119 !!event->xbutton.state);
122 else if (event->xany.type == MotionNotify &&
125 gltrackball_track (cp->trackball,
126 event->xmotion.x, event->xmotion.y,
127 MI_WIDTH (mi), MI_HEIGHT (mi));
135 static Bool draw_main(cubicgrid_conf *cp)
139 glClear(GL_COLOR_BUFFER_BIT);
141 glTranslatef(0, 0, zpos);
143 glScalef(size/ticks, size/ticks, size/ticks);
144 gltrackball_rotate (cp->trackball);
145 get_rotation (cp->rot, &x, &y, &z, !cp->button_down_p);
146 glRotatef (x * 360, 1.0, 0.0, 0.0);
147 glRotatef (y * 360, 0.0, 1.0, 0.0);
148 glRotatef (z * 360, 0.0, 0.0, 1.0);
150 glTranslatef(-ticks/2.0, -ticks/2.0, -ticks/2.0);
151 glCallList(cp->list);
155 static void init_gl(ModeInfo *mi)
157 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
161 glDrawBuffer(GL_BACK);
165 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
166 glShadeModel(GL_FLAT);
168 cp->list = glGenLists(1);
169 glNewList(cp->list, GL_COMPILE);
171 glColor3f(1.0, 1.0, 1.0);
173 for(x = 0; x < ticks; x++) {
174 for(y = 0; y < ticks; y++) {
175 for(z = 0; z < ticks; z++) {
186 for(x = 0; x < ticks; x++) {
187 for(y = 0; y < ticks; y++) {
188 for(z = 0; z < ticks; z++) {
189 glColor3f(x/tf, y/tf, z/tf);
200 /*************************************************************************/
202 ENTRYPOINT void reshape_cubicgrid(ModeInfo *mi, int width, int height)
204 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
205 if(!height) height = 1;
206 cp->ratio = (GLfloat)width/(GLfloat)height;
207 glViewport(0, 0, (GLint) width, (GLint) height);
208 glMatrixMode(GL_PROJECTION);
210 gluPerspective(30.0, cp->ratio, 1.0, 100.0);
211 glMatrixMode(GL_MODELVIEW);
212 glClear(GL_COLOR_BUFFER_BIT);
215 ENTRYPOINT void release_cubicgrid(ModeInfo *mi)
217 if (cubicgrid != NULL) {
219 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
220 cubicgrid_conf *cp = &cubicgrid[screen];
221 if (cp->glx_context) {
222 cp->glx_context = NULL;
225 free((void *)cubicgrid);
231 ENTRYPOINT void init_cubicgrid(ModeInfo *mi)
235 cubicgrid = (cubicgrid_conf *)calloc(MI_NUM_SCREENS(mi), sizeof(cubicgrid_conf));
236 if(!cubicgrid) return;
238 cp = &cubicgrid[MI_SCREEN(mi)];
240 if ((cp->glx_context = init_GL(mi)) != NULL) {
242 reshape_cubicgrid(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
248 double spin_speed = 0.045 * speed;
249 double spin_accel = 0.005 * speed;
251 cp->rot = make_rotator (spin_speed, spin_speed, spin_speed,
252 spin_accel, 0, True);
253 cp->trackball = gltrackball_init ();
257 ENTRYPOINT void draw_cubicgrid(ModeInfo * mi)
259 Display *display = MI_DISPLAY(mi);
260 Window window = MI_WINDOW(mi);
262 if (!cubicgrid) return;
263 cp = &cubicgrid[MI_SCREEN(mi)];
264 MI_IS_DRAWN(mi) = True;
265 if (!cp->glx_context) return;
266 glXMakeCurrent(display, window, *(cp->glx_context));
267 if (!draw_main(cp)) {
268 release_cubicgrid(mi);
271 mi->polygon_count = cp->npoints;
272 if (MI_IS_FPS(mi)) do_fps (mi);
274 glXSwapBuffers(display, window);
278 ENTRYPOINT void change_cubicgrid(ModeInfo * mi)
280 cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)];
281 if (!cp->glx_context) return;
282 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(cp->glx_context));
285 #endif /* !STANDALONE */
288 XSCREENSAVER_MODULE ("CubicGrid", cubicgrid)