Directx 3D编程实例:绘制可变速旋转的三角形

时间:2023-03-08 23:53:56
Directx 3D编程实例:绘制可变速旋转的三角形

最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。

写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。

Directx 3D编程实例:绘制可变速旋转的三角形

第一步:修改Program.cs,主要是判断显卡支不支持

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms; namespace SimpleDirect3DExample
{
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 SimpleDirect3DExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private Device device = null; //Device指显卡适配器,一个显卡至少有一个适配器
private VertexBuffer vertexBuffer = null; private Microsoft.DirectX.Direct3D.Font d3dfont; private string adapterInformationString;
private bool showAdapterString = true;
private float angle = 0.0f;
private float incrementAngle = 0.1f;
private bool enableRotator = true; 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 Form1_Load(object sender, EventArgs e)
{
//设置窗体显示方式
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
this.Width = 600;
this.Height = 500;
//为了能响应键盘事件,该属性必须设为true
this.KeyPreview = true;
adapterInformationString = "F1:显示/隐藏提示信息\r\n" +
"<F2>:旋转/不旋转\r\n" +
"上箭头:提高转速\n" +
"下箭头:降低转速\n" +
"<Esc>:退出\n\n\n";
AdapterDetails adapterDetails = Manager.Adapters.Default.Information;
adapterInformationString += string.Format(
"显卡驱动程序:{0}\n", adapterDetails.DriverName);
adapterInformationString += string.Format(
"显卡驱动程序版本:{0}\n", adapterDetails.DriverVersion);
DisplayMode displayMode = Manager.Adapters.Default.CurrentDisplayMode;
adapterInformationString += string.Format(
"显示器当前分辨率:{0} X {1}\n", displayMode.Width, displayMode.Height);
adapterInformationString += string.Format(
"显示器当前颜色质量:{0}\n", displayMode.Format);
adapterInformationString += string.Format(
"显示器当前刷新频率(Hz):{0}\n", displayMode.RefreshRate); //创建3D字体对象,显示字符用,这两句不能放在场景中,否则会很慢
System.Drawing.Font winFont = new System.Drawing.Font("宋体", 12, FontStyle.Regular);
d3dfont = new Microsoft.DirectX.Direct3D.Font(device, winFont);
d3dfont.PreloadText(adapterInformationString); //创建顶点缓冲
vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored),
3, device, Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionColored.Format, Pool.Default);
vertexBuffer.Created += new EventHandler(OnVertexBufferCreate);
OnVertexBufferCreate(vertexBuffer, null); } private void OnVertexBufferCreate(object sender, EventArgs e)
{
//锁定顶点缓冲-->定义顶点-->解除锁定。
VertexBuffer buffer = (VertexBuffer)sender;
CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])buffer.Lock(0, 0);
verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f);
verts[0].Color = Color.BlueViolet.ToArgb();
verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f);
verts[1].Color = Color.GreenYellow.ToArgb();
verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f);
verts[2].Color = Color.Red.ToArgb();
buffer.Unlock();
} private void SetupCamera()
{
//--------设置世界矩阵
Vector3 world = new Vector3(angle, angle / 2.0f, angle / 4.0f); device.Transform.World = Matrix.RotationAxis(world, angle);
if (enableRotator)
{
angle += incrementAngle / (float)(Math.PI);
}
//--------设置投影矩阵
//纵横比
float aspectRatio = 1;
//只能显示nearPlane到farPlane之间的场景
float nearPlane = 1;
float farPlane = 100;
//视界
float fieldOfView = (float)Math.PI / 4.0f;
device.Transform.Projection = Matrix.PerspectiveFovLH(fieldOfView, aspectRatio, nearPlane, farPlane);
//--------设置视图矩阵
Vector3 cameraPosition = new Vector3(0, 0, -5);
Vector3 cameraTarget = new Vector3(0, 0, 0);
Vector3 upDirection = new Vector3(0, 1, 0);
device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, upDirection);
//--------不进行背面剔除
device.RenderState.CullMode = Cull.None;
//--------不要灯光
device.RenderState.Lighting = false;
} private void Form1_Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.AliceBlue, 1.0f, 0);
SetupCamera();
//--------------场景处理
device.BeginScene();
device.VertexFormat = CustomVertex.PositionColored.Format;
device.SetStreamSource(0, vertexBuffer, 0);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
if (showAdapterString == true)
{
d3dfont.DrawText(null, adapterInformationString, 25, 30, Color.Green);
}
device.EndScene();
//---------------发送场景
device.Present();
//---------------强制重新调用Form1_Paint事件
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:
showAdapterString = !showAdapterString;
break;
case Keys.F2:
enableRotator = !enableRotator;
break;
case Keys.Up:
if (enableRotator)
{
incrementAngle += 0.01f;
}
break;
case Keys.Down:
if (enableRotator && incrementAngle > 0.02f)
{
incrementAngle -= 0.01f;
}
break;
}
}
}
}