zoukankan      html  css  js  c++  java
  • OpenGL中基本三维物体的绘制

    本文介绍一下OpenGL下绘制三维物体的基本方法。编译环境:OpenTK, c#。

     以下是OpenGL的基本绘图函数:

    Geometric Primitive Types in OpenTK.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();
    
            }
  • 相关阅读:
    [Xcode 实际操作]九、实用进阶-(2)遍历设备(输出系统)上的所有字体
    [Xcode 实际操作]九、实用进阶-(1)隐藏顶部的状态栏
    [Xcode 实际操作]八、网络与多线程-(25)实现ShareSdk的社会化分享功能
    [Xcode 实际操作]八、网络与多线程-(24)社会化分享功能开发包的安装和配置:微信、QQ、微博
    [Xcode 实际操作]八、网络与多线程-(23)多线程的同步与异步的区别
    Moving Tables-贪心
    HTTP状态码
    CSS3中transform,transition和animation的简单介绍和使用方法演示样例
    用NODEJS处理EXCEL文件导入导出,文件上传
    内存区域划分
  • 原文地址:https://www.cnblogs.com/xpvincent/p/2819735.html
Copyright © 2011-2022 走看看