本文介绍一下OpenGL下绘制三维物体的基本方法。编译环境:OpenTK, c#。
以下是OpenGL的基本绘图函数:
1. 绘制正方体
View Code
//draw a cube: solid void DrawCube(Color color, Vector3d refMarker, Vector3d size) { List<Vector3d> points = new List<Vector3d>(); //points //back points (anti-clockwise) points.Add(refMarker); points.Add(new Vector3d(points[0].X + size.X, points[0].Y, points[0].Z)); points.Add(new Vector3d(points[0].X + size.X, points[0].Y + size.Y, points[0].Z)); points.Add(new Vector3d(points[0].X, points[0].Y + size.Y, points[0].Z)); //front points (anti-clockwise) points.Add(new Vector3d(points[0].X, points[0].Y, points[0].Z + size.Z)); points.Add(new Vector3d(points[1].X, points[1].Y, points[1].Z + size.Z)); points.Add(new Vector3d(points[2].X, points[2].Y, points[2].Z + size.Z)); points.Add(new Vector3d(points[3].X, points[3].Y, points[3].Z + size.Z)); //sequency int[] seqs = { 0, 1, 2, 3, //back side 4, 5, 6, 7, //front side 0, 4, 7, 3, //left side 1, 5, 6, 2, //right side 0, 4, 5, 1, //bottom side 3, 7, 6, 2 //tope side }; GL.ShadeModel(ShadingModel.Flat); GL.Color3(color); GL.Begin(BeginMode.Quads); foreach (int seq in seqs) { GL.Vertex3(points[seq]); } GL.End(); }
2. 圆筒
View Code
void DrawCylinder(Color color, Vector3d refMarker, double radius, double length, int segments = 20, int sides = 20) { GL.Color3(color); GL.ShadeModel(ShadingModel.Flat); double thetaSegments = 2 * Math.PI / segments; double thetaSides = 2 * Math.PI / sides; //bottom GL.Begin(BeginMode.Polygon); for (double i = 0; i < segments; i++) { Vector3d point = new Vector3d(); point.X = refMarker.X + radius * Math.Cos(thetaSegments * i); point.Y = refMarker.Y + radius * Math.Sin(thetaSegments * i); point.Z = refMarker.Z; GL.Vertex3(point); } GL.End(); //top GL.Begin(BeginMode.Polygon); for (double i = 0; i < segments; i++) { Vector3d point = new Vector3d(); point.X = refMarker.X + radius * Math.Cos(thetaSegments * i); point.Y = refMarker.Y + radius * Math.Sin(thetaSegments * i); point.Z = refMarker.Z + length; GL.Vertex3(point); } GL.End(); //side GL.Begin(BeginMode.QuadStrip); for (double i = 0; i <= sides; i++) { Vector3d point1 = new Vector3d(); point1.X = refMarker.X + radius * Math.Cos(thetaSides * i); point1.Y = refMarker.Y + radius * Math.Sin(thetaSides * i); point1.Z = refMarker.Z; GL.Vertex3(point1); Vector3d point2 = new Vector3d(); point2.X = refMarker.X + radius * Math.Cos(thetaSides * i); point2.Y = refMarker.Y + radius * Math.Sin(thetaSides * i); point2.Z = refMarker.Z + length; GL.Vertex3(point2); } GL.End(); }
3. 球型
View Code
//draw a sphere: solid void DrawSphere(Color color, Vector3d refMarker, double radius) { int longitudes = 20; int latitudes = 20; GL.Color3(color); GL.ShadeModel(ShadingModel.Smooth); for (double i = 0; i < latitudes; i++) { double lat0 = -Math.PI / 2 + Math.PI/latitudes * i ; double z0 = Math.Sin(lat0) * radius; double r0 = Math.Abs(Math.Cos(lat0) * radius); double lat1 = -Math.PI / 2 + Math.PI / latitudes * (i + 1); double z1 = Math.Sin(lat1) * radius; double r1 = Math.Abs(Math.Cos(lat1) * radius); GL.Begin(BeginMode.QuadStrip); for (double j = 0; j < longitudes; j++) { double lng = 2 * Math.PI * j / longitudes; double x = Math.Cos(lng); double y = Math.Sin(lng); Vector3d pt0 = new Vector3d(x * r0 + refMarker.X, y * r0 + refMarker.Y, z0 + refMarker.Z); GL.Normal3(pt0); GL.Vertex3(pt0); Vector3d pt1 = new Vector3d(x * r1 + refMarker.X, y * r1 + refMarker.Y, z1 + refMarker.Z); GL.Normal3(pt1); GL.Vertex3(pt1); } GL.End(); } }
4. Marker
View Code
//Draw a marker void DrawMarker(Color color, Vector3d origin, double size=1) { DrawMarkerAxis(color, origin, new Vector3d(size, 0, 0)); //x DrawMarkerAxis(color, origin, new Vector3d(0, size, 0)); //y DrawMarkerAxis(color, origin, new Vector3d(0, 0, size)); //z } void DrawMarkerAxis(Color color, Vector3d origin, Vector3d size) { double len1 = 0.1; double len2 = 0.05; List<Vector3d> points = new List<Vector3d>(); points.Add(origin); points.Add(new Vector3d(origin.X + size.X, origin.Y + size.Y, origin.Z+size.Z)); points.Add(new Vector3d(points[1].X * (1 - len1), points[1].Y * (1 - len1), points[1].Z * (1 - len1))); if (size.X != 0) { points.Add(new Vector3d(points[2].X, points[2].Y - len2, points[2].Z)); points.Add(new Vector3d(points[2].X, points[2].Y + len2, points[2].Z)); points.Add(new Vector3d(points[2].X, points[2].Y, points[2].Z - len2)); points.Add(new Vector3d(points[2].X, points[2].Y, points[2].Z + len2)); } else if (size.Y != 0) { points.Add(new Vector3d(points[2].X - len2, points[2].Y, points[2].Z)); points.Add(new Vector3d(points[2].X + len2, points[2].Y, points[2].Z)); points.Add(new Vector3d(points[2].X, points[2].Y, points[2].Z - len2)); points.Add(new Vector3d(points[2].X, points[2].Y, points[2].Z + len2)); } else { points.Add(new Vector3d(points[2].X - len2, points[2].Y, points[2].Z)); points.Add(new Vector3d(points[2].X + len2, points[2].Y, points[2].Z)); points.Add(new Vector3d(points[2].X, points[2].Y - len2, points[2].Z)); points.Add(new Vector3d(points[2].X, points[2].Y + len2, points[2].Z)); } GL.Color3(color); GL.Begin(BeginMode.Lines); GL.Vertex3(points[0]); GL.Vertex3(points[1]); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(points[1]); GL.Vertex3(points[3]); GL.Vertex3(points[4]); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(points[1]); GL.Vertex3(points[5]); GL.Vertex3(points[6]); GL.End(); }