Пример #1
0
static int
draw_colon (ModeInfo *mi)
{
  splitflap_configuration *bp = &bps[MI_SCREEN(mi)];
  GLfloat s = 1.0 / (bp->ascent + bp->descent);
  GLfloat z = 0.01;
  int count = 0;
  XCharStruct m;

  texture_string_metrics (bp->font_data, ":", &m, 0, 0);

  s *= 2;

  glPushMatrix();

  glTranslatef (-(1 + COLON_WIDTH), 0, 0);
  glScalef (s, s, 1);

  glTranslatef (-m.lbearing - (m.rbearing - m.lbearing)/2,
                -(m.ascent + m.descent) / 2,
                0);

  glEnable (GL_TEXTURE_2D);

  /* draw the text five times, to give it a border. */
  {
    const XPoint offsets[] = {{ -1, -1 },
                              { -1,  1 },
                              {  1,  1 },
                              {  1, -1 },
                              {  0,  0 }};
    int i;
    GLfloat n = 1.5;

    glColor3f (0, 0, 0);
    for (i = 0; i < countof(offsets); i++)
      {
        glPushMatrix();
        if (offsets[i].x == 0)
          {
            glColor4fv (bp->text_color);
            glTranslatef (0, 0, z * 2);
          }
        glTranslatef (n * offsets[i].x, n * offsets[i].y, 0);
        print_texture_string (bp->font_data, ":");
        count++;
        glPopMatrix();
      }
  }

  glPopMatrix();

  return count;
}
Пример #2
0
static void
loading_msg (ModeInfo *mi, int n)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  char text[100];
  GLfloat scale;

  if (wire) return;

  if (n == 0)
    sprintf (text, "Loading images...");
  else
    sprintf (text, "Loading images...  (%d%%)",
             (int) (n * 100 / MI_COUNT(mi)));

  if (ss->loading_sw == 0)    /* only do this once, so that the string doesn't move. */
    ss->loading_sw = texture_string_width (ss->texfont, text, &ss->loading_sh);

  scale = ss->loading_sh / (GLfloat) MI_HEIGHT(mi);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi));

  glTranslatef ((MI_WIDTH(mi)  - ss->loading_sw) / 2,
                (MI_HEIGHT(mi) - ss->loading_sh) / 2,
                0);
  glColor3f (1, 1, 0);
  glEnable (GL_TEXTURE_2D);
  glDisable (GL_DEPTH_TEST);
  print_texture_string (ss->texfont, text);
  glEnable (GL_DEPTH_TEST);
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glMatrixMode(GL_MODELVIEW);

  glFinish();
  glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi));
}
Пример #3
0
static void
loading_msg (ModeInfo *mi)
{
  photopile_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  const char text[] = "Loading...";

  if (wire) return;

  if (ss->loading_sw == 0)    /* only do this once */
    {
      XCharStruct e;
      texture_string_metrics (ss->texfont, text, &e, 0, 0);
      ss->loading_sw = e.width;
      ss->loading_sh = e.ascent + e.descent;
    }

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);

  glTranslatef ((MI_WIDTH(mi)  - ss->loading_sw) / 2,
                (MI_HEIGHT(mi) - ss->loading_sh) / 2,
                0);
  glColor3f (1, 1, 0);
  glEnable (GL_TEXTURE_2D);
  glDisable (GL_DEPTH_TEST);
  print_texture_string (ss->texfont, text);
  glEnable (GL_DEPTH_TEST);
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glMatrixMode(GL_MODELVIEW);

  glFinish();
  glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi));
}
Пример #4
0
static void
draw_unichar (ModeInfo *mi)
{
  unicrud_configuration *bp = &bps[MI_SCREEN(mi)];

  char text[10];
  char title[400];
  XCharStruct e;
  int w, h, i, j;
  GLfloat s;

  i = utf8_encode (bp->unichar, text, sizeof(text) - 1);
  text[i] = 0;

  *title = 0;
  sprintf (title + strlen(title), "Plane:\t%s\n", bp->charplane);
  sprintf (title + strlen(title), "Block:\t%s\n", bp->charblock);
# ifdef HAVE_JWXYZ
  sprintf (title + strlen(title), "Name:\t%s\n",
           (bp->charname ? bp->charname : ""));
#endif
  sprintf (title + strlen(title), "Unicode:\t%04lX\n", bp->unichar);
  sprintf (title + strlen(title), "UTF-8:\t");
  for (j = 0; j < i; j++)
    sprintf (title + strlen(title), "%02X ", ((unsigned char *)text)[j]);

  texture_string_metrics (bp->char_font, text, &e, 0, 0);
  w = e.width;
  h = e.ascent;

  s = 9;
  glScalef (s, s, s);
  
  s = 1.0 / (h > w ? h : w);	/* Scale to unit */
  glScalef (s, s, s);

  glTranslatef (-w/2, -h/2, 0);
  glColor4fv (bp->color);
  print_texture_string (bp->char_font, text);

  glColor3f (1, 1, 0);
  if (do_titles)
    print_texture_label (mi->dpy, bp->title_font,
                         mi->xgwa.width, mi->xgwa.height,
                         1, title);
}
Пример #5
0
static void
draw_string (sws_configuration *sc, GLfloat x, GLfloat y, const char *s)
{
  const char *os = s;
  if (!s || !*s) return;
  glPushMatrix ();
  glTranslatef (x, y, 0);

  if (textures_p)
    print_texture_string (sc->texfont, s);
  else
    while (*s)
      glutStrokeCharacter (GLUT_FONT, *s++);
  glPopMatrix ();

  if (debug_p)
    {
      GLfloat w;
      GLfloat h = sc->line_height / sc->font_scale;
      char c[2];
      c[1]=0;
      s = os;
      if (textures_p) glDisable (GL_TEXTURE_2D);
      glLineWidth (1);
      glColor3f (0.4, 0.4, 0.4);
      glPushMatrix ();
      glTranslatef (x, y, 0);
      while (*s)
        {
          *c = *s++;
          w = string_width (sc, c);
          glBegin (GL_LINE_LOOP);
          glVertex3f (0, 0, 0);
          glVertex3f (w, 0, 0);
          glVertex3f (w, h, 0);
          glVertex3f (0, h, 0);
          glEnd();
          glTranslatef (w, 0, 0);
        }
      glPopMatrix ();
      if (textures_p) glEnable (GL_TEXTURE_2D);
    }
}
Пример #6
0
static void
draw_frame (ModeInfo *mi, image_frame *frame, time_t now, Bool body_p)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);

  GLfloat texw  = frame->current.geom.width  / (GLfloat) frame->current.tw;
  GLfloat texh  = frame->current.geom.height / (GLfloat) frame->current.th;
  GLfloat texx1 = frame->current.geom.x / (GLfloat) frame->current.tw;
  GLfloat texy1 = frame->current.geom.y / (GLfloat) frame->current.th;
  GLfloat texx2 = texx1 + texw;
  GLfloat texy2 = texy1 + texh;
  GLfloat aspect = ((GLfloat) frame->current.geom.height /
                    (GLfloat) frame->current.geom.width);

  glBindTexture (GL_TEXTURE_2D, frame->current.texid);

  glPushMatrix();

  /* Position this image on the wheel.
   */
  glRotatef (frame->theta, 0, 1, 0);
  glTranslatef (0, 0, frame->r);

  /* Scale down the image so that all N frames fit on the wheel
     without bumping in to each other.
  */
  {
    GLfloat t, s;
    switch (ss->nframes)
      {
      case 1:  t = -1.0; s = 1.7; break;
      case 2:  t = -0.8; s = 1.6; break;
      case 3:  t = -0.4; s = 1.5; break;
      case 4:  t = -0.2; s = 1.3; break;
      default: t =  0.0; s = 6.0 / ss->nframes; break;
      }
    glTranslatef (0, 0, t);
    glScalef (s, s, s);
  }

  /* Center this image on the wheel plane.
   */
  glTranslatef (-0.5, -(aspect/2), 0);

  /* Move as per the "zoom in and out" setting.
   */
  if (zoom_p)
    {
      double x, y, z;
      /* Only use the Z component of the rotator for in/out position. */
      get_position (frame->rot, &x, &y, &z, !ss->button_down_p);
      glTranslatef (0, 0, z/2);
    }

  /* Compute the "drop in and out" state.
   */
  switch (frame->mode)
    {
    case EARLY:
      abort();
      break;
    case NORMAL:
      if (!ss->button_down_p &&
          now >= frame->expires &&
          ss->loads_in_progress == 0)  /* only load one at a time */
        load_image (mi, frame);
      break;
    case LOADING:
      break;
    case OUT:
      if (--frame->mode_tick <= 0) {
        image swap = frame->current;
        frame->current = frame->loading;
        frame->loading = swap;

        frame->mode = IN;
        frame->mode_tick = fade_ticks / speed;
      }
      break;
    case IN:
      if (--frame->mode_tick <= 0)
        frame->mode = NORMAL;
      break;
    default:
      abort();
    }

  /* Now translate for current in/out state.
   */
  if (frame->mode == OUT || frame->mode == IN)
    {
      GLfloat t = (frame->mode == OUT
                   ? frame->mode_tick / (fade_ticks / speed)
                   : (((fade_ticks / speed) - frame->mode_tick + 1) /
                      (fade_ticks / speed)));
      t = 5 * (1 - t);
      if (frame->from_top_p) t = -t;
      glTranslatef (0, t, 0);
    }

  if (body_p)					/* Draw the image quad. */
    {
      if (! wire)
        {
          glColor3f (1, 1, 1);
          glNormal3f (0, 0, 1);
          glEnable (GL_TEXTURE_2D);
          glBegin (GL_QUADS);
          glNormal3f (0, 0, 1);
          glTexCoord2f (texx1, texy2); glVertex3f (0, 0, 0);
          glTexCoord2f (texx2, texy2); glVertex3f (1, 0, 0);
          glTexCoord2f (texx2, texy1); glVertex3f (1, aspect, 0);
          glTexCoord2f (texx1, texy1); glVertex3f (0, aspect, 0);
          glEnd();
        }

      /* Draw a box around it.
       */
      glLineWidth (2.0);
      glColor3f (0.5, 0.5, 0.5);
      glDisable (GL_TEXTURE_2D);
      glBegin (GL_LINE_LOOP);
      glVertex3f (0, 0, 0);
      glVertex3f (1, 0, 0);
      glVertex3f (1, aspect, 0);
      glVertex3f (0, aspect, 0);
      glEnd();

    }
  else					/* Draw a title under the image. */
    {
      int sw, sh;
      GLfloat scale = 0.05;
      char *title = frame->current.title ? frame->current.title : "(untitled)";
      sw = texture_string_width (ss->texfont, title, &sh);

      glTranslatef (0, -scale, 0);

      scale /= sh;
      glScalef (scale, scale, scale);

      glTranslatef (((1/scale) - sw) / 2, 0, 0);
      glColor3f (1, 1, 1);

      if (!wire)
        {
          glEnable (GL_TEXTURE_2D);
          print_texture_string (ss->texfont, title);
        }
      else
        {
          glBegin (GL_LINE_LOOP);
          glVertex3f (0,  0,  0);
          glVertex3f (sw, 0,  0);
          glVertex3f (sw, sh, 0);
          glVertex3f (0,  sh, 0);
          glEnd();
        }
    }

  glPopMatrix();
}
Пример #7
0
static void
loading_msg (ModeInfo *mi, int n)
{
  carousel_state *ss = &sss[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  char text[100];

  if (wire) return;

  if (n == 0)
    sprintf (text, "Loading images...");
  else
    sprintf (text, "Loading images...  (%d%%)",
             (int) (n * 100 / MI_COUNT(mi)));

  if (ss->loading_sw == 0)
    {
      /* only do this once, so that the string doesn't move. */
      XCharStruct e;
      texture_string_metrics (ss->texfont, text, &e, 0, 0);
      ss->loading_sw = e.width;
      ss->loading_sh = e.ascent + e.descent;
    }

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

/*
  {
    double rot = current_device_rotation();
    glRotatef(rot, 0, 0, 1);
    if ((rot >  45 && rot <  135) ||
        (rot < -45 && rot > -135))
      {
        GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
        glScalef (s, 1/s, 1);
      }
  }
*/

# ifdef HAVE_MOBILE
  if (MI_WIDTH(mi) < MI_HEIGHT(mi))  /* portrait orientation */
    {
      GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi));
      glScalef (s, s, s);
      glTranslatef(-s/2, 0, 0);
    }
# endif

  glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
  glTranslatef ((MI_WIDTH(mi)  - ss->loading_sw) / 2,
                (MI_HEIGHT(mi) - ss->loading_sh) / 2,
                0);
  glColor3f (1, 1, 0);
  glEnable (GL_TEXTURE_2D);
  glDisable (GL_DEPTH_TEST);
  print_texture_string (ss->texfont, text);
  glEnable (GL_DEPTH_TEST);
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glMatrixMode(GL_MODELVIEW);

  glFinish();
  glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi));
}
Пример #8
0
/* The segments, numbered arbitrarily from the top left:
             ________         _      ________
             \      /\      /\ \    |\      /
              \ 0  /  \    /  \3>   | \ 5  /
               \  / 1  \  / 2  \| ..|4 \  /-6-..
     ___________\/______\/______\/______\/______\
    |   /\      /\      /\      /\      /\   
    |7 /  \ 9  /  \ 11 /  \ 13 /  \ 15 /  \  
    | / 8  \  / 10 \  / 12 \  / 14 \  / 16 \ 
    |/______\/______\/______\/______\/______\
     \      /\      /       /\      /\
      \ 17 /  \ 18 /       /  \ 20 /  \
       \  /    \  /       / 19 \  / 21 \
        \/      \/       /______\/______\

   Each triangle can be connected to at most two other triangles.
   We start from the middle, #12, and work our way to the edges.
   Its centroid is 0,0.
 */
static void
triangle (ModeInfo *mi, int which, Bool frontp, 
          GLfloat fold_ratio, GLfloat stel_ratio)
{
  planetstruct *gp = &planets[MI_SCREEN(mi)];
  const GLfloat fg[3] = { 1, 1, 1 };
  const GLfloat bg[3] = { 0.3, 0.3, 0.3 };
  int a = -1, b = -1;
  GLfloat max = acos (sqrt(5)/3);
  GLfloat rot = -max * fold_ratio / (M_PI/180);
  Bool wire = MI_IS_WIREFRAME(mi);

  if (wire)
    glColor3fv (fg);

  switch (which) {
  case 3:				/* One third of the face. */
    triangle0 (mi, frontp, stel_ratio, 1<<3 | 1<<4);
    break;
  case 4:				/* Two thirds of the face: convex. */
    triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3 | 1<<4);
    break;
  case 6:				/* One half of the face. */
    triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3);
    break;
  case 7:				/* One half of the face. */
    triangle0 (mi, frontp, stel_ratio, 1<<2 | 1<<3 | 1<<4);
    break;
  default:				/* Full face. */
    triangle0 (mi, frontp, stel_ratio, 0x3F);
    break;
  }

  if (wire)
    {
      char tag[20];
      glColor3fv (bg);
      sprintf (tag, "%d", which);
      glPushMatrix();
      glTranslatef (-0.1, 0.2, 0);
      glScalef (0.005, 0.005, 0.005);
      print_texture_string (gp->font_data, tag);
      glPopMatrix();
      mi->polygon_count++;
    }


  /* The connection hierarchy of the faces starting at the middle, #12. */
  switch (which) {
  case  0: break;
  case  1: a =  0; b = -1; break;
  case  2: a = -1; b =  3; break;
  case  3: break;
  case  4: a = -1; b =  5; break;
  case  5: a = -1; b =  6; break;
  case  7: break;
  case  6: break;
  case  8: a = 17; b =  7; break;
  case  9: a =  8; b = -1; break;
  case 10: a = 18; b =  9; break;
  case 11: a = 10; b =  1; break;
  case 12: a = 11; b = 13; break;
  case 13: a =  2; b = 14; break;
  case 14: a = 15; b = 20; break;
  case 15: a =  4; b = 16; break;
  case 16: break;
  case 17: break;
  case 18: break;
  case 19: break;
  case 20: a = 21; b = 19; break;
  case 21: break;
  default: abort(); break;
  }

  if (a != -1)
    {
      glPushMatrix();
      glTranslatef (-0.5, 0, 0);	/* Move model matrix to upper left */
      glRotatef (60, 0, 0, 1);
      glTranslatef ( 0.5, 0, 0);

      glMatrixMode(GL_TEXTURE);
      /* glPushMatrix(); */
      glTranslatef (-0.5, 0, 0);	/* Move texture matrix the same way */
      glRotatef (60, 0, 0, 1);
      glTranslatef ( 0.5, 0, 0);

      glMatrixMode(GL_MODELVIEW);

      glRotatef (rot, 1, 0, 0);
      triangle (mi, a, frontp, fold_ratio, stel_ratio);

      /* This should just be a PopMatrix on the TEXTURE stack, but
         f*****g iOS has GL_MAX_TEXTURE_STACK_DEPTH == 4!  WTF!
         So we have to undo our rotations and translations manually.
       */
      glMatrixMode(GL_TEXTURE);
      /* glPopMatrix(); */
      glTranslatef (-0.5, 0, 0);
      glRotatef (-60, 0, 0, 1);
      glTranslatef (0.5, 0, 0);

      glMatrixMode(GL_MODELVIEW);
      glPopMatrix();
    }

  if (b != -1)
    {
      glPushMatrix();
      glTranslatef (0.5, 0, 0);		/* Move model matrix to upper right */
      glRotatef (-60, 0, 0, 1);
      glTranslatef (-0.5, 0, 0);

      glMatrixMode(GL_TEXTURE);
      /* glPushMatrix(); */
      glTranslatef (0.5, 0, 0);		/* Move texture matrix the same way */
      glRotatef (-60, 0, 0, 1);
      glTranslatef (-0.5, 0, 0);

      glMatrixMode(GL_MODELVIEW);

      glRotatef (rot, 1, 0, 0);
      triangle (mi, b, frontp, fold_ratio, stel_ratio);

      /* See above. Grr. */
      glMatrixMode(GL_TEXTURE);
      /* glPopMatrix(); */
      glTranslatef (0.5, 0, 0);
      glRotatef (60, 0, 0, 1);
      glTranslatef (-0.5, 0, 0);

      glMatrixMode(GL_MODELVIEW);
      glPopMatrix();
    }
}
Пример #9
0
static void
draw_line (ModeInfo *mi, line *line)
{
  int wire = MI_IS_WIREFRAME(mi);
  fliptext_configuration *sc = &scs[MI_SCREEN(mi)];

  if (! line->text || !*line->text ||
      line->state == NEW || line->state == HESITATE || line->state == DEAD)
    return;

  glPushMatrix();
  glTranslatef (line->current.x, line->current.y, line->current.z);

  glRotatef (line->cth, 0, 1, 0);

  if (sc->alignment == 1)
    glTranslatef (-line->width, 0, 0);
  else if (sc->alignment == 0)
    glTranslatef (-line->width/2, 0, 0);

  glScalef (sc->font_scale, sc->font_scale, sc->font_scale);

  glColor4f (line->color[0], line->color[1], line->color[2], line->color[3]);

  if (!wire)
    print_texture_string (sc->texfont, line->text);
  else
    {
      int w, h;
      char *s = line->text;
      char c[2];
      c[1]=0;
      glDisable (GL_TEXTURE_2D);
      glColor3f (0.4, 0.4, 0.4);
      while (*s)
        {
          XCharStruct e;
          *c = *s++;
          texture_string_metrics (sc->texfont, c, &e, 0, 0);
          w = e.width;
          h = e.ascent + e.descent;
          glBegin (GL_LINE_LOOP);
          glVertex3f (0, 0, 0);
          glVertex3f (w, 0, 0);
          glVertex3f (w, h, 0);
          glVertex3f (0, h, 0);
          glEnd();
          glTranslatef (w, 0, 0);
        }
    }

#if 0
  glDisable (GL_TEXTURE_2D);
  glColor3f (0.4, 0.4, 0.4);
  glBegin (GL_LINE_LOOP);
  glVertex3f (0, 0, 0);
  glVertex3f (line->width/sc->font_scale, 0, 0);
  glVertex3f (line->width/sc->font_scale, line->height/sc->font_scale, 0);
  glVertex3f (0, line->height/sc->font_scale, 0);
  glEnd();
  if (!wire) glEnable (GL_TEXTURE_2D);
#endif

  glPopMatrix();

  mi->polygon_count += strlen (line->text);
}
Пример #10
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();
}
Пример #11
0
static int
draw_text (ModeInfo *mi, const char *string, GLfloat r, GLfloat th, 
           GLfloat ttl, GLfloat size)
{
  sonar_configuration *sp = &sps[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  int polys = 0;
  GLfloat font_scale = 0.001 * (size > 0 ? size : font_size) / 14.0;
  int lines = 0, max_w = 0, lh = 0;
  char *string2 = strdup (string);
  char *token = string2;
  char *line;
  GLfloat color[4];

  if (size <= 0)   /* if size not specified, draw in yellow with alpha */
    {
      color[0] = 1;
      color[1] = 1;
      color[2] = 0;
      color[3] = (ttl / (M_PI * 2)) * 1.2;
      if (color[3] > 1) color[3] = 1;

      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
      if (wire)
        glColor3f (color[0]*color[3], color[1]*color[3], color[2]*color[3]);
    }

  while ((line = strtok (token, "\r\n")))
    {
      int w = texture_string_width (sp->texfont, line, &lh);
      if (w > max_w) max_w = w;
      lines++;
      token = 0;
    }

  glPushMatrix();
  glTranslatef (r * cos (th), r * sin(th), 0);
  glScalef (font_scale, font_scale, font_scale);

  if (size <= 0)		/* Draw the dot */
    {
      GLfloat s = font_size * 1.7;
      glDisable (GL_TEXTURE_2D);
      glFrontFace (GL_CW);
      glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
      glVertex3f (0, s, 0);
      glVertex3f (s, s, 0);
      glVertex3f (s, 0, 0);
      glVertex3f (0, 0, 0);
      glEnd();
      glTranslatef (-max_w/2, -lh, 0);
    }
  else
    glTranslatef (-max_w/2, -lh/2, 0);

  /* draw each line, centered */
  if (! wire) glEnable (GL_TEXTURE_2D);
  free (string2);
  string2 = strdup (string);
  token = string2;
  while ((line = strtok (token, "\r\n")))
    {
      int w = texture_string_width (sp->texfont, line, 0);
      glPushMatrix();
      glTranslatef ((max_w-w)/2, 0, 0);

      if (wire)
        {
          glBegin (GL_LINE_LOOP);
          glVertex3f (0, 0, 0);
          glVertex3f (w, 0, 0);
          glVertex3f (w, lh, 0);
          glVertex3f (0, lh, 0);
          glEnd();
        }
      else
        {
          glFrontFace (GL_CW);
          print_texture_string (sp->texfont, line);
        }
      glPopMatrix();
      glTranslatef (0, -lh, 0);
      polys++;
      token = 0;
    }
  glPopMatrix();

  free (string2);

  if (! wire) glEnable (GL_DEPTH_TEST);

  return polys;
}