form1.cs
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 XNAGame_022
{
public partial class Form1 : Form
{
/*
* 1.编写Direct3D程序,首先需要安装direct3d sdk程序。
* 2.项目引用中,需要添加Microsoft.DirectX,Microsoft.DirectX.Direct3D,Microsoft.Direct3DX,
* 3.上面的引用,我的电脑的路径是C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0
* 4.vs项目属性中,引用路径要把C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\,
* 和C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\,都包含进来。
* 5.在form1.cs中,需要引用 using Microsoft.DirectX,using Microsoft.DirectX.Direct3D;
* 6.非常重要的一点,此点不解决,窗体不显示,在App.config配置文件中,加入<startup useLegacyV2RuntimeActivationPolicy="true">
*
*
*/
//设备类
private Device device1 = null;
//
bool pause = false;
//显卡缓存
VertexBuffer buffer1 = null;
//
float Angle = 0; // 表示三角形旋转角度
float ViewZ = -6.0f; //观察者位置的z坐标,z值增加,三角形离开观察者越近。当ViewZ大于0,观察者移动到三角形另一侧。
public Form1()
{
InitializeComponent();
}
public bool InitializeGraphics()
{
try
{
PresentParameters param1 = new PresentParameters();
param1.Windowed = true; // 非全屏模式,即窗口模式
param1.SwapEffect = SwapEffect.Discard; // 后备缓存模式,新帧显示,旧帧丢弃
param1.EnableAutoDepthStencil = true; //自动深度测试
param1.AutoDepthStencilFormat = DepthFormat.D16; //深度缓存区单元为16位二进制
device1 = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, param1);
device1.DeviceReset += new System.EventHandler(this.OnResetDevice);
this.OnCreateDevice(device1, null);
this.OnResetDevice(device1, null);
return true;
}
catch (DirectXException ex)
{
return false;
}
}
//第四步,修改此方法
public void Render()
{
if (device1 == null) return; // 设备类没有初始化,为空,不渲染
if (pause) return; // 暂停,窗体最小化,不可见,不渲染
device1.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1.0f, 0);
SetupMatrices();
device1.BeginScene();
device1.SetStreamSource(0, buffer1, 0);
device1.VertexFormat = CustomVertex.PositionColored.Format;
//
device1.Transform.World = Matrix.Translation(0, 0, -1); //沿z轴观察者方向移动1单位
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); //绘制正前面
//旋转180度是为了从外侧看,按顺时针绘制三角形,因背面剔除打开,内侧不会被看到
device1.Transform.World = Matrix.RotationY((float)Math.PI) * Matrix.Translation(0, 0, 1);
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); //绘制正后面
device1.Transform.World = Matrix.RotationY(-(float)Math.PI / 2) * Matrix.Translation(1, 0, 0);
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); //绘制右侧面
device1.Transform.World = Matrix.RotationY((float)Math.PI / 2) * Matrix.Translation(-1, 0, 0);
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); // 绘制左侧面
device1.Transform.World = Matrix.RotationX((float)Math.PI / 2) * Matrix.Translation(0, 1, 0);
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); //绘制下面
device1.Transform.World = Matrix.RotationX(-(float)Math.PI / 2) * Matrix.Translation(0, -1, 0);
device1.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); //绘制上面
device1.EndScene();
device1.Present();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
this.Render();
}
//第一步,修改此方法,
public void OnCreateDevice(object sender, EventArgs e)
{
Device dev = (Device)sender; //绘制正方体用6个顶点
buffer1 = new VertexBuffer(typeof(CustomVertex.PositionColored), 6, dev, 0, CustomVertex.PositionColored.Format, Pool.Default);
buffer1.Created += new System.EventHandler(this.OnCreateVertexBuffer);
this.OnCreateVertexBuffer(buffer1, null);
}
//第三步,修改此方法
public void OnResetDevice(object sender, EventArgs e)
{
Device dev = (Device)sender;
dev.RenderState.CullMode = Cull.CounterClockwise; //背面剔除方式为只显示顺时针三角形
dev.RenderState.Lighting = false; // 取消灯光
}
private void Form1_Resize(object sender, EventArgs e)
{
pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);
}
//第二步,修改此方法,
public void OnCreateVertexBuffer(object sender, EventArgs e)
{
//建模,创建一个正方体的6个顶点
CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])buffer1.Lock(0, 0);
verts[0].Position = new Vector3(-1.0f, -1.0f, 0.0f);
verts[0].Color = Color.Aqua.ToArgb();
verts[1].Position = new Vector3(1.0f, 1.0f, 0.0f);
verts[1].Color = Color.Brown.ToArgb();
verts[2].Position = new Vector3(1.0f, -1.0f, 0.0f);
verts[2].Color = Color.LightPink.ToArgb();
verts[3].Position = new Vector3(-1.0f, -1.0f, 0.0f);
verts[3].Color = Color.Aqua.ToArgb();
verts[4].Position = new Vector3(-1.0f, 1.0f, 0.0f);
verts[4].Color = Color.Red.ToArgb();
verts[5].Position = new Vector3(1.0f, 1.0f, 0.0f);
verts[5].Color = Color.Brown.ToArgb();
//注意,正方形平面在xy平面上,即z坐标为0,正方形平面中心在原点
buffer1.Unlock();
//显卡缓存,设定点时,先锁定,再解锁。
}
//第五步,修改这个方法
private void SetupMatrices()
{
Vector3 v1 = new Vector3(0.0f, 0.0f, -5.0f);
v1.TransformCoordinate(Matrix.RotationYawPitchRoll(Angle,ViewZ,0));
//
device1.Transform.View = Matrix.LookAtLH(v1,
new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); // 观察变换矩阵
device1.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f); //投影变换矩阵
}
//第六步,增加此方法
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Down:
ViewZ += 0.1f;
break;
case Keys.Up:
ViewZ -= 0.1f;
break;
case Keys.Left:
Angle += 0.1f;
break;
case Keys.Right:
Angle -= 0.1f;
break;
}
}
}
}
progarm.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace XNAGame_022
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
using (Form1 frm = new Form1())
{
if (frm.InitializeGraphics() == false)
{
MessageBox.Show("无法初始化Direct 3D,退出");
return;
}
frm.Show();
while (frm.Created == true)
{
frm.Render();
Application.DoEvents();
}
}
}
}
}
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>