作为一个.Net程序员学习3D开发好尴尬啊,因为不论是OpenGL还是Direct3D都是用C/C++开发的比较多。虽然有计划使用C++进行开发,但是平时还是C#使用的多。很少用C++做东西,如果仅仅是学习是很难有进步的,学习C++很长时间了至今仍感觉很肤浅,而且语言并不是编程的全部,真正的高手是不区分语言的,所以决定注重基本原理的学习,具体实现用C#也是可以的,这里选择Slimdx。
环境:
VS2010+C#
SlimDX SDK (January 2012).msi
d3d9.dll, D3DX9_43.dll
1 using System;
2 using System.Drawing;
3 using System.Windows.Forms;
4 using SlimDX.Direct3D9;
5 using SlimDX;
6 using System.Runtime.InteropServices;
7
8 namespace D3Ddemo01
9 {
10 public partial class Form1 : Form
11 {
12 public Form1()
13 {
14 InitializeComponent();
15 }
16 Device device = null;
17 private void Form1_Load(object sender, EventArgs e)
18 {
19 this.ClientSize = new System.Drawing.Size(800, 600);
20 this.Text = " 第1个D3D程序";
21
22 }
23 public bool InitializeDirect3D()
24 {
25 try
26 {
27 Direct3D direct3d = new Direct3D();
28 //direct3d.GetAdapterDisplayMode(1);
29 PresentParameters presentParams = new PresentParameters();
30 presentParams.Windowed = true; //指定以Windows窗体形式显示
31 presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
32 device = new Device(direct3d, 0, DeviceType.Hardware, this.Handle,
33 CreateFlags.SoftwareVertexProcessing, presentParams); //实例化device对象
34 return true;
35 }
36 catch (Exception e)
37 {
38 MessageBox.Show(e.ToString(), "Error"); //处理异常
39 return false;
40 }
41 }
42 public void Render()
43 {
44 if (device == null) //如果device为空则不渲染
45 {
46 return;
47 }
48 Vector3 eye = new Vector3(0,0, -30);
49 Vector3 at = new Vector3(0, 0, 10);
50 Vector3 up = new Vector3(0, 1, 0);
51 Matrix viewMatrix = Matrix.LookAtLH(eye, at, up);
52
53 Matrix projection = Matrix.PerspectiveFovLH((float)Math.PI / 4,
54 this.Width / this.Height, 1.0f, 50.0f);
55 device.SetTransform(TransformState.Projection, projection);
56 device.SetTransform(TransformState.View, viewMatrix);
57 device.SetRenderState(RenderState.FillMode, FillMode.Solid);
58 device.SetRenderState(RenderState.Lighting, false);
59 //深度偏移
60 //device.SetRenderState(RenderState.DepthBias, drawArgs.CurrentWorld.CurrentDepthBias - 0.00001f);//防止闪烁
61 device.SetRenderState(RenderState.ZEnable, true);
62 device.SetRenderState(RenderState.CullMode, Cull.None);
63
64 //在此添加渲染图形代码
65 VertexBuffer Vertices = new VertexBuffer(device, 3 * 20, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
66 DataStream stream = Vertices.Lock(0, 0, LockFlags.None);
67 Vertex[] vertexData = new Vertex[3];
68 vertexData[0].PositionRhw = new Vector4(0.0f, 1.0f, 10.0f, 1.0f);
69 vertexData[0].Color = Color.Red.ToArgb();
70 vertexData[1].PositionRhw = new Vector4(1.0f, 0.0f, 10.0f, 1.0f);
71 vertexData[1].Color = Color.Blue.ToArgb();
72 vertexData[2].PositionRhw = new Vector4(2.0f, 2.0f, 10.0f, 1.0f);
73 vertexData[2].Color = Color.Green.ToArgb();
74 stream.WriteRange(vertexData);
75 Vertices.Unlock();
76 //PositionColored[] vertices = new PositionColored[3];//定义顶点
77 //vertices[0].Position = new Vector3(0f, 0f, 0f);
78 //vertices[0].Color = Color.Red.ToArgb();
79 //vertices[1].Position = new Vector3(5f, 10f, 0f);
80 //vertices[1].Color = Color.Green.ToArgb();
81 //vertices[2].Position = new Vector3(10f, 0f, 0f);
82 //vertices[2].Color = Color.Yellow.ToArgb();
83 //device.VertexFormat = VertexFormat.Position;
84 //device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, Vertices);
85 //device.RenderState.CullMode = Cull.None;
86 // device.Clear(ClearFlags.Target, Color.DarkSlateBlue, 1.0f, 0); //清除windows界面为深蓝色
87 device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
88 device.BeginScene();
89 device.SetStreamSource(0, Vertices, 0, 20);
90 device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse;
91 device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
92 device.EndScene();
93 device.Present();
94 }
95 }
96 [StructLayout(LayoutKind.Sequential)]
97 struct Vertex
98 {
99 public Vector4 PositionRhw;
100 public int Color;
101 }
102 }
调用代码:
1 static class Program
2 {
3 /// <summary>
4 /// 应用程序的主入口点。
5 /// </summary>
6 [STAThread]
7 static void Main()
8 {
9 Form1 basicForm = new Form1(); //创建窗体对象
10 if (basicForm.InitializeDirect3D() == false) //检查Direct3D是否启动
11 {
12 MessageBox.Show("无法启动Direct3D!", "错误!");
13 return;
14 }
15 basicForm.Show(); //如果一切都初始化成功,则显示窗体
16 while (basicForm.Created) //设置一个循环用于实时更新渲染状态
17 {
18 basicForm.Render(); //保持device渲染,直到程序结束
19 Application.DoEvents(); //处理键盘鼠标等输入事件
20 }
21 }
22 }
结果: