JMU
Bézier Curves in OpenGL
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Review of Bézier Curves
Bézier Curves in OpenGL
Bézier Curves in OpenGL (cont.)
Using an Evaluator
To Generate Points/Line Strips
openglexamples/curves/draw.c (Fragment: curve)
          //
  // Create and draw the curves for every 4 points
  for (int i = 0; (i + 3) < numPoints; i += 3) {
    // The evaluator with a stride of 3 and an order of 4
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points[i][0]);

    // Draw the curve
    glBegin(GL_POINTS);  // Use GL_LINE_STRIP instead to fill the gaps
    {
      for (int i = 0; i < 100; i++) {
        glEvalCoord1f(((float) i) / 100.0);
      }
    }
    glEnd();
  }
        
Bézier Curves in OpenGL (cont.)
Using Evenly Spaced Points
openglexamples/curves/drawWithMesh.c (Fragment: mesh)
          //
  // Create and draw the curves for every 4 points
  for (int i = 0; (i + 3) < numPoints; i += 3) {
    // The evaluator with a stride of 3 and an order of 4
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points[i][0]);

    glMapGrid1f(100, 0.0, 1.0);
    glEvalMesh1(GL_LINE, 0, 100);
  }
        
A Curve Drawing Program
Adding Points
openglexamples/curves/draw.c (Fragment: mouse)
        /**
 * The mouse callback (i.e., the function that is called
 * each time a mouse button is pressed or released).
 *
 * @param button The button (e.g., GLUT_LEFT_BUTTON)
 * @param state  The state (e.g., GLUT_UP or GLUT_DOWN)
 * @param x      The x-position of the mouse
 * @param y      The y-position of the mouse
 */
void mouse(int button, int state, int x, int y) {
  GLfloat fx, fy;

  screen2ortho(x, y, fx, fy);

  if (button == GLUT_LEFT_BUTTON) {
    if (state == GLUT_DOWN) {
      points[numPoints][0] = fx;
      points[numPoints][1] = fy;
      points[numPoints][2] = 0.;

      numPoints++;

      glutPostRedisplay();
    }
  } else if (button == GLUT_RIGHT_BUTTON) {
    if (state == GLUT_DOWN) {
      selectedPoint = closestPointTo(fx, fy, 0.0);
    } else {
      selectedPoint = -1;
    }

    glutPostRedisplay();
  }
}
        
A Curve Drawing Program (cont.)
Moving Points
openglexamples/curves/draw.c (Fragment: motion)
        /**
 * The mouse drag callback
 *
 * @param x      The x-position of the mouse
 * @param y      The y-position of the mouse
 */
void motion(int x, int y) {
  GLfloat fx, fy;

  screen2ortho(x, y, fx, fy);

  if (selectedPoint >= 0) {
    points[selectedPoint][0] = fx;
    points[selectedPoint][1] = fy;

    glutPostRedisplay();
  }
}
        
A Curve Drawing Program (cont.)
Drawing the Points
openglexamples/curves/draw.c (Fragment: points)
          // Show the points
  glBegin(GL_POINTS);
  {
    for (int i = 0; i < numPoints; i++) {
      if (i == selectedPoint) {
        glColor3f(1.0, 0.0, 1.0);
        glVertex3f(points[i][0], points[i][1], points[i][2]);
      } else {
        glColor3f(0.0, 1.0, 0.0);
        glVertex3f(points[i][0], points[i][1], points[i][2]);
      }
    }
    glEnd();
  }

  // Connect the points (using a piecewise linear curve)
  if (numPoints >= 2) {
    glColor3f(0.75, 0.75, 0.75);
    glBegin(GL_LINE_STRIP);
    {
      for (int i = 0; i < numPoints; i++) {
        glVertex3f(points[i][0], points[i][1], points[i][2]);
      }
    }
    glEnd();
  }