DrawBasicGeometry.cs
上传用户:lslight
上传日期:2022-01-10
资源大小:14248k
文件大小:17k
源码类别:

DirextX编程

开发平台:

C#

  1. ///////////////////////////////////////////////////////////////////////
  2. //      ■■■■     ■■■■■       ■■■■       ■       ■      //
  3. //    ■                 ■         ■               ■       ■      //
  4. //    ■                 ■         ■    ■■■     ■       ■      //
  5. //    ■                 ■         ■       ■      ■       ■      //
  6. //      ■■■■         ■           ■■■■         ■■■■       //
  7. // Copyright (c) 三峡大学水利与环境学院 肖泽云. All rights reserved.  //
  8. ////////////////////////////////////////////////////////////////////////
  9. using System;
  10. using System.ComponentModel;
  11. using System.Data;
  12. using System.Drawing;
  13. using System.Windows.Forms;
  14. using Microsoft.DirectX;
  15. using Microsoft.DirectX.Direct3D;
  16. namespace 绘制基本几何体
  17. {
  18.     public partial class DrawBasicGeometry : Form
  19.     {
  20.         Device device = null;//定义绘图设备
  21.         private CustomVertex.PositionColored[] vertices;//定义顶点变量
  22.         private VertexBuffer vertexBuffer;//定义顶点缓冲变量
  23.         private IndexBuffer indexBuffer;//定义索引缓冲变量
  24.         private int[] indexData;//定义顶点索引
  25.         private float angleY=0.01f;//定义绕Y轴旋转变量
  26.         private Vector3 CamPostion = new Vector3(10, 10, -50);//定义摄像机位置
  27.         private Vector3 CamTarget = new Vector3(10, 10, 0);//定义摄像机目标位置
  28.         private int mouseLastX,mouseLastY;//记录鼠标按下时的坐标位置
  29.         private bool isRotateByMouse=false;//记录是否由鼠标控制旋转
  30.         private bool isMoveByMouse = false;//记录是否由鼠标控制移动
  31.         public DrawBasicGeometry()
  32.         {
  33.             this.ClientSize = new Size(800, 600);//指定窗体尺寸
  34.             this.Text = "绘制基本几何体";//指定窗体标题
  35.         }
  36.         public bool InitializeDirect3D()
  37.         {
  38.             try
  39.             {
  40.                 PresentParameters presentParams = new PresentParameters();
  41.                 presentParams.Windowed = true; //指定以Windows窗体形式显示
  42.                 presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
  43.                 device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //实例化device对象
  44.                 VertexDeclaration();//定义顶点
  45.                 IndicesDeclaration();//定义索引
  46.                 return true;
  47.             }
  48.             catch (DirectXException e)
  49.             {
  50.                 MessageBox.Show(e.ToString(), "Error"); //处理异常
  51.                 return false;
  52.             }
  53.         }
  54.         private void VertexDeclaration()//定义顶点
  55.         {
  56.             vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored), 9, device,
  57.                 Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
  58.             vertices = new CustomVertex.PositionColored[9];
  59.             vertices[0].Position = new Vector3(0f, 20f, 0f);
  60.             vertices[0].Color = Color.Yellow.ToArgb();
  61.             vertices[1].Position = new Vector3(10f, 20f, 0f);
  62.             vertices[1].Color = Color.White.ToArgb();
  63.             vertices[2].Position = new Vector3(0f, 10f, 0f);
  64.             vertices[2].Color = Color.Green.ToArgb();
  65.             vertices[3].Position = new Vector3(20f, 20f, 0f);
  66.             vertices[3].Color = Color.IndianRed.ToArgb();
  67.             vertices[4].Position = new Vector3(10f, 10f, 0f);
  68.             vertices[4].Color = Color.LightPink.ToArgb();
  69.             vertices[5].Position = new Vector3(0f, 0f, 0f);
  70.             vertices[5].Color = Color.Orange.ToArgb();
  71.             vertices[6].Position = new Vector3(20f, 10f, 0f);
  72.             vertices[6].Color = Color.Green.ToArgb();
  73.             vertices[7].Position = new Vector3(10f, 0f, 0f);
  74.             vertices[7].Color = Color.DeepPink.ToArgb();
  75.             vertices[8].Position = new Vector3(20f, 0f, 0f);
  76.             vertices[8].Color = Color.IndianRed.ToArgb();
  77.             vertexBuffer.SetData(vertices, 0, LockFlags.None);//设置顶点数据至顶点缓冲中
  78.         }
  79.        
  80.         private void IndicesDeclaration()//定义索引
  81.         {
  82.             indexBuffer = new IndexBuffer(typeof(int), 24, device, Usage.WriteOnly, Pool.Default);
  83.             indexData = new int[24];
  84.             indexData[0] = 0;indexData[1] = 1;indexData[2] = 2;
  85.             indexData[3] = 2;indexData[4] = 1;indexData[5] = 4;
  86.             indexData[6] = 1;indexData[7] = 3;indexData[8] = 4;
  87.             indexData[9] = 3;indexData[10] = 6;indexData[11] = 4;
  88.             indexData[12] = 5;indexData[13] = 2;indexData[14] = 4;
  89.             indexData[15] = 5;indexData[16] = 4;indexData[17] = 7;
  90.             indexData[18] = 6;indexData[19] = 7;indexData[20] = 4;
  91.             indexData[21] = 7;indexData[22] = 6;indexData[23] = 8;
  92.             indexBuffer.SetData(indexData, 0, LockFlags.None);
  93.         }
  94.         
  95.         /*
  96.         private void LoadTexturesAndMaterials()//导入贴图和材质
  97.         {
  98.             material = new Material();
  99.             material.Diffuse = Color.White;
  100.             material.Specular = Color.LightGray;
  101.             material.SpecularSharpness = 15.0F;
  102.             device.Material = material;
  103.             texture = TextureLoader.FromFile(device, "CTGU.jpg");
  104.         }
  105.          */ 
  106.         public void Render()
  107.         {
  108.             System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
  109.             stopWatch.Start();
  110.             if (device == null)   //如果device为空则不渲染
  111.             {
  112.                 return;
  113.             }
  114.             SetUpCamera();
  115.             device.Clear(ClearFlags.Target, Color.DarkSlateBlue, 1.0f, 0);  //清除windows界面为深蓝色
  116.             device.BeginScene();
  117.             //在此添加渲染图形代码
  118.             //device.RenderState.CullMode=Cull.None;
  119.             device.RenderState.Lighting = false;
  120.             device.VertexFormat = CustomVertex.PositionColored.Format;
  121.             //device.DrawUserPrimitives(PrimitiveType.TriangleList,8, vertices);
  122.             device.RenderState.FillMode = FillMode.WireFrame;
  123.             //device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, vertices.Length, indexData.Length/3, indexData, false, vertices);
  124.             device.SetStreamSource(0, vertexBuffer,0);//设置顶点缓冲为绘图设备的数据流
  125.             device.Indices = indexBuffer;//设置索引缓冲为绘图设备的索引数据
  126.             //device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 9, 0, 8);
  127.             //device.DrawPrimitives(PrimitiveType.TriangleList, 0, 8);
  128.             //device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
  129.             //device.DrawPrimitives(PrimitiveType.TriangleList, 18, 1);
  130.             Vector3[] points = new Vector3[8];
  131.             points[0] = new Vector3(30f, 20f, 0f);
  132.             points[1] = new Vector3(30f, 20f, 10f);
  133.             points[2] = new Vector3(40f, 20f, 10f);
  134.             points[3] = new Vector3(40f, 20f, 0f);
  135.             points[4] = new Vector3(30f, 10f, 0f);
  136.             points[5] = new Vector3(30f, 10f, 10f);
  137.             points[6] = new Vector3(40f, 10f, 10f);
  138.             points[7] = new Vector3(40f, 10f, 0f);
  139.             DrawHexClass drawTri = new DrawHexClass(device, points);
  140.             //drawTri.DrawHex();
  141.             /*
  142.             Vector3 sphereCenter = new Vector3(10,10,0);
  143.             DrawSphereClass drawSphere = new DrawSphereClass(device, sphereCenter, 50f, 50, 50);
  144.             drawSphere.DrawSphere();
  145.              */
  146.             /*
  147.             Vector3 circleCenter = new Vector3(10, 10, 10);
  148.             Vector3 circleNormal = new Vector3(1, 1, 1);
  149.             DrawCircleClass drawCircle = new DrawCircleClass(device, circleCenter, 10f, circleNormal, 16, 5);
  150.             drawCircle.DrawCircle();
  151.              */
  152.             /*
  153.             Vector3 taperCenter = new Vector3(10, 10, 10);
  154.             Vector3 taperTop = new Vector3(15, 15, 15);
  155.             DrawTaperClass drawTaper = new DrawTaperClass(device, taperCenter, 10f, taperTop, 16, 5);
  156.             drawTaper.DrawTaper();
  157.              */
  158.             Vector3 topCenter = new Vector3(25, 25, 25);
  159.             Vector3 underCenter = new Vector3(10, 10, 10);
  160.             DrawCylinderClass drawCylinder = new DrawCylinderClass(device, topCenter, underCenter,10f, 16, 5,10);
  161.             drawCylinder.DrawCylinder();
  162.        
  163.  
  164.             
  165.             device.EndScene();
  166.             device.Present();
  167.             stopWatch.Stop();
  168.             Console.WriteLine(stopWatch.Elapsed.ToString());
  169.         }
  170.         private void SetUpCamera()//摄像机
  171.         {
  172.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  173.             device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 0.3f, 500f);
  174.             device.Transform.View = viewMatrix;
  175.         }
  176.         protected override void OnKeyDown(KeyEventArgs e)
  177.         {
  178.             Vector4 tempV4;
  179.             Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  180.             switch (e.KeyCode)
  181.             {
  182.                 case Keys.Left:
  183.                     CamPostion.Subtract(CamTarget);
  184.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  185.                             Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), -angleY)));
  186.                     CamPostion.X = tempV4.X + CamTarget.X;
  187.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  188.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  189.                     break;
  190.                 case Keys.Right:
  191.                     CamPostion.Subtract(CamTarget);
  192.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  193.                             Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), angleY)));
  194.                     CamPostion.X = tempV4.X + CamTarget.X;
  195.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  196.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  197.                     break;
  198.                 case Keys.Up:
  199.                     CamPostion.Subtract(CamTarget);
  200.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  201.                        Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
  202.                        , device.Transform.View.M21, device.Transform.View.M31), -angleY)));
  203.                     CamPostion.X = tempV4.X + CamTarget.X;
  204.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  205.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  206.                     break;
  207.                 case Keys.Down:
  208.                     CamPostion.Subtract(CamTarget);
  209.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  210.                        Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
  211.                        , device.Transform.View.M21, device.Transform.View.M31), angleY)));
  212.                     CamPostion.X = tempV4.X + CamTarget.X;
  213.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  214.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  215.                     break;
  216.                 case Keys.Add:
  217.                     CamPostion.Subtract(CamTarget);
  218.                     CamPostion.Scale(0.95f);
  219.                     CamPostion.Add(CamTarget);
  220.                     break;
  221.                 case Keys.Subtract:
  222.                     CamPostion.Subtract(CamTarget);
  223.                     CamPostion.Scale(1.05f);
  224.                     CamPostion.Add(CamTarget);
  225.                     break;
  226.                 case Keys.Enter:
  227.                     Vector3[] points = new Vector3[8];
  228.                     points[0] = new Vector3(30f, 20f, 0f);
  229.                     points[1] = new Vector3(30f, 20f, 10f);
  230.                     points[2] = new Vector3(40f, 20f, 0f);
  231.                     points[3] = new Vector3(40f, 20f, 10f);
  232.                     points[4] = new Vector3(30f, 10f, 0f);
  233.                     points[5] = new Vector3(30f, 10f, 10f);
  234.                     points[6] = new Vector3(40f, 10f, 0f);
  235.                     points[7] = new Vector3(40f, 10f, 10f);
  236.                     DrawHexClass drawTri = new DrawHexClass(device, points);
  237.                     drawTri.DrawHex();
  238.                     break;
  239.             }
  240.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  241.             device.Transform.View = viewMatrix;
  242.         }
  243.         protected override void OnMouseDown(MouseEventArgs e)
  244.         {
  245.             if (e.Button == MouseButtons.Left)
  246.             {
  247.                 mouseLastX = e.X;
  248.                 mouseLastY = e.Y;
  249.                 isRotateByMouse = true;
  250.             }
  251.             else if (e.Button == MouseButtons.Middle)
  252.             {
  253.                 mouseLastX = e.X;
  254.                 mouseLastY = e.Y;
  255.                 isMoveByMouse=true;
  256.             }
  257.         }
  258.         
  259.         protected override void OnMouseUp(MouseEventArgs e)
  260.         {
  261.             isRotateByMouse = false;
  262.             isMoveByMouse = false;
  263.         }
  264.         protected override void OnMouseMove(MouseEventArgs e)
  265.         {
  266.             if (isRotateByMouse)
  267.             {
  268.                 Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  269.                 float tempAngleY = 2 * (float)(e.X - mouseLastX) / this.Width;
  270.                 CamPostion.Subtract(CamTarget);
  271.                 Vector4 tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  272.                     Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), tempAngleY)));
  273.                 CamPostion.X = tempV4.X;
  274.                 CamPostion.Y = tempV4.Y;
  275.                 CamPostion.Z = tempV4.Z;
  276.                 float tempAngleX = 4 * (float)(e.Y - mouseLastY) / this.Height;
  277.                 tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  278.                     Quaternion.RotationAxis(new Vector3(currentView.M11, currentView.M21, currentView.M31), tempAngleX)));
  279.                 CamPostion.X = tempV4.X + CamTarget.X;
  280.                 CamPostion.Y = tempV4.Y + CamTarget.Y;
  281.                 CamPostion.Z = tempV4.Z + CamTarget.Z;
  282.                 Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  283.                 device.Transform.View = viewMatrix;
  284.                 mouseLastX = e.X;
  285.                 mouseLastY = e.Y;
  286.             }
  287.             else if (isMoveByMouse)
  288.             {
  289.                 Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  290.                 float moveFactor=0.01f;
  291.                 CamTarget.X += -moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
  292.                 CamTarget.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
  293.                 CamTarget.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
  294.                 CamPostion.X +=- moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
  295.                 CamPostion.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
  296.                 CamPostion.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
  297.              
  298.                 Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  299.                 device.Transform.View = viewMatrix;
  300.                 mouseLastX = e.X;
  301.                 mouseLastY = e.Y;
  302.             }
  303.         }
  304.         protected override void OnMouseWheel(MouseEventArgs e)
  305.         {
  306.             float scaleFactor = -(float)e.Delta / 2000 + 1f;
  307.             CamPostion.Subtract(CamTarget);
  308.             CamPostion.Scale(scaleFactor);
  309.             CamPostion.Add(CamTarget);
  310.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  311.             device.Transform.View = viewMatrix;
  312.         }
  313.         protected override void OnPaint(PaintEventArgs e)
  314.         {
  315.             Render(); //保持device渲染,直到程序结束
  316.         }
  317.         static void Main()
  318.         {
  319.             DrawBasicGeometry drawBasicGeometry = new DrawBasicGeometry(); //创建窗体对象
  320.             if (drawBasicGeometry.InitializeDirect3D() == false) //检查Direct3D是否启动
  321.             {
  322.                 MessageBox.Show("无法启动Direct3D!", "错误!");
  323.                 return;
  324.             }
  325.             drawBasicGeometry.Show(); //如果一切都初始化成功,则显示窗体
  326.             while (drawBasicGeometry.Created)
  327.             {
  328.                 drawBasicGeometry.Render(); //保持device渲染,直到程序结束
  329.                 Application.DoEvents();
  330.             }            
  331.         }
  332.     }
  333. }