December 04, 2009 at 19:04
This article will cover the basics of drawing bezier curves in openGL and how to convert from other curves to Bezier, such as Bspline and CatmullRom curves.
Declaring control Points
The way to declare a list of control points for openGL usage is an one dimensional matrix. Since a curve segment only has in account 4 control points:
cntlPoints[] 
= 

p0x 
p0y 
p0z 
p1x 
p1y 
p1z 
p2x 
p2y 
p2z 
p3x 
p3y 
p3z 
 

A Bezier curve only needs the last point of the previous curve to be continuous. CatmullRom and Bspline need to know the last 3 points from the previous curve to be continuous.
In the case you have more than 4 points, lets say 7, you would draw 2 curves from p0 to p3 and p3 to p6 in case of a Bezier curve and 5 curves in CatmullRom and Bspline going from p0 to p3, p1 to p4, p2 to p5 and p3 to p6 for them to become continous.
Drawing a Bezier curve in openGL
mBezier[] 
= 

1 
3 
3 
1 
3 
6 
3 
0 
3 
3 
0 
0 
1 
0 
0 
0 
 

OpenGL has the ability to draw Bezier curves almost directly using the map function but for completeness sake the matrix for a bezier curve is the following:
The following code in JOGL will draw a Bezier line using the map procedure:
public void drawLine(GL gl, double[] controlPoints) {
DoubleBuffer ctrlPointBuffer = BufferUtil.newDoubleBuffer(3*controlPoints.length);
for(int i = 0; i < controlPoints.length; i++)
ctrlPointBuffer.put(controlPoints[i]);
ctrlPointBuffer.rewind();
gl.glMap1d(GL.GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, ctrlPointBuffer);
gl.glEnable(GL.GL_MAP1_VERTEX_3);
gl.glBegin(GL.GL_LINE_STRIP);
for (int i = 0; i <= 30; i++) {
gl.glEvalCoord1f(i / 30.0f);
}
gl.glEnd();
gl.glFlush();
}
Converting other curves to Bezier
To convert the control points of another type of curve to a Bezier control points you need to:
mInverseBezier * mCustom * customCntlPoints = bezierCntlPoints
mBezier[] 
^{1} 
= 

0 
0 
0 
1 
0 
0 
1/3 
1 
0 
1/3 
2/3 
1 
1 
1 
1 
1 
 

The inverse of the Bezier matrix used for the conversion of the control points is:
Example of a conversion from CatmullRom to Bezier

0 
0 
0 
1 
0 
0 
1/3 
1 
0 
1/3 
2/3 
1 
1 
1 
1 
1 
 


1/2 
3/2 
3/2 
1/2 
1 
5/2 
2 
1/2 
1/2 
0 
1/2 
0 
0 
1 
0 
0 
 


p0x 
p0y 
p0z 
p1x 
p1y 
p1z 
p2x 
p2y 
p2z 
p3x 
p3y 
p3z 
 

= 
bezierCntlPoints[] 
Example of a conversion from BSpline to Bezier

0 
0 
0 
1 
0 
0 
1/3 
1 
0 
1/3 
2/3 
1 
1 
1 
1 
1 
 


1/6 
1/2 
1/2 
1/6 
1/2 
1 
1/2 
0 
1/2 
0 
1/2 
0 
1/6 
4/6 
1/6 
0 
 


p0x 
p0y 
p0z 
p1x 
p1y 
p1z 
p2x 
p2y 
p2z 
p3x 
p3y 
p3z 
 

= 
bezierCntlPoints[] 
That was it, thank you for reading.
Comments are welcome!
Note: I used Matrices in HTML to present the matrices in this post. It uses css and tables to present them correctly.