/*- * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Cubic Grid - a 3D lattice. The observer is located in the centre of * a spinning finite lattice. As it rotates, various view-throughs appear and * evolve. A simple idea with interesting results. * * Vasek Potocek (Dec-28-2007) * vasek.potocek@post.cz */ #define DEFAULTS "*delay: 20000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ "*suppressRotationAnimation: True\n" \ # define free_cubicgrid 0 # define release_cubicgrid 0 #include "xlockmore.h" #ifdef USE_GL #define DEF_SPEED "1.0" #define DEF_DIV "30" #define DEF_ZOOM "20" #define DEF_BIGDOTS "True" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) #include "rotator.h" #include "gltrackball.h" /*************************************************************************/ static int ticks; static float size; static float speed; static Bool bigdots; static argtype vars[] = { { &speed, "speed", "Speed", DEF_SPEED, t_Float }, { &size, "zoom", "Zoom", DEF_ZOOM, t_Float }, { &ticks, "ticks", "Ticks", DEF_DIV, t_Int }, { &bigdots, "bigdots", "BigDots", DEF_BIGDOTS, t_Bool }, }; static XrmOptionDescRec opts[] = { { "-speed", ".speed", XrmoptionSepArg, 0 }, { "-zoom", ".zoom", XrmoptionSepArg, 0 }, { "-ticks", ".ticks", XrmoptionSepArg, 0 }, { "-bigdots", ".bigdots", XrmoptionNoArg, "True" }, { "+bigdots", ".bigdots", XrmoptionNoArg, "False" }, }; ENTRYPOINT ModeSpecOpt cubicgrid_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES ModStruct cubicgrid_description = { "cubicgrid", "init_cubicgrid", "draw_cubicgrid", NULL, "draw_cubicgrid", "change_cubicgrid", NULL, &cubicgrid_opts, 25000, 1, 1, 1, 1.0, 4, "", "Shows a rotating 3D lattice from inside", 0, NULL }; #endif typedef struct { GLXContext *glx_context; GLfloat ratio; GLint list; rotator *rot; trackball_state *trackball; Bool button_down_p; int npoints; } cubicgrid_conf; static cubicgrid_conf *cubicgrid = NULL; static const GLfloat zpos = -18.0; /*************************************************************************/ ENTRYPOINT Bool cubicgrid_handle_event (ModeInfo *mi, XEvent *event) { cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)]; if (gltrackball_event_handler (event, cp->trackball, MI_WIDTH (mi), MI_HEIGHT (mi), &cp->button_down_p)) return True; return False; } static Bool draw_main(ModeInfo *mi) { cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)]; double x, y, z; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glRotatef (180, 1, 0, 0); /* Make trackball track the right way */ glRotatef (180, 0, 1, 0); glTranslatef(0, 0, zpos); glScalef(size/ticks, size/ticks, size/ticks); # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ { GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); int o = (int) current_device_rotation(); if (o != 0 && o != 180 && o != -180) glScalef (1/h, 1/h, 1); } # endif gltrackball_rotate (cp->trackball); get_rotation (cp->rot, &x, &y, &z, !cp->button_down_p); glRotatef (-x * 360, 1.0, 0.0, 0.0); glRotatef (-y * 360, 0.0, 1.0, 0.0); glRotatef (-z * 360, 0.0, 0.0, 1.0); glTranslatef(-ticks/2.0, -ticks/2.0, -ticks/2.0); glCallList(cp->list); return True; } static void init_gl(ModeInfo *mi) { cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)]; int x, y, z; float tf = ticks; glDrawBuffer(GL_BACK); if(bigdots) { glPointSize(2.0); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glShadeModel(GL_FLAT); cp->list = glGenLists(1); glNewList(cp->list, GL_COMPILE); if(MI_IS_MONO(mi)) { glColor3f(1.0, 1.0, 1.0); glBegin(GL_POINTS); for(x = 0; x < ticks; x++) { for(y = 0; y < ticks; y++) { for(z = 0; z < ticks; z++) { glVertex3f(x, y, z); cp->npoints++; } } } glEnd(); } else { glBegin(GL_POINTS); for(x = 0; x < ticks; x++) { for(y = 0; y < ticks; y++) { for(z = 0; z < ticks; z++) { glColor3f(x/tf, y/tf, z/tf); glVertex3f(x, y, z); cp->npoints++; } } } glEnd(); } glEndList(); } /*************************************************************************/ ENTRYPOINT void reshape_cubicgrid(ModeInfo *mi, int width, int height) { cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)]; int y = 0; if(!height) height = 1; cp->ratio = (GLfloat)width/(GLfloat)height; if (width > height * 3) { /* tiny window: show middle */ height = width; y = -height/2; cp->ratio = (GLfloat)width/(GLfloat)height; } glViewport(0, y, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(30.0, cp->ratio, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); } ENTRYPOINT void init_cubicgrid(ModeInfo *mi) { cubicgrid_conf *cp; MI_INIT(mi, cubicgrid); cp = &cubicgrid[MI_SCREEN(mi)]; if ((cp->glx_context = init_GL(mi)) != NULL) { init_gl(mi); reshape_cubicgrid(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); } { double spin_speed = 0.045 * speed; double spin_accel = 0.005 * speed; cp->rot = make_rotator (spin_speed, spin_speed, spin_speed, spin_accel, 0, True); cp->trackball = gltrackball_init (True); } } ENTRYPOINT void draw_cubicgrid(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); cubicgrid_conf *cp; if (!cubicgrid) return; cp = &cubicgrid[MI_SCREEN(mi)]; MI_IS_DRAWN(mi) = True; if (!cp->glx_context) return; glXMakeCurrent(display, window, *(cp->glx_context)); if (!draw_main(mi)) { MI_ABORT(mi); return; } mi->polygon_count = cp->npoints; if (MI_IS_FPS(mi)) do_fps (mi); glFlush(); glXSwapBuffers(display, window); } #ifndef STANDALONE ENTRYPOINT void change_cubicgrid(ModeInfo * mi) { cubicgrid_conf *cp = &cubicgrid[MI_SCREEN(mi)]; if (!cp->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(cp->glx_context)); init_gl(mi); } #endif /* !STANDALONE */ XSCREENSAVER_MODULE ("CubicGrid", cubicgrid) #endif