最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。
写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。
第一步:修改Program.cs,主要是判断显卡支不支持
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace _3DPrimitive { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Form1 form1 = new Form1(); if (form1.InitializeGraphics() == false) { MessageBox.Show("显卡不支持3D或者未安装配套的显卡驱动程序!"); } Application.Run(form1); } } }
第二步:主程序代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace _3DPrimitive { public partial class Form1 : Form { private Device device = null; private VertexBuffer vertexBuffer = null; private const int vertexNumber = 18; private string primitivesType = "点列"; private Microsoft.DirectX.Direct3D.Font d3dfont; private string helpString; private bool showHelpString = true; private float angle = 0.0f; private bool enableRotator = false; private int rotatorXYZ = 0; private bool enableCullMode = false; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; presentParams.AutoDepthStencilFormat=DepthFormat.D16; presentParams.EnableAutoDepthStencil=true; device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); return true; } catch (DirectXException) { return false; } } private void SetupCamera() { //设置投影矩阵 float fieldOfView = (float)Math.PI / 4; float aspectRatio = this.Width / this.Height; float nearPlane = 1.0f; float farPlane = 100.0f; device.Transform.Projection = Matrix.PerspectiveFovLH(fieldOfView, aspectRatio, nearPlane, farPlane); //设置视图矩阵 Vector3 cameraPosition = new Vector3(0, 0, -30.0f); Vector3 cameraTarget = new Vector3(0, 0, 0); Vector3 upDirection = new Vector3(0, 1, 0); device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, upDirection); //点的大小 device.RenderState.PointSize = 4.0f; //不要灯光 device.RenderState.Lighting = false; //背面剔除 if (enableCullMode == true) { device.RenderState.CullMode = Cull.CounterClockwise; } else { device.RenderState.CullMode = Cull.None; } } private void OnVertexBufferCreate(object sender, EventArgs e) { //锁定顶点缓冲-->定义顶点-->解除锁定。 VertexBuffer buffer = (VertexBuffer)sender; CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])buffer.Lock(0, 0); Random random = new Random(); for (int i = 0; i < vertexNumber; i++) { float x = (float)(vertexNumber * (random.NextDouble() - 0.5f)); float y = (float)(vertexNumber * (random.NextDouble() - 0.5f)); float z = (float)(vertexNumber * (random.NextDouble() - 0.5f)); verts[i].Position = new Vector3(x, y, z); Color color = Color.FromArgb(random.Next(byte.MaxValue), random.Next(byte.MaxValue), random.Next(byte.MaxValue)); verts[i].Color = color.ToArgb(); } buffer.Unlock(); } private void Form1_Load(object sender, EventArgs e) { this.Width = 570; this.Height = 430; this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); this.KeyPreview = true; helpString = "<Esc>:退出 <F1>:显示/隐藏提示信息 " + "<F2>:变换顶点 " + "<F3>:旋转/不旋转 " + "<F4>:旋转轴(x轴、y轴、z轴) " + "<F5>:背面剔除/不剔除 " + "<1>:点列 " + "<2>:线列 " + "<3>:线带 " + "<4>:三角形列 " + "<5>:三角形带 " + "<6>:三角扇形 "; System.Drawing.Font winFont = new System.Drawing.Font("宋体", 9, FontStyle.Regular); d3dfont = new Microsoft.DirectX.Direct3D.Font(device, winFont); d3dfont.PreloadText(helpString); //创建顶点缓冲 vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored), vertexNumber, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default); vertexBuffer.Created += new EventHandler(OnVertexBufferCreate); OnVertexBufferCreate(vertexBuffer, null); } private void Form1_Paint(object sender, PaintEventArgs e) { SetupCamera(); // device.Clear(ClearFlags.Target, System.Drawing.Color.AliceBlue, 1.0f, 0); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.AliceBlue, 1.0f, 0); device.BeginScene(); device.VertexFormat = CustomVertex.PositionColored.Format; device.SetStreamSource(0, vertexBuffer, 0); switch (primitivesType) { case "点列": device.DrawPrimitives(PrimitiveType.PointList, 0, vertexNumber); break; case "线列": device.DrawPrimitives(PrimitiveType.LineList, 0, vertexNumber / 2); break; case "线带": device.DrawPrimitives(PrimitiveType.LineStrip, 0, vertexNumber - 2); break; case "三角形列": device.DrawPrimitives(PrimitiveType.TriangleList, 0, vertexNumber / 3); break; case "三角形带": device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, vertexNumber - 2); break; case "三角扇形": device.DrawPrimitives(PrimitiveType.TriangleFan, 0, vertexNumber - 2); break; } if (showHelpString == true) { d3dfont.DrawText(null, helpString, 25, 30, Color.Green); } if (enableRotator == true) { Vector3 world; if (rotatorXYZ == 0) { world = new Vector3(angle, 0, 0); } else if (rotatorXYZ == 1) { world = new Vector3(0, angle, 0); } else { world = new Vector3(0, 0, angle); } device.Transform.World = Matrix.RotationAxis(world, angle); angle += 0.05f / (float)Math.PI; } device.EndScene(); device.Present(); if (WindowState != FormWindowState.Minimized) { this.Invalidate(); } } private void Form1_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.Escape: this.Close(); break; case Keys.F1: showHelpString = !showHelpString; break; case Keys.F2: OnVertexBufferCreate(vertexBuffer, null); break; case Keys.F3: enableRotator = !enableRotator; break; case Keys.F4: rotatorXYZ = (rotatorXYZ + 1) % 3; break; case Keys.F5: enableCullMode = !enableCullMode; break; case Keys.D1: primitivesType = "点列"; break; case Keys.D2: primitivesType = "线列"; break; case Keys.D3: primitivesType = "线带"; break; case Keys.D4: primitivesType = "三角形列"; break; case Keys.D5: primitivesType = "三角形带"; break; case Keys.D6: primitivesType = "三角扇形"; break; } } } }