Example #1
0
static void
print_title_string (ModeInfo *mi, const char *string,
                    GLfloat x, GLfloat y, GLfloat line_height)
{
  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];

  y -= line_height;

  glPushAttrib (GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
  glDisable (GL_LIGHTING);
  glDisable (GL_DEPTH_TEST);
  {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    {
      glLoadIdentity();

      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      {
        int i;
        glLoadIdentity();

        gluOrtho2D (0, MI_WIDTH(mi), 0, MI_HEIGHT(mi));

        set_atom_color (mi, 0, True);

        glRasterPos2f (x, y);
        for (i = 0; i < (int) strlen(string); i++)
          {
            char c = string[i];
            if (c == '\n')
              glRasterPos2f (x, (y -= line_height));
            else
              glCallList (mc->font2_dlist + (int)(c));
          }
      }
      glPopMatrix();
    }
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
  }
  glPopAttrib();

  glMatrixMode(GL_MODELVIEW);
}
Example #2
0
/* Constructs the GL shapes of the current molecule
 */
static void
build_molecule (ModeInfo *mi, Bool transparent_p)
{
  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  int i;
  GLfloat alpha = transparent_p ? shell_alpha : 1.0;
  int polys = 0;

  molecule *m = &mc->molecules[mc->which];

  if (wire)
    {
      glDisable(GL_CULL_FACE);
      glDisable(GL_LIGHTING);
      glDisable(GL_LIGHT0);
      glDisable(GL_DEPTH_TEST);
      glDisable(GL_NORMALIZE);
      glDisable(GL_CULL_FACE);
    }
  else
    {
      glEnable(GL_CULL_FACE);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_NORMALIZE);
      glEnable(GL_CULL_FACE);
    }

  if (!wire)
    set_atom_color (mi, 0, False, alpha);

  if (do_bonds)
    for (i = 0; i < m->nbonds; i++)
      {
        const molecule_bond *b = &m->bonds[i];
        const molecule_atom *from = get_atom (m->atoms, m->natoms, b->from);
        const molecule_atom *to   = get_atom (m->atoms, m->natoms, b->to);

        if (wire)
          {
            glBegin(GL_LINES);
            glVertex3f(from->x, from->y, from->z);
            glVertex3f(to->x,   to->y,   to->z);
            glEnd();
            polys++;
          }
        else
          {
            int faces = (mc->scale_down ? TUBE_FACES_2 : TUBE_FACES);
# ifdef SMOOTH_TUBE
            int smooth = True;
# else
            int smooth = False;
# endif
            GLfloat thickness = 0.07 * b->strength;
            GLfloat cap_size = 0.03;
            if (thickness > 0.3)
              thickness = 0.3;

            polys += tube (from->x, from->y, from->z,
                           to->x,   to->y,   to->z,
                           thickness, cap_size,
                           faces, smooth, (!do_atoms || do_shells), wire);
          }
      }

  if (!wire && do_atoms)
    for (i = 0; i < m->natoms; i++)
      {
        const molecule_atom *a = &m->atoms[i];
        GLfloat size = atom_size (a);
        set_atom_color (mi, a, False, alpha);
        polys += sphere (mc, a->x, a->y, a->z, size, wire);
      }

  if (do_bbox && !transparent_p)
    {
      draw_bounding_box (mi);
      polys += 4;
    }

  mc->polygon_count += polys;
}
Example #3
0
ENTRYPOINT void
draw_molecule (ModeInfo *mi)
{
  time_t now = time ((time_t *) 0);
  GLfloat speed = 4.0;  /* speed at which the zoom out/in happens */

  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);

  if (!mc->glx_context)
    return;

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

  if (mc->draw_time == 0)
    {
      pick_new_molecule (mi, mc->draw_time);
      mc->draw_time = now;
    }
  else if (mc->mode == 0)
    {
      if (mc->draw_tick++ > 10)
        {
          time_t now = time((time_t *) 0);
          if (mc->draw_time == 0) mc->draw_time = now;
          mc->draw_tick = 0;

          if (!mc->button_down_p &&
              mc->nmolecules > 1 &&
              mc->draw_time + timeout <= now)
            {
              /* randomize molecules every -timeout seconds */
              mc->mode = 1;    /* go out */
              mc->mode_tick = 10 * speed;
              mc->draw_time = now;
            }
        }
    }
  else if (mc->mode == 1)   /* out */
    {
      if (--mc->mode_tick <= 0)
        {
          mc->mode_tick = 10 * speed;
          mc->mode = 2;  /* go in */
          pick_new_molecule (mi, mc->draw_time);
          mc->draw_time = now;
        }
    }
  else if (mc->mode == 2)   /* in */
    {
      if (--mc->mode_tick <= 0)
        mc->mode = 0;  /* normal */
    }
  else
    abort();

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

  {
    double x, y, z;
    get_position (mc->rot, &x, &y, &z, !mc->button_down_p);
    glTranslatef((x - 0.5) * 9,
                 (y - 0.5) * 9,
                 (z - 0.5) * 9);

    gltrackball_rotate (mc->trackball);

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

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  if (mc->mode != 0)
    {
      GLfloat s = (mc->mode == 1
                   ? mc->mode_tick / (10 * speed)
                   : ((10 * speed) - mc->mode_tick + 1) / (10 * speed));
      glScalef (s, s, s);
    }

  glPushMatrix();
  glCallList (mc->molecule_dlist);

  if (mc->mode == 0)
    {
      molecule *m = &mc->molecules[mc->which];

      draw_labels (mi);

      /* This can't go in the display list, or the characters are spaced
         wrongly when the window is resized. */
      if (do_titles && m->label && *m->label)
        {
          set_atom_color (mi, 0, True, 1);
          print_gl_string (mi->dpy, mc->xfont3, mc->font3_dlist,
                           mi->xgwa.width, mi->xgwa.height,
                           10, mi->xgwa.height - 10,
                           m->label, False);
        }
    }
  glPopMatrix();

  if (do_shells)
    {
      glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
      glPushMatrix();
      glCallList (mc->shell_dlist);
      glPopMatrix();
      glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

      glDepthFunc (GL_EQUAL);
      glEnable (GL_BLEND);
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glPushMatrix();
      glCallList (mc->shell_dlist);
      glPopMatrix();
      glDepthFunc (GL_LESS);
      glDisable (GL_BLEND);
    }

  glPopMatrix ();

  mi->polygon_count = mc->polygon_count;

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

  glXSwapBuffers(dpy, window);
}
Example #4
0
/* Put the labels on the atoms.
   This can't be a part of the display list because of the games
   we play with the translation matrix.
 */
static void
draw_labels (ModeInfo *mi)
{
  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
  int wire = MI_IS_WIREFRAME(mi);
  molecule *m = &mc->molecules[mc->which];
  XFontStruct *xfont = (mc->scale_down ? mc->xfont2 : mc->xfont1);
  GLuint font_dlist  = (mc->scale_down ? mc->font2_dlist : mc->font1_dlist);
  int i, j;

  if (!do_labels)
    return;

  if (!wire)
    glDisable (GL_LIGHTING);   /* don't light fonts */

  for (i = 0; i < m->natoms; i++)
    {
      molecule_atom *a = &m->atoms[i];
      GLfloat size = atom_size (a);
      GLfloat m[4][4];

      glPushMatrix();

      if (!wire)
        set_atom_color (mi, a, True, 1);

      /* First, we translate the origin to the center of the atom.

         Then we retrieve the prevailing modelview matrix (which
         includes any rotation, wandering, and user-trackball-rolling
         of the scene.

         We set the top 3x3 cells of that matrix to be the identity
         matrix.  This removes all rotation from the matrix, while
         leaving the translation alone.  This has the effect of
         leaving the prevailing coordinate system perpendicular to
         the camera view: were we to draw a square face, it would
         be in the plane of the screen.

         Now we translate by `size' toward the viewer -- so that the
         origin is *just in front* of the ball.

         Then we draw the label text, allowing the depth buffer to
         do its work: that way, labels on atoms will be occluded
         properly when other atoms move in front of them.

         This technique (of neutralizing rotation relative to the
         observer, after both rotations and translations have been
         applied) is known as "billboarding".
       */

      glTranslatef(a->x, a->y, a->z);               /* get matrix */
      glGetFloatv (GL_MODELVIEW_MATRIX, &m[0][0]);  /* load rot. identity */
      m[0][0] = 1; m[1][0] = 0; m[2][0] = 0;
      m[0][1] = 0; m[1][1] = 1; m[2][1] = 0;
      m[0][2] = 0; m[1][2] = 0; m[2][2] = 1;
      glLoadIdentity();                             /* reset modelview */
      glMultMatrixf (&m[0][0]);                     /* replace with ours */

      glTranslatef (0, 0, (size * 1.1));           /* move toward camera */

      glRasterPos3f (0, 0, 0);                     /* draw text here */

      /* Before drawing the string, shift the origin to center
         the text over the origin of the sphere. */
      glBitmap (0, 0, 0, 0,
                -string_width (xfont, a->label, 0) / 2,
                -xfont->descent,
                NULL);

      for (j = 0; j < strlen(a->label); j++)

        glCallList (font_dlist + (int)(a->label[j]));

      glPopMatrix();
    }

  /* More efficient to always call glEnable() with correct values
     than to call glPushAttrib()/glPopAttrib(), since reading
     attributes from GL does a round-trip and  stalls the pipeline.
   */
  if (!wire)
    glEnable (GL_LIGHTING);
}
Example #5
0
/* Constructs the GL shapes of the current molecule
 */
static void
build_molecule (ModeInfo *mi)
{
  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
  int wire = cur_wire;
  int i;

  molecule *m = &mc->molecules[mc->which];

  if (wire)
    {
      glDisable(GL_CULL_FACE);
      glDisable(GL_LIGHTING);
      glDisable(GL_LIGHT0);
      glDisable(GL_DEPTH_TEST);
      glDisable(GL_NORMALIZE);
      glDisable(GL_CULL_FACE);
    }
  else
    {
      glEnable(GL_CULL_FACE);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_NORMALIZE);
      glEnable(GL_CULL_FACE);
    }

  if (!wire)
    set_atom_color (mi, 0, False);

  if (do_bonds)
    for (i = 0; i < m->nbonds; i++)
      {
        molecule_bond *b = &m->bonds[i];
        molecule_atom *from = get_atom(m->atoms, m->natoms, b->from,
		MI_IS_VERBOSE(mi));
        molecule_atom *to   = get_atom(m->atoms, m->natoms, b->to,
		MI_IS_VERBOSE(mi));

        if (wire)
          {
            glBegin(GL_LINES);
            glVertex3f(from->x, from->y, from->z);
            glVertex3f(to->x,   to->y,   to->z);
            glEnd();
          }
        else
          {
            int faces = (scale_down ? TUBE_FACES_2 : TUBE_FACES);
# ifdef SMOOTH_TUBE
            int smooth = True;
# else
            int smooth = False;
# endif
            GLfloat thickness = 0.07 * b->strength;
            GLfloat cap_size = 0.03;
            if (thickness > 0.3)
              thickness = 0.3;

            tube (from->x, from->y, from->z,
                  to->x,   to->y,   to->z,
                  thickness, cap_size,
                  faces, smooth, !do_atoms, wire);
          }
      }

  for (i = 0; i < m->natoms; i++)
    {
      molecule_atom *a = &m->atoms[i];
      int i;

      if (!wire && do_atoms)
        {
          GLfloat size = atom_size (a);
          set_atom_color (mi, a, False);
          sphere (a->x, a->y, a->z, size, wire);
        }

      if (do_labels)
        {
          glPushAttrib (GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
          glDisable (GL_LIGHTING);
          glDisable (GL_DEPTH_TEST);

          if (!wire)
            set_atom_color (mi, a, True);

          glRasterPos3f (a->x, a->y, a->z);

          {
            GLdouble mm[17], pm[17];
            GLint vp[5];
            GLdouble wx=-1, wy=-1, wz=-1;
            glGetDoublev (GL_MODELVIEW_MATRIX, mm);
            glGetDoublev (GL_PROJECTION_MATRIX, pm);
            glGetIntegerv (GL_VIEWPORT, vp);

            /* Convert 3D coordinates to window coordinates */
            gluProject (a->x, a->y, a->z, mm, pm, vp, &wx, &wy, &wz);

            /* Fudge the window coordinates to center the string */
            wx -= string_width (mc->xfont1, a->label) / 2;
            wy -= mc->xfont1->descent;

            /* Convert new window coordinates back to 3D coordinates */
            gluUnProject (wx, wy, wz, mm, pm, vp, &wx, &wy, &wz);
            glRasterPos3f (wx, wy, wz);
          }

          for (i = 0; i < (int) strlen(a->label); i++)
            glCallList (mc->font1_dlist + (int)(a->label[i]));

          glPopAttrib();
        }
    }

  if (do_bbox)
    draw_bounding_box (mi);

  if (do_titles && m->label && *m->label)
    print_title_string (mi, m->label,
                        10, MI_HEIGHT(mi) - 10,
                        mc->xfont2->ascent + mc->xfont2->descent);
}