ENTRYPOINT void init_cow (ModeInfo *mi) { cow_configuration *bp; int wire = MI_IS_WIREFRAME(mi); int i; Bool tex_p = False; MI_INIT (mi, bps); bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_cow (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); if (!wire) { GLfloat pos[4] = {0.4, 0.2, 0.4, 0.0}; /* GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};*/ GLfloat amb[4] = {0.2, 0.2, 0.2, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } bp->trackball = gltrackball_init (False); bp->dlists = (GLuint *) calloc (countof(all_objs)+1, sizeof(GLuint)); for (i = 0; i < countof(all_objs); i++) bp->dlists[i] = glGenLists (1); tex_p = load_texture (mi, do_texture); if (tex_p) glBindTexture (GL_TEXTURE_2D, bp->texture); for (i = 0; i < countof(all_objs); i++) { GLfloat black[4] = {0, 0, 0, 1}; const struct gllist *gll = *all_objs[i]; glNewList (bp->dlists[i], GL_COMPILE); glDisable (GL_TEXTURE_2D); if (i == HIDE) { GLfloat color[4] = {0.63, 0.43, 0.36, 1.00}; if (tex_p) { /* if we have a texture, make the base color be white. */ color[0] = color[1] = color[2] = 1.0; glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_2D); /* approximately line it up with ../images/earth.png */ glMatrixMode (GL_TEXTURE); glLoadIdentity(); glTranslatef (0.45, 0.58, 0); glScalef (0.08, 0.16, 1); glRotatef (-5, 0, 0, 1); glMatrixMode (GL_MODELVIEW); } glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, black); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); } else if (i == TAIL) { GLfloat color[4] = {0.63, 0.43, 0.36, 1.00}; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, black); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); } else if (i == UDDER) { GLfloat color[4] = {1.00, 0.53, 0.53, 1.00}; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, black); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); } else if (i == HOOFS || i == HORNS) { GLfloat color[4] = {0.20, 0.20, 0.20, 1.00}; GLfloat spec[4] = {0.30, 0.30, 0.30, 1.00}; GLfloat shiny = 8.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else if (i == FACE) { GLfloat color[4] = {0.10, 0.10, 0.10, 1.00}; GLfloat spec[4] = {0.10, 0.10, 0.10, 1.00}; GLfloat shiny = 8.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else { GLfloat color[4] = {1.00, 1.00, 1.00, 1.00}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.00}; GLfloat shiny = 128.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } renderList (gll, wire); glEndList (); } bp->nfloaters = MI_COUNT (mi); bp->floaters = (floater *) calloc (bp->nfloaters, sizeof (floater)); for (i = 0; i < bp->nfloaters; i++) { floater *f = &bp->floaters[i]; f->rot = make_rotator (10.0, 0, 0, 4, 0.05 * speed, True); if (bp->nfloaters == 2) { f->x = (i ? 6 : -6); } else if (i != 0) { double th = (i - 1) * M_PI*2 / (bp->nfloaters-1); double r = 10; f->x = r * cos(th); f->z = r * sin(th); } f->ix = f->x; f->iy = f->y; f->iz = f->z; reset_floater (mi, f); } }
ENTRYPOINT void draw_toasters (ModeInfo *mi) { toaster_configuration *bp = &bps[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i; if (!bp->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glRotatef(current_device_rotation(), 0, 0, 1); glRotatef(bp->view_x, 1, 0, 0); glRotatef(bp->view_y, 0, 1, 0); /* Rotate the scene around a point that's a little deeper in. */ glTranslatef (0, 0, -50); gltrackball_rotate (bp->user_trackball); glTranslatef (0, 0, 50); #if 0 { floater F; F.toaster_p = 0; F.toast_type = 1; F.handle_pos = 0; F.knob_pos = -90; F.loaded = 3; F.x = F.y = F.z = 0; F.dx = F.dy = F.dz = 0; glScalef(2,2,2); if (!MI_IS_WIREFRAME(mi)) glDisable(GL_LIGHTING); if (!MI_IS_WIREFRAME(mi) && do_texture) glDisable(GL_TEXTURE_2D); glBegin(GL_LINES); glVertex3f(-10, 0, 0); glVertex3f(10, 0, 0); glVertex3f(0, -10, 0); glVertex3f(0, 10, 0); glVertex3f(0, 0, -10); glVertex3f(0, 0, 10); glEnd(); if (!MI_IS_WIREFRAME(mi)) glEnable(GL_LIGHTING); if (!MI_IS_WIREFRAME(mi) && do_texture) glEnable(GL_TEXTURE_2D); draw_floater (mi, &F); glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); return; } #endif glScalef (0.5, 0.5, 0.5); draw_origin (mi); glTranslatef (0, 0, -GRID_DEPTH/2.5); draw_grid (mi); mi->polygon_count = 0; for (i = 0; i < bp->nfloaters; i++) { floater *f = &bp->floaters[i]; draw_floater (mi, f); tick_floater (mi, f); } auto_track (mi); glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }
/*- * init_swirl * * Initialise things for swirling * * - win is the window to draw in */ void init_swirl(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); swirlstruct *sp; /* does the swirls array exist? */ if (swirls == NULL) { int i; /* allocate an array, one entry for each screen */ if ((swirls = (swirlstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (swirlstruct))) == NULL) return; /* initialise them all */ for (i = 0; i < MI_NUM_SCREENS(mi); i++) initialise_swirl(&swirls[i]); } /* get a pointer to this swirl */ sp = &(swirls[MI_SCREEN(mi)]); sp->mi = mi; /* get window parameters */ sp->width = MI_WIDTH(mi); sp->height = MI_HEIGHT(mi); sp->depth = MI_DEPTH(mi); sp->rdepth = sp->depth; sp->visual = MI_VISUAL(mi); if (sp->depth > 16) sp->depth = 16; /* initialise image for speeding up drawing */ if (!initialise_image(display, sp)) { free_swirl(display, sp); return; } MI_CLEARWINDOW(mi); if (!sp->gc) { if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { XColor color; #ifndef STANDALONE sp->fg = MI_FG_PIXEL(mi); sp->bg = MI_BG_PIXEL(mi); #endif sp->blackpixel = MI_BLACK_PIXEL(mi); sp->whitepixel = MI_WHITE_PIXEL(mi); if ((sp->cmap = XCreateColormap(display, window, MI_VISUAL(mi), AllocNone)) == None) { free_swirl(display, sp); return; } XSetWindowColormap(display, window, sp->cmap); (void) XParseColor(display, sp->cmap, "black", &color); (void) XAllocColor(display, sp->cmap, &color); MI_BLACK_PIXEL(mi) = color.pixel; (void) XParseColor(display, sp->cmap, "white", &color); (void) XAllocColor(display, sp->cmap, &color); MI_WHITE_PIXEL(mi) = color.pixel; #ifndef STANDALONE (void) XParseColor(display, sp->cmap, background, &color); (void) XAllocColor(display, sp->cmap, &color); MI_BG_PIXEL(mi) = color.pixel; (void) XParseColor(display, sp->cmap, foreground, &color); (void) XAllocColor(display, sp->cmap, &color); MI_FG_PIXEL(mi) = color.pixel; #endif sp->colors = (XColor *) NULL; sp->ncolors = 0; } if ((sp->gc = XCreateGC(display, MI_WINDOW(mi), (unsigned long) 0, (XGCValues *) NULL)) == None) { free_swirl(display, sp); return; } } MI_CLEARWINDOW(mi); /* Set up colour map */ sp->direction = (LRAND() & 1) ? 1 : -1; if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { if (sp->colors != NULL) { if (sp->ncolors && !sp->no_colors) free_colors(display, sp->cmap, sp->colors, sp->ncolors); free(sp->colors); sp->colors = (XColor *) NULL; } sp->ncolors = MI_NCOLORS(mi); if (sp->ncolors < 2) sp->ncolors = 2; if (sp->ncolors <= 2) sp->mono_p = True; else sp->mono_p = False; if (sp->mono_p) sp->colors = (XColor *) NULL; else if ((sp->colors = (XColor *) malloc(sizeof (*sp->colors) * (sp->ncolors + 1))) == NULL) { free_swirl(display, sp); return; } sp->cycle_p = has_writable_cells(mi); if (sp->cycle_p) { if (MI_IS_FULLRANDOM(mi)) { if (!NRAND(8)) sp->cycle_p = False; else sp->cycle_p = True; } else { sp->cycle_p = cycle_p; } } if (!sp->mono_p) { if (!(LRAND() % 10)) make_random_colormap( #if STANDALONE display, MI_WINDOW(mi), #else mi, #endif sp->cmap, sp->colors, &sp->ncolors, True, True, &sp->cycle_p); else if (!(LRAND() % 2)) make_uniform_colormap( #if STANDALONE display, MI_WINDOW(mi), #else mi, #endif sp->cmap, sp->colors, &sp->ncolors, True, &sp->cycle_p); else make_smooth_colormap( #if STANDALONE display, MI_WINDOW(mi), #else mi, #endif sp->cmap, sp->colors, &sp->ncolors, True, &sp->cycle_p); } XInstallColormap(display, sp->cmap); if (sp->ncolors < 2) { sp->ncolors = 2; sp->no_colors = True; } else sp->no_colors = False; if (sp->ncolors <= 2) sp->mono_p = True; if (sp->mono_p) sp->cycle_p = False; } if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { if (sp->mono_p) { sp->cur_color = MI_BLACK_PIXEL(mi); } } /* resolution starts off chunky */ sp->resolution = MIN_RES + 1; /* calculate the pixel step for this resulution */ sp->r = (1 << (sp->resolution - 1)); /* how many knots? */ sp->n_knots = random_no((unsigned int) MI_COUNT(mi) / 2) + MI_COUNT(mi) + 1; /* what type of knots? */ sp->knot_type = ALL; /* for now */ /* use two_plane mode occaisionally */ if (random_no(100) <= TWO_PLANE_PCNT) { sp->two_plane = sp->first_plane = True; sp->max_resolution = 2; } else sp->two_plane = False; /* fix the knot values */ if (!create_knots(sp)) { free_swirl(display, sp); return; } /* we are off */ sp->started = True; sp->drawing = False; }
ENTRYPOINT void init_mgears (ModeInfo *mi) { mgears_configuration *bp; int wire = MI_IS_WIREFRAME(mi); int i; if (!bps) { bps = (mgears_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (mgears_configuration)); if (!bps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_mgears (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } { double spin_speed = 0.5; double wander_speed = 0.01; double spin_accel = 2.0; bp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, spin_accel, do_wander ? wander_speed : 0, False /* don't randomize */ ); bp->trackball = gltrackball_init (); } { int total_gears = MI_COUNT(mi); double gears_per_turn; double gear_r, tw, th, thick, slope; int nubs, size; if (! (total_gears & 1)) total_gears++; /* must be odd or gears intersect */ /* Number of teeth must be odd if number of gears is odd, or teeth don't mesh when the loop closes. And since number of gears must be odd... */ if (! (teeth_arg & 1)) teeth_arg++; if (teeth_arg < 7) teeth_arg = 7; if (total_gears < 13) /* gear mesh angle is too steep with less */ total_gears = 13; thick = 0.2; nubs = (random() & 3) ? 0 : (random() % teeth_arg) / 2; slope = 0; /* Sloping gears are incompatible with "-roll" ... */ /* slope= -M_PI * 2 / total_gears; */ gears_per_turn = total_gears / 2.0; bp->ring_r = 3; gear_r = M_PI * bp->ring_r / gears_per_turn; tw = 0; th = gear_r * 2.5 / teeth_arg; /* If the gears are small, use a lower density mesh. */ size = (gear_r > 0.32 ? INVOLUTE_LARGE : gear_r > 0.13 ? INVOLUTE_MEDIUM : INVOLUTE_SMALL); /* If there are lots of teeth, use a lower density mesh. */ if (teeth_arg > 77) size = INVOLUTE_SMALL; if (teeth_arg > 45 && size == INVOLUTE_LARGE) size = INVOLUTE_MEDIUM; bp->ngears = total_gears; bp->gears = (mogear *) calloc (bp->ngears, sizeof(*bp->gears)); for (i = 0; i < bp->ngears; i++) { mogear *mg = &bp->gears[i]; gear *g = &mg->g; g->r = gear_r; g->size = size; g->nteeth = teeth_arg; g->tooth_w = tw; g->tooth_h = th; g->tooth_slope = slope; g->thickness = g->r * thick; g->thickness2 = g->thickness * 0.1; g->thickness3 = g->thickness; g->inner_r = g->r * 0.80; g->inner_r2 = g->r * 0.60; g->inner_r3 = g->r * 0.55; g->nubs = nubs; mg->pos_th = (M_PI * 2 / gears_per_turn) * i; mg->pos_thz = (M_PI / 2 / gears_per_turn) * i; g->th = ((i & 1) ? (M_PI * 2 / g->nteeth) : 0); /* Colorize */ g->color[0] = 0.7 + frand(0.3); g->color[1] = 0.7 + frand(0.3); g->color[2] = 0.7 + frand(0.3); g->color[3] = 1.0; g->color2[0] = g->color[0] * 0.85; g->color2[1] = g->color[1] * 0.85; g->color2[2] = g->color[2] * 0.85; g->color2[3] = g->color[3]; /* Now render the gear into its display list. */ g->dlist = glGenLists (1); if (! g->dlist) { check_gl_error ("glGenLists"); abort(); } glNewList (g->dlist, GL_COMPILE); g->polygons += draw_involute_gear (g, wire); glEndList (); } } }
ENTRYPOINT void init_toasters (ModeInfo *mi) { toaster_configuration *bp; int wire = MI_IS_WIREFRAME(mi); int i; MI_INIT (mi, bps, NULL); bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_toasters (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); if (!wire) { GLfloat pos[4] = {0.4, 0.2, 0.4, 0.0}; /* GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};*/ GLfloat amb[4] = {0.2, 0.2, 0.2, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } # ifdef HAVE_TEXTURE if (!wire && do_texture) load_textures (mi); # endif bp->user_trackball = gltrackball_init (False); auto_track_init (mi); bp->dlists = (GLuint *) calloc (countof(all_objs)+1, sizeof(GLuint)); for (i = 0; i < countof(all_objs); i++) bp->dlists[i] = glGenLists (1); for (i = 0; i < countof(all_objs); i++) { const struct gllist *gll = *all_objs[i]; glNewList (bp->dlists[i], GL_COMPILE); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMatrixMode(GL_TEXTURE); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glRotatef (-90, 1, 0, 0); glRotatef (180, 0, 0, 1); glScalef (6, 6, 6); glBindTexture (GL_TEXTURE_2D, 0); glDisable (GL_TEXTURE_2D); if (i == BASE_TOASTER) { GLfloat color[4] = {1.00, 1.00, 1.00, 1.00}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.0}; GLfloat shiny = 20.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); #ifdef HAVE_TEXTURE if (do_texture) { #ifndef HAVE_JWZGLES /* No SPHERE_MAP yet */ glEnable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); glBindTexture (GL_TEXTURE_2D, bp->chrome_texture); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); #endif } # endif } else if (i == TOAST || i == TOAST_BITTEN) { GLfloat color[4] = {0.80, 0.80, 0.00, 1.0}; GLfloat spec[4] = {0.00, 0.00, 0.00, 1.0}; GLfloat shiny = 0.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); #ifdef HAVE_TEXTURE if (do_texture) { glEnable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); glBindTexture (GL_TEXTURE_2D, bp->toast_texture); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); } # endif glMatrixMode(GL_TEXTURE); glTranslatef(0.5, 0.5, 0); glMatrixMode(GL_MODELVIEW); } else if (i == SLOTS || i == HANDLE_SLOT) { GLfloat color[4] = {0.30, 0.30, 0.40, 1.0}; GLfloat spec[4] = {0.40, 0.40, 0.70, 1.0}; GLfloat shiny = 128.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else if (i == HANDLE) { GLfloat color[4] = {0.80, 0.10, 0.10, 1.0}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.0}; GLfloat shiny = 20.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else if (i == KNOB) { GLfloat color[4] = {0.80, 0.10, 0.10, 1.0}; GLfloat spec[4] = {0.00, 0.00, 0.00, 1.0}; GLfloat shiny = 0.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else if (i == JET || i == JET_WING) { GLfloat color[4] = {0.70, 0.70, 0.70, 1.0}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.0}; GLfloat shiny = 20.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else if (i == BASE) { GLfloat color[4] = {0.50, 0.50, 0.50, 1.0}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.0}; GLfloat shiny = 20.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } else { GLfloat color[4] = {1.00, 1.00, 1.00, 1.00}; GLfloat spec[4] = {1.00, 1.00, 1.00, 1.0}; GLfloat shiny = 128.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shiny); } renderList (gll, wire); glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEndList (); } bp->nfloaters = ntoasters + nslices; bp->floaters = (floater *) calloc (bp->nfloaters, sizeof (floater)); for (i = 0; i < bp->nfloaters; i++) { floater *f = &bp->floaters[i]; /* arrange the list so that half the toasters are in front of bread, and half are behind. */ f->toaster_p = ((i < ntoasters / 2) || (i >= (nslices + (ntoasters / 2)))); reset_floater (mi, f); /* Position the first generation randomly, but make sure they aren't on screen yet (until we rotate the view into position.) */ { GLfloat min = -GRID_DEPTH/2; GLfloat max = GRID_DEPTH/3.5; f->z = frand (max - min) + min; } } }
ENTRYPOINT void init_tunnel (ModeInfo *mi) { int i; tunnel_configuration *tc; wire = MI_IS_WIREFRAME(mi); # ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ wire = 0; # endif if (!tconf) { tconf = (tunnel_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (tunnel_configuration)); if (!tconf) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } tc = &tconf[MI_SCREEN(mi)]; tc->glx_context = init_GL(mi); tc->cyllist = glGenLists(1); tc->diamondlist = glGenLists(1); tc->num_effects = 12; tc->num_texshifts = 3; tc->effect_time = 0.0; tc->effect_maxsecs = 30.00; /* check bounds on cmd line opts */ if (start > tc->effect_maxsecs) start = tc->effect_maxsecs; if (end > tc->effect_maxsecs) end = tc->effect_maxsecs; if (start < tc->effect_time) start = tc->effect_time; if (end < tc->effect_time) end = tc->effect_time; /* set loop times, in seconds */ tc->start_time = start; tc->end_time = end; /* reset animation knots, effect 0 not defined. */ tc->effects = malloc(sizeof(effect_t) * ( tc->num_effects + 1)); for ( i = 1; i <= tc->num_effects ; i++) init_effects(&tc->effects[i], i); if (wire) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); do_texture = False; } if (do_texture) { /* the following textures are loaded, and possible overridden: tunnel 1, tunnel 2, tunnel 3, marquee, tardis, head */ glGenTextures(MAX_TEXTURE, tc->texture_binds); /*LoadTexture(*mi, **fn, *filename, texbind, bluralpha, bw_color, anegative, onealpha)*/ if (strcasecmp (do_tun1, "(none)")) /* tunnel 1 */ LoadTexture(mi, NULL, do_tun1, tc->texture_binds[0], 0,0.0, False, False); else LoadTexture(mi, timetunnel0_xpm, NULL, tc->texture_binds[0], 0, 0.0, False, False); if (strcasecmp (do_tun2, "(none)")) /* tunnel 2 */ LoadTexture(mi, NULL, do_tun2, tc->texture_binds[2], 0,0.0, False, False); else LoadTexture(mi, timetunnel1_xpm, NULL, tc->texture_binds[2], 0, 0.0, False, False); if (strcasecmp (do_tun3, "(none)")) /* tunnel 3 */ LoadTexture(mi, NULL, do_tun3, tc->texture_binds[5], 0,0.0, False, False); else LoadTexture(mi, timetunnel2_xpm, NULL, tc->texture_binds[5], 0, 0.0, False, False); LoadTexture(mi, tunnelstar_xpm, NULL, tc->texture_binds[4], 0, 0.0, False, False); if (strcasecmp (do_tx1, "(none)")) /* marquee */ LoadTexture(mi, NULL, do_tx1, tc->texture_binds[3], 0,0.0, False, False); #ifndef HAVE_JWZGLES /* logo_180_xpm is 180px which is not a power of 2! */ else LoadTexture(mi, (char **) logo_180_xpm, NULL, tc->texture_binds[3], 0,0.0, False, False); #endif if (strcasecmp (do_tx2, "(none)")) /* tardis */ LoadTexture(mi, NULL, do_tx2, tc->texture_binds[1], 0, 0.0 ,False, False); #ifndef HAVE_JWZGLES /* logo_180_xpm is 180px which is not a power of 2! */ else LoadTexture(mi, (char **) logo_180_xpm, NULL, tc->texture_binds[1], 0,0.0, False, False); #endif if (strcasecmp (do_tx3, "(none)")) { /* head */ LoadTexture(mi, NULL, do_tx3, tc->texture_binds[6], 0, 0.0 ,False, False); /* negative */ LoadTexture(mi, NULL, do_tx3, tc->texture_binds[9], 2,1.0, True, True); #ifndef HAVE_JWZGLES /* logo_180_xpm is 180px which is not a power of 2! */ } else { LoadTexture(mi, (char **) logo_180_xpm, NULL, tc->texture_binds[6], 0,0.0, False, False); /* negative */ LoadTexture(mi, (char **) logo_180_xpm, NULL, tc->texture_binds[9], 2,1.0, True, True); #endif } glEnable(GL_TEXTURE_2D); check_gl_error("tex"); } reshape_tunnel (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glDisable(GL_DEPTH_TEST); /* who needs it? ;-) */ if (do_fog) glEnable(GL_FOG); if (!wire) { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5); } tc->trackball = gltrackball_init (); tc->texshift = calloc(tc->num_texshifts, sizeof(GLfloat)); for ( i = 0 ; i < tc->num_texshifts; i++) tc->texshift[i] = 0.0; glNewList(tc->cyllist, GL_COMPILE); makecyl(30, -0.1, CYL_LEN, 1., 10. / 40.0 * CYL_LEN); /*makecyl(30, -0.5, DIAMOND_LEN, 1., 4. / 40 * DIAMOND_LEN); */ glEndList(); glNewList(tc->diamondlist, GL_COMPILE); makecyl(4, -0.5, DIAMOND_LEN, 1., 4. / 40 * DIAMOND_LEN); glEndList(); }
void init_hop(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); double range; hopstruct *hp; if (hops == NULL) { if ((hops = (hopstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (hopstruct))) == NULL) return; } hp = &hops[MI_SCREEN(mi)]; hp->centerx = MI_WIDTH(mi) / 2; hp->centery = MI_HEIGHT(mi) / 2; /* Make the other operations less common since they are less interesting */ if (MI_IS_FULLRANDOM(mi)) { hp->op = NRAND(OPS); } else { if (martin) hp->op = MARTIN; else if (popcorn) hp->op = POPCORN; else if (ejk1) hp->op = EJK1; else if (ejk2) hp->op = EJK2; else if (ejk3) hp->op = EJK3; else if (ejk4) hp->op = EJK4; else if (ejk5) hp->op = EJK5; else if (ejk6) hp->op = EJK6; else if (rr) hp->op = RR; else if (jong) hp->op = JONG; else if (sine) hp->op = SINE; else hp->op = NRAND(OPS); } range = sqrt((double) hp->centerx * hp->centerx + (double) hp->centery * hp->centery) / (1.0 + LRAND() / MAXRAND); hp->i = hp->j = 0.0; hp->inc = (int) ((LRAND() / MAXRAND) * 200) - 100; #undef XMARTIN switch (hp->op) { case MARTIN: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 1500.0 + 40.0; hp->b = (LRAND() / MAXRAND) * 17.0 + 3.0; hp->c = (LRAND() / MAXRAND) * 3000.0 + 100.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0; hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0; if (LRAND() & 1) hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0; else hp->c = 0.0; #endif if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "sqrt a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK1: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 500.0; hp->c = (LRAND() / MAXRAND) * 100.0 + 10.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 40.0; #endif hp->b = (LRAND() / MAXRAND) * 0.4; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk1 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK2: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 500.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0; #endif hp->b = pow(10.0, 6.0 + (LRAND() / MAXRAND) * 24.0); if (LRAND() & 1) hp->b = -hp->b; hp->c = pow(10.0, (LRAND() / MAXRAND) * 9.0); if (LRAND() & 1) hp->c = -hp->c; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk2 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK3: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 500.0; hp->c = (LRAND() / MAXRAND) * 80.0 + 30.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 70.0; #endif hp->b = (LRAND() / MAXRAND) * 0.35 + 0.5; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk3 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK4: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 1000.0; hp->c = (LRAND() / MAXRAND) * 40.0 + 30.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 2.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0; #endif hp->b = (LRAND() / MAXRAND) * 9.0 + 1.0; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk4 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK5: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 600.0; hp->c = (LRAND() / MAXRAND) * 90.0 + 20.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 2.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0; #endif hp->b = (LRAND() / MAXRAND) * 0.3 + 0.1; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk5 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c); break; case EJK6: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 100.0 + 550.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0; #endif hp->b = (LRAND() / MAXRAND) + 0.5; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "ejk6 a=%g, b=%g\n", hp->a, hp->b); break; case RR: #ifdef XMARTIN hp->a = (LRAND() / MAXRAND) * 100.0; hp->b = (LRAND() / MAXRAND) * 20.0; hp->c = (LRAND() / MAXRAND) * 200.0; #else hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 40.0; hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0; #endif hp->d = (LRAND() / MAXRAND) * 0.9; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "rr a=%g, b=%g, c=%g, d=%g\n", hp->a, hp->b, hp->c, hp->d); break; case POPCORN: hp->a = 0.0; hp->b = 0.0; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.24 + 0.25; hp->inc = 100; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "popcorn a=%g, b=%g, c=%g, d=%g\n", hp->a, hp->b, hp->c, hp->d); break; case JONG: hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI; hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI; hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI; hp->d = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI; if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "jong a=%g, b=%g, c=%g, d=%g\n", hp->a, hp->b, hp->c, hp->d); break; case SINE: /* MARTIN2 */ #ifdef XMARTIN hp->a = M_PI + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.07; #else hp->a = M_PI + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.7; #endif if (MI_IS_VERBOSE(mi)) (void) fprintf(stdout, "sine a=%g\n", hp->a); break; } if (MI_NPIXELS(mi) > 2) hp->pix = NRAND(MI_NPIXELS(mi)); hp->bufsize = MI_COUNT(mi); if (hp->bufsize < 1) hp->bufsize = 1; if (hp->pointBuffer == NULL) { if ((hp->pointBuffer = (XPoint *) malloc(hp->bufsize * sizeof (XPoint))) == NULL) return; } MI_CLEARWINDOW(mi); XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); hp->count = 0; }
/* Called to init the mode. */ void init_penrose(ModeInfo * mi) { tiling_c *tp; fringe_node_c *fp; int i, size; if (tilings == NULL) { if ((tilings = (tiling_c *) calloc(MI_NUM_SCREENS(mi), sizeof (tiling_c))) == NULL) return; } tp = &tilings[MI_SCREEN(mi)]; if (MI_IS_FULLRANDOM(mi)) tp->ammann = (Bool) (LRAND() & 1); else tp->ammann = ammann; tp->done = False; tp->busyLoop = 0; tp->failures = 0; tp->width = MI_WIDTH(mi); tp->height = MI_HEIGHT(mi); if (MI_NPIXELS(mi) > 2) { tp->thick_color = NRAND(MI_NPIXELS(mi)); /* Insure good contrast */ tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color + MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi); } else { if (LRAND() & 1) { tp->thick_color = MI_WHITE_PIXEL(mi); tp->thin_color = MI_BLACK_PIXEL(mi); } else { tp->thick_color = MI_BLACK_PIXEL(mi); tp->thin_color = MI_WHITE_PIXEL(mi); } } size = MI_SIZE(mi); if (size < -MINSIZE) tp->edge_length = NRAND(MIN(-size, MAX(MINSIZE, MIN(tp->width, tp->height) / 2)) - MINSIZE + 1) + MINSIZE; else if (size < MINSIZE) { if (!size) tp->edge_length = MAX(MINSIZE, MIN(tp->width, tp->height) / 2); else tp->edge_length = MINSIZE; } else tp->edge_length = MIN(size, MAX(MINSIZE, MIN(tp->width, tp->height) / 2)); tp->origin.x = (tp->width / 2 + NRAND(tp->width)) / 2; tp->origin.y = (tp->height / 2 + NRAND(tp->height)) / 2; tp->fringe.n_nodes = 2; if (tp->fringe.nodes != NULL) free_penrose(tp); if (tp->fringe.nodes != NULL || tp->forced.first != 0) { if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); (void) fprintf(stderr, "tp->fringe.nodes = NULL && tp->forced.first = 0\n"); } free_penrose(tp); /* Try again */ tp->done = True; } tp->forced.n_nodes = tp->forced.n_visible = 0; if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) { free_penrose(tp); return; } if (fp == 0) { if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); (void) fprintf(stderr, "fp = 0\n"); } if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) { free_penrose(tp); return; } tp->done = True; } /* First vertex. */ fp->rule_mask = (1 << N_VERTEX_RULES) - 1; fp->list_ptr = 0; if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) { free_penrose(tp); return; } if (fp->next == 0) { if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in init_penrose()\n"); (void) fprintf(stderr, "fp->next = 0\n"); } if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) { free_penrose(tp); return; } tp->done = True; } fp->n_tiles = 0; fp->loc = tp->origin; fp->off_screen = False; for (i = 0; i < 5; i++) fp->fived[i] = 0; /* Second vertex. */ *(fp->next) = *fp; fp->next->prev = fp->next->next = fp; fp = fp->next; i = NRAND(5); fp->fived[i] = 2 * NRAND(2) - 1; fived_to_loc(fp->fived, tp, &(fp->loc)); /* That's it! We have created our first edge. */ }
/*- * Draw a tile on the display. Vertices must be given in a * counterclockwise order. vtype is the vertex type of v1 (and thus * also gives the tile type). */ static void draw_tile(fringe_node_c * v1, fringe_node_c * v2, fringe_node_c * v3, fringe_node_c * v4, vertex_type_c vtype, ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); tiling_c *tp = &tilings[MI_SCREEN(mi)]; XPoint pts[5]; vertex_type_c corner = vtype & VT_CORNER_MASK; if (v1->off_screen && v2->off_screen && v3->off_screen && v4->off_screen) return; pts[corner] = v1->loc; pts[VT_RIGHT(corner)] = v2->loc; pts[VT_FAR(corner)] = v3->loc; pts[VT_LEFT(corner)] = v4->loc; pts[4] = pts[0]; if (MI_NPIXELS(mi) > 2) { if ((vtype & VT_TYPE_MASK) == VT_THICK) XSetForeground(display, gc, MI_PIXEL(mi, tp->thick_color)); else XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color)); } else { if ((vtype & VT_TYPE_MASK) == VT_THICK) XSetForeground(display, gc, tp->thick_color); else XSetForeground(display, gc, tp->thin_color); } XFillPolygon(display, window, gc, pts, 4, Convex, CoordModeOrigin); if (MI_NPIXELS(mi) <= 2) { if ((vtype & VT_TYPE_MASK) == VT_THICK) XSetForeground(display, gc, tp->thin_color); else XSetForeground(display, gc, tp->thick_color); } else XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); XDrawLines(display, window, gc, pts, 5, CoordModeOrigin); if (tp->ammann) { /* Draw some Ammann lines for debugging purposes. This will probably fail miserably on a b&w display. */ if ((vtype & VT_TYPE_MASK) == VT_THICK) { static float r = .0; if (r == .0) { float pi10 = 2 * atan(1.) / 5; r = 1 - sin(pi10) / (2 * sin(3 * pi10)); } if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color)); else { XSetForeground(display, gc, tp->thin_color); XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter); } XDrawLine(display, window, gc, (int) (r * pts[3].x + (1 - r) * pts[0].x + .5), (int) (r * pts[3].y + (1 - r) * pts[0].y + .5), (int) (r * pts[1].x + (1 - r) * pts[0].x + .5), (int) (r * pts[1].y + (1 - r) * pts[0].y + .5)); if (MI_NPIXELS(mi) <= 2) XSetLineAttributes(display, gc, 1, LineSolid, CapNotLast, JoinMiter); } else { if (MI_NPIXELS(mi) > 2) XSetForeground(display, gc, MI_PIXEL(mi, tp->thick_color)); else { XSetForeground(display, gc, tp->thick_color); XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter); } XDrawLine(display, window, gc, (int) ((pts[3].x + pts[2].x) / 2 + .5), (int) ((pts[3].y + pts[2].y) / 2 + .5), (int) ((pts[1].x + pts[2].x) / 2 + .5), (int) ((pts[1].y + pts[2].y) / 2 + .5)); if (MI_NPIXELS(mi) <= 2) XSetLineAttributes(display, gc, 1, LineSolid, CapNotLast, JoinMiter); } } }
/*- * Add a randomly chosen tile to a given vertex. This requires more checking * as we must make sure the new tile conforms to the vertex rules at every * vertex it touches. */ static void add_random_tile(fringe_node_c * vertex, ModeInfo * mi) { fringe_node_c *right, *left, *far; int i, j, n, n_hits, n_good; unsigned side, fc, no_good, s; vertex_type_c vtypes[MAX_COMPL]; rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES]; tiling_c *tp = &tilings[MI_SCREEN(mi)]; if (MI_NPIXELS(mi) > 2) { tp->thick_color = NRAND(MI_NPIXELS(mi)); /* Insure good contrast */ tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color + MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi); } else { unsigned long temp = tp->thick_color; tp->thick_color = tp->thin_color; tp->thin_color = temp; } n_hits = match_rules(vertex, hits, False); side = NRAND(2) ? S_LEFT : S_RIGHT; n = find_completions(vertex, hits, n_hits, side, vtypes /*, False */ ); /* One answer would mean a forced tile. */ if (n <= 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n = %d\n", n); } } no_good = 0; n_good = n; for (i = 0; i < n; i++) { fc = fringe_changes(mi, vertex, side, vtypes[i], &right, &far, &left); if (fc & FC_BAG) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG); } } if (right) { s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_LEFT)) ? S_RIGHT : S_LEFT); if (!legal_move(right, s, VT_RIGHT(vtypes[i]))) { no_good |= (1 << i); n_good--; continue; } } if (left) { s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_RIGHT)) ? S_LEFT : S_RIGHT); if (!legal_move(left, s, VT_LEFT(vtypes[i]))) { no_good |= (1 << i); n_good--; continue; } } if (far) { s = ((fc & FC_CUT_LEFT) ? S_RIGHT : S_LEFT); if (!legal_move(far, s, VT_FAR(vtypes[i]))) { no_good |= (1 << i); n_good--; } } } if (n_good <= 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n_good = %d\n", n_good); } } n = NRAND(n_good); for (i = j = 0; i <= n; i++, j++) while (no_good & (1 << j)) j++; if (!add_tile(mi, vertex, side, vtypes[j - 1])) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); } free_penrose(tp); } }
/* One step of the growth algorithm. */ void draw_penrose(ModeInfo * mi) { int i = 0, n; forced_node_c *p; tiling_c *tp; if (tilings == NULL) return; tp = &tilings[MI_SCREEN(mi)]; if (tp->fringe.nodes == NULL) return; MI_IS_DRAWN(mi) = True; p = tp->forced.first; if (tp->busyLoop > 0) { tp->busyLoop--; return; } if (tp->done || tp->failures >= 100) { init_penrose(mi); return; } /* Check for the initial "2-gon". */ if (tp->fringe.nodes->prev == tp->fringe.nodes->next) { vertex_type_c vtype = (unsigned char) (VT_TOTAL_MASK & LRAND()); MI_CLEARWINDOW(mi); if (!add_tile(mi, tp->fringe.nodes, S_LEFT, vtype)) free_penrose(tp); return; } /* No visible nodes left. */ if (tp->fringe.n_nodes == 0) { tp->done = True; tp->busyLoop = COMPLETION; /* Just finished drawing */ return; } if (tp->forced.n_visible > 0 && tp->failures < 10) { n = NRAND(tp->forced.n_visible); for (;;) { while (p->vertex->off_screen) p = p->next; if (i++ < n) p = p->next; else break; } } else if (tp->forced.n_nodes > 0) { n = NRAND(tp->forced.n_nodes); while (i++ < n) p = p->next; } else { fringe_node_c *fringe_p = tp->fringe.nodes; n = NRAND(tp->fringe.n_nodes); i = 0; for (; i <= n; i++) do { fringe_p = fringe_p->next; } while (fringe_p->off_screen); add_random_tile(fringe_p, mi); tp->failures = 0; return; } if (add_forced_tile(mi, p)) tp->failures = 0; else tp->failures++; }
ENTRYPOINT void draw_planet (ModeInfo * mi) { planetstruct *gp = &planets[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); double x, y, z; if (!gp->glx_context) return; glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glXMakeCurrent (dpy, window, *(gp->glx_context)); mi->polygon_count = 0; if (gp->button_down_p) gp->draw_axis = 60; else if (!gp->draw_axis && !(random() % 1000)) gp->draw_axis = 60 + (random() % 90); if (do_rotate && !gp->button_down_p) { gp->z -= 0.001; /* the sun sets in the west */ if (gp->z < 0) gp->z += 1; } glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glPushMatrix(); get_position (gp->rot, &x, &y, &z, !gp->button_down_p); x = (x - 0.5) * 6; y = (y - 0.5) * 6; z = (z - 0.5) * 3; glTranslatef(x, y, z); gltrackball_rotate (gp->trackball); if (do_roll) { get_rotation (gp->rot, &x, &y, 0, !gp->button_down_p); glRotatef (x * 360, 1.0, 0.0, 0.0); glRotatef (y * 360, 0.0, 1.0, 0.0); } else glRotatef (current_device_rotation(), 0, 0, 1); if (do_stars) { glDisable(GL_TEXTURE_2D); glPushMatrix(); glScalef (60, 60, 60); glRotatef (90, 1, 0, 0); glRotatef (35, 1, 0, 0); glCallList (gp->starlist); mi->polygon_count += gp->starcount; glPopMatrix(); glClear(GL_DEPTH_BUFFER_BIT); } glRotatef (90, 1, 0, 0); glRotatef (35, 1, 0, 0); glRotatef (10, 0, 1, 0); glRotatef (120, 0, 0, 1); glScalef (3, 3, 3); # ifdef HAVE_MOBILE glScalef (2, 2, 2); # endif if (wire) glColor3f (0.5, 0.5, 1); else glColor3f (1, 1, 1); if (do_texture) { glEnable(GL_TEXTURE_2D); glBindTexture (GL_TEXTURE_2D, gp->tex1); } glPushMatrix(); glRotatef (gp->z * 360, 0, 0, 1); glCallList (gp->platelist); mi->polygon_count += resolution*resolution; glPopMatrix(); /* Originally we just used GL_LIGHT0 to produce the day/night sides of the planet, but that always looked crappy, even with a vast number of polygons, because the day/night terminator didn't exactly line up with the polygon edges. So instead, draw the full "day" sphere; clear the depth buffer; draw a rotated/tilted half-sphere into the depth buffer only; then draw the "night" sphere. That lets us divide the sphere into the two maps, and the dividing line can be at any angle, regardless of polygon layout. The half-sphere is scaled slightly larger to avoid polygon fighting, since those triangles won't exactly line up because of the rotation. The downside of this is that the day/night terminator is 100% sharp. It would be nice if it was a little blurry. */ if (wire) { glPushMatrix(); glRotatef (gp->tilt, 1, 0, 0); glColor3f(0, 0, 0); glLineWidth(4); glCallList (gp->shadowlist); glLineWidth(1); mi->polygon_count += resolution*(resolution/2); glPopMatrix(); } else if (do_texture && gp->tex2) { glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_TEXTURE_2D); glColorMask (0, 0, 0, 0); glPushMatrix(); glRotatef (gp->tilt, 1, 0, 0); glScalef (1.01, 1.01, 1.01); glCallList (gp->shadowlist); mi->polygon_count += resolution*(resolution/2); glPopMatrix(); glColorMask (1, 1, 1, 1); glEnable(GL_TEXTURE_2D); glBindTexture (GL_TEXTURE_2D, gp->tex2); glPushMatrix(); glRotatef (gp->z * 360, 0, 0, 1); glCallList (gp->platelist); mi->polygon_count += resolution*resolution; glPopMatrix(); } if (gp->draw_axis) { glPushMatrix(); glRotatef (gp->z * 360, 0.0, 0.0, 1.0); glScalef (1.02, 1.02, 1.02); glDisable (GL_TEXTURE_2D); glDisable (GL_LIGHTING); glDisable (GL_LINE_SMOOTH); glColor3f (0.1, 0.3, 0.1); glCallList (gp->latlonglist); mi->polygon_count += 24*24; glPopMatrix(); if (gp->draw_axis) gp->draw_axis--; } glPopMatrix(); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }
ENTRYPOINT void init_planet (ModeInfo * mi) { planetstruct *gp; int screen = MI_SCREEN(mi); Bool wire = MI_IS_WIREFRAME(mi); if (planets == NULL) { if ((planets = (planetstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (planetstruct))) == NULL) return; } gp = &planets[screen]; if ((gp->glx_context = init_GL(mi)) != NULL) { reshape_planet(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } { char *f = get_string_resource(mi->dpy, "imageForeground", "Foreground"); char *b = get_string_resource(mi->dpy, "imageBackground", "Background"); char *s; if (!f) f = strdup("white"); if (!b) b = strdup("black"); for (s = f + strlen(f)-1; s > f; s--) if (*s == ' ' || *s == '\t') *s = 0; for (s = b + strlen(b)-1; s > b; s--) if (*s == ' ' || *s == '\t') *s = 0; if (!XParseColor(mi->dpy, mi->xgwa.colormap, f, &gp->fg)) { fprintf(stderr, "%s: unparsable color: \"%s\"\n", progname, f); exit(1); } if (!XParseColor(mi->dpy, mi->xgwa.colormap, b, &gp->bg)) { fprintf(stderr, "%s: unparsable color: \"%s\"\n", progname, f); exit(1); } free (f); free (b); } { double spin_speed = 0.1; double wander_speed = 0.005; gp->rot = make_rotator (do_roll ? spin_speed : 0, do_roll ? spin_speed : 0, 0, 1, do_wander ? wander_speed : 0, True); gp->z = frand (1.0); gp->tilt = frand (23.4); gp->trackball = gltrackball_init (True); } if (wire) do_texture = False; if (do_texture) setup_texture (mi); if (do_stars) init_stars (mi); /* construct the polygons of the planet */ gp->platelist = glGenLists(1); glNewList (gp->platelist, GL_COMPILE); glFrontFace(GL_CCW); glPushMatrix(); glRotatef (90, 1, 0, 0); unit_sphere (resolution, resolution, wire); glPopMatrix(); glEndList(); gp->shadowlist = glGenLists(1); glNewList (gp->shadowlist, GL_COMPILE); glFrontFace(GL_CCW); unit_dome (resolution, resolution, wire); glEndList(); /* construct the polygons of the latitude/longitude/axis lines. */ gp->latlonglist = glGenLists(1); glNewList (gp->latlonglist, GL_COMPILE); glPushMatrix (); glRotatef (90, 1, 0, 0); /* unit_sphere is off by 90 */ glRotatef (8, 0, 1, 0); /* line up the time zones */ unit_sphere (12, 24, 1); unit_sphere (12, 24, 1); glBegin(GL_LINES); glVertex3f(0, -2, 0); glVertex3f(0, 2, 0); glEnd(); glPopMatrix (); glEndList(); }
ENTRYPOINT void draw_cow (ModeInfo *mi) { cow_configuration *bp = &bps[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i; if (!bp->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); # 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/h); glRotatef(o, 0, 0, 1); } # endif glScalef (0.5, 0.5, 0.5); mi->polygon_count = 0; # if 0 { floater F; F.x = F.y = F.z = 0; F.dx = F.dy = F.dz = 0; F.ddx = F.ddy = F.ddz = 0; F.rot = make_rotator (0, 0, 0, 1, 0, False); glScalef(2,2,2); draw_floater (mi, &F); } # else for (i = 0; i < bp->nfloaters; i++) { /* "Don't kid yourself, Jimmy. If a cow ever got the chance, he'd eat you and everyone you care about!" -- Troy McClure in "Meat and You: Partners in Freedom" */ floater *f = &bp->floaters[i]; draw_floater (mi, f); tick_floater (mi, f); } # endif glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }
static void draw_frame (ModeInfo *mi, image_frame *frame, time_t now, Bool body_p) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); GLfloat texw = frame->current.geom.width / (GLfloat) frame->current.tw; GLfloat texh = frame->current.geom.height / (GLfloat) frame->current.th; GLfloat texx1 = frame->current.geom.x / (GLfloat) frame->current.tw; GLfloat texy1 = frame->current.geom.y / (GLfloat) frame->current.th; GLfloat texx2 = texx1 + texw; GLfloat texy2 = texy1 + texh; GLfloat aspect = ((GLfloat) frame->current.geom.height / (GLfloat) frame->current.geom.width); glBindTexture (GL_TEXTURE_2D, frame->current.texid); glPushMatrix(); /* Position this image on the wheel. */ glRotatef (frame->theta, 0, 1, 0); glTranslatef (0, 0, frame->r); /* Scale down the image so that all N frames fit on the wheel without bumping in to each other. */ { GLfloat t, s; switch (ss->nframes) { case 1: t = -1.0; s = 1.7; break; case 2: t = -0.8; s = 1.6; break; case 3: t = -0.4; s = 1.5; break; case 4: t = -0.2; s = 1.3; break; default: t = 0.0; s = 6.0 / ss->nframes; break; } glTranslatef (0, 0, t); glScalef (s, s, s); } /* Center this image on the wheel plane. */ glTranslatef (-0.5, -(aspect/2), 0); /* Move as per the "zoom in and out" setting. */ if (zoom_p) { double x, y, z; /* Only use the Z component of the rotator for in/out position. */ get_position (frame->rot, &x, &y, &z, !ss->button_down_p); glTranslatef (0, 0, z/2); } /* Compute the "drop in and out" state. */ switch (frame->mode) { case EARLY: abort(); break; case NORMAL: if (!ss->button_down_p && now >= frame->expires && ss->loads_in_progress == 0) /* only load one at a time */ load_image (mi, frame); break; case LOADING: break; case OUT: if (--frame->mode_tick <= 0) { image swap = frame->current; frame->current = frame->loading; frame->loading = swap; frame->mode = IN; frame->mode_tick = fade_ticks / speed; } break; case IN: if (--frame->mode_tick <= 0) frame->mode = NORMAL; break; default: abort(); } /* Now translate for current in/out state. */ if (frame->mode == OUT || frame->mode == IN) { GLfloat t = (frame->mode == OUT ? frame->mode_tick / (fade_ticks / speed) : (((fade_ticks / speed) - frame->mode_tick + 1) / (fade_ticks / speed))); t = 5 * (1 - t); if (frame->from_top_p) t = -t; glTranslatef (0, t, 0); } if (body_p) /* Draw the image quad. */ { if (! wire) { glColor3f (1, 1, 1); glNormal3f (0, 0, 1); glEnable (GL_TEXTURE_2D); glBegin (GL_QUADS); glNormal3f (0, 0, 1); glTexCoord2f (texx1, texy2); glVertex3f (0, 0, 0); glTexCoord2f (texx2, texy2); glVertex3f (1, 0, 0); glTexCoord2f (texx2, texy1); glVertex3f (1, aspect, 0); glTexCoord2f (texx1, texy1); glVertex3f (0, aspect, 0); glEnd(); } /* Draw a box around it. */ glLineWidth (2.0); glColor3f (0.5, 0.5, 0.5); glDisable (GL_TEXTURE_2D); glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (1, 0, 0); glVertex3f (1, aspect, 0); glVertex3f (0, aspect, 0); glEnd(); } else /* Draw a title under the image. */ { XCharStruct e; int sw, sh; GLfloat scale = 0.05; char *title = frame->current.title ? frame->current.title : "(untitled)"; texture_string_metrics (ss->texfont, title, &e, 0, 0); sw = e.width; sh = e.ascent + e.descent; glTranslatef (0, -scale, 0); scale /= sh; glScalef (scale, scale, scale); glTranslatef (((1/scale) - sw) / 2, 0, 0); glColor3f (1, 1, 1); if (!wire) { glEnable (GL_TEXTURE_2D); print_texture_string (ss->texfont, title); } else { glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (sw, 0, 0); glVertex3f (sw, sh, 0); glVertex3f (0, sh, 0); glEnd(); } } glPopMatrix(); }
/*- * Add a tile described by vtype to the side of vertex. This must be * allowed by the rules -- we do not check it here. New vertices are * allocated as necessary. The fringe and the forced vertex pool are updated. * The new tile is drawn on the display. * * One thing we do check here is whether the new tile causes an untiled * area to become enclosed by the tiling. If this would happen, the tile * is not added. The return value is true iff a tile was added. */ static int add_tile(ModeInfo * mi, fringe_node_c * vertex, unsigned side, vertex_type_c vtype) { tiling_c *tp = &tilings[MI_SCREEN(mi)]; fringe_node_c *left = (fringe_node_c *) NULL, *right = (fringe_node_c *) NULL, *far = (fringe_node_c *) NULL, *node; unsigned fc = fringe_changes(mi, vertex, side, vtype, &right, &far, &left); vertex_type_c ltype = VT_LEFT(vtype), rtype = VT_RIGHT(vtype), ftype = VT_FAR(vtype); /* By our conventions vertex->next lies to the left of vertex and vertex->prev to the right. */ /* This should never occur. */ if (fc & FC_BAG) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_tile()\n"); (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG); } } if (side == S_LEFT) { if (right == NULL) if ((right = alloc_vertex(mi, vertex_dir(mi, vertex, S_LEFT) - vtype_angle(vtype), vertex, tp)) == NULL) return False; if (far == NULL) if ((far = alloc_vertex(mi, vertex_dir(mi, left, S_RIGHT) + vtype_angle(ltype), left, tp)) == NULL) return False; } else { if (left == NULL) if ((left = alloc_vertex(mi, vertex_dir(mi, vertex, S_RIGHT) + vtype_angle(vtype), vertex, tp)) == NULL) return False; if (far == NULL) if ((far = alloc_vertex(mi, vertex_dir(mi, right, S_LEFT) - vtype_angle(rtype), right, tp)) == NULL) return False; } /* Having allocated the new vertices, but before joining them with the rest of the fringe, check if vertices with same coordinates already exist. If any such are found, give up. */ node = tp->fringe.nodes; do { if (((fc & FC_NEW_LEFT) && fived_equal(node->fived, left->fived)) || ((fc & FC_NEW_RIGHT) && fived_equal(node->fived, right->fived)) || ((fc & FC_NEW_FAR) && fived_equal(node->fived, far->fived))) { /* Better luck next time. */ if (fc & FC_NEW_LEFT) delete_vertex(mi, left, tp); if (fc & FC_NEW_RIGHT) delete_vertex(mi, right, tp); if (fc & FC_NEW_FAR) delete_vertex(mi, far, tp); return False; } node = node->next; } while (node != tp->fringe.nodes); /* Rechain. */ if (!(fc & FC_CUT_THIS)) { if (side == S_LEFT) { vertex->next = right; right->prev = vertex; } else { vertex->prev = left; left->next = vertex; } } if (!(fc & FC_CUT_FAR)) { if (!(fc & FC_CUT_LEFT)) { far->next = left; left->prev = far; } if (!(fc & FC_CUT_RIGHT)) { far->prev = right; right->next = far; } } draw_tile(vertex, right, far, left, vtype, mi); /* Delete vertices that are no longer on the fringe. Check the others. */ if (fc & FC_CUT_THIS) { tp->fringe.nodes = far; delete_vertex(mi, vertex, tp); } else { add_vtype(vertex, side, vtype); check_vertex(mi, vertex, tp); tp->fringe.nodes = vertex; } if (fc & FC_CUT_FAR) delete_vertex(mi, far, tp); else { add_vtype(far, fc & FC_CUT_RIGHT ? S_LEFT : S_RIGHT, ftype); check_vertex(mi, far, tp); } if (fc & FC_CUT_LEFT) delete_vertex(mi, left, tp); else { add_vtype(left, fc & FC_CUT_FAR ? S_LEFT : S_RIGHT, ltype); check_vertex(mi, left, tp); } if (fc & FC_CUT_RIGHT) delete_vertex(mi, right, tp); else { add_vtype(right, fc & FC_CUT_FAR ? S_RIGHT : S_LEFT, rtype); check_vertex(mi, right, tp); } return True; }
ENTRYPOINT void draw_carousel (ModeInfo *mi) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int i; if (!ss->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(ss->glx_context)); if (ss->awaiting_first_images_p) if (!load_initial_images (mi)) return; /* Only check the wall clock every 10 frames */ { if (ss->now == 0 || ss->draw_tick++ > 10) { ss->now = time((time_t *) 0); if (ss->last_time == 0) ss->last_time = ss->now; ss->draw_tick = 0; } } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(current_device_rotation(), 0, 0, 1); /* Run the startup "un-shrink" animation. */ switch (ss->mode) { case IN: if (--ss->mode_tick <= 0) { ss->mode = NORMAL; ss->last_time = time((time_t *) 0); } break; case NORMAL: break; default: abort(); } /* Scale as per the startup "un-shrink" animation. */ if (ss->mode != NORMAL) { GLfloat s = (ss->mode == OUT ? ss->mode_tick / (fade_ticks / speed) : (((fade_ticks / speed) - ss->mode_tick + 1) / (fade_ticks / speed))); glScalef (s, s, s); } /* Rotate and tilt as per the user, and the motion modeller. */ { double x, y, z; gltrackball_rotate (ss->trackball); /* Tilt the tube up or down by up to 30 degrees */ get_position (ss->rot, &x, &y, &z, !ss->button_down_p); if (tilt_x_p) glRotatef (15 - (x * 30), 1, 0, 0); if (tilt_y_p) glRotatef (7 - (y * 14), 0, 0, 1); /* Only use the Y component of the rotator. */ get_rotation (ss->rot, &x, &y, &z, !ss->button_down_p); glRotatef (y * 360, 0, 1, 0); } /* First draw each image, then draw the titles. GL insists that you draw back-to-front in order to make alpha blending work properly, so we need to draw all of the 100% opaque images before drawing any of the not-100%-opaque titles. */ for (i = 0; i < ss->nframes; i++) draw_frame (mi, ss->frames[i], ss->now, True); if (titles_p) for (i = 0; i < ss->nframes; i++) draw_frame (mi, ss->frames[i], ss->now, False); glPopMatrix(); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi)); }
static void Init(ModeInfo *mi) { atlantisstruct *ap = &atlantis[MI_SCREEN(mi)]; static const float ambient[] = {0.1, 0.1, 0.1, 1.0}; static const float diffuse[] = {1.0, 1.0, 1.0, 1.0}; static const float position[] = {0.0, 1.0, 0.0, 0.0}; static const float mat_shininess[] = {90.0}; static const float mat_specular[] = {0.8, 0.8, 0.8, 1.0}; static const float mat_diffuse[] = {0.46, 0.66, 0.795, 1.0}; static const float mat_ambient[] = {0.0, 0.1, 0.2, 1.0}; static const float lmodel_ambient[] = {0.4, 0.4, 0.4, 1.0}; static const float lmodel_localviewer[] = {0.0}; float fblue = 0.0, fgreen; glFrontFace(GL_CCW); if (ap->wire) { glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); } else { glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_localviewer); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); } if (ap->wire || !do_texture) { glDisable(GL_TEXTURE_2D); } else { GLfloat scale = 0.0005; if (!ap->texture) parse_image_data (mi); clear_gl_error(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ap->texture->width, ap->texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ap->texture->data); check_gl_error("texture"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); # ifndef HAVE_JWZGLES { GLfloat s_plane[] = { 1, 0, 0, 0 }; GLfloat t_plane[] = { 0, 0, 1, 0 }; glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } # endif glEnable(GL_TEXTURE_2D); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(scale, scale, 1); glMatrixMode(GL_MODELVIEW); } InitFishs(ap); /* Add a little randomness */ fblue = ((float) (NRAND(30)) / 100.0) + 0.70; fgreen = fblue * 0.56; glClearColor(0.0, fgreen, fblue, 1.0); }
ENTRYPOINT void draw_tunnel (ModeInfo *mi) { tunnel_configuration *tc = &tconf[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); if (!tc->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(tc->glx_context)); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); /* glEnable(GL_CULL_FACE); */ glClear(GL_COLOR_BUFFER_BIT ); update_animation(tc); glPushMatrix (); glRotatef(180., 0., 1., 0.); gltrackball_rotate (tc->trackball); glRotatef(180., 0., 1., 0.); mi->polygon_count = 0; update_fog(tc->effects[4].state[0], /*color*/ tc->effects[4].state[1], /*density*/ tc->effects[4].state[2], /*start*/ tc->effects[4].state[3]); /*end*/ /* --- begin composite image assembly --- */ /* head mask and draw diamond tunnel */ glEnable(GL_BLEND); draw_cyl(mi, tc, tc->effects[6].state[0], 5, tc->diamondlist, 2); if (drawlogo) draw_sign(mi, tc,tc->effects[12].state[0], tc->effects[12].state[1], 1.0 / 1.33, 9, 1); glDisable(GL_BLEND); /* then tardis tunnel */ make_wall_tunnel(mi, tc, tc->effects[1].state[0], tc->effects[7].state[0]); /* then cylinder tunnel */ glEnable(GL_BLEND); draw_cyl(mi, tc, tc->effects[3].state[0], 2, tc->cyllist, 1); /*void draw_sign(mi, tc,z,alpha,aspect,tex,blendmode)*/ /* tardis */ if (drawlogo) draw_sign(mi, tc, tc->effects[2].state[0], tc->effects[2].state[1], 2.0, 1, 0); /* marquee */ if (drawlogo) draw_sign(mi, tc, tc->effects[5].state[0], tc->effects[5].state[1], 1.0, 3, 0); /*who head brite*/ if (drawlogo) draw_sign(mi, tc,1.0, tc->effects[10].state[0], 1.0 / 1.33, 6, 2); /*who head psychadelic REMOVED*/ /* draw_sign(mi, tc,1.0, tc->effects[11].state[0], 1.0 / 1.33, 8, 0); */ /* star */ /* draw_sign(mi, tc, tc->effects[8].state[0]tc->effects[8].state[0], 1.0 , 1.0, 4, 1); */ draw_sign(mi, tc, tc->effects[8].state[0], tc->effects[8].state[0], 1.0, 4, 1); /* normal head */ if (drawlogo) draw_sign(mi, tc,1.0, tc->effects[9].state[0], 1.0 / 1.33, 6, 0); /* --- end composite image assembly --- */ glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); check_gl_error("drawing done, calling swap buffers"); glXSwapBuffers(dpy, window); }
void init_life1d(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int size = MI_SIZE(mi); int i; life1dstruct *lp; if (life1ds == NULL) { if ((life1ds = (life1dstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (life1dstruct))) == NULL) return; } lp = &life1ds[MI_SCREEN(mi)]; if (!init_stuff(mi)) { free_life1d(display, lp); return; } lp->screen_generation = 0; lp->row = 0; if (totalistic) { maxstates = MAXSTATES; maxradius = 4; maxsum_size = (maxstates - 1) * (maxradius * 2 + 1) + 1; } else { maxstates = MAXSTATES - 1; maxradius = 1; maxsum_size = (int) power(maxstates, (2 * maxradius + 1)); } if (lp->nextstate == NULL) { if ((lp->nextstate = (char *) malloc(maxsum_size * sizeof (char))) == NULL) { free_life1d(display, lp); return; } } if (lp->init_bits == 0) { XGCValues gcv; gcv.fill_style = FillOpaqueStippled; if ((lp->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv)) == None) { free_life1d(display, lp); return; } for (i = 0; i < MAXSTATES - 1; i++) { LIFE1DBITS(stipples[i + NUMSTIPPLES - MAXSTATES + 1], STIPPLESIZE, STIPPLESIZE); } LIFE1DBITS(stipples[NUMSTIPPLES / 2], STIPPLESIZE, STIPPLESIZE); /* grey */ } if (lp->newcells != NULL) free(lp->newcells); if (lp->oldcells != NULL) free(lp->oldcells); if (lp->buffer != NULL) free(lp->buffer); if (lp->previousBuffer != NULL) free(lp->previousBuffer); lp->previousBuffer = (unsigned char *) NULL; lp->width = MI_WIDTH(mi); lp->height = MI_HEIGHT(mi); if (lp->width < 2) lp->width = 2; if (lp->height < 2) lp->height = 2; if (size == 0 || MINGRIDSIZE * size > lp->width || MINGRIDSIZE * size > lp->height) { if (lp->width > MINGRIDSIZE * lp->logo->width && lp->height > MINGRIDSIZE * lp->logo->height) { lp->pixelmode = False; lp->xs = lp->logo->width; lp->ys = lp->logo->height; } else { int min = MIN(lp->width, lp->height) / (12 * MINGRIDSIZE); int max = MIN(lp->width, lp->height) / (4 * MINGRIDSIZE); lp->xs = lp->ys = MAX(MINSIZE, min + NRAND(max - min + 1)); lp->pixelmode = True; } } else { lp->pixelmode = True; if (size < -MINSIZE) { lp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(lp->width, lp->height) / MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; } else if (size < MINSIZE) { lp->ys = MINSIZE; } else { lp->ys = MIN(size, MAX(MINSIZE, MIN(lp->width, lp->height) / MINGRIDSIZE)); } lp->xs = lp->ys; } lp->ncols = MAX(lp->width / lp->xs, 2); lp->nrows = MAX(lp->height / lp->ys, 2); lp->border = (lp->nrows / 2 + 1) * MI_CYCLES(mi); if ((lp->newcells = (unsigned char *) calloc(lp->ncols + 2 * lp->border, sizeof (unsigned char))) == NULL) { free_life1d(display, lp); return; } if ((lp->oldcells = (unsigned char *) calloc(lp->ncols + 2 * (maxradius + lp->border), sizeof (unsigned char))) == NULL) { free_life1d(display, lp); return; } if ((lp->buffer = (unsigned char *) calloc(lp->ncols * lp->nrows, sizeof (unsigned char))) == NULL) { free_life1d(display, lp); return; } lp->xb = (lp->width - lp->xs * lp->ncols) / 2; lp->yb = (lp->height - lp->ys * lp->nrows) / 2; GetRule(lp, (int) NRAND((totalistic) ? TOTALISTICRULES : LCAURULES)); if (MI_IS_VERBOSE(mi)) { (void) fprintf(stdout, "colors %d, radius %d, code %ld, ", lp->k, lp->r, lp->code); if (totalistic) { (void) fprintf(stdout, "totalistic rule "); for (i = (lp->k - 1) * (lp->r * 2 + 1); i >= 0; i--) (void) fprintf(stdout, "%d", (int) lp->nextstate[i]); } else { (void) fprintf(stdout, "LCAU rule "); for (i = (int) power(lp->k, (lp->r * 2 + 1)); i >= 0; i--) (void) fprintf(stdout, "%d", (int) lp->nextstate[i]); } (void) fprintf(stdout, "\n"); } if (MI_NPIXELS(mi) > 2) for (i = 0; i < lp->k - 1; i++) lp->colors[i] = (NRAND(MI_NPIXELS(mi)) + i * MI_NPIXELS(mi)) / (lp->k - 1); RandomSoup(lp, 40, 25); (void) memcpy((char *) (lp->oldcells + maxradius + lp->border), (char *) (lp->newcells + lp->border), lp->ncols); lp->busyLoop = 0; MI_CLEARWINDOWCOLORMAP(mi, lp->backGC, lp->black); }
void draw_hop(ModeInfo * mi) { double oldj, oldi; XPoint *xp; int k; hopstruct *hp; if (hops == NULL) return; hp = &hops[MI_SCREEN(mi)]; if (hp->pointBuffer == NULL) return; xp = hp->pointBuffer; k = hp->bufsize; MI_IS_DRAWN(mi) = True; hp->inc++; if (MI_NPIXELS(mi) > 2) { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_PIXEL(mi, hp->pix)); if (++hp->pix >= MI_NPIXELS(mi)) hp->pix = 0; } while (k--) { oldj = hp->j; switch (hp->op) { case MARTIN: /* SQRT, MARTIN1 */ oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj + ((hp->i < 0) ? sqrt(fabs(hp->b * oldi - hp->c)) : -sqrt(fabs(hp->b * oldi - hp->c))); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK1: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i > 0) ? (hp->b * oldi - hp->c) : -(hp->b * oldi - hp->c)); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK2: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i < 0) ? log(fabs(hp->b * oldi - hp->c)) : -log(fabs(hp->b * oldi - hp->c))); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK3: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i > 0) ? sin(hp->b * oldi) - hp->c : -sin(hp->b * oldi) - hp->c); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK4: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i > 0) ? sin(hp->b * oldi) - hp->c : -sqrt(fabs(hp->b * oldi - hp->c))); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK5: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i > 0) ? sin(hp->b * oldi) - hp->c : -(hp->b * oldi - hp->c)); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case EJK6: oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - asin((hp->b * oldi) - (long) (hp->b * oldi)); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case RR: /* RR1 */ oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - ((hp->i < 0) ? -pow(fabs(hp->b * oldi - hp->c), hp->d) : pow(fabs(hp->b * oldi - hp->c), hp->d)); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; case POPCORN: #define HVAL 0.05 #define INCVAL 50 { double tempi, tempj; if (hp->inc >= 100) hp->inc = 0; if (hp->inc == 0) { if (hp->a++ >= INCVAL) { hp->a = 0; if (hp->b++ >= INCVAL) hp->b = 0; } hp->i = (-hp->c * INCVAL / 2 + hp->c * hp->a) * M_PI / 180.0; hp->j = (-hp->c * INCVAL / 2 + hp->c * hp->b) * M_PI / 180.0; } tempi = hp->i - HVAL * sin(hp->j + tan(3.0 * hp->j)); tempj = hp->j - HVAL * sin(hp->i + tan(3.0 * hp->i)); xp->x = hp->centerx + (int) (MI_WIDTH(mi) / 40 * tempi); xp->y = hp->centery + (int) (MI_HEIGHT(mi) / 40 * tempj); hp->i = tempi; hp->j = tempj; } break; case JONG: if (hp->centerx > 0) oldi = hp->i + 4 * hp->inc / hp->centerx; else oldi = hp->i; hp->j = sin(hp->c * hp->i) - cos(hp->d * hp->j); hp->i = sin(hp->a * oldj) - cos(hp->b * oldi); xp->x = hp->centerx + (int) (hp->centerx * (hp->i + hp->j) / 4.0); xp->y = hp->centery - (int) (hp->centery * (hp->i - hp->j) / 4.0); break; case SINE: /* MARTIN2 */ oldi = hp->i + hp->inc; hp->j = hp->a - hp->i; hp->i = oldj - sin(oldi); xp->x = hp->centerx + (int) (hp->i + hp->j); xp->y = hp->centery - (int) (hp->i - hp->j); break; } xp++; } XDrawPoints(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), hp->pointBuffer, hp->bufsize, CoordModeOrigin); if (++hp->count > MI_CYCLES(mi)) { init_hop(mi); } }
void draw_life1d(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); int col; life1dstruct *lp; if (life1ds == NULL) return; lp = &life1ds[MI_SCREEN(mi)]; if (lp->buffer == NULL) return; MI_IS_DRAWN(mi) = True; if (lp->busyLoop) { if (lp->busyLoop >= 250) lp->busyLoop = 0; else lp->busyLoop++; return; } if (lp->row == 0) { lp->repeating = 0; if (lp->screen_generation > MI_CYCLES(mi)) init_life1d(mi); if (!lp->previousBuffer && lp->screen_generation > 1) { lp->previousBuffer = (unsigned char *) calloc(lp->ncols * lp->nrows, sizeof (unsigned char)); } if (lp->previousBuffer) { (void) memcpy((char *) (lp->previousBuffer), (char *) (lp->buffer), lp->nrows * lp->ncols); } for (col = 0; col < lp->ncols; col++) if (lp->buffer[col] != lp->newcells[col + lp->border]) drawcell(mi, col, 0, lp->newcells[col + lp->border]); (void) memcpy((char *) lp->buffer, (char *) (lp->newcells + lp->border), lp->ncols); } else { for (col = 0; col < lp->ncols + 2 * lp->border; col++) { int sum = 0, m; if (totalistic) { for (m = col - lp->r; m <= col + lp->r; m++) sum += lp->oldcells[m + maxradius]; } else { int pow_size = 1; for (m = col + lp->r; m >= col - lp->r; m--) { sum += lp->oldcells[m + maxradius] * pow_size; pow_size *= lp->k; } } lp->newcells[col] = (unsigned char) lp->nextstate[sum]; } (void) memcpy((char *) (lp->oldcells + maxradius), (char *) lp->newcells, lp->ncols + 2 * lp->border); for (col = 0; col < lp->ncols; col++) { if (lp->buffer[col + lp->row * lp->ncols] != lp->newcells[col + lp->border]) drawcell(mi, col, lp->row, lp->newcells[col + lp->border]); } (void) memcpy((char *) (lp->buffer + lp->row * lp->ncols), (char *) (lp->newcells + lp->border), lp->ncols); { int temp = compare(mi); if (temp) lp->repeating += temp; else lp->repeating = 0; } lp->repeating += (lp->row == lp->nrows - 1) ? (lp->nrows - 1) * compare(mi) : 0; } if (lp->repeating >= 1) { XGCValues gcv; gcv.stipple = lp->pixmaps[MAXSTATES - 1]; gcv.fill_style = FillStippled; gcv.foreground = lp->black; XChangeGC(MI_DISPLAY(mi), lp->stippledGC, GCStipple | GCFillStyle | GCForeground, &gcv); XFillRectangle(display, MI_WINDOW(mi), lp->stippledGC, 0, lp->yb + lp->ys * lp->row, lp->width, lp->ys); } lp->row++; if (lp->repeating >= lp->nrows - 1) { if (lp->row < lp->nrows) { XSetForeground(display, lp->backGC, lp->black); XFillRectangle(display, MI_WINDOW(mi), lp->backGC, 0, lp->yb + lp->ys * lp->row, lp->width, lp->height - lp->ys * lp->row - lp->yb); } lp->screen_generation = MI_CYCLES(mi); lp->row = lp->nrows; } if (lp->row >= lp->nrows) { lp->screen_generation++; lp->busyLoop = 1; lp->row = 0; } }
ENTRYPOINT void draw_mgears (ModeInfo *mi) { mgears_configuration *bp = &bps[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i; if (!bp->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context)); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glScalef(1.1, 1.1, 1.1); { double x, y, z; get_position (bp->rot, &x, &y, &z, !bp->button_down_p); glTranslatef ((x - 0.5) * 4, (y - 0.5) * 4, (z - 0.5) * 7); /* Do it twice because we don't track the device's orientation. */ glRotatef( current_device_rotation(), 0, 0, 1); gltrackball_rotate (bp->trackball); glRotatef(-current_device_rotation(), 0, 0, 1); get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p); /* add a little rotation for -no-spin mode */ x -= 0.14; y -= 0.06; 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); } mi->polygon_count = 0; glScalef (1.5, 1.5, 1.5); /*#define DEBUG*/ #ifdef DEBUG glScalef (.5, .5, .5); glTranslatef (0, -bp->gears[0].g.r * bp->ngears, 0); #endif for (i = 0; i < bp->ngears; i++) { mogear *mg = &bp->gears[i]; gear *g = &mg->g; glPushMatrix(); #ifndef DEBUG glRotatef (mg->pos_th * 180 / M_PI, 0, 0, 1); /* rotation on ring */ glTranslatef (bp->ring_r, 0, 0); /* position on ring */ glRotatef (mg->pos_thz * 180 / M_PI, 0, 1, 0); /* twist a bit */ if (do_roll) { glRotatef (bp->roll_th * 180 / M_PI, 0, 1, 0); bp->roll_th += speed * 0.0005; } #else glTranslatef (0, i * 2 * g->r, 0); #endif glRotatef (g->th * 180 / M_PI, 0, 0, 1); glCallList (g->dlist); mi->polygon_count += g->polygons; glPopMatrix (); } glPopMatrix (); #ifndef DEBUG /* spin gears */ for (i = 0; i < bp->ngears; i++) { mogear *mg = &bp->gears[i]; mg->g.th += speed * (M_PI / 100) * (i & 1 ? 1 : -1); } #endif if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }
/* Callback that tells us that the texture has been loaded. */ static void image_loaded_cb (const char *filename, XRectangle *geom, int image_width, int image_height, int texture_width, int texture_height, void *closure) { image_frame *frame = (image_frame *) closure; ModeInfo *mi = frame->mi; carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); if (wire) { frame->loading.w = MI_WIDTH (mi) * (0.5 + frand (1.0)); frame->loading.h = MI_HEIGHT (mi); frame->loading.geom.width = frame->loading.w; frame->loading.geom.height = frame->loading.h; goto DONE; } if (image_width == 0 || image_height == 0) exit (1); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); if (ss->anisotropic >= 1.0) glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, ss->anisotropic); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); frame->loading.w = image_width; frame->loading.h = image_height; frame->loading.tw = texture_width; frame->loading.th = texture_height; frame->loading.geom = *geom; if (frame->loading.title) free (frame->loading.title); frame->loading.title = (filename ? strdup (filename) : 0); /* xscreensaver-getimage returns paths relative to the image directory now, so leave the sub-directory part in. Unless it's an absolute path. */ if (frame->loading.title && frame->loading.title[0] == '/') { /* strip filename to part after last /. */ char *s = strrchr (frame->loading.title, '/'); if (s) strcpy (frame->loading.title, s+1); } if (debug_p) fprintf (stderr, "%s: loaded %4d x %-4d %4d x %-4d \"%s\"\n", progname, frame->loading.geom.width, frame->loading.geom.height, frame->loading.tw, frame->loading.th, (frame->loading.title ? frame->loading.title : "(null)")); DONE: frame->loaded_p = True; if (ss->loads_in_progress <= 0) abort(); ss->loads_in_progress--; /* This image expires N seconds after it finished loading. */ frame->expires = time((time_t *) 0) + (duration * MI_COUNT(mi)); switch (frame->mode) { case EARLY: /* part of the initial batch of images */ { image swap = frame->current; frame->current = frame->loading; frame->loading = swap; } break; case LOADING: /* start dropping the old image out */ { frame->mode = OUT; frame->mode_tick = fade_ticks / speed; frame->from_top_p = random() & 1; } break; default: abort(); } }
static void draw_floater (ModeInfo *mi, floater *f) { toaster_configuration *bp = &bps[MI_SCREEN(mi)]; GLfloat n; glFrontFace(GL_CCW); glPushMatrix(); glTranslatef (f->x, f->y, f->z); if (f->toaster_p) { glPushMatrix(); glRotatef (180, 0, 1, 0); glCallList (bp->dlists[BASE_TOASTER]); mi->polygon_count += (*all_objs[BASE_TOASTER])->points / 3; glPopMatrix(); glPushMatrix(); glTranslatef(0, 1.01, 0); n = 0.91; glScalef(n,n,n); glCallList (bp->dlists[SLOTS]); mi->polygon_count += (*all_objs[SLOTS])->points / 3; glPopMatrix(); glPushMatrix(); glRotatef (180, 0, 1, 0); glTranslatef(0, -0.4, -2.38); n = 0.33; glScalef(n,n,n); glCallList (bp->dlists[HANDLE_SLOT]); mi->polygon_count += (*all_objs[HANDLE_SLOT])->points / 3; glPopMatrix(); glPushMatrix(); glTranslatef(0, -1.1, 3); n = 0.3; glScalef (n,n,n); glTranslatef(0, f->handle_pos * 4.8, 0); glCallList (bp->dlists[HANDLE]); mi->polygon_count += (*all_objs[HANDLE])->points / 3; glPopMatrix(); glPushMatrix(); glRotatef (180, 0, 1, 0); glTranslatef(0, -1.1, -3); /* where the handle is */ glTranslatef (1, -0.4, 0); /* down and to the left */ n = 0.08; glScalef (n,n,n); glRotatef (f->knob_pos, 0, 0, 1); glCallList (bp->dlists[KNOB]); mi->polygon_count += (*all_objs[KNOB])->points / 3; glPopMatrix(); glPushMatrix(); glRotatef (180, 0, 1, 0); glTranslatef (0, -2.3, 0); glCallList (bp->dlists[BASE]); mi->polygon_count += (*all_objs[BASE])->points / 3; glPopMatrix(); glPushMatrix(); glTranslatef(-4.8, 0, 0); glCallList (bp->dlists[JET_WING]); mi->polygon_count += (*all_objs[JET_WING])->points / 3; glScalef (0.5, 0.5, 0.5); glTranslatef (-2, -1, 0); glCallList (bp->dlists[JET]); mi->polygon_count += (*all_objs[JET])->points / 3; glPopMatrix(); glPushMatrix(); glTranslatef(4.8, 0, 0); glScalef(-1, 1, 1); glFrontFace(GL_CW); glCallList (bp->dlists[JET_WING]); mi->polygon_count += (*all_objs[JET_WING])->points / 3; glScalef (0.5, 0.5, 0.5); glTranslatef (-2, -1, 0); glCallList (bp->dlists[JET]); mi->polygon_count += (*all_objs[JET])->points / 3; glFrontFace(GL_CCW); glPopMatrix(); if (f->loaded) { glPushMatrix(); glTranslatef(0, 1.01, 0); n = 0.91; glScalef(n,n,n); glRotatef (90, 0, 0, 1); glRotatef (90, 0, 1, 0); glTranslatef(0, 0, -0.95); glTranslatef(0, 0.72, 0); if (f->loaded & 1) { glCallList (bp->dlists[TOAST]); mi->polygon_count += (*all_objs[TOAST])->points / 3; } glTranslatef(0, -1.46, 0); if (f->loaded & 2) { glCallList (bp->dlists[TOAST]); mi->polygon_count += (*all_objs[TOAST])->points / 3; } glPopMatrix(); } } else { glScalef (0.7, 0.7, 0.7); if (f->toast_type == 0) { glCallList (bp->dlists[TOAST]); mi->polygon_count += (*all_objs[TOAST])->points / 3; } else { glCallList (bp->dlists[TOAST_BITTEN]); mi->polygon_count += (*all_objs[TOAST_BITTEN])->points / 3; } } glPopMatrix(); }
static void loading_msg (ModeInfo *mi, int n) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); char text[100]; if (wire) return; if (n == 0) sprintf (text, "Loading images..."); else sprintf (text, "Loading images... (%d%%)", (int) (n * 100 / MI_COUNT(mi))); if (ss->loading_sw == 0) { /* only do this once, so that the string doesn't move. */ XCharStruct e; texture_string_metrics (ss->texfont, text, &e, 0, 0); ss->loading_sw = e.width; ss->loading_sh = e.ascent + e.descent; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); /* { double rot = current_device_rotation(); glRotatef(rot, 0, 0, 1); if ((rot > 45 && rot < 135) || (rot < -45 && rot > -135)) { GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi); glScalef (s, 1/s, 1); } } */ # ifdef HAVE_MOBILE if (MI_WIDTH(mi) < MI_HEIGHT(mi)) /* portrait orientation */ { GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)); glScalef (s, s, s); glTranslatef(-s/2, 0, 0); } # endif glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1); glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2, (MI_HEIGHT(mi) - ss->loading_sh) / 2, 0); glColor3f (1, 1, 0); glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); print_texture_string (ss->texfont, text); glEnable (GL_DEPTH_TEST); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glFinish(); glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi)); }
static void draw(ModeInfo *mi) { Bool wireframe_p = MI_IS_WIREFRAME(mi); gasketstruct *gp = &gasket[MI_SCREEN(mi)]; static const GLfloat pos[] = {-4.0, 3.0, 10.0, 1.0}; static const GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; GLfloat color0[] = {0.0, 0.0, 0.0, 1.0}; GLfloat color1[] = {0.0, 0.0, 0.0, 1.0}; GLfloat color2[] = {0.0, 0.0, 0.0, 1.0}; GLfloat color3[] = {0.0, 0.0, 0.0, 1.0}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (!wireframe_p) { glColor4fv (white); glLightfv(GL_LIGHT0, GL_POSITION, pos); color0[0] = gp->colors[gp->ccolor0].red / 65536.0; color0[1] = gp->colors[gp->ccolor0].green / 65536.0; color0[2] = gp->colors[gp->ccolor0].blue / 65536.0; color1[0] = gp->colors[gp->ccolor1].red / 65536.0; color1[1] = gp->colors[gp->ccolor1].green / 65536.0; color1[2] = gp->colors[gp->ccolor1].blue / 65536.0; color2[0] = gp->colors[gp->ccolor2].red / 65536.0; color2[1] = gp->colors[gp->ccolor2].green / 65536.0; color2[2] = gp->colors[gp->ccolor2].blue / 65536.0; color3[0] = gp->colors[gp->ccolor3].red / 65536.0; color3[1] = gp->colors[gp->ccolor3].green / 65536.0; color3[2] = gp->colors[gp->ccolor3].blue / 65536.0; gp->ccolor0++; gp->ccolor1++; gp->ccolor2++; gp->ccolor3++; if (gp->ccolor0 >= gp->ncolors) gp->ccolor0 = 0; if (gp->ccolor1 >= gp->ncolors) gp->ccolor1 = 0; if (gp->ccolor2 >= gp->ncolors) gp->ccolor2 = 0; if (gp->ccolor3 >= gp->ncolors) gp->ccolor3 = 0; glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glPushMatrix(); { double x, y, z; get_position (gp->rot, &x, &y, &z, !gp->button_down_p); glTranslatef((x - 0.5) * 10, (y - 0.5) * 10, (z - 0.5) * 20); gltrackball_rotate (gp->trackball); get_rotation (gp->rot, &x, &y, &z, !gp->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); } glScalef( 8.0, 8.0, 8.0 ); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color0); glCallList(gp->gasket0); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1); glCallList(gp->gasket1); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2); glCallList(gp->gasket2); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color3); glCallList(gp->gasket3); glPopMatrix(); if (gp->tick++ >= speed) { gp->tick = 0; if (gp->current_depth >= max_depth) gp->current_depth = -max_depth; gp->current_depth++; /* We make four different lists so that each face of the tetrahedrons can have a different color (all triangles facing in the same direction have the same color, which is different from all triangles facing in other directions.) */ glDeleteLists (gp->gasket0, 1); glDeleteLists (gp->gasket1, 1); glDeleteLists (gp->gasket2, 1); glDeleteLists (gp->gasket3, 1); mi->polygon_count = 0; glNewList (gp->gasket0, GL_COMPILE); compile_gasket (mi, 0); glEndList(); glNewList (gp->gasket1, GL_COMPILE); compile_gasket (mi, 1); glEndList(); glNewList (gp->gasket2, GL_COMPILE); compile_gasket (mi, 2); glEndList(); glNewList (gp->gasket3, GL_COMPILE); compile_gasket (mi, 3); glEndList(); } }
ENTRYPOINT void init_carousel (ModeInfo *mi) { int screen = MI_SCREEN(mi); carousel_state *ss; int wire = MI_IS_WIREFRAME(mi); if (sss == NULL) { if ((sss = (carousel_state *) calloc (MI_NUM_SCREENS(mi), sizeof(carousel_state))) == NULL) return; } ss = &sss[screen]; if ((ss->glx_context = init_GL(mi)) != NULL) { reshape_carousel (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */ } else { MI_CLEARWINDOW(mi); } if (!tilt_str || !*tilt_str) ; else if (!strcasecmp (tilt_str, "0")) ; else if (!strcasecmp (tilt_str, "X")) tilt_x_p = 1; else if (!strcasecmp (tilt_str, "Y")) tilt_y_p = 1; else if (!strcasecmp (tilt_str, "XY")) tilt_x_p = tilt_y_p = 1; else { fprintf (stderr, "%s: tilt must be 'X', 'Y', 'XY' or '', not '%s'\n", progname, tilt_str); exit (1); } { double spin_speed = speed * 0.2; /* rotation of tube around axis */ double spin_accel = speed * 0.1; double wander_speed = speed * 0.001; /* tilting of axis */ spin_speed *= 0.9 + frand(0.2); wander_speed *= 0.9 + frand(0.2); ss->rot = make_rotator (spin_speed, spin_speed, spin_speed, spin_accel, wander_speed, True); ss->trackball = gltrackball_init (False); } if (strstr ((char *) glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic")) glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &ss->anisotropic); else ss->anisotropic = 0.0; glDisable (GL_LIGHTING); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); if (! wire) { glShadeModel (GL_SMOOTH); glEnable (GL_LINE_SMOOTH); /* This gives us a transparent diagonal slice through each image! */ /* glEnable (GL_POLYGON_SMOOTH); */ glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_ALPHA_TEST); glEnable (GL_POLYGON_OFFSET_FILL); glPolygonOffset (1.0, 1.0); } ss->texfont = load_texture_font (MI_DISPLAY(mi), "font"); if (debug_p) hack_resources (MI_DISPLAY (mi)); ss->nframes = 0; ss->frames_size = 10; ss->frames = (image_frame **) calloc (1, ss->frames_size * sizeof(*ss->frames)); ss->mode = IN; ss->mode_tick = fade_ticks / speed; ss->awaiting_first_images_p = True; }
/*- * draw_swirl * * Draw one iteration of swirling * * - win is the window to draw in */ void draw_swirl(ModeInfo * mi) { swirlstruct *sp; if (swirls == NULL) return; sp = &(swirls[MI_SCREEN(mi)]); if (sp->knots == NULL) return; MI_IS_DRAWN(mi) = True; /* are we going? */ if (sp->started) { /* in the middle of drawing? */ if (sp->drawing) { if(sp->cycle_p) { rotate_colors(MI_DISPLAY(mi), sp->cmap, sp->colors, sp->ncolors, sp->direction); if (!(LRAND() % 1000)) sp->direction = -sp->direction; } /* draw a batch of points */ sp->batch_todo = BATCH_DRAW; while ((sp->batch_todo > 0) && sp->drawing) { /* draw a point */ draw_point(mi, sp); /* move to the next point */ next_point(sp); /* done a point */ sp->batch_todo--; } } else { if(sp->cycle_p) { rotate_colors(MI_DISPLAY(mi), sp->cmap, sp->colors, sp->ncolors, sp->direction); if (!(LRAND() % 1000)) sp->direction = -sp->direction; } /* time for a higher resolution? */ if (sp->resolution > sp->max_resolution) { /* move to higher resolution */ sp->resolution--; /* calculate the pixel step for this resulution */ sp->r = (1 << (sp->resolution - 1)); /* start drawing again */ sp->drawing = True; /* start in the middle of the screen */ sp->x = (sp->width - sp->r) / 2; sp->y = (sp->height - sp->r) / 2; /* initialise spiral drawing parameters */ sp->dir = DRAW_RIGHT; sp->dir_todo = 1; sp->dir_done = 0; } else { /* all done, decide when to restart */ if (sp->start_again == -1) { /* start the counter */ sp->start_again = RESTART; } else if (sp->start_again == 0) { /* reset the counter */ sp->start_again = -1; /* start again */ init_swirl(mi); } else /* decrement the counter */ sp->start_again--; } } } }
ENTRYPOINT void draw_matrix (ModeInfo *mi) { matrix_configuration *mp = &mps[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i; if (!mp->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glRotatef(current_device_rotation(), 0, 0, 1); if (do_texture) { glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); /* Jeff Epler points out: By using GL_ONE instead of GL_SRC_ONE_MINUS_ALPHA, glyphs are added to each other, so that a bright glyph with a darker one in front is a little brighter than the bright glyph alone. */ glBlendFunc (GL_SRC_ALPHA, GL_ONE); } if (do_rotate) { glRotatef (mp->view_x, 1, 0, 0); glRotatef (mp->view_y, 0, 1, 0); } #ifdef DEBUG # if 0 glScalef(0.5, 0.5, 0.5); # endif # if 0 glRotatef(-30, 0, 1, 0); # endif draw_grid (mi); #endif mi->polygon_count = 0; /* Render (and tick) each strip, starting at the back (draw the ones farthest from the camera first, to make the alpha transparency work out right.) */ { strip **sorted = malloc (mp->nstrips * sizeof(*sorted)); for (i = 0; i < mp->nstrips; i++) sorted[i] = &mp->strips[i]; qsort (sorted, i, sizeof(*sorted), cmp_strips); for (i = 0; i < mp->nstrips; i++) { strip *s = sorted[i]; tick_strip (mi, s); draw_strip (mi, s); } free (sorted); } auto_track (mi); #if 0 glBegin(GL_QUADS); glColor3f(1,1,1); glTexCoord2f (0,0); glVertex3f(-15,-15,0); glTexCoord2f (0,1); glVertex3f(-15,15,0); glTexCoord2f (1,1); glVertex3f(15,15,0); glTexCoord2f (1,0); glVertex3f(15,-15,0); glEnd(); #endif glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }