C# Managed DirectX 学习笔记 一 (基础环境,画三角形,输入的处理)

 这是我学习 Managed DirectX 的过程笔记. 因为都是 边学习边用代码来练习. 所以 就都以代码的形式来展现. 注释得很清淅明确,还包括.我个人的理解.都在代码的注释中.

这是第一篇: 主要练习的是 基础的 设备的初始化 (如:显卡设备,键盘设备,鼠标设备等 , 还有如何创建顶点,及画三角形. 以及如果处理输入 (鼠标及键盘).  这是一个标准的MDX程序的流程

View Code
  1 using System;
2 using System.Collections.Generic;
3 using System.Drawing;
4 using System.Windows.Forms;
5 using Microsoft.DirectX;
6 using Microsoft.DirectX.Direct3D;
7 using Microsoft.DirectX.DirectInput;
8 using System.Threading;
9
10 namespace DXTest
11 {
12 public partial class MainForm : Form
13 {
14 // 声明 显示设备
15 private Microsoft.DirectX.Direct3D.Device device = null;
16 // 输入设备
17 private Microsoft.DirectX.DirectInput.Device keyBoard;
18 // 鼠标设置
19 private Microsoft.DirectX.DirectInput.Device mouse;
20
21 private float xx;
22 private float yy;
23
24 // 因为我们要画一个三角形. 所以声明一个 自定义点的数组
25 // 在DX中.顶点在CustomVertex 类中.类中有各种顶点的结构. 比如 位置+颜色/变换+颜色/位置+贴图等等.
26 // 本例中,我们使用 位置+颜色的顶点格式. 因这一个三角形有三个顶点, 所以数组的长度为3.
27 private CustomVertex.PositionColored[] Vertex = new CustomVertex.PositionColored[3];
28
29 //构造函数,初始使用用到的设备,相机,及顶点位置与颜色
30 public MainForm()
31 {
32 InitializeComponent();
33 InitializeDevice(); // 初始化 显视卡
34 InitializeCamera(); // 初始化 相机
35 InitializeVecticies(); // 初始化顶点
36 InitializeKeyboard(); // 初始化键盘
37 InitializeMouse();
38 RenderSettings(); // 渲染设置
39
40 // 允许跨纯种改变UI
41 Control.CheckForIllegalCrossThreadCalls = false;
42
43 // 开启一个监听输入的线程
44 Thread Listener = new Thread(new ThreadStart(KeyboardListener));
45 Listener.Start();
46 }
47 // 初始化 设置函数
48 private void InitializeDevice()
49 {
50 PresentParameters pp = new PresentParameters();
51 pp.Windowed = true;
52 pp.SwapEffect = SwapEffect.Discard;
53
54 device = new Microsoft.DirectX.Direct3D.Device(0,Microsoft.DirectX.Direct3D.DeviceType.Hardware,this,CreateFlags.SoftwareVertexProcessing,pp);
55 }
56 // 初始化相机, 需要定义Projection--视锥矩阵 及 相机矩阵.
57 private void InitializeCamera()
58 {
59 // 设置投射变换 视野(FOV) 高宽比 近截面 Z 值 离截面 Z 值
60 device.Transform.Projection = Matrix.PerspectiveFovLH(3.14f / 4,Width / Height,1f,10000f);
61 // 设置相机变换 位置 目标点 Y轴向上
62 device.Transform.View = Matrix.LookAtLH(new Vector3(0,0,30),new Vector3(),new Vector3(0,1,0));
63 }
64 // 渲染设置
65 private void RenderSettings()
66 {
67 // 关闭灯光以显示线框颜色
68 device.RenderState.Lighting = false;
69 // 取消背后消隐
70 device.RenderState.CullMode = Cull.None;
71 // 线框显示
72 // device.RenderState.FillMode = FillMode.WireFrame;
73 }
74 // 初始化 顶点的位置及颜色
75 private void InitializeVecticies()
76 {
77 Vertex[0] = new CustomVertex.PositionColored(new Vector3(),Color.Red.ToArgb());
78 Vertex[1] = new CustomVertex.PositionColored(new Vector3(10 + xx,yy,0),Color.Blue.ToArgb());
79 Vertex[2] = new CustomVertex.PositionColored(new Vector3(0,5,0),Color.Yellow.ToArgb());
80 }
81 // 初始化 输入设备
82 private void InitializeKeyboard()
83 {
84 // 实例化 输入设备 SystemGuid.Keyboard 是将系统默认的键盘 做为输入设备
85 keyBoard = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
86 keyBoard.SetCooperativeLevel(this,CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
87 // 链接输入设备
88 keyBoard.Acquire();
89 }
90 // 初始化 鼠标
91 private void InitializeMouse()
92 {
93 mouse = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse);
94 mouse.Properties.AxisModeAbsolute = true;
95 mouse.SetCooperativeLevel(this,CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Background);
96 mouse.Acquire();
97 }
98 // 自定义处理 键盘输入 的方法
99 public void KeyboardListener()
100 {
101 // 得到当前键盘输入的内容
102 KeyboardState keys = keyBoard.GetCurrentKeyboardState();
103 if( keys[Key.LeftArrow]) {
104 xx += 1;
105 //Render();
106 // this.label1.Invoke(new MethodInvoker(() => this.label1.Text = xx.ToString()));
107 }
108 if( keys[Key.RightArrow])
109 xx -= 1;
110 if( keys[Key.UpArrow])
111 yy ++;
112 if( keys[Key.DownArrow])
113 yy --;
114 InitializeVecticies();
115 }
116 // 自定义 处理 鼠标的方法
117 public void MouseListener()
118 {
119 MouseState ms = mouse.CurrentMouseState;
120 byte[] buttons = ms.GetMouseButtons();
121
122 for (int i = 0; i < buttons.Length; i++) {
123 if (buttons[i] != 0) {
124 switch (i) {
125 case 0:
126 label1.Text = "Left Mouse Pressed" + ms.X.ToString() + " " + ms.Y.ToString();
127 break;
128 case 1:
129 label1.Text = "Right Pressed" + ms.X.ToString() + " " + ms.Y.ToString();
130 break;
131 case 2:
132 label1.Text = "Middle Pressed" + ms.X.ToString() + " " + ms.Y.ToString();
133 break;
134 }
135 }
136 }
137 }
138 // 渲染方法
139 public void Render()
140 {
141 if (device == null) { // 如果 显示设备 没能正确加载 结束
142 return;
143 }
144 // 清空画面
145 device.Clear(ClearFlags.Target,Color.CornflowerBlue,0,1);
146 // 开始渲染场景
147 device.BeginScene();
148
149 // 渲染场景 的方法
150 // 告诉显卡, 你使用的点的格式. 本次使用的点的格式为 位置+颜色 的格式.
151 device.VertexFormat = CustomVertex.PositionColored.Format;
152 // 让 显示 去画这个Triangle.
153 device.DrawUserPrimitives(PrimitiveType.TriangleList,Vertex.Length / 3,Vertex);
154
155 // 结束渲染场景
156 device.EndScene();
157 // 将当前的结果显示 在显示器上的一个矩形区域,如果没有指定区域,则以当前的控件做为显示区
158 device.Present();
159 }
160 /*
161 * 除了, 我们可以手动的链接输入设备 如 键盘 或 鼠标 .
162 * 再手动的编写 输入 设备的监听函数外, 我们可以简单的
163 * 重写Form类的 OnMouseDown (鼠标按下),与OnKeyDown(键盘按下)
164 * 来处理鼠标与键盘的输入
165 * 值得一提的是 重写OnPaint,是为了把DX的结果写在控件上.
166 * **这里一定要注意这个控件的 双缓冲 要关闭** 不然无法正确重画
167 */
168 // 重写 OnPaint 方法 . 将DX的结果画在控件上
169 protected override void OnPaint(PaintEventArgs e)
170 {
171 Render();
172 }
173 // 重写 OnMouseDown 方法 . 来处理鼠标事件
174 protected override void OnMouseDown(MouseEventArgs e)
175 {
176 label1.Text = e.X.ToString() + " " + e.Y.ToString();
177 }
178 // 重写 OnKeyDown 方法 . 来处理键盘输入事件
179 protected override void OnKeyDown(KeyEventArgs e)
180 {
181 if (e.KeyCode == Keys.Escape) {
182 DialogResult result = MessageBox.Show("ESCAPE?","ERROR",MessageBoxButtons.YesNo);
183 if (result == DialogResult.Yes) {
184 Application.Exit();
185 }
186 }
187 }
188 }
189 }



原文地址:https://www.cnblogs.com/easyfrog/p/2343787.html