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

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 LightsForm : Form
  19.     {
  20.         Device device = null;//定义绘图设备
  21.         private Mesh meshObj;//定义网格模型对象
  22.         private Material material;//定义材质变量
  23.         private float angleY=0.01f;//定义绕Y轴旋转变量
  24.         private Vector3 CamPostion = new Vector3(0, 30, -30);//定义摄像机位置
  25.         private Vector3 CamTarget = new Vector3(0, 0, 0);//定义摄像机目标位置
  26.         private int mouseLastX,mouseLastY;//记录鼠标按下时的坐标位置
  27.         private bool isRotateByMouse=false;//记录是否由鼠标控制旋转
  28.         private bool isMoveByMouse = false;//记录是否由鼠标控制移动
  29.         public LightsForm()
  30.         {
  31.             this.ClientSize = new Size(800, 600);//指定窗体尺寸
  32.             this.Text = "灯光";//指定窗体标题
  33.         }
  34.         public bool InitializeDirect3D()
  35.         {
  36.             try
  37.             {
  38.                 PresentParameters presentParams = new PresentParameters();
  39.                 presentParams.Windowed = true; //指定以Windows窗体形式显示
  40.                 presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
  41.                 presentParams.AutoDepthStencilFormat = DepthFormat.D16;
  42.                 presentParams.EnableAutoDepthStencil = true;
  43.                 presentParams.PresentationInterval = PresentInterval.Immediate;
  44.                 device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //实例化device对象
  45.                 meshObj = Mesh.Teapot(device);//定义茶壶模型
  46.                 //定义材质
  47.                 material = new Material();
  48.                 material.Diffuse = Color.White;
  49.                 material.Specular = Color.LightGray;
  50.                 material.SpecularSharpness = 15.0F; 
  51.                 return true;
  52.             }
  53.             catch (DirectXException e)
  54.             {
  55.                 MessageBox.Show(e.ToString(), "Error"); //处理异常
  56.                 return false;
  57.             }
  58.         }
  59.         public void Render()
  60.         {
  61.             if (device == null)   //如果device为空则不渲染
  62.             {
  63.                 return;
  64.             }
  65.             SetUpCamera();
  66.             device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0);  //清除windows界面为深蓝色
  67.             device.BeginScene();
  68.             //在此添加渲染图形代码
  69.             //打开灯光
  70.             device.RenderState.Lighting = true;
  71.             //设置点光源
  72.             //device.Lights[0].Type = LightType.Point;
  73.             //device.Lights[0].Diffuse = System.Drawing.Color.Green;
  74.             //device.Lights[0].Position = new Vector3(5.0f, 5.0f, 5.0f);
  75.             //device.Lights[0].Range = 50.0f;
  76.             //device.Lights[0].Attenuation1 = 0.1f;
  77.             //device.Lights[0].Enabled = true; //打开灯光
  78.             //设置平行光
  79.             //device.Lights[0].Type = LightType.Directional;
  80.             //device.Lights[0].Diffuse = System.Drawing.Color.Green;
  81.             //device.Lights[0].Direction = new Vector3(0.0f, -1.0f, 1.0f);
  82.             //device.Lights[0].Enabled = true; //打开灯光
  83.             //设置聚光灯
  84.             //device.Lights[0].Type = LightType.Spot;
  85.             //device.Lights[0].Diffuse = System.Drawing.Color.Green;
  86.             //device.Lights[0].Position = new Vector3(5.0f, 5.0f, 5.0f);
  87.             //device.Lights[0].Direction = new Vector3(0.0f, -1.0f, 1.0f);
  88.             //device.Lights[0].Range = 50.0f;
  89.             //device.Lights[0].Attenuation1 = 0.1f;
  90.             //device.Lights[0].OuterConeAngle = 45f;
  91.             //device.Lights[0].Enabled = true; //打开灯光
  92.             //设置三种不同类型的灯光
  93.             LightsCollection lightsCollection=device.Lights;
  94.             //第一个灯光为点光源
  95.             lightsCollection[0].Type = LightType.Point;
  96.             lightsCollection[0].Diffuse = System.Drawing.Color.Green;
  97.             lightsCollection[0].Position = new Vector3(-10.0f, 10.0f, 10.0f);
  98.             lightsCollection[0].Range = 50.0f;
  99.             lightsCollection[0].Attenuation1 = 0.1f;
  100.             lightsCollection[0].Enabled = true; //打开灯光
  101.             //第二个灯光为平行光
  102.             lightsCollection[1].Type = LightType.Directional;
  103.             lightsCollection[1].Diffuse = System.Drawing.Color.Green;
  104.             lightsCollection[1].Direction = new Vector3(0.0f, -1.0f, 1.0f);
  105.             lightsCollection[1].Enabled = true; //打开灯光
  106.             //第三个灯光为聚光灯
  107.             lightsCollection[2].Type = LightType.Spot;
  108.             lightsCollection[2].Diffuse = System.Drawing.Color.Green;
  109.             lightsCollection[2].Position = new Vector3(5.0f, 5.0f, 5.0f);
  110.             lightsCollection[2].Direction = new Vector3(0.0f, -1.0f, 1.0f);
  111.             lightsCollection[2].Range = 50.0f;
  112.             lightsCollection[2].Attenuation1 = 0.1f;
  113.             lightsCollection[2].OuterConeAngle = 45f;
  114.             lightsCollection[2].Enabled = true; //打开灯光
  115.             
  116.             device.RenderState.CullMode = Cull.None;
  117.             Console.WriteLine(device.Lights[0].Range.ToString());
  118.             //设置绘图设备当前的材质属性
  119.             device.Material = material;
  120.             meshObj.DrawSubset(0);//绘制模型
  121.             
  122.             device.EndScene();
  123.             device.Present();
  124.         }
  125.         private void SetUpCamera()//摄像机
  126.         {
  127.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  128.             device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 0.3f, 500f);
  129.             device.Transform.View = viewMatrix;
  130.         }
  131.         protected override void OnKeyDown(KeyEventArgs e)
  132.         {
  133.             Vector4 tempV4;
  134.             Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  135.             switch (e.KeyCode)
  136.             {
  137.                 case Keys.Left:
  138.                     CamPostion.Subtract(CamTarget);
  139.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  140.                             Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), -angleY)));
  141.                     CamPostion.X = tempV4.X + CamTarget.X;
  142.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  143.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  144.                     break;
  145.                 case Keys.Right:
  146.                     CamPostion.Subtract(CamTarget);
  147.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  148.                             Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), angleY)));
  149.                     CamPostion.X = tempV4.X + CamTarget.X;
  150.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  151.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  152.                     break;
  153.                 case Keys.Up:
  154.                     CamPostion.Subtract(CamTarget);
  155.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  156.                        Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
  157.                        , device.Transform.View.M21, device.Transform.View.M31), -angleY)));
  158.                     CamPostion.X = tempV4.X + CamTarget.X;
  159.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  160.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  161.                     break;
  162.                 case Keys.Down:
  163.                     CamPostion.Subtract(CamTarget);
  164.                     tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  165.                        Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
  166.                        , device.Transform.View.M21, device.Transform.View.M31), angleY)));
  167.                     CamPostion.X = tempV4.X + CamTarget.X;
  168.                     CamPostion.Y = tempV4.Y + CamTarget.Y;
  169.                     CamPostion.Z = tempV4.Z + CamTarget.Z;
  170.                     break;
  171.                 case Keys.Add:
  172.                     CamPostion.Subtract(CamTarget);
  173.                     CamPostion.Scale(0.95f);
  174.                     CamPostion.Add(CamTarget);
  175.                     break;
  176.                 case Keys.Subtract:
  177.                     CamPostion.Subtract(CamTarget);
  178.                     CamPostion.Scale(1.05f);
  179.                     CamPostion.Add(CamTarget);
  180.                     break;
  181.             }
  182.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  183.             device.Transform.View = viewMatrix;
  184.         }
  185.         protected override void OnMouseDown(MouseEventArgs e)
  186.         {
  187.             if (e.Button == MouseButtons.Left)
  188.             {
  189.                 mouseLastX = e.X;
  190.                 mouseLastY = e.Y;
  191.                 isRotateByMouse = true;
  192.             }
  193.             else if (e.Button == MouseButtons.Middle)
  194.             {
  195.                 mouseLastX = e.X;
  196.                 mouseLastY = e.Y;
  197.                 isMoveByMouse=true;
  198.             }
  199.         }
  200.         
  201.         protected override void OnMouseUp(MouseEventArgs e)
  202.         {
  203.             isRotateByMouse = false;
  204.             isMoveByMouse = false;
  205.         }
  206.         protected override void OnMouseMove(MouseEventArgs e)
  207.         {
  208.             if (isRotateByMouse)
  209.             {
  210.                 Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  211.                 float tempAngleY = 2 * (float)(e.X - mouseLastX) / this.Width;
  212.                 CamPostion.Subtract(CamTarget);
  213.                 Vector4 tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  214.                     Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), tempAngleY)));
  215.                 CamPostion.X = tempV4.X;
  216.                 CamPostion.Y = tempV4.Y;
  217.                 CamPostion.Z = tempV4.Z;
  218.                 float tempAngleX = 4 * (float)(e.Y - mouseLastY) / this.Height;
  219.                 tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
  220.                     Quaternion.RotationAxis(new Vector3(currentView.M11, currentView.M21, currentView.M31), tempAngleX)));
  221.                 CamPostion.X = tempV4.X + CamTarget.X;
  222.                 CamPostion.Y = tempV4.Y + CamTarget.Y;
  223.                 CamPostion.Z = tempV4.Z + CamTarget.Z;
  224.                 Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  225.                 device.Transform.View = viewMatrix;
  226.                 mouseLastX = e.X;
  227.                 mouseLastY = e.Y;
  228.             }
  229.             else if (isMoveByMouse)
  230.             {
  231.                 Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
  232.                 float moveFactor=0.01f;
  233.                 CamTarget.X += -moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
  234.                 CamTarget.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
  235.                 CamTarget.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
  236.                 CamPostion.X +=- moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
  237.                 CamPostion.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
  238.                 CamPostion.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
  239.              
  240.                 Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  241.                 device.Transform.View = viewMatrix;
  242.                 mouseLastX = e.X;
  243.                 mouseLastY = e.Y;
  244.             }
  245.         }
  246.         protected override void OnMouseWheel(MouseEventArgs e)
  247.         {
  248.             float scaleFactor = -(float)e.Delta / 2000 + 1f;
  249.             CamPostion.Subtract(CamTarget);
  250.             CamPostion.Scale(scaleFactor);
  251.             CamPostion.Add(CamTarget);
  252.             Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
  253.             device.Transform.View = viewMatrix;
  254.         }
  255.         static void Main()
  256.         {
  257.             LightsForm lightsForm = new LightsForm(); //创建窗体对象
  258.             if (lightsForm.InitializeDirect3D() == false) //检查Direct3D是否启动
  259.             {
  260.                 MessageBox.Show("无法启动Direct3D!", "错误!");
  261.                 return;
  262.             }
  263.             lightsForm.Show(); //如果一切都初始化成功,则显示窗体
  264.             while (lightsForm.Created) //设置一个循环用于实时更新渲染状态
  265.             {
  266.                 lightsForm.Render(); //保持device渲染,直到程序结束
  267.                 Application.DoEvents(); //处理键盘鼠标等输入事件
  268.             }
  269.         }
  270.     }
  271. }