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 Catmull-Rom 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. Catmull-Rom 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 Catmull-Rom 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:
mCustom * mInverseBezier * 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 Catmull-Rom to Bezier
|   |
| -1/2 |
3/2 |
-3/2 |
1/2 |
| 1 |
-5/2 |
2 |
-1/2 |
| -1/2 |
0 |
1/2 |
0 |
| 0 |
1 |
0 |
0 |
|   |
|
|   |
| 0 |
0 |
0 |
1 |
| 0 |
0 |
1/3 |
1 |
| 0 |
1/3 |
2/3 |
1 |
| 1 |
1 |
1 |
1 |
|   |
|
|   |
| p0x |
p0y |
p0z |
| p1x |
p1y |
p1z |
| p2x |
p2y |
p2z |
| p3x |
p3y |
p3z |
|   |
|
= |
bezierCntlPoints[] |
Example of a conversion from B-Spline to Bezier
|   |
| -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 |
|   |
|
|   |
| 0 |
0 |
0 |
1 |
| 0 |
0 |
1/3 |
1 |
| 0 |
1/3 |
2/3 |
1 |
| 1 |
1 |
1 |
1 |
|   |
|
|   |
| 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.