Managed DirectX® 9学习笔记
第一章 介绍
1、命名空间
Table 1. Managed DirectX Namespaces | |
Microsoft.DirectX |
Parent namespace, holds all common code. |
Microsoft.DirectX.Direct3D |
Direct3D graphics API, as well as the D3DX helper library. |
Microsoft.DirectX.DirectDraw |
DirectDraw graphics API. |
Microsoft.DirectX.DirectPlay |
DirectPlay networking API. |
Microsoft.DirectX.DirectSound |
DirectSound audio API. |
Microsoft.DirectX.DirectInput |
DirectInput user input API. |
Microsoft.DirectX.AudioVideoPlayback |
Simple audio and video playback API. |
Microsoft.DirectX.Diagnostics |
Simple diagnostics API. |
Microsoft.DirectX.Security |
Underlying structure for DirectX code access security. |
Microsoft.DirectX.Security.Permissions |
Permission classes for DirectX code access security. |
2、引入
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
3、Direct3D Device
device class是所有Direct3D的根,我们可以把它想象为在机器上得真实图形设备,我们的PC上可能有0到多个devices。
一共有三个构造函数可以创建一个设备,我们先介绍第一个。
public Device ( System.Int32 adapter , Microsoft.DirectX.Direct3D.DeviceType deviceType ,
System.Windows.Forms.Control renderWindow , Microsoft.DirectX.Direct3D.CreateFlags
behaviorFlags, Microsoft.DirectX.Direct3D.PresentParameters presentationParameters )
我们介绍一下这些参数,adapter是指向我们可以操纵的物理设备,0通常是默认的设备。
DeviceType是说我们要创建什么类型的device,通常使用DeviceType.Hardware,就是用硬件设备,
有时候我们也用DeviceType.Reference,会很慢,一般用来测试和检测显卡是否支持DirectX版本。
renderWindow参数将设备绑定在一个窗口上,我们可以用form,panel或者其他control-derived class作为这个参数。
behaviorFlags是用来指定在创建设备以后用什么来控制这个设备的外貌,这个枚举有很多的选择,但他们有的是互斥的,不能选。
目前我们选择SoftwareVertexProcessing,这个选项指定所有的vertex processing用CPU来计算,比起用GPU这样自然会慢一点,
但安全起见,还是用这个选项,因为我们并不知道你的GPU是否可以完成这项任务,也许你的PC根本就没有GPU.
presentationParameters指定数据是如何被写到屏幕的,其中有一些属性“Windowed”他是一个Boolean,false表示用全屏
幕模式,true表示用窗口模式。SwapEffect用来控制缓冲区。
我们设计一个函数,以后的程序都可以用
private Device device = null;
public void InitializeGraphics()
{
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard
// 创建一个新的设备
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
}
上面写的代码并没有被调用,我们必须修改一下主函数,修改如下:
static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
我们修改以后,并没有发现和向导中创建的空windows form有什么变化,因为我们并没有做什么改动,
为了使其有变化,我们必须重写OnPaint函数,达到重绘窗口的目的
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);
device.Present();
}
我们用Clear方法填充窗口,第一个参数表示要填充的目标,用的是ClearFlags这个枚举值中的Target;
第二个参数是颜色值;第三个参数代表Z轴的buffer;第四个参数为stencil-buffer,可以设定为0。
(具体参数可查看DSDK). Present方法可以立即更新屏幕,这个方法有许多重载,以后介绍或可自己查帮助文件。
我们下面将绘制一个三角形,利用CustomVertex,D3D中有很多结构通用的"vertex format",
每个vertex可以表示一个点。现在我们用TransformedColored来绘制这个三角形,这个结构告诉D3D运行
时我们这个三角形不需要变换(旋转或移动)。我们把下面的代码插入到OnPaint override的方法中。
(注:不同版本的SDK提供的方法和属性有变动,请根据自己的sdk修改代码)
CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0].SetPosition(new Vector4(this.Width / 2.0f, 50.0f, 0.5f, 1.0f));
verts[0].Color = System.Drawing.Color.Aqua.ToArgb();
verts[1].SetPosition(new Vector4(this.Width - (this.Width / 5.0f), this.Height –
(this.Height / 5.0f), 0.5f, 1.0f));
verts[1].Color = System.Drawing.Color.Black.ToArgb();
verts[2].SetPosition(new Vector4(this.Width / 5.0f, this.Height - (this.Height / 5.0f)
, 0.5f, 1.0f));
verts[2].Color = System.Drawing.Color.Purple.ToArgb();
我们将创建三个Member,每个Member代表三角形的一个点,每个member用一个结构Vector4初始化
他的位置,另两个参数表示z位置和rhw。
结构定义好了,我们可以花三角形了
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
现在可以绘制了,为了在改变窗口大小的时候重绘窗口,我们用this.Invalidate();来使窗口重绘时
立即更新。而此函数必须搭配设置窗口类型的方法一起使用
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
整个源代码如下:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace Chapter1Code
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
}
/// <summary>
/// We will initialize our graphics device here
/// </summary>
public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
// Create our device
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);
CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0].Position=(new Vector4(this.Width / 2.0f, 50.0f, 0.5f, 1.0f));
verts[0].Color = System.Drawing.Color.Aqua.ToArgb();
verts[1].Position=(new Vector4(this.Width - (this.Width / 5.0f), this.Height - (this.Height / 5.0f), 0.5f, 1.0f));
verts[1].Color = System.Drawing.Color.Black.ToArgb();
verts[2].Position=(new Vector4(this.Width / 5.0f, this.Height - (this.Height / 5.0f), 0.5f, 1.0f));
verts[2].Color = System.Drawing.Color.Purple.ToArgb();
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
device.Present();
this.Invalidate();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
}
}