Directx 3D编程实例:绘制3DMesh
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。
第一步:判断显卡是否支持
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace _3DMesh { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Form1 frm = new Form1(); if (frm.InitializeGraphics() == false) { MessageBox.Show("显卡不支持3D或者未安装配套的显卡驱动程序!"); return; } Application.Run(frm); } } }
第二步:程序源码
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 _3DMesh { public partial class Form1 : Form { private Device device = null; private Mesh boxMesh = null; private Mesh cylinderMesh = null; private Mesh polygonMesh = null; private Mesh sphereMesh = null; private Mesh teapotMesh = null; private Mesh torusMesh = null; private Mesh textMesh = null; private Microsoft.DirectX.Direct3D.Font d3dfont; private string helpString; private bool showHelpString = true; private float angle = 0.0f; private int rotatorXYZ = 0; private bool enableRotator = true; private bool enableCullMode = false; private bool enableSolidMode = false; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; 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, -18.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.Lighting = false; device.RenderState.CullMode = (enableCullMode ? Cull.CounterClockwise : Cull.None); device.RenderState.FillMode = (enableSolidMode ? FillMode.Solid : FillMode.WireFrame); } private void SetWorldTransform(float x, float y, float z) { 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) * Matrix.Translation(x, y, z); if (enableRotator == true) { angle += 0.03f / (float)Math.PI; } } private void Form1_Load(object sender, EventArgs e) { this.Width = 575; this.Height = 475; this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); this.KeyPreview = true; helpString = "<Esc>:退出\n\n\n" + "<F1>:显示/隐藏提示信息\n" + "<F2>:实心/线框\n" + "<F3>:旋转/不旋转\n" + "<F4>:旋转轴(x轴、y轴、z轴)\n" + "<F5>:背景剔除/不剔除\n\n"; System.Drawing.Font winFont = new System.Drawing.Font("宋体", 9, FontStyle.Regular); d3dfont = new Microsoft.DirectX.Direct3D.Font(device, winFont); d3dfont.PreloadText(helpString); textMesh = Mesh.TextFromFont( device, new System.Drawing.Font("宋体", 12), "Mesh对象展示", 1.0f, 0.3f); boxMesh = Mesh.Box(device, 2.0f, 2.0f, 2.0f); cylinderMesh = Mesh.Cylinder(device, 1.0f, 0.5f, 2.0f, 10, 10); polygonMesh = Mesh.Polygon(device, 0.4f, 20); sphereMesh = Mesh.Sphere(device, 1.0f, 20, 10); teapotMesh = Mesh.Teapot(device); torusMesh = Mesh.Torus(device, 0.3f, 1.0f, 20, 20); } private void Form1_Paint(object sender, PaintEventArgs e) { SetupCamera(); device.Clear(ClearFlags.Target, Color.DarkSeaGreen, 1.0f, 0); device.BeginScene(); // 绘制文本 SetWorldTransform(0, 5, 0); textMesh.DrawSubset(0); // 绘制立方体 SetWorldTransform(-5, 0, 0); boxMesh.DrawSubset(0); // 绘制圆筒 SetWorldTransform(0, 0, 0); cylinderMesh.DrawSubset(0); // 绘制多边形 SetWorldTransform(5, 0, 0); polygonMesh.DrawSubset(0); // 绘制球形 SetWorldTransform(-5, -5, 0); sphereMesh.DrawSubset(0); // 绘制茶壶 SetWorldTransform(0, -5, 0); teapotMesh.DrawSubset(0); // 绘制圆环 SetWorldTransform(5, -5, 0); torusMesh.DrawSubset(0); if (showHelpString == true) { d3dfont.DrawText(null, helpString, 25, 30, Color.Tomato); } 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: enableSolidMode = !enableSolidMode; break; case Keys.F3: enableRotator = !enableRotator; break; case Keys.F4: rotatorXYZ = (rotatorXYZ + 1) % 3; break; case Keys.F5: enableCullMode = !enableCullMode; break; } } } }