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

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