Пример #1
0
ENTRYPOINT void 
init_boing (ModeInfo *mi)
{
  boing_configuration *bp;
  int wire = MI_IS_WIREFRAME(mi);

  if (!bps) {
    bps = (boing_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (boing_configuration));
    if (!bps) {
      fprintf(stderr, "%s: out of memory\n", progname);
      exit(1);
    }
  }

  bp = &bps[MI_SCREEN(mi)];

  bp->glx_context = init_GL(mi);

  if (tiles < 1) tiles = 1;

  if (smooth_p)
    {
      if (meridians < 1) meridians = 1;
      if (parallels < 1) parallels = 1;
    }
  else
    {
      if (meridians < 3) meridians = 3;
      if (parallels < 2) parallels = 2;
    }

  if (meridians > 1 && meridians & 1) meridians++;  /* odd numbers look bad */


  if (thickness <= 0) thickness = 0.001;
  else if (thickness > 1) thickness = 1;

  reshape_boing (mi, MI_WIDTH(mi), MI_HEIGHT(mi));

  parse_color (mi, "ballColor1",  ball_color1_str,  bp->ball_color1);
  parse_color (mi, "ballColor2",  ball_color2_str,  bp->ball_color2);
  parse_color (mi, "gridColor",   grid_color_str,   bp->grid_color);
  parse_color (mi, "shadowColor", shadow_str,       bp->shadow_color);
  parse_color (mi, "background",  bg_str,           bp->bg_color);

  bp->shadow_color[3] = 0.9;

  glClearColor (bp->bg_color[0], bp->bg_color[1], bp->bg_color[2], 1);

  if (!wire)
    {
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_CULL_FACE);
    }

  bp->lightpos[0] = 0.5;
  bp->lightpos[1] = 0.5;
  bp->lightpos[2] = -1;
  bp->lightpos[3] = 0;

  if (lighting_p && !wire)
    {
      GLfloat amb[4] = {0, 0, 0, 1};
      GLfloat dif[4] = {1, 1, 1, 1};
      GLfloat spc[4] = {1, 1, 1, 1};
      glEnable(GL_LIGHT0);
      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
    }

  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  speed = speed / 800.0;

  bp->ball_dth = (spin ? -speed * 7 * 360 : 0);

  bp->ball_x   = 0.5 - ((ball_size/2) + frand(1-ball_size));
  bp->ball_y   = 0.2;
  bp->ball_dx  = speed * 6 + frand(speed);
  bp->ball_ddy = -speed;

  bp->ball_dz  = speed * 6 + frand(speed);

  bp->trackball = gltrackball_init ();
}
Пример #2
0
ENTRYPOINT void
draw_pinion (ModeInfo *mi)
{
  pinion_configuration *pp = &pps[MI_SCREEN(mi)];
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);
  Bool wire_p = MI_IS_WIREFRAME(mi);

  if (!pp->glx_context)
    return;

  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(pp->glx_context));

  if (!pp->button_down_p)
    {
      if (!debug_one_gear_p || pp->ngears == 0)
        scroll_gears (mi);
      spin_gears (mi);
    }

  glShadeModel(GL_SMOOTH);

  glEnable(GL_DEPTH_TEST);
  glEnable(GL_NORMALIZE);
  glEnable(GL_CULL_FACE);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix ();
  {
    gltrackball_rotate (pp->trackball);
    mi->polygon_count = 0;

    glScalef (16, 16, 16);   /* map vp_width/height to the screen */

    if (debug_one_gear_p)    /* zoom in */
      glScalef (3, 3, 3);
    else if (debug_p)        /* show the "visible" and "layout" areas */
      {
        GLfloat ow = pp->layout_right - pp->render_left;
        GLfloat rw = pp->render_right - pp->render_left;
        GLfloat s = (pp->vp_width / ow) * 0.85;
        glScalef (s, s, s);
        glTranslatef (-(ow - rw) / 2, 0, 0);
      }
    else
      {
        GLfloat s = 1.2;
        glScalef (s, s, s);           /* zoom in a little more */
        glRotatef (-35, 1, 0, 0);     /* tilt back */
        glRotatef (  8, 0, 1, 0);     /* tilt left */
        glTranslatef (0.02, 0.1, 0);  /* pan up */
      }

    draw_gears (mi);

    if (debug_p)
      {
        if (!wire_p) glDisable(GL_LIGHTING);
        glColor3f (0.6, 0, 0);
        glBegin(GL_LINE_LOOP);
        glVertex3f (pp->render_left,  pp->vp_top,    0);
        glVertex3f (pp->render_right, pp->vp_top,    0);
        glVertex3f (pp->render_right, pp->vp_bottom, 0);
        glVertex3f (pp->render_left,  pp->vp_bottom, 0);
        glEnd();
        glColor3f (0.4, 0, 0);
        glBegin(GL_LINES);
        glVertex3f (pp->vp_left,      pp->vp_top,    0);
        glVertex3f (pp->vp_left,      pp->vp_bottom, 0);
        glVertex3f (pp->vp_right,     pp->vp_top,    0);
        glVertex3f (pp->vp_right,     pp->vp_bottom, 0);
        glEnd();
        glColor3f (0, 0.4, 0);
        glBegin(GL_LINE_LOOP);
        glVertex3f (pp->layout_left,  pp->vp_top,    0);
        glVertex3f (pp->layout_right, pp->vp_top,    0);
        glVertex3f (pp->layout_right, pp->vp_bottom, 0);
        glVertex3f (pp->layout_left,  pp->vp_bottom, 0);
        glEnd();
        if (!wire_p) glEnable(GL_LIGHTING);
      }

    if (pp->draw_tick++ > 10)   /* only do this every N frames */
      {
        pp->draw_tick = 0;
        find_mouse_gear (mi);
        new_label (mi);
      }
  }
  glPopMatrix ();

  glCallList (pp->title_list);

  if (mi->fps_p) do_fps (mi);
  glFinish();

  glXSwapBuffers(dpy, window);
}
Пример #3
0
/* Draw the given sprite at the phase of its animation dictated by
   its creation time compared to the current wall clock.
 */
static void
draw_sprite (ModeInfo *mi, sprite *sp)
{
  slideshow_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  image *img = sp->img;

  if (! sp->img) abort();
  if (! img->loaded_p) abort();

  glPushMatrix();
  {
    glTranslatef (sp->current.x, sp->current.y, 0);
    glScalef (sp->current.w, sp->current.h, 1);

    if (wire)			/* Draw a grid inside the box */
      {
        GLfloat dy = 0.1;
        GLfloat dx = dy * img->w / img->h;
        GLfloat x, y;

        if (sp->id & 1)
          glColor4f (sp->opacity, 0, 0, 1);
        else
          glColor4f (0, 0, sp->opacity, 1);

        glBegin(GL_LINES);
        glVertex3f (0, 0, 0); glVertex3f (1, 1, 0);
        glVertex3f (1, 0, 0); glVertex3f (0, 1, 0);

        for (y = 0; y < 1+dy; y += dy)
          {
            GLfloat yy = (y > 1 ? 1 : y);
            for (x = 0.5; x < 1+dx; x += dx)
              {
                GLfloat xx = (x > 1 ? 1 : x);
                glVertex3f (0, xx, 0); glVertex3f (1, xx, 0);
                glVertex3f (yy, 0, 0); glVertex3f (yy, 1, 0);
              }
            for (x = 0.5; x > -dx; x -= dx)
              {
                GLfloat xx = (x < 0 ? 0 : x);
                glVertex3f (0, xx, 0); glVertex3f (1, xx, 0);
                glVertex3f (yy, 0, 0); glVertex3f (yy, 1, 0);
              }
          }
        glEnd();
      }
    else			/* Draw the texture quad */
      {
        GLfloat texw  = img->geom.width  / (GLfloat) img->tw;
        GLfloat texh  = img->geom.height / (GLfloat) img->th;
        GLfloat texx1 = img->geom.x / (GLfloat) img->tw;
        GLfloat texy1 = img->geom.y / (GLfloat) img->th;
        GLfloat texx2 = texx1 + texw;
        GLfloat texy2 = texy1 + texh;

        glBindTexture (GL_TEXTURE_2D, img->texid);
        glColor4f (1, 1, 1, sp->opacity);
        glNormal3f (0, 0, 1);
        glBegin (GL_QUADS);
        glTexCoord2f (texx1, texy2); glVertex3f (0, 0, 0);
        glTexCoord2f (texx2, texy2); glVertex3f (1, 0, 0);
        glTexCoord2f (texx2, texy1); glVertex3f (1, 1, 0);
        glTexCoord2f (texx1, texy1); glVertex3f (0, 1, 0);
        glEnd();

        if (debug_p)		/* Draw a border around the image */
          {
            if (!wire) glDisable (GL_TEXTURE_2D);

            if (sp->id & 1)
              glColor4f (sp->opacity, 0, 0, 1);
            else
              glColor4f (0, 0, sp->opacity, 1);

            glBegin (GL_LINE_LOOP);
            glVertex3f (0, 0, 0);
            glVertex3f (0, 1, 0);
            glVertex3f (1, 1, 0);
            glVertex3f (1, 0, 0);
            glEnd();

            if (!wire) glEnable (GL_TEXTURE_2D);
          }
      }


    if (do_titles &&
        img->title && *img->title &&
        (sp->state == IN || sp->state == FULL))
      {
        glColor4f (1, 1, 1, sp->opacity);
        print_texture_label (mi->dpy, ss->font_data,
                             mi->xgwa.width, mi->xgwa.height,
                             1, img->title);
      }
  }
  glPopMatrix();

  if (debug_p)
    {
      if (!wire) glDisable (GL_TEXTURE_2D);

      if (sp->id & 1)
        glColor4f (1, 0, 0, 1);
      else
        glColor4f (0, 0, 1, 1);

      /* Draw the "from" and "to" boxes
       */
      glBegin (GL_LINE_LOOP);
      glVertex3f (sp->from.x,              sp->from.y,              0);
      glVertex3f (sp->from.x + sp->from.w, sp->from.y,              0);
      glVertex3f (sp->from.x + sp->from.w, sp->from.y + sp->from.h, 0);
      glVertex3f (sp->from.x,              sp->from.y + sp->from.h, 0);
      glEnd();

      glBegin (GL_LINE_LOOP);
      glVertex3f (sp->to.x,                sp->to.y,                0);
      glVertex3f (sp->to.x + sp->to.w,     sp->to.y,                0);
      glVertex3f (sp->to.x + sp->to.w,     sp->to.y + sp->to.h,     0);
      glVertex3f (sp->to.x,                sp->to.y + sp->to.h,     0);
      glEnd();

      if (!wire) glEnable (GL_TEXTURE_2D);
    }
}
Пример #4
0
ENTRYPOINT void 
init_glblur (ModeInfo *mi)
{
  glblur_configuration *bp;
  int wire = MI_IS_WIREFRAME(mi);

  MI_INIT (mi, bps);

  bp = &bps[MI_SCREEN(mi)];

  bp->glx_context = init_GL(mi);

  reshape_glblur (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */

  if (!wire)
    {
      GLfloat gamb[4]= {0.2, 0.2,  0.2, 1.0};
      GLfloat pos[4] = {0.0, 5.0, 10.0, 1.0};
      GLfloat amb[4] = {0.2, 0.2,  0.2, 1.0};
      GLfloat dif[4] = {0.3, 0.3,  0.3, 1.0};
      GLfloat spc[4] = {0.8, 0.8,  0.8, 1.0};
      GLfloat shiny = 128;

      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);

      glEnable(GL_DEPTH_TEST);
      glEnable(GL_CULL_FACE);
      glEnable(GL_NORMALIZE);
      glShadeModel(GL_SMOOTH);

      glLightModelfv (GL_LIGHT_MODEL_AMBIENT, gamb);

      glLightfv(GL_LIGHT0, GL_POSITION, pos);
      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);

      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);

      glMaterialf(GL_FRONT, GL_SHININESS, shiny);
    }

  {
    Bool spinx=False, spiny=False, spinz=False;
    double spin_speed   = 0.9;
    double wander_speed = 0.06;

    char *s = do_spin;
    while (*s)
      {
        if      (*s == 'x' || *s == 'X') spinx = True;
        else if (*s == 'y' || *s == 'Y') spiny = True;
        else if (*s == 'z' || *s == 'Z') spinz = True;
        else if (*s == '0') ;
        else
          {
            fprintf (stderr,
         "%s: spin must contain only the characters X, Y, or Z (not \"%s\")\n",
                     progname, do_spin);
            exit (1);
          }
        s++;
      }

    bp->rot = make_rotator (spinx ? spin_speed : 0,
                            spiny ? spin_speed : 0,
                            spinz ? spin_speed : 0,
                            1.0,
                            do_wander ? wander_speed : 0,
                            False);
    bp->trackball = gltrackball_init (True);
  }

  if (blursize < 0) blursize = 0;
  if (blursize > 200) blursize = 200;

  bp->ncolors = 128;
  bp->colors0 = (XColor *) calloc(bp->ncolors, sizeof(XColor));
  bp->colors1 = (XColor *) calloc(bp->ncolors, sizeof(XColor));
  bp->colors2 = (XColor *) calloc(bp->ncolors, sizeof(XColor));
  bp->colors3 = (XColor *) calloc(bp->ncolors, sizeof(XColor));
  make_smooth_colormap (0, 0, 0, bp->colors0, &bp->ncolors, False, 0, False);
  make_smooth_colormap (0, 0, 0, bp->colors1, &bp->ncolors, False, 0, False);
  make_smooth_colormap (0, 0, 0, bp->colors2, &bp->ncolors, False, 0, False);
  make_smooth_colormap (0, 0, 0, bp->colors3, &bp->ncolors, False, 0, False);
  bp->ccolor = 0;

  bp->obj_dlist0   = glGenLists (1);
  bp->obj_dlist1   = glGenLists (1);
  bp->obj_dlist2   = glGenLists (1);
  bp->obj_dlist3   = glGenLists (1);
  bp->scene_dlist1 = glGenLists (1);
  bp->scene_dlist2 = glGenLists (1);

  init_texture (mi);

  generate_object (mi);
}
Пример #5
0
ENTRYPOINT void
init_cube (ModeInfo *mi)
{
  cube_configuration *bp;
  int wire = MI_IS_WIREFRAME(mi);
  int i;

  if (!bps) {
    bps = (cube_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (cube_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_cube (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.7, 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 ();

  bp->dlists = (GLuint *) calloc (countof(all_objs)+2, sizeof(GLuint));
  for (i = 0; i < countof(all_objs)+1; 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);
      renderList (gll, wire);
      glEndList ();
    }

  glNewList (bp->dlists[i], GL_COMPILE);
  bp->cube_polys = build_cube (mi);
  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];
      double spin_speed   = do_spin ? 0.7 : 10;
      double wander_speed = do_wander ? 0.02 : 0.05 * speed * SPEED_SCALE;
      double spin_accel   = 0.5;
      f->rot = make_rotator (spin_speed, spin_speed, spin_speed,
                             spin_accel,
                             wander_speed,
                             True);
      if (bp->nfloaters == 2)
        {
          f->x = (i ? 2 : -2);
        }
      else if (i != 0)
        {
          double th = (i - 1) * M_PI*2 / (bp->nfloaters-1);
          double r = 3;
          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);
    }
}
Пример #6
0
static void
draw_image (ModeInfo *mi, int i, GLfloat t, GLfloat s, GLfloat z)
{
  int wire = MI_IS_WIREFRAME(mi);
  photopile_state *ss = &sss[MI_SCREEN(mi)];
  image *frame = ss->frames + i;

  position pos = interpolate(t, frame->pos);
  GLfloat w = frame->geom.width * 0.5;
  GLfloat h = frame->geom.height * 0.5;
  GLfloat z1 = z - 0.25 / (MI_COUNT(mi) + 1);
  GLfloat z2 = z - 0.5  / (MI_COUNT(mi) + 1); 
  GLfloat w1 = w;
  GLfloat h1 = h;
  GLfloat h2 = h;

  if (polaroid_p)
    {
      GLfloat minSize = MIN(w, h);
      GLfloat maxSize = MAX(w, h);

      /* Clip or scale image to fit in the frame.
       */
      if (clip_p)
        {
          w = h = minSize;
        }
      else
        {
          GLfloat scale = minSize / maxSize;
          w *= scale;
          h *= scale;
        }

      w1 = minSize * 1.16;      /* enlarge frame border */
      h1 = minSize * 1.5;
      h2 = w1;
      s /= 1.5;                 /* compensate for border size */
    }

  glPushMatrix();

  /* Position and scale this image.
   */
  glTranslatef (pos.x, pos.y, 0);
  glRotatef (pos.angle, 0, 0, 1);
  glScalef (s, s, 1);

  /* Draw the drop shadow. */
  if (shadows_p && !wire)
    {
      glColor3f (0, 0, 0);
      draw_drop_shadow(ss->shadow, -w1, -h1, z2, 2.0 * w1, h1 + h2, 20.0);
      glDisable (GL_BLEND);
    }

  glDisable (GL_LIGHTING);
  glEnable (GL_DEPTH_TEST);
  glDisable (GL_CULL_FACE);

  /* Draw the retro instant-film frame.
   */
  if (polaroid_p)
    {
      if (! wire)
        {
          glShadeModel (GL_SMOOTH);
          glEnable (GL_LINE_SMOOTH);
          glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);

          glColor3f (1, 1, 1);
          glBegin (GL_QUADS);
          glVertex3f (-w1, -h1, z2);
          glVertex3f ( w1, -h1, z2);
          glVertex3f ( w1,  h2, z2);
          glVertex3f (-w1,  h2, z2);
          glEnd();
        }

      glLineWidth (1.0);
      glColor3f (0.5, 0.5, 0.5);
      glBegin (GL_LINE_LOOP);
      glVertex3f (-w1, -h1, z);
      glVertex3f ( w1, -h1, z);
      glVertex3f ( w1,  h2, z);
      glVertex3f (-w1,  h2, z);
      glEnd();
    }

  /* Draw the image quad.
   */
  if (! wire)
    {
      GLfloat texw = w / frame->tw;
      GLfloat texh = h / frame->th;
      GLfloat texx = (frame->geom.x + 0.5 * frame->geom.width)  / frame->tw;
      GLfloat texy = (frame->geom.y + 0.5 * frame->geom.height) / frame->th;

      glBindTexture (GL_TEXTURE_2D, frame->texid);
      glEnable (GL_TEXTURE_2D);
      glColor3f (1, 1, 1);
      glBegin (GL_QUADS);
      glTexCoord2f (texx - texw, texy + texh); glVertex3f (-w, -h, z1);
      glTexCoord2f (texx + texw, texy + texh); glVertex3f ( w, -h, z1);
      glTexCoord2f (texx + texw, texy - texh); glVertex3f ( w,  h, z1);
      glTexCoord2f (texx - texw, texy - texh); glVertex3f (-w,  h, z1);
      glEnd();
      glDisable (GL_TEXTURE_2D);
    }

  /* Draw a box around it.
   */
  if (! wire)
    {
      glShadeModel (GL_SMOOTH);
      glEnable (GL_LINE_SMOOTH);
      glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
    }
  glLineWidth (1.0);
  glColor3f (0.5, 0.5, 0.5);
  glBegin (GL_LINE_LOOP);
  glVertex3f (-w, -h, z);
  glVertex3f ( w, -h, z);
  glVertex3f ( w,  h, z);
  glVertex3f (-w,  h, z);
  glEnd();

  /* Draw a title under the image.
   */
  if (titles_p)
    {
      int sw, sh, ascent, descent;
      GLfloat scale = 1;
      const char *title = frame->title ? frame->title : "(untitled)";
      XCharStruct e;

      /* #### Highly approximate, but doing real clipping is harder... */
      int max = 35;
      if (strlen(title) > max)
        title += strlen(title) - max;

      texture_string_metrics (ss->texfont, title, &e, &ascent, &descent);
      sw = e.width;
      sh = ascent + descent;

      /* Scale the text to match the pixel size of the photo */
      scale *= w / 300.0;

      /* Move to below photo */
      glTranslatef (0, -h - sh * (polaroid_p ? 2.2 : 0.5), 0);
      glTranslatef (-sw*scale/2, sh*scale/2, z);
      glScalef (scale, scale, 1);

      if (wire || !polaroid_p)
        {
          glColor3f (1, 1, 1);
        }
      else
        {
          glColor3f (0, 0, 0);
        }

      if (!wire)
        {
          glEnable (GL_TEXTURE_2D);
          glEnable (GL_BLEND);
          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();
}
Пример #7
0
ENTRYPOINT void
draw_bit (ModeInfo *mi)
{
  bit_configuration *bp = &bps[MI_SCREEN(mi)];
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);
  int wire = MI_IS_WIREFRAME(mi);

  if (!bp->glx_context)
    return;

  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  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);
      glLightfv(GL_LIGHT0, GL_POSITION, pos);
      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
    }

  glPushMatrix ();
  glScalef(1.1, 1.1, 1.1);

# 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

  {
    double x, y, z;
    get_position (bp->rot, &x, &y, &z, !bp->button_down_p);
    glTranslatef((x - 0.5) * 11,
                 (y - 0.5) * 5,
                 (z - 0.5) * 3);
    gltrackball_rotate (bp->trackball);

    get_rotation (bp->rot, &x, &y, &z, !bp->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);
  }

  mi->polygon_count = 0;

  glScalef (6, 6, 6);

  {
    int nmodel = bp->history [bp->history_fp];
    int omodel = bp->history [bp->history_fp > 0
                              ? bp->history_fp-1
                              : countof(bp->history)-1];
    double now = double_time();
    double ratio = 1 - ((bp->last_time + bp->frequency) - now) / bp->frequency;
    if (ratio > 1) ratio = 1;
    mi->polygon_count += draw_histogram (mi, ratio);

    if (MI_WIDTH(mi) > MI_HEIGHT(mi) * 5) {   /* wide window: scale up */
      glScalef (8, 8, 8);
    }

    mi->polygon_count += animate_bits (mi, omodel, nmodel, ratio);
    tick_bit (mi, now);
  }
  glPopMatrix ();

  if (mi->fps_p) do_fps (mi);
  glFinish();

  glXSwapBuffers(dpy, window);
}
Пример #8
0
ENTRYPOINT void 
init_gears (ModeInfo *mi)
{
  gears_configuration *bp;
  int wire = MI_IS_WIREFRAME(mi);
  int i;

  if (!bps) {
    bps = (gears_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (gears_configuration));
    if (!bps) {
      fprintf(stderr, "%s: out of memory\n", progname);
      exit(1);
    }

    bp = &bps[MI_SCREEN(mi)];
  }

  bp = &bps[MI_SCREEN(mi)];

  bp->glx_context = init_GL(mi);

  reshape_gears (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   = 0.25;

    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,
                            True
                            );
    bp->trackball = gltrackball_init ();
  }

  if (!(random() % 8))
    {
      planetary_gears (mi);
    }
  else
    {
      gear *g = 0;
      int total_gears = MI_COUNT (mi);
      int i;
      if (total_gears <= 0)
        total_gears = 3 + abs (BELLRAND (8) - 4);  /* 3 - 7, mostly 3. */

      bp->gears = (gear **) calloc (total_gears+2, sizeof(**bp->gears));
      bp->ngears = 0;

      for (i = 0; i < total_gears; i++)
        g = place_new_gear (mi, g);
    }


  /* Center gears in scene. */
  {
    GLfloat minx=99999, miny=99999, maxx=-99999, maxy=-99999;
    int i;
    for (i = 0; i < bp->ngears; i++)
      {
        gear *g = bp->gears[i];
        if (g->x - g->r < minx) minx = g->x - g->r;
        if (g->x + g->r > maxx) maxx = g->x + g->r;
        if (g->y - g->r < miny) miny = g->y - g->r;
        if (g->y + g->r > maxy) maxy = g->y + g->r;
      }
    bp->bbox.x1 = minx;
    bp->bbox.y1 = miny;
    bp->bbox.x2 = maxx;
    bp->bbox.y2 = maxy;
  }

  /* Now render each gear into its display list.
   */
  for (i = 0; i < bp->ngears; i++)
    {
      gear *g = bp->gears[i];
      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 ();
    }
  if (bp->planetary_p)
    armature (mi);
}
Пример #9
0
/* setup */
ENTRYPOINT void 
init_topBlock (ModeInfo *mi)
{
  topBlockSTATE *tb;
  int wire = MI_IS_WIREFRAME(mi);

  if (!tbs) {
    tbs = (topBlockSTATE *)
      calloc (MI_NUM_SCREENS(mi), sizeof (topBlockSTATE));
    if (!tbs) abort();
  }

  tb = &tbs[MI_SCREEN(mi)];

  tb->glx_context = init_GL(mi);

  reshape_topBlock (mi, MI_WIDTH(mi), MI_HEIGHT(mi));

/*	if (wire) { drawNipples=False; }*/
  tb->numFallingBlocks=0;

	if (size>10) { size = 10; }
	if (size<1) { size = 2; }
	tb->carpetWidth = 8 * size;
	tb->carpetLength = tb->carpetWidth;
  
  maxFalling*=size;

	if (spawn<4) { spawn=4; }
	if (spawn>1000) { spawn=1000; }

	if (rotateSpeed<1) {rotateSpeed=1; }
	if (rotateSpeed>1000) {rotateSpeed=1000;}
  rotateSpeed /= 100;

	if (resolution<4) {resolution=4;}
	if (resolution>20) {resolution=20;}
  resolution*=2;

	if (maxColors<1) {maxColors=1;}
	if (maxColors>8) {maxColors=8;}

	if (dropSpeed<1) {dropSpeed=1;}
	if (dropSpeed>9) {dropSpeed=9;} /* 10+ produces blocks that can pass through each other */
  
	dropSpeed = 80/dropSpeed;
	dropSpeed = (blockHeight/dropSpeed); 

  reshape_topBlock (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  glClearDepth(1.0f);
  if (!wire) {
    GLfloat pos[4] = {10.0, 10.0, 1.0, 0.0};
    GLfloat amb[4] = {0.1, 0.1, 0.1, 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);
    glLightfv(GL_LIGHT0, GL_POSITION, pos);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  amb); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
    glLightfv(GL_LIGHT0, GL_SPECULAR, spc); 
  }
	glDepthFunc(GL_LEQUAL);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_CULL_FACE); /* all objects exhibit a reverse side */
  glCullFace(GL_BACK); 

	if (drawBlob) {
    buildBlobBlock(mi); 
	} else {
	  buildBlock(mi);		/* build the display list holding the simple block */
	}
  buildCarpet(mi);		/* build the base */
	tb->highest=0;
	tb->highestFalling=0;
	tb->eyeLine=tb->highest;
	tb->eyeX=0;
	tb->eyeY=0;
	tb->eyeZ=0;
	tb->followMode=0;
  if (follow) {
    tb->plusheight=100;
    camZ=camZ-60;
  } else {
    tb->rotation=random() % 360;
    tb->eyeY=10;
    tb->plusheight=30;
  }
	tb->followRadius=0;
  /* override camera settings */
  if (override) {
    tb->plusheight=100;
    drawCarpet=False;
    camX=0;
    camY=1;
    camZ=0;
    tb->eyeX=-1;
    tb->eyeY=20;
    tb->eyeZ=0;
  }
  tb->trackball = gltrackball_init ();
}
Пример #10
0
static void new_ship(ModeInfo *mi)
{
  commander_conf *cp = &commander[MI_SCREEN(mi)];
  int i;
  GLfloat *this_v;
  GLint *p;
  /*GLfloat *this_n;*/
  int count;
#if 0
  int wire = MI_IS_WIREFRAME(mi);

  GLfloat bcolor[4] = {0.2, 0.2, 0.2, 0.2};
  GLfloat bspec[4]  = {0.1, 0.1, 0.1, 0.1};
  GLfloat bshiny    = 32.0;
  GLfloat pos[4] = {-8.0, -8.0, -16.0, 0.0}; /* -6 -6 -16 */
  GLfloat amb[4] = {0.2, 0.2, 0.2, 0.4};
  GLfloat dif[4] = {0.2, 0.2, 0.2, 0.2};
  GLfloat spc[4] = {0.0, 0.0, 0.0, 0.0};

	if(!wire) {
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);

		glLightfv(GL_LIGHT0, GL_POSITION, pos);
		glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
		glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
		glLightfv(GL_LIGHT0, GL_SPECULAR, spc);

		glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bcolor);
		glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, bspec);
		glMateriali  (GL_FRONT_AND_BACK, GL_SHININESS, bshiny);
	}
#endif

  cp->list = glGenLists(1);
  glNewList(cp->list, GL_COMPILE);
  if(MI_IS_MONO(mi)) {
    /* FIXME support mono display */
    abort();
  }

	/* wireframe strategy: use stencil buffer, not polygon offset,
	 * because it's impossible to get the right parameters for
	 * glPolygonOffset() reliably */
  
	/* hidden-line removal as per
	 * http://glprogramming.com/red/chapter14.html#name16
	 */

	/* TODO:
		 - reinstate choice of wireframe vs filled
		 - rationalise some of the duplicated code below
	 */

	glEnable(GL_STENCIL_TEST);
	glEnable(GL_DEPTH_TEST);
	glClear(GL_STENCIL_BUFFER_BIT);
	glStencilFunc(GL_ALWAYS, 0, 1);
	glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);

	glColor3f(1.0, 1.0, 1.0);

	p=ship_f[cp->which];
	this_v=ship_v[cp->which];

	/* for debugging - draw axes */
#if 0
	glLineWidth(1); 
	glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(10,0,0); glEnd();
	glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,10,0); glEnd();
	glBegin(GL_LINES); glVertex3f(0.1,0,0); glVertex3f(0.1,10,0); glEnd();
	glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,0,10); glEnd();
	glBegin(GL_LINES); glVertex3f(0,0.1,0); glVertex3f(0,0.1,10); glEnd();
	glBegin(GL_LINES); glVertex3f(0,0.2,0); glVertex3f(0,0.2,10); glEnd();
#endif

	/* draw the wireframe shape */
	while(*p != 0) {
		count=*p; p++;

		/* draw outline polygon */

		if(count==1) { glBegin(GL_POINTS); }
		else if(count==2) {
			/* chunky lines :-) */
			glLineWidth(2); 
			glBegin(GL_LINES);
		}
		else {
			glLineWidth(2); 
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			glBegin(GL_POLYGON); 
			do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2],
				this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2],
				this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]);
		}
		for (i = 0 ; i < count ; i++) {
			glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]);
		}
		glEnd();

		glColor3f(0.0, 0.0, 0.0);

		glStencilFunc(GL_EQUAL, 0, 1);
		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

		/* draw filled polygon */

		if(count>=3) {
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
			glBegin(GL_POLYGON); 
			do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2],
				this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2],
				this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]);
			for (i = 0 ; i < count ; i++) {
				glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]);
			}
			glEnd();
		}

		glColor3f(1.0, 1.0, 1.0);

		glStencilFunc(GL_ALWAYS, 0, 1);
		glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);

		/* draw outline polygon */

		if(count==1) { glBegin(GL_POINTS); }
		else if(count==2) {
			/* chunky lines :-) */
			glLineWidth(2); 
			glBegin(GL_LINES);
		}
		else {
			glLineWidth(2); 
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			glBegin(GL_POLYGON); 
			do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2],
				this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2],
				this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]);
		}
		for (i = 0 ; i < count ; i++) {
			glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]);
		}
		glEnd();

		cp->npoints++;
		p+=count;
	}

  glEndList();
}
Пример #11
0
static void
armature (ModeInfo *mi)
{
  gears_configuration *bp = &bps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);

  static const GLfloat spec[4] = {1.0, 1.0, 1.0, 1.0};
  GLfloat shiny = 128.0;
  GLfloat color[4];

  color[0] = 0.5 + frand(0.5);
  color[1] = 0.5 + frand(0.5);
  color[2] = 0.5 + frand(0.5);
  color[3] = 1.0;

  bp->armature_polygons = 0;

  bp->armature_dlist = glGenLists (1);
  if (! bp->armature_dlist)
    {
      check_gl_error ("glGenLists");
      abort();
    }

  glNewList (bp->armature_dlist, GL_COMPILE);

  glMaterialfv (GL_FRONT, GL_SPECULAR,  spec);
  glMateriali  (GL_FRONT, GL_SHININESS, shiny);
  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
  glColor3f (color[0], color[1], color[2]);

  glPushMatrix();

  {
    GLfloat s = bp->gears[0]->r * 2.7;
    s = s/5.6;
    glScalef (s, s, s);
  }

  glTranslatef (0, 0, 1.4 + bp->gears[0]->thickness);
  glRotatef (30, 0, 0, 1);

  bp->armature_polygons += ctube (0.5, 10, wire);       /* center axle */

  glPushMatrix();
  glTranslatef(0.0, 4.2, -1);
  bp->armature_polygons += ctube (0.5, 3, wire);       /* axle 1 */
  glTranslatef(0, 0, 1.8);
  bp->armature_polygons += ctube (0.7, 0.7, wire);
  glPopMatrix();

  glPushMatrix();
  glRotatef(120, 0.0, 0.0, 1.0);
  glTranslatef(0.0, 4.2, -1);
  bp->armature_polygons += ctube (0.5, 3, wire);       /* axle 2 */
  glTranslatef(0, 0, 1.8);
  bp->armature_polygons += ctube (0.7, 0.7, wire);
  glPopMatrix();

  glPushMatrix();
  glRotatef(240, 0.0, 0.0, 1.0);
  glTranslatef(0.0, 4.2, -1);
  bp->armature_polygons += ctube (0.5, 3, wire);       /* axle 3 */
  glTranslatef(0, 0, 1.8);
  bp->armature_polygons += ctube (0.7, 0.7, wire);
  glPopMatrix();

  glTranslatef(0, 0, 1.5);			      /* center disk */
  bp->armature_polygons += ctube (1.5, 2, wire);

  glPushMatrix();
  glRotatef(270, 0, 0, 1);
  glRotatef(-10, 0, 1, 0);
  glTranslatef(-2.2, 0, 0);
  bp->armature_polygons += arm (4.0, 1.0, 0.5,
                                2.0, 1.0, wire);	/* arm 1 */
  glPopMatrix();

  glPushMatrix();
  glRotatef(30, 0, 0, 1);
  glRotatef(-10, 0, 1, 0);
  glTranslatef(-2.2, 0, 0);
  bp->armature_polygons += arm (4.0, 1.0, 0.5,
                                2.0, 1.0, wire);	/* arm 2 */
  glPopMatrix();

  glPushMatrix();
  glRotatef(150, 0, 0, 1);
  glRotatef(-10, 0, 1, 0);
  glTranslatef(-2.2, 0, 0);
  bp->armature_polygons += arm (4.0, 1.0, 0.5,
                                2.0, 1.0, wire);	/* arm 3 */
  glPopMatrix();

  glPopMatrix();

  glEndList ();
}
Пример #12
0
static void
pinit(ModeInfo * mi)
{
   boxedstruct *gp = &boxed[MI_SCREEN(mi)];
   int wire = MI_IS_WIREFRAME (mi);
   ballman *bman;
   int i,texpixels;
   char *texpixeldata;
   char *texpixeltarget;

   glShadeModel(GL_SMOOTH);
   glClearDepth(1.0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   /* Load configuration */
   setdefaultconfig(&gp->config);

   /* give the decay parameter a better curve */
   if (gp->config.decay <= 0.8182) { gp->config.decay = gp->config.decay / 3; }
   else                            { gp->config.decay = (gp->config.decay - 0.75) * 4; }
   
   bman = &gp->bman;
   
   bman->balls = (ball *)malloc(gp->config.numballs * sizeof(ball));
   bman->num_balls = gp->config.numballs;
   bman->ballsize = gp->config.ballsize;
   bman->explosion = gp->config.explosion;
   
   gp->tman = (triman *)malloc(bman->num_balls * sizeof(triman));
   memset(gp->tman,0,bman->num_balls * sizeof(triman));
   
   for(i=0;i<bman->num_balls;i++) {
      gp->tman[i].explosion = (float) (((int)gp->config.explosion) / 15.0f );
      gp->tman[i].decay = gp->config.decay;
      gp->tman[i].momentum = gp->config.momentum;
      gp->tman[i].vertices = NULL;
      gp->tman[i].normals = NULL;
      gp->tman[i].tris = NULL;
      createball(&bman->balls[i]);
      bman->balls[i].loc.y *= rnd();
   }

   generatesphere(gp);
   
   if (!wire) {
     glEnable(GL_CULL_FACE);
     glEnable(GL_LIGHTING);
   }

   /* define cam path */
   gp->cam_x_speed = 1.0f/((float)gp->config.camspeed/50.0 + rnd()*((float)gp->config.camspeed/50.0));
   gp->cam_z_speed = 1.0f/((float)gp->config.camspeed/50.0 + rnd()*((float)gp->config.camspeed/50.0));
   gp->cam_y_speed = 1.0f/((float)gp->config.camspeed/250.0 + rnd()*((float)gp->config.camspeed/250.0));
   if (rnd() < 0.5f) gp->cam_x_speed = -gp->cam_x_speed;
   if (rnd() < 0.5f) gp->cam_z_speed = -gp->cam_z_speed;

   /* define initial cam position */
   gp->tic = gp->camtic = rnd() * 100.0f;
   
   /* define tex1 (bottom plate) */
   gp->tex1 = (char *)malloc(3*width*height*sizeof(GLuint));
   texpixels = 256*256; /*width*height;*/
   texpixeldata = header_data;
   texpixeltarget = gp->tex1;
   for (i=0; i < texpixels; i++) {
	HEADER_PIXEL(texpixeldata,texpixeltarget);
	texpixeltarget += 3;
   }
   
   
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

   clear_gl_error();
#if 0
   i = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 256, 256,
                         GL_RGB, GL_UNSIGNED_BYTE, gp->tex1);
   if (i)
     {
       const char *s = (char *) gluErrorString (i);
       fprintf (stderr, "%s: error mipmapping texture: %s\n",
                progname, (s ? s : "(unknown)"));
       exit (1);
     }
   check_gl_error("mipmapping");
#else
   glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0,
		       GL_RGB, GL_UNSIGNED_BYTE,
                 gp->tex1);
   check_gl_error("texture");
#endif

   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   
}
Пример #13
0
/*
 * main rendering loop
 */
static void draw(ModeInfo * mi)
{
   boxedstruct *gp = &boxed[MI_SCREEN(mi)];
   int wire = MI_IS_WIREFRAME (mi);
   vectorf v1,v2;
   GLfloat r;
   int dx, dz;
   int i;   
   
   GLfloat dgray[4] = {0.3f, 0.3f, 0.3f, 1.0f};
   GLfloat black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
   GLfloat lblue[4] = {0.4f,0.6f,1.0f };
   
   GLfloat l0_ambient[] =    {0.0, 0.0, 0.0, 1.0};
   GLfloat l0_specular[] =    {1.0, 1.0, 1.0, 1.0};
   GLfloat l0_diffuse[] =    {1.0, 1.0, 1.0, 1.0};
   GLfloat l0_position[] =  {0.0, 0.0, 0.0, 1.0}; /* w != 0 -> positional light */
   GLfloat l1_ambient[] =    {0.0, 0.0, 0.0, 1.0};
   GLfloat l1_specular[] =    {1.0, 1.0, 1.0, 1.0};
   GLfloat l1_diffuse[] =    {0.5, 0.5, 0.5, 1.0};
   GLfloat l1_position[] =  {0.0, 1.0, 0.0, 0.0}; /* w = 0 -> directional light */
   
   mi->polygon_count = 0;

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();
   
# 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

   gp->tic += 0.01f;
   gp->camtic += 0.01f + 0.01f * sin(gp->tic * speed);
   
   /* rotate camera around (0,0,0), looking at (0,0,0), up is (0,1,0) */
   r = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->camtic/CAMDISTANCE_SPEED) * speed);
   v1.x = r * sin((gp->camtic/gp->cam_x_speed) * speed);
   v1.z = r * cos((gp->camtic/gp->cam_x_speed) * speed);
   v1.y = CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT;

   v2.x = LOOKAT_R * sin((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed);
   v2.z = LOOKAT_R * cos((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed);
   v2.y = (CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT)/10.0;

   gluLookAt(v1.x,v1.y,v1.z,v2.x,v2.y,v2.x,0.0,1.0,0.0); 

   if (!wire) {
     glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); 
     glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diffuse); 
     glLightfv(GL_LIGHT0, GL_SPECULAR, l0_specular); 
     glLightfv(GL_LIGHT0, GL_POSITION, l0_position);
     glLightfv(GL_LIGHT1, GL_AMBIENT, l1_ambient); 
     glLightfv(GL_LIGHT1, GL_DIFFUSE, l1_diffuse); 
     glLightfv(GL_LIGHT1, GL_SPECULAR, l1_specular); 
     glLightfv(GL_LIGHT1, GL_POSITION, l1_position);
     glEnable(GL_LIGHT0);
     glEnable(GL_LIGHT1);
   
     glFrontFace(GL_CW);
   
     glMaterialfv(GL_FRONT, GL_SPECULAR, black);
     glMaterialfv(GL_FRONT, GL_EMISSION, lblue);
     glMaterialfv(GL_FRONT,GL_AMBIENT,black);
     glMaterialf(GL_FRONT, GL_SHININESS, 5.0);
   }
   
   
   /* draw ground grid */
   /* glDisable(GL_DEPTH_TEST); */
   glDisable(GL_LIGHTING);
   
   glColor3f(0.1,0.1,0.6);
   for (dx= -2; dx<3; dx++) {
      for (dz= -2; dz<3; dz++) {
	 glPushMatrix();
	 glTranslatef(dx*30.0f, 0.0f, dz*30.0f);
	 drawpattern(gp);
	 glPopMatrix();
      }   
   }
   
   /* Set drawing mode for the boxes */
   glEnable(GL_DEPTH_TEST);
   if (!wire) glEnable(GL_TEXTURE_2D);
   glPushMatrix();
   glColor3f(1.0,1.0,1.0);
   glScalef(20.0,0.25,20.0);
   glTranslatef(0.0,2.0,0.0);
   mi->polygon_count += drawfilledbox(gp, wire);
   glPopMatrix();
   glDisable(GL_TEXTURE_2D);

   glPushMatrix();
   glColor3f(0.2,0.5,0.2);
   glScalef(20.0,20.0,0.25);
   glTranslatef(0.0,1.0,81.0);
   mi->polygon_count += drawbox(gp);
   glPopMatrix();

   glPushMatrix();
   glColor3f(0.2,0.5,0.2);
   glScalef(20.0,20.0,0.25);
   glTranslatef(0.0,1.0,-81.0);
   mi->polygon_count += drawbox(gp);
   glPopMatrix();

   glPushMatrix();
   glColor3f(0.2,0.5,0.2);
   glScalef(.25,20.0,20.0);
   glTranslatef(-81.0,1.0,0.0);
   mi->polygon_count += drawbox(gp);
   glPopMatrix();

   glPushMatrix();
   glColor3f(0.2,0.5,0.2);
   glScalef(.25,20.0,20.0);
   glTranslatef(81.0,1.0,0.0);
   mi->polygon_count += drawbox(gp);
   glPopMatrix();

   if (!wire) {
     glEnable(GL_LIGHTING);
   
     glMaterialfv(GL_FRONT, GL_DIFFUSE, dgray);
     glMaterialfv(GL_FRONT, GL_EMISSION, black); /* turn it off before painting the balls */
   }

   /* move the balls and shrapnel */
   updateballs(&gp->bman);

   glFrontFace(GL_CCW);
   for (i=0;i<gp->bman.num_balls;i++) {
      if (gp->bman.balls[i].justcreated) {
	 gp->bman.balls[i].justcreated = FALSE;
	 freetris(&gp->tman[i]);
      }
      if (gp->bman.balls[i].bounced) { 
	 if (gp->tman[i].vertices == NULL) {
	    createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]);
	 } else {
	    updatetris(&gp->tman[i]);
	 }
	 glDisable(GL_CULL_FACE);
	 mi->polygon_count += drawtriman(&gp->tman[i], wire);
	 if (!wire) glEnable(GL_CULL_FACE);
      } else {
         mi->polygon_count += drawball(gp, &gp->bman.balls[i], wire);
      }
   }
      
   glFlush();
}
Пример #14
0
static void init_gl(ModeInfo *mi) 
{
  cube21_conf *cp = &cube21[MI_SCREEN(mi)];
#ifdef MIPMAP
  int status;
#endif
  parse_colmode();
  cp->wire = MI_IS_WIREFRAME(mi);
  cp->cmat = !cp->wire && (colmode != CUBE21_COLOR_WHITE);
  if(MI_IS_MONO(mi)) {
    tex = False;
    cp->cmat = False;
  }

# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
  cp->wire = 0;
# endif

  if(cp->wire) {
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    return;
  }
  if(!tex)
    cp->color_inner[0] = cp->color_inner[1] = cp->color_inner[2] = 0.4;
  else
    cp->color_inner[0] = cp->color_inner[1] = cp->color_inner[2] = 1.0;

  glClearDepth(1.0);
  glDrawBuffer(GL_BACK);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glShadeModel(GL_FLAT);
  glDepthFunc(GL_LESS);
  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  glLightfv(GL_LIGHT0, GL_POSITION, position0);
  glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  glLightfv(GL_LIGHT1, GL_POSITION, position1);
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHT1);
  glEnable(GL_LIGHTING);
  glEnable(GL_NORMALIZE);
  glEnable(GL_COLOR_MATERIAL);
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  if(!tex) return;
  glEnable(GL_TEXTURE_2D);
#ifdef MIPMAP
  clear_gl_error();
  status = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEX_WIDTH, TEX_HEIGHT,
      GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
  if (status) {
    const char *s = gluErrorString(status);
    fprintf (stderr, "%s: error mipmapping texture: %s\n", progname, (s?s:"(unknown)"));
    exit (1);
  }
  check_gl_error("mipmapping");
#else    
  glTexImage2D(GL_TEXTURE_2D, 0, 1, TEX_WIDTH, TEX_HEIGHT,
      0, GL_LUMINANCE, GL_UNSIGNED_BYTE, cp->texture);
#endif  
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef MIPMAP
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
#else
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#endif
}
Пример #15
0
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();
}
Пример #16
0
/* provides the per frame entertainment */
ENTRYPOINT void
draw_topBlock (ModeInfo *mi)
{
  	Display *dpy = MI_DISPLAY(mi);
  	Window window = MI_WINDOW(mi);
  	NODE *llCurrent;
  	NODE *llNode;
  	topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
  	GLfloat spcN1x,spcN1y,spcN2x,spcN2y;
  	GLfloat spcC1x,spcC1y,spcC2x,spcC2y;
  	int wire = MI_IS_WIREFRAME(mi);
	  GLfloat color[4];	

  if (!tb->glx_context)
    return;
  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(tb->glx_context));
  mi->polygon_count = 0;

	generateNewBlock(mi);

	if (rotate && (!tb->button_down_p)) { tb->rotation += rotateSpeed; } 
	if (tb->rotation>=360) { tb->rotation=tb->rotation-360; } 

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		/* clear current */
	glLoadIdentity();	/* resets directions, do it every time ! */
        glRotatef(current_device_rotation(), 0, 0, 1);

	if (!follow) {
		if (tb->highest>tb->eyeLine) { tb->eyeLine+=((tb->highest-tb->eyeLine)/100);	} /* creates a smooth camera transition */
		gluLookAt(camX, camY+tb->eyeLine, camZ, tb->eyeX, tb->eyeY+tb->eyeLine, tb->eyeZ, 0.0, 1.0, 0.0);		/* setup viewer, xyz cam, xyz looking at and where is up normaly 0,1,0 */
		glRotatef(90, 1.0, 0.0, 0.0);			/* x axis */
	} else {
		glRotatef(90, 0.0, 0.0, 1.0);     /* z axis */
		followBlock(mi);
	}

        /* Rotate the scene around a point that's a little higher up. */
        glTranslatef (0, 0, -5);
        gltrackball_rotate (tb->trackball);
        glTranslatef (0, 0, 5);

	/* rotate the world */
	glRotatef(tb->rotation, 0.0, 0.0, 1.0);		

	llCurrent = tb->blockNodeRoot;
	if (drawCarpet) {
		/* center carpet */
		glTranslatef(0.0-(tb->carpetWidth/2),0.0-(tb->carpetLength/2),0.0);
		glCallList(tb->carpet);
                mi->polygon_count += tb->carpet_polys;
		glTranslatef(0.0+(tb->carpetWidth/2),0.0+(tb->carpetLength/2),0.0);
		glTranslatef(0.0,0.0,-0.55);
	}
	tb->highestFalling=0;
	while (llCurrent != NULL) {	/* for each block */
		glPushMatrix();	/* save state */
		/* set color */
		switch (llCurrent->color) { 
			case 0:
				color[0] = 1.0f;	
				color[1] = 0.0f;	
				color[2] = 0.0f;	
				color[3] = 1.0f;	
				break;
			case 1:
				color[0] = 0.0f;	
				color[1] = 1.0f;	
				color[2] = 0.0f;	
				color[3] = 1.0f;	
				break;
			case 2:
				color[0] = 0.0f;	
				color[1] = 0.0f;	
				color[2] = 1.0f;	
				color[3] = 1.0f;	
				break;
			case 3:
				color[0] = 0.95f;	
				color[1] = 0.95f;	
				color[2] = 0.95f;	
				color[3] = 1.0f;	
				break;
			case 4:
				color[0] = 1.0f;	
				color[1] = 0.5f;	
				color[2] = 0.0f;	
				color[3] = 1.0f;	
				break;
			case 5:
				color[0] = 1.0f;	
				color[1] = 1.0f;	
				color[2] = 0.0f;	
				color[3] = 1.0f;	
				break;
			case 6: 
				color[0] = 0.5f;	
				color[1] = 0.5f;	
				color[2] = 0.5f;	
				color[3] = 1.0f;	
				break;
			case 7:
				color[0] = 0.05f;	
				color[1] = 0.05f;	
				color[2] = 0.05f;	
				color[3] = 1.0f;	
				break;
		} 
		if (wire) { glColor3fv(color); }
		else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); }

		if (llCurrent->falling==1) {
    	spcC2x = 0;
	    spcC2y = 0;
	    spcN2x = 0;
	    spcN2y = 0;
			if (llCurrent->height>tb->highestFalling) {tb->highestFalling=llCurrent->height;}
			/* all blocks fall at the same rate to avoid mid air collisions */
			llCurrent->height-=dropSpeed;
			if (llCurrent->height<=0) {
				llCurrent->falling=0;
				if (tb->highest==0) { 
					tb->highest+=blockHeight; 
				}
			} 
			if ( (llCurrent->height<=tb->highest+1) && (llCurrent->falling==1) ) {
				/* check for collision */
				llNode = tb->blockNodeRoot;
				spcC1x = llCurrent->x;
				spcC1y = llCurrent->y;
				switch(llCurrent->rotation) {
					case getOrientation(0):
						spcC2x = spcC1x;
						spcC2y = spcC1y-2;
						break;
					case getOrientation(1):
						spcC2x = spcC1x+2;
						spcC2y = spcC1y;
						break;
					case getOrientation(2):
						spcC2x = spcC1x;
						spcC2y = spcC1y+2;
						break;
					case getOrientation(3):
						spcC2x = spcC1x-2;
						spcC2y = spcC1y;
						break;
				}
				while (llNode != NULL) {
					if ( (llNode->falling==0) && (llCurrent->falling==1) ) {
						spcN1x = llNode->x;
						spcN1y = llNode->y;
						switch(llNode->rotation) {
							case getOrientation(0):
								spcN2x = spcN1x;
								spcN2y = spcN1y-2;
								break;
							case getOrientation(1):
								spcN2x = spcN1x+2;
								spcN2y = spcN1y;
								break;
							case getOrientation(2):
								spcN2x = spcN1x;
								spcN2y = spcN1y+2;
								break;
							case getOrientation(3):
								spcN2x = spcN1x-2;
								spcN2y = spcN1y;
								break;
						}
						if ( 
							( (spcC1x==spcN1x) && (spcC1y==spcN1y) ) ||
							( (spcC1x==spcN2x) && (spcC1y==spcN2y) ) ||
							( (spcC2x==spcN2x) && (spcC2y==spcN2y) ) ||
							( (spcC2x==spcN1x) && (spcC2y==spcN1y) )
						){
              if ( fabs(llCurrent->height-(llNode->height+blockHeight)) <= TOLERANCE) { 

						    llCurrent->falling=0;
							  llCurrent->height=llNode->height+blockHeight; /* if this is missing then small errors build up until the model fails */
                if ( fabs(llCurrent->height-tb->highest) <= TOLERANCE+blockHeight ) {
                 tb->highest+=blockHeight; 
							  }
						  }
					  }
				  }
				  llNode=llNode->next;
			  }				
		  }
	  } 
  	/* set location in space */
	  glTranslatef(llCurrent->x,llCurrent->y,-llCurrent->height);
	  /* rotate */
  	glRotatef(llCurrent->rotation, 0.0f, 0.0f, 1.0f);
  	if ((tb->followMode==0) && (llCurrent->next==NULL)) {
  		tb->blockNodeFollow = llCurrent;
  		tb->followMode=1;
  	} 
  	llCurrent = llCurrent->next;
  	/* draw   */
  	glCallList(tb->block); 
        mi->polygon_count += tb->block_polys;
  	glPopMatrix();	/* restore state */
  } 
  if (mi->fps_p) do_fps (mi);
  glFinish();

	if (tb->highest>(5*maxFalling)) { drawCarpet=False; }
  glXSwapBuffers(dpy, window);
}
Пример #17
0
/* 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)
{
  photopile_state *ss = (photopile_state *) closure;
  ModeInfo *mi = ss->mi;
  int wire = MI_IS_WIREFRAME(mi);
  image *frame = ss->frames + ss->nframe;

  if (wire)
    {
      if (random() % 2)
        {
          frame->w = (int)(MI_WIDTH(mi)  * scale) - 1;
          frame->h = (int)(MI_HEIGHT(mi) * scale) - 1;
        }
      else
        {
          frame->w = (int)(MI_HEIGHT(mi) * scale) - 1;
          frame->h = (int)(MI_WIDTH(mi)  * scale) - 1;
        }
      if (frame->w <= 10) frame->w = 10;
      if (frame->h <= 10) frame->h = 10;
      frame->geom.width  = frame->w;
      frame->geom.height = frame->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);

  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  frame->w  = image_width;
  frame->h  = image_height;
  frame->tw = texture_width;
  frame->th = texture_height;
  frame->geom = *geom;

  if (frame->title)
    free (frame->title);
  frame->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->title && frame->title[0] == '/')
    {
      /* strip filename to part after last /. */
      char *s = strrchr (frame->title, '/');
      if (s) strcpy (frame->title, s+1);
    }

  if (debug_p)
    fprintf (stderr, "%s:   loaded %4d x %-4d  %4d x %-4d  \"%s\"\n",
             progname,
             frame->geom.width, 
             frame->geom.height, 
             frame->tw, frame->th,
             (frame->title ? frame->title : "(null)"));

 DONE:
  frame->loaded_p = True;
}
Пример #18
0
/* called at init this creates the 'carpet' display list item */
static void buildCarpet(ModeInfo *mi)
{
	int i,c,x,y;
	GLfloat color[4];
  	int wire = MI_IS_WIREFRAME(mi);
  	topBlockSTATE *tb = &tbs[MI_SCREEN(mi)];
		color[0] = 0.0f;	
		color[1] = 1.0f;	
		color[2] = 0.0f;	
		color[3] = 1.0f;	
	tb->carpet=glGenLists(1);	/* only one */
	glNewList(tb->carpet,GL_COMPILE);
        tb->carpet_polys=0;
	glPushMatrix();	/* save state */
  	x=tb->carpetWidth;
  	y=tb->carpetLength;
	if (wire) { glColor3fv(color); }
	else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); }
	/* draw carpet plane */
	glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
		/* draw top */
		glNormal3f( 0, 0, -1 );
		glVertex3f(0.0,0.0,0.0);
		glVertex3f(x,0.0,0.0);
		glVertex3f(x,y,0.0);
		glVertex3f(0.0,y,0.0);
                tb->carpet_polys++;
	    if (!wire) {
		/* add edge pieces */
		/* side 1 */
		glNormal3f( 0, -1, 0 );
		glVertex3f(0.0,0.0,0.0);
		glVertex3f(x,0.0,0.0);
		glVertex3f(x,0,singleThick);
		glVertex3f(0.0,0,singleThick);
                tb->carpet_polys++;
		/* side 2 */
		glNormal3f( -1, 0, 0 );
		glVertex3f(0.0,0.0,0.0);
		glVertex3f(0,y,0.0);
		glVertex3f(0,y,singleThick);
		glVertex3f(0.0,0,singleThick);
                tb->carpet_polys++;
		/* side 3 */
		glNormal3f( 1, 0, 0 );
		glVertex3f(x,0.0,0.0);
		glVertex3f(x,y,0.0);
		glVertex3f(x,y,singleThick);
		glVertex3f(x,0,singleThick);
                tb->carpet_polys++;
		/* side 4 */
		glNormal3f( 0, 1, 0 );
		glVertex3f(0,y,0.0);
		glVertex3f(x,y,0.0);
		glVertex3f(x,y,singleThick);
		glVertex3f(0,y,singleThick);
                tb->carpet_polys++;
		}
	glEnd();
	/* nipples */
	if (drawNipples) {
		glTranslatef(0.5f,0.5f,-.25);			/* move to the cylinder center */
		for (c=0;c<x;c++) {
			glPushMatrix();	/* save state */
			for (i=0;i<y;i++) {
                          tb->carpet_polys += tube(0, 0, -0.1,
                                                   0, 0, 0.26,
                                                   cylSize, 0,
                                                   resolution, True, True,
                                                   wire);
                          glRotatef(180, 0.0f, 1.0f, 0.0f); /* they are upside down */
                          glRotatef(180, 0.0f, 1.0f, 0.0f); /* recover */
                          glTranslatef(0.0f,1.0f,0.0f);			/* move to the next cylinder center (backward) */
			}
			glPopMatrix();	/* save state */
			glTranslatef(1.0f,0.0f,0.0f);			/* reset   */
		}
	}
	glPopMatrix();	/* restore state */
	glEndList();	
}
Пример #19
0
/** initialization handler */
ENTRYPOINT void init_chess(ModeInfo *mi) 
{
  Chesscreen *cs;
  int screen = MI_SCREEN(mi);

  if(!qs && 
     !(qs = (Chesscreen *) calloc(MI_NUM_SCREENS(mi), sizeof(Chesscreen))))
    return;
  
  cs = &qs[screen];
  cs->window = MI_WINDOW(mi);
  cs->wire = MI_IS_WIREFRAME(mi);
  cs->trackball = gltrackball_init ();
  
  cs->oldwhite = -1;

  cs->colors[0][0] = 1.0;
  cs->colors[0][1] = 0.5;
  cs->colors[0][2] = 0.0;

  cs->colors[1][0] = 0.6;
  cs->colors[1][1] = 0.6;
  cs->colors[1][2] = 0.6;

  cs->done = 1;
  cs->count = 99;
  cs->mod = 1.4;

/*   cs->position[0] = 0.0; */
/*   cs->position[1] = 5.0; */
/*   cs->position[2] = 5.0; */
/*   cs->position[3] = 1.0; */

  cs->position[0] = 0.0;
  cs->position[1] = 24.0;
  cs->position[2] = 2.0;
  cs->position[3] = 1.0;


  cs->position2[0] = 5.0;
  cs->position2[1] = 5.0;
  cs->position2[2] = 5.0;
  cs->position2[3] = 1.0;

  cs->ground[0] = 0.0;
  cs->ground[1] = 1.0;
  cs->ground[2] = 0.0;
  cs->ground[3] = -0.00001;

  cs->oldgame = -1;


  if((cs->glx_context = init_GL(mi)))
    reshape_chess(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  else
    MI_CLEARWINDOW(mi);

  glClearColor(0.0, 0.0, 0.0, 0.0);

  if (!cs->wire) {
    glDepthFunc(GL_LEQUAL);
    glClearStencil(0);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    make_piece_texture(cs);
    make_board_texture(cs);
  }
  gen_model_lists( classic, cs->poly_counts);

  if(!cs->wire) {
    setup_lights(cs);
    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_DEPTH_TEST);
  }
  else
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
Пример #20
0
/* Draw a single character at the given position and brightness.
 */
static void
draw_glyph (ModeInfo *mi, int glyph, Bool highlight,
            GLfloat x, GLfloat y, GLfloat z,
            GLfloat brightness)
{
  matrix_configuration *mp = &mps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  GLfloat w = mp->tex_char_width;
  GLfloat h = mp->tex_char_height;
  GLfloat cx = 0, cy = 0;
  GLfloat S = 1;
  Bool spinner_p = (glyph < 0);

  if (glyph == 0) abort();
  if (glyph < 0) glyph = -glyph;

  if (spinner_p)
    brightness *= 1.5;

  if (!do_texture)
    {
      S  = 0.8;
      x += 0.1;
      y += 0.1;
    }
  else
    {
      int ccx = ((glyph - 1) % CHAR_COLS);
      int ccy = ((glyph - 1) / CHAR_COLS);

      cx = ccx * w;
      cy = (mp->real_char_rows - ccy - 1) * h;

      if (do_fog)
        {
          GLfloat depth;
          depth = (z / GRID_DEPTH) + 0.5;  /* z ratio from back/front      */
          depth = 0.2 + (depth * 0.8);     /* scale to range [0.2 - 1.0]   */
          brightness *= depth;             /* so no row goes all black.    */
        }
    }

  {
    GLfloat r, g, b, a;

    if (highlight)
      brightness *= 2;

    if (!do_texture && !spinner_p)
      r = b = 0, g = 1;
    else
      r = g = b = 1;

    a = brightness;

    /* If the glyph is very close to the screen (meaning it is very large,
       and is about to splash into the screen and vanish) then start fading
       it out, proportional to how close to the glass it is.
    */
    if (z > GRID_DEPTH/2)
      {
        GLfloat ratio = ((z - GRID_DEPTH/2) /
                         ((GRID_DEPTH * SPLASH_RATIO) - GRID_DEPTH/2));
        int i = ratio * WAVE_SIZE;

        if (i < 0) i = 0;
        else if (i >= WAVE_SIZE) i = WAVE_SIZE-1;

        a *= mp->brightness_ramp[i];
      }

    glColor4f (r,g,b,a);
  }

  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
  glNormal3f (0, 0, 1);
  glTexCoord2f (cx,   cy);   glVertex3f (x,   y,   z);
  glTexCoord2f (cx+w, cy);   glVertex3f (x+S, y,   z);
  glTexCoord2f (cx+w, cy+h); glVertex3f (x+S, y+S, z);
  glTexCoord2f (cx,   cy+h); glVertex3f (x,   y+S, z);
  glEnd ();

  if (wire && spinner_p)
    {
      glBegin (GL_LINES);
      glVertex3f (x,   y,   z);
      glVertex3f (x+S, y+S, z);
      glVertex3f (x,   y+S, z);
      glVertex3f (x+S, y,   z);
      glEnd();
    }

  mi->polygon_count++;
}
Пример #21
0
static void
generate_object (ModeInfo *mi)
{
  glblur_configuration *bp = &bps[MI_SCREEN(mi)];
  Bool wire = MI_IS_WIREFRAME (mi);
  int s = 10;

  bp->scene_polys1 = 0;
  bp->scene_polys2 = 0;

  glNewList (bp->obj_dlist0, GL_COMPILE);
  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* front */
  glNormal3f (0, 0, 1);
  glTexCoord2f(1, 0); glVertex3f ( 0.5, -0.5,  0.5);
  glTexCoord2f(0, 0); glVertex3f ( 0.5,  0.5,  0.5);
  glTexCoord2f(0, 1); glVertex3f (-0.5,  0.5,  0.5);
  glTexCoord2f(1, 1); glVertex3f (-0.5, -0.5,  0.5);
  bp->scene_polys1++;
  glEnd();

  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* back */
  glNormal3f (0, 0, -1);
  glTexCoord2f(0, 0); glVertex3f (-0.5, -0.5, -0.5);
  glTexCoord2f(0, 1); glVertex3f (-0.5,  0.5, -0.5);
  glTexCoord2f(1, 1); glVertex3f ( 0.5,  0.5, -0.5);
  glTexCoord2f(1, 0); glVertex3f ( 0.5, -0.5, -0.5);
  bp->scene_polys1++;
  glEnd();
  glEndList();

  glNewList (bp->obj_dlist1, GL_COMPILE);
  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* left */
  glNormal3f (-1, 0, 0);
  glTexCoord2f(1, 1); glVertex3f (-0.5,  0.5,  0.5);
  glTexCoord2f(1, 0); glVertex3f (-0.5,  0.5, -0.5);
  glTexCoord2f(0, 0); glVertex3f (-0.5, -0.5, -0.5);
  glTexCoord2f(0, 1); glVertex3f (-0.5, -0.5,  0.5);
  bp->scene_polys1++;
  glEnd();

  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* right */
  glNormal3f (1, 0, 0);
  glTexCoord2f(1, 1); glVertex3f ( 0.5, -0.5, -0.5);
  glTexCoord2f(1, 0); glVertex3f ( 0.5,  0.5, -0.5);
  glTexCoord2f(0, 0); glVertex3f ( 0.5,  0.5,  0.5);
  glTexCoord2f(0, 1); glVertex3f ( 0.5, -0.5,  0.5);
  bp->scene_polys1++;
  glEnd();
  glEndList();

  glNewList (bp->obj_dlist2, GL_COMPILE);
  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* top */
  glNormal3f (0, 1, 0);
  glTexCoord2f(0, 0); glVertex3f ( 0.5,  0.5,  0.5);
  glTexCoord2f(0, 1); glVertex3f ( 0.5,  0.5, -0.5);
  glTexCoord2f(1, 1); glVertex3f (-0.5,  0.5, -0.5);
  glTexCoord2f(1, 0); glVertex3f (-0.5,  0.5,  0.5);
  bp->scene_polys1++;
  glEnd();

  glBegin (wire ? GL_LINE_LOOP : GL_QUADS);	/* bottom */
  glNormal3f (0, -1, 0);
  glTexCoord2f(1, 0); glVertex3f (-0.5, -0.5,  0.5);
  glTexCoord2f(0, 0); glVertex3f (-0.5, -0.5, -0.5);
  glTexCoord2f(0, 1); glVertex3f ( 0.5, -0.5, -0.5);
  glTexCoord2f(1, 1); glVertex3f ( 0.5, -0.5,  0.5);
  bp->scene_polys1++;
  glEnd();
  glEndList();

  glNewList (bp->obj_dlist3, GL_COMPILE);
  glLineWidth (1);
  glBegin(GL_LINES);
  glVertex3f(-s, 0, 0); glVertex3f(s, 0, 0);	/* face spikes */
  glVertex3f(0, -s, 0); glVertex3f(0, s, 0);
  glVertex3f(0, 0, -s); glVertex3f(0, 0, s);
  bp->scene_polys2 += 3;
  glEnd();

  glLineWidth (8);
  glBegin(GL_LINES);
  glVertex3f(-s, -s, -s); glVertex3f( s,  s,  s);  /* corner spikes */
  glVertex3f(-s, -s,  s); glVertex3f( s,  s, -s);
  glVertex3f(-s,  s, -s); glVertex3f( s, -s,  s);
  glVertex3f( s, -s, -s); glVertex3f(-s,  s,  s);
  bp->scene_polys2 += 4;
  glEnd();
  glEndList ();

  check_gl_error ("object generation");
}
Пример #22
0
ENTRYPOINT void
init_matrix (ModeInfo *mi)
{
  matrix_configuration *mp;
  int wire = MI_IS_WIREFRAME(mi);
  Bool flip_p = 0;
  int i;

  if (wire)
    do_texture = False;

  if (!mps) {
    mps = (matrix_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (matrix_configuration));
    if (!mps) {
      fprintf(stderr, "%s: out of memory\n", progname);
      exit(1);
    }
  }

  mp = &mps[MI_SCREEN(mi)];
  mp->glx_context = init_GL(mi);

  if (!mode_str || !*mode_str || !strcasecmp(mode_str, "matrix"))
    {
      flip_p = 1;
      mp->glyph_map = matrix_encoding;
      mp->nglyphs   = countof(matrix_encoding);
    }
  else if (!strcasecmp (mode_str, "dna"))
    {
      flip_p = 0;
      mp->glyph_map = dna_encoding;
      mp->nglyphs   = countof(dna_encoding);
    }
  else if (!strcasecmp (mode_str, "bin") ||
           !strcasecmp (mode_str, "binary"))
    {
      flip_p = 0;
      mp->glyph_map = binary_encoding;
      mp->nglyphs   = countof(binary_encoding);
    }
  else if (!strcasecmp (mode_str, "hex") ||
           !strcasecmp (mode_str, "hexadecimal"))
    {
      flip_p = 0;
      mp->glyph_map = hex_encoding;
      mp->nglyphs   = countof(hex_encoding);
    }
  else if (!strcasecmp (mode_str, "dec") ||
           !strcasecmp (mode_str, "decimal"))
    {
      flip_p = 0;
      mp->glyph_map = decimal_encoding;
      mp->nglyphs   = countof(decimal_encoding);
    }
  else
    {
      fprintf (stderr,
           "%s: `mode' must be matrix, dna, binary, or hex: not `%s'\n",
               progname, mode_str);
      exit (1);
    }

  reshape_matrix (mi, MI_WIDTH(mi), MI_HEIGHT(mi));

  glShadeModel(GL_SMOOTH);

  glDisable(GL_DEPTH_TEST);
  glDisable(GL_CULL_FACE);
  glEnable(GL_NORMALIZE);

  if (do_texture)
    {
      load_textures (mi, flip_p);
      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);
    }

  /* to scale coverage-percent to strips, this number looks about right... */
  mp->nstrips = (int) (density * 2.2);
  if      (mp->nstrips < 1)    mp->nstrips = 1;
  else if (mp->nstrips > 2000) mp->nstrips = 2000;


  mp->strips = calloc (mp->nstrips, sizeof(strip));
  for (i = 0; i < mp->nstrips; i++)
    {
      strip *s = &mp->strips[i];
      reset_strip (mi, s);

      /* If we start all strips from zero at once, then the first few seconds
         of the animation are much denser than normal.  So instead, set all
         the initial strips to erase-mode with random starting positions.
         As these die off at random speeds and are re-created, we'll get a
         more consistent density. */
      s->erasing_p = True;
      s->spinner_y = frand(GRID_SIZE);
      memset (s->glyphs, 0, sizeof(s->glyphs));  /* no visible glyphs */
    }

  /* Compute the brightness ramp.
   */
  for (i = 0; i < WAVE_SIZE; i++)
    {
      GLfloat j = ((WAVE_SIZE - i) / (GLfloat) (WAVE_SIZE - 1));
      j *= (M_PI / 2);       /* j ranges from 0.0 - PI/2  */
      j = sin (j);           /* j ranges from 0.0 - 1.0   */
      j = 0.2 + (j * 0.8);   /* j ranges from 0.2 - 1.0   */
      mp->brightness_ramp[i] = j;
      /* printf("%2d %8.2f\n", i, j); */
    }


  auto_track_init (mi);
}
Пример #23
0
static int
build_face (ModeInfo *mi)
{
  int polys = 0;
  cube_configuration *bp = &bps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  GLfloat s;
  const struct gllist *gll;

  GLfloat base_color[4]   = {0.53, 0.60, 0.66, 1.00};
  GLfloat heart_color[4]  = {0.92, 0.67, 1.00, 1.00};
  GLfloat disc_color[4]   = {0.75, 0.92, 1.00, 1.00};
  GLfloat corner_color[4] = {0.75, 0.92, 1.00, 1.00};

  if (!wire) 
    {
      GLfloat w = 0.010;
      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, base_color);
      glPushMatrix();
      glNormal3f (0, 0, -1);
      glTranslatef (-0.5, -0.5, -0.5);

      glBegin(GL_QUADS);
      glVertex3f (0,     0,     0);
      glVertex3f (0,     0.5-w, 0);
      glVertex3f (0.5-w, 0.5-w, 0);
      glVertex3f (0.5-w, 0,     0);

      glVertex3f (0.5+w, 0,     0);
      glVertex3f (0.5+w, 0.5-w, 0);
      glVertex3f (1,     0.5-w, 0);
      glVertex3f (1,     0,     0);

      glVertex3f (0,     0.5+w, 0);
      glVertex3f (0,     1,     0);
      glVertex3f (0.5-w, 1,     0);
      glVertex3f (0.5-w, 0.5+w, 0);

      glVertex3f (0.5+w, 0.5+w, 0);
      glVertex3f (0.5+w, 1,     0);
      glVertex3f (1,     1,     0);
      glVertex3f (1,     0.5+w, 0);
      glEnd();

      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, heart_color);

      glNormal3f (0, -1, 0);
      glBegin(GL_QUADS);
      glVertex3f (0, 0.5+w, 0);
      glVertex3f (1, 0.5+w, 0);
      glVertex3f (1, 0.5+w, w);
      glVertex3f (0, 0.5+w, w);
      glEnd();

      glNormal3f (0, 1, 0);
      glBegin(GL_QUADS);
      glVertex3f (0, 0.5-w, w);
      glVertex3f (1, 0.5-w, w);
      glVertex3f (1, 0.5-w, 0);
      glVertex3f (0, 0.5-w, 0);
      glEnd();

      glNormal3f (-1, 0, 0);
      glBegin(GL_QUADS);
      glVertex3f (0.5+w, 0, w);
      glVertex3f (0.5+w, 1, w);
      glVertex3f (0.5+w, 1, 0);
      glVertex3f (0.5+w, 0, 0);
      glEnd();

      glNormal3f (1, 0, 0);
      glBegin(GL_QUADS);
      glVertex3f (0.5-w, 0, 0);
      glVertex3f (0.5-w, 1, 0);
      glVertex3f (0.5-w, 1, w);
      glVertex3f (0.5-w, 0, w);
      glEnd();

      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, heart_color);

      glNormal3f (0, 0, -1);
      glTranslatef (0, 0, w);
      glBegin(GL_QUADS);
      glVertex3f (0, 0, 0);
      glVertex3f (0, 1, 0);
      glVertex3f (1, 1, 0);
      glVertex3f (1, 0, 0);
      glEnd();

      glPopMatrix();
    }

  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, corner_color);

  glPushMatrix();
  polys += build_corner (mi); glRotatef (90, 0, 0, 1);
  polys += build_corner (mi); glRotatef (90, 0, 0, 1);
  polys += build_corner (mi); glRotatef (90, 0, 0, 1);
  polys += build_corner (mi);

  glRotatef (90, 0, 0, 1);
  glTranslatef (0.585, -0.585, -0.5655);

  s = 10.5;
  glScalef (s, s, s);
  glRotatef (180, 0, 1, 0);

  if (! wire)
    {
      gll = *all_objs[BASE_HEART];
      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, heart_color);
      glCallList (bp->dlists[BASE_HEART]);
      polys += gll->points / 3;
    }

  gll = *all_objs[BASE_DISC];
  glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, disc_color);
  glCallList (bp->dlists[BASE_DISC]);
  polys += gll->points / 3;

  glPopMatrix();
  return polys;
}
Пример #24
0
static void DrawFire(ModeInfo * mi)
{
    int j;
    firestruct *fs = &fire[MI_SCREEN(mi)];
    Bool wire = MI_IS_WIREFRAME(mi);

    mi->polygon_count = 0;

    if (do_wander && !fs->button_down_p)
    {
	GLfloat x, y, z;

#       define SINOID(SCALE,SIZE) \
        ((((1 + sin((fs->frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2)

        x = SINOID(0.031, 0.85);
        y = SINOID(0.017, 0.25);
        z = SINOID(0.023, 0.85);
        fs->frame++;
        fs->obs[0] = x + DEF_OBS[0];
        fs->obs[1] = y + DEF_OBS[1];
        fs->obs[2] = z + DEF_OBS[2];
        fs->dir[1] = y;
        fs->dir[2] = z;
    }

    glEnable(GL_DEPTH_TEST);

    if (fs->fog)
	glEnable(GL_FOG);
    else
	glDisable(GL_FOG);

    glDepthMask(GL_TRUE);
    glClearColor(0.5, 0.5, 0.8, 1.0);	/* sky in the distance */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();

    calcposobs(fs);

    gltrackball_rotate (fs->trackball);

    gluLookAt(fs->obs[0], fs->obs[1], fs->obs[2],
              fs->obs[0] + fs->dir[0], 
              fs->obs[1] + fs->dir[1],
              fs->obs[2] + fs->dir[2],
              0.0, 1.0, 0.0);

    glEnable(GL_TEXTURE_2D);

    /* draw ground using the computed texture */
    if (do_texture) {
	glColor4f(1.0,1.0,1.0,1.0);	/* white to get texture in it's true color */
#ifdef HAVE_GLBINDTEXTURE
	glBindTexture(GL_TEXTURE_2D, fs->groundid);
#endif /* HAVE_GLBINDTEXTURE */
    }
    else
        glColor4f(0.54, 0.27, 0.07, 1.0);	/* untextured ground color */
    glBegin(GL_QUADS);
    glTexCoord2fv(qt[0]);
    glVertex3fv(q[0]);
    glTexCoord2fv(qt[1]);
    glVertex3fv(q[1]);
    glTexCoord2fv(qt[2]);
    glVertex3fv(q[2]);
    glTexCoord2fv(qt[3]);
    glVertex3fv(q[3]);
    mi->polygon_count++;
    glEnd();

    glAlphaFunc(GL_GEQUAL, 0.9);
    if (fs->num_trees)
    {
	/* here do_texture IS True - and color used is white */
	glEnable(GL_ALPHA_TEST);
#ifdef HAVE_GLBINDTEXTURE
	glBindTexture(GL_TEXTURE_2D,fs->treeid);
#endif /* HAVE_GLBINDTEXTURE */
	for(j=0;j<fs->num_trees;j++)
      mi->polygon_count += drawtree(fs->treepos[j].x ,fs->treepos[j].y ,fs->treepos[j].z );
    	glDisable(GL_ALPHA_TEST);
    }
    glDisable(GL_TEXTURE_2D);
    glDepthMask(GL_FALSE);

    if (fs->shadows) {
	/* draw shadows with black color */
	glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES);
	for (j = 0; j < fs->np; j++) {
	    glColor4f(black[0], black[1], black[2], fs->p[j].c[0][3]);
	    glVertex3f(fs->p[j].p[0][0], 0.1, fs->p[j].p[0][2]);

	    glColor4f(black[0], black[1], black[2], fs->p[j].c[1][3]);
	    glVertex3f(fs->p[j].p[1][0], 0.1, fs->p[j].p[1][2]);

	    glColor4f(black[0], black[1], black[2], fs->p[j].c[2][3]);
	    glVertex3f(fs->p[j].p[2][0], 0.1, fs->p[j].p[2][2]);
        mi->polygon_count++;
	}
	glEnd();
    }

    glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES);
    for (j = 0; j < fs->np; j++) {
	/* draw particles: colors are computed in setpart */
	glColor4fv(fs->p[j].c[0]);
	glVertex3fv(fs->p[j].p[0]);

	glColor4fv(fs->p[j].c[1]);
	glVertex3fv(fs->p[j].p[1]);

	glColor4fv(fs->p[j].c[2]);
	glVertex3fv(fs->p[j].p[2]);
    mi->polygon_count++;

	setpart(fs, &fs->p[j]);
    }
    glEnd();

    /* draw rain particles if no fire particles */
    if (!fs->np)
    {
        float timeused = gettimerain();
        glDisable(GL_TEXTURE_2D);
	glShadeModel(GL_SMOOTH);
	glBegin(GL_LINES);
	for (j = 0; j < NUMPART; j++) {
	    glColor4f(0.7f,0.95f,1.0f,0.0f);
	    glVertex3fv(fs->r[j].oldpos);
	    glColor4f(0.3f,0.7f,1.0f,1.0f);
	    glVertex3fv(fs->r[j].pos);
	    setpartrain(fs, &fs->r[j],timeused);
        mi->polygon_count++;
	}
	glEnd();
	glShadeModel(GL_FLAT);
    }

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_FOG);

    /* manage framerate display */
    if (MI_IS_FPS(mi)) do_fps (mi);
    glPopMatrix();
}
Пример #25
0
/* Render one gear in the proper position, creating the gear's
   display list first if necessary.
 */
static void
draw_gear (ModeInfo *mi, int which)
{
  Bool wire_p = MI_IS_WIREFRAME(mi);
  pinion_configuration *pp = &pps[MI_SCREEN(mi)];
  gear *g = pp->gears[which];
  GLfloat th;

  Bool visible_p = (g->x + g->r + g->tooth_h >= pp->render_left &&
                    g->x - g->r - g->tooth_h <= pp->render_right);

  if (!visible_p && !debug_p)
    return;

  if (! g->dlist)
    {
      g->dlist = glGenLists (1);
      if (! g->dlist)
        {
          /* I don't know how many display lists a GL implementation
             is supposed to provide, but hopefully it's more than
             "a few hundred", or we'll be in trouble...
           */
          check_gl_error ("glGenLists");
          abort();
        }

      glNewList (g->dlist, GL_COMPILE);
      g->polygons = draw_involute_gear (g, (wire_p && debug_p ? 2 : wire_p));
      glEndList ();
    }

  glPushMatrix();

  glTranslatef (g->x, g->y, g->z);

  if (g->motion_blur_p && !pp->button_down_p)
    {
      /* If we're in motion-blur mode, then draw the gear so that each
         frame rotates it by exactly one half tooth-width, so that it
         looks flickery around the edges.  But, revert to the normal
         way when the mouse button is down lest the user see overlapping
         polygons.
       */
      th = g->motion_blur_p * 180.0 / g->nteeth * (g->th > 0 ? 1 : -1);
      g->motion_blur_p++;
    }
  else
    th = g->th;

  glRotatef (th, 0, 0, 1);

  glPushName (g->id);

  if (! visible_p)
    mi->polygon_count += draw_involute_schematic (g, wire_p);
  else
    {
      glCallList (g->dlist);
      mi->polygon_count += g->polygons;
    }

  glPopName();
  glPopMatrix();
}
Пример #26
0
ENTRYPOINT void
init_ball (ModeInfo *mi)
{
  int wire = MI_IS_WIREFRAME(mi);
  blinkboxstruct *bp;
  
  if(blinkbox == NULL) {
    if((blinkbox = (blinkboxstruct *) calloc(MI_NUM_SCREENS(mi),
                                             sizeof (blinkboxstruct))) == NULL)
      return;
  }
  bp = &blinkbox[MI_SCREEN(mi)];

  if ((bp->glx_context = init_GL(mi)) != NULL) {
    reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
    glDrawBuffer(GL_BACK);
  }
  else
    MI_CLEARWINDOW(mi);

  bp->ball.d = 1;
  bp->bscale.wh = bscale_wh;
  bp->bscale.d = 0.25;

  bp->mo.x = 1;
  bp->mo.y = 1;
  bp->mo.z = 1;

  bp->moh.x = -1.0;
  bp->moh.y = -1.5;
  bp->moh.z = -1.5;

  bp->bpos.x = 1;
  bp->bpos.y = 1;
  bp->bpos.z = 1;

  bp->des_amt = 1;

  bp->lside.counter = MAX_COUNT;
  bp->rside.counter = MAX_COUNT;
  bp->tside.counter = MAX_COUNT;
  bp->bside.counter = MAX_COUNT;
  bp->fside.counter = MAX_COUNT;
  bp->aside.counter = MAX_COUNT;

  bp->lside.color[0] = 1;
  bp->rside.color[1] = 1;
  bp->tside.color[2] = 1;

  bp->bside.color[0] = 1;
  bp->bside.color[1] = 0.5;

  bp->fside.color[0] = 1;
  bp->fside.color[1] = 1;

  bp->aside.color[0] = 0.5;
  bp->aside.color[2] = 1;

  bp->lside.rot[0] = 90;
  bp->rside.rot[0] = 90;
  bp->tside.rot[0] = 90;
  bp->bside.rot[0] = 90;
  bp->fside.rot[0] = 90;
  bp->aside.rot[0] = 90;

  bp->lside.rot[2] = 1;
  bp->rside.rot[2] = 1;
  bp->tside.rot[1] = 1;
  bp->bside.rot[1] = 1;
  bp->fside.rot[3] = 1;
  bp->aside.rot[3] = 1;

  bp->lside.des_count = 1;
  bp->rside.des_count = 1;
  bp->tside.des_count = 1;
  bp->bside.des_count = 1;
  bp->fside.des_count = 1;
  bp->aside.des_count = 1;

  bp->lside.alpha_count = 1;
  bp->rside.alpha_count = 1;
  bp->tside.alpha_count = 1;
  bp->bside.alpha_count = 1;
  bp->fside.alpha_count = 1;
  bp->aside.alpha_count = 1;


#define SPHERE_SLICES 12  /* how densely to render spheres */
#define SPHERE_STACKS 16

  bp->sp = malloc(sizeof(*bp->sp));
  if(bp->sp == NULL){
    fprintf(stderr,"Could not allocate memory\n");
    exit(1);
  }
  if( (bp->bscale.wh < 1) ||
      (bp->bscale.wh > 8) ) {
    fprintf(stderr,"Boxsize out of range. Using default\n");
    bp->bscale.wh = 2;
  }
  if (do_dissolve){
    bp->des_amt = bp->bscale.wh / MAX_COUNT;
  }

  reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  bp->ballList = glGenLists(1);
  glNewList(bp->ballList, GL_COMPILE);
  unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire);
  glEndList ();

  bp->boxList = glGenLists(1);
  glNewList(bp->boxList, GL_COMPILE);
  unit_cube(wire);
  glEndList();

  if (wire) return;

  glEnable(GL_COLOR_MATERIAL);
  glShadeModel(GL_SMOOTH);
  glClearDepth(1.0f);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
  glEnable(GL_LIGHTING);
  glClearDepth(1);
  glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
  glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
  glEnable(GL_LIGHT1);
  if (do_fade || do_blur) {
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
  }
}
Пример #27
0
/* 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 *img = (image *) closure;
  ModeInfo *mi = img->mi;
  /* slideshow_state *ss = &sss[MI_SCREEN(mi)]; */

  int wire = MI_IS_WIREFRAME(mi);

  if (wire)
    {
      img->w = MI_WIDTH (mi) * (0.5 + frand (1.0));
      img->h = MI_HEIGHT (mi);
      img->geom.width  = img->w;
      img->geom.height = img->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);

  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  img->w  = image_width;
  img->h  = image_height;
  img->tw = texture_width;
  img->th = texture_height;
  img->geom = *geom;
  img->title = (filename ? strdup (filename) : 0);

  /* If the image's width doesn't come back as the width of the screen,
     then the image must have been scaled down (due to insufficient
     texture memory.)  Scale up the coordinates to stretch the image
     to fill the window.
   */
  if (img->w != MI_WIDTH(mi))
    {
      double scale = (double) MI_WIDTH(mi) / img->w;
      img->w  *= scale;
      img->h  *= scale;
      img->tw *= scale;
      img->th *= scale;
      img->geom.x      *= scale;
      img->geom.y      *= scale;
      img->geom.width  *= scale;
      img->geom.height *= scale;
    }

  /* xscreensaver-getimage returns paths relative to the image directory
     now, so leave the sub-directory part in.  Unless it's an absolute path.
  */
  if (img->title && img->title[0] == '/')
    {
      /* strip filename to part between last "/" and last ".". */
      char *s = strrchr (img->title, '/');
      if (s) strcpy (img->title, s+1);
      s = strrchr (img->title, '.');
      if (s) *s = 0;
    }

  if (debug_p)
    fprintf (stderr, "%s: loaded   img %2d: \"%s\"\n",
             blurb(), img->id, (img->title ? img->title : "(null)"));
 DONE:

  img->loaded_p = True;
}
Пример #28
0
ENTRYPOINT void
draw_ball (ModeInfo *mi)
{
   blinkboxstruct *bp = &blinkbox[MI_SCREEN(mi)];

   Display *dpy = MI_DISPLAY(mi);
   Window window = MI_WINDOW(mi);
   int i = 0;

   if (! bp->glx_context)
     return;
   mi->polygon_count = 0;
   glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));

   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   hit_top_bottom(bp);
   hit_front_back(bp);
   hit_side(bp);

   glRotated(0.25,0,0,1);
   glRotated(0.25,0,1,0);
   glRotated(0.25,1,0,0);


   glPushMatrix();
   glScalef(0.5,0.5,0.5);

   glColor3f(1,1,1);
   glPushMatrix();

   if (!do_blur || MI_IS_WIREFRAME(mi)) {
     glTranslatef(bp->ball.x += bp->mo.x,
                  bp->ball.y += bp->mo.y,
                  bp->ball.z += bp->mo.z);

     glScalef(2,2,2);
     glCallList(bp->ballList);
     mi->polygon_count += SPHERE_SLICES*SPHERE_STACKS;

   } else {

#    define blur_detail 24.0
     float ball_alpha = 1 / blur_detail;

     glBlendFunc(GL_SRC_ALPHA,GL_ONE);
     glTranslatef(bp->ball.x, bp->ball.y, bp->ball.z);
   
     for (i = 0; i < blur_detail; ++i) {
       glTranslatef(bp->mo.x / blur_detail,
                    bp->mo.y / blur_detail,
                    bp->mo.z / blur_detail);

       /* comment the following line for quick but boring linear blur */
       ball_alpha = sin((M_PI / blur_detail) * i) / blur_detail;
     
       glColor4f(1, 1, 1, ball_alpha);

       glScalef(2, 2, 2);
       glCallList(bp->ballList);
       mi->polygon_count += SPHERE_SLICES*SPHERE_STACKS;
       glScalef(.5, .5, .5);
     }
     i = 0;
   
     bp->ball.x += bp->mo.x;
     bp->ball.y += bp->mo.y;
     bp->ball.z += bp->mo.z;
   }
   
   glPopMatrix();

   while(i < 6){
    switch(i){
      case 0:{
               bp->sp = &bp->lside;
               bp->bpos.x = bp->lside.pos.z*-1;
               bp->bpos.y = bp->lside.pos.y;
               bp->bpos.z = bbox.bottom.x - bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y);
               break;
             }
      case 1:{
               bp->sp = &bp->rside;
               bp->bpos.x = bp->rside.pos.z*-1;
               bp->bpos.y = bp->rside.pos.y;
               bp->bpos.z = bbox.top.x + bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y);
               break;
             }
      case 2:{
               bp->sp = &bp->tside;
               bp->bpos.x = bp->tside.pos.x;
               bp->bpos.y = bp->tside.pos.z;
               bp->bpos.z = bbox.bottom.y - bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z);
               break;
             }
      case 3:{
               bp->sp = &bp->bside;
               bp->bpos.x = bp->bside.pos.x;
               bp->bpos.y = bp->bside.pos.z;
               bp->bpos.z = bbox.top.y + bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z);
               break;
             }
      case 4:{
               bp->sp = &bp->fside;
               bp->bpos.x = bp->fside.pos.y;
               bp->bpos.y = bp->fside.pos.x*-1;
               bp->bpos.z = bbox.top.z + bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x);
               break;
             }
      case 5:{
               bp->sp = &bp->aside;
               bp->bpos.x = bp->aside.pos.y;
               bp->bpos.y = bp->aside.pos.x*-1;
               bp->bpos.z = bbox.bottom.z + bp->bscale.d;
               if (bp->sp->hit)
                CheckBoxPos(bp, bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x);
               break;
             }
    }
    if(bp->sp->hit){
      if(do_fade){
        glColor4f(bp->sp->color[0],bp->sp->color[1],bp->sp->color[2],1-(ALPHA_AMT * bp->sp->alpha_count));
      }else{
        glColor3fv(bp->sp->color);
      }
      glBlendFunc(GL_SRC_ALPHA,GL_ONE);
      glPushMatrix();
      glRotatef(bp->sp->rot[0],bp->sp->rot[1],bp->sp->rot[2],bp->sp->rot[3]);
      glTranslatef(bp->bpos.x,bp->bpos.y,bp->bpos.z);
      if (do_dissolve) {
         glScalef(bp->bscale.wh-(bp->des_amt*bp->sp->des_count),bp->bscale.wh-(bp->des_amt*bp->sp->des_count),bp->bscale.d);
      }else{
        glScalef(bp->bscale.wh,bp->bscale.wh,bp->bscale.d);
      }
      glCallList(bp->boxList);
      mi->polygon_count += 6;
      glPopMatrix();
      bp->sp->counter--;
      bp->sp->des_count++;
      bp->sp->alpha_count++;
      if(!bp->sp->counter)
      {
        bp->sp->hit = 0;
      }
    }
    i++;
  }


   glPopMatrix();
  if (mi->fps_p) do_fps (mi);
   glFinish();
   glXSwapBuffers(dpy, window);

}
Пример #29
0
void
init_molecule (ModeInfo *mi)
{
  molecule_configuration *mc;
  int wire;

#ifndef STANDALONE
  timeout = MI_CYCLES(mi);
#endif
  if (!mcs) {
    mcs = (molecule_configuration *)
      calloc (MI_NUM_SCREENS(mi), sizeof (molecule_configuration));
    if (!mcs) {
       return;
    }
  }

  mc = &mcs[MI_SCREEN(mi)];
  if (mc->glx_context) {
	/* Free font stuff */
	free_fonts (mi);
  }

  if ((mc->glx_context = init_GL(mi)) != NULL) {
    glDrawBuffer(GL_BACK);
    gl_init();
    last = 0;
    reshape_molecule (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
  }

  if (!load_fonts (mi)) {
	release_molecule(mi);
	return;
  }
  if (firstcall)
  startup_blurb (mi);
  cur_wire = MI_IS_WIREFRAME(mi);
  wire = cur_wire;

  mc->rotx = FLOATRAND(1.0) * RANDSIGN();
  mc->roty = FLOATRAND(1.0) * RANDSIGN();
  mc->rotz = FLOATRAND(1.0) * RANDSIGN();

  /* bell curve from 0-6 degrees, avg 3 */
  mc->dx = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2);
  mc->dy = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2);
  mc->dz = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2);

  mc->d_max = mc->dx * 8;

  mc->ddx = 0.00006 + FLOATRAND(0.00003);
  mc->ddy = 0.00006 + FLOATRAND(0.00003);
  mc->ddz = 0.00006 + FLOATRAND(0.00003);

  {
    char *s = do_spin;
    while (*s)
      {
        if      (*s == 'x' || *s == 'X') mc->spin_x = 1;
        else if (*s == 'y' || *s == 'Y') mc->spin_y = 1;
        else if (*s == 'z' || *s == 'Z') mc->spin_z = 1;
        else
          {
            (void) fprintf (stderr,
         "molecule: spin must contain only the characters X, Y, or Z (not \"%s\")\n",
                     do_spin);
            /* exit (1); */
          }
        s++;
      }
  }

  mc->molecule_dlist = glGenLists(1);

  load_molecules (mi);
  mc->which =  NRAND(mc->nmolecules);

#ifdef STANDALONE
  mc->no_label_threshold = get_float_resource ("noLabelThreshold",
                                               "NoLabelThreshold");
  mc->wireframe_threshold = get_float_resource ("wireframeThreshold",
                                                "WireframeThreshold");
#else
  mc->no_label_threshold = 30;
  mc->wireframe_threshold = 150;
#endif

  if (wire)
    do_bonds = 1;
}
Пример #30
0
static void
draw_ball (ModeInfo *mi)
{
  boing_configuration *bp = &bps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  int x, y;
  int xx = meridians;
  int yy = parallels;
  int scale = (smooth_p ? 5 : 1);

  if (lighting_p && !wire)
    glEnable (GL_LIGHTING);

  if (parallels < 3)
    scale *= 2;

  xx *= scale;
  yy *= scale;

  glFrontFace (GL_CW);

  glPushMatrix();
  glTranslatef (bp->ball_x, bp->ball_y, bp->ball_z);
  glScalef (ball_size, ball_size, ball_size);
  glRotatef (-angle,      0, 0, 1);
  glRotatef (bp->ball_th, 0, 1, 0);

  for (y = 0; y < yy; y++)
    {
      GLfloat thy0 = y     * (M_PI * 2) / (yy * 2) + M_PI_2;
      GLfloat thy1 = (y+1) * (M_PI * 2) / (yy * 2) + M_PI_2;

      for (x = 0; x < xx; x++)
        {
          GLfloat thx0 = x     * (M_PI * 2) / xx;
          GLfloat thx1 = (x+1) * (M_PI * 2) / xx;
          XYZ p;
          Bool bgp = ((x/scale) & 1) ^ ((y/scale) & 1);

          if (wire && bgp) continue;

          glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
                        (bgp ? bp->ball_color2 : bp->ball_color1));
          glColor3fv (bgp ? bp->ball_color2 : bp->ball_color1);

          glBegin (wire ? GL_LINE_LOOP : GL_QUADS);

          if (!smooth_p)
            {
              p.x = cos((thy0+thy1)/2) * cos((thx0+thx1)/2);
              p.y = sin((thy0+thy1)/2);
              p.z = cos((thy0+thy1)/2) * sin((thx0+thx1)/2);
              glNormal3f (-p.x, -p.y, -p.z);
            }

          p.x = cos(thy0) * cos(thx0) / 2;
          p.y = sin(thy0)             / 2;
          p.z = cos(thy0) * sin(thx0) / 2;
          if (smooth_p)
            glNormal3f (-p.x, -p.y, -p.z);
          glVertex3f (p.x, p.y, p.z);

          p.x = cos(thy1) * cos(thx0) / 2;
          p.y = sin(thy1)             / 2;
          p.z = cos(thy1) * sin(thx0) / 2;
          if (smooth_p)
            glNormal3f (-p.x, -p.y, -p.z);
          glVertex3f (p.x, p.y, p.z);

          p.x = cos(thy1) * cos(thx1) / 2;
          p.y = sin(thy1)             / 2;
          p.z = cos(thy1) * sin(thx1) / 2;
          if (smooth_p)
            glNormal3f (-p.x, -p.y, -p.z);
          glVertex3f (p.x, p.y, p.z);

          p.x = cos(thy0) * cos(thx1) / 2;
          p.y = sin(thy0)             / 2;
          p.z = cos(thy0) * sin(thx1) / 2;
          if (smooth_p)
            glNormal3f (-p.x, -p.y, -p.z);
          glVertex3f (p.x, p.y, p.z);

          glEnd ();
          mi->polygon_count++;
        }
    }

  glPopMatrix();

  if (lighting_p && !wire)
    glDisable(GL_LIGHTING);
}