时间过的真快,学习Direct3D也有一段时间了,顺便也把学习的过程记录下来.先看看怎么创建一个空的Direct3D应用程序吧.
在这里先介绍一下什么是Direct3D?Microsoft Direct3D是Microsoft DirectX交互媒体技术的实时三维(3-D)图形组件,Direct3D以及其它的DirectX技术意图给程序员们同时提供两个最好的环境一个底层的,高性能的接口,它同硬件相结合,具有同设备无关的灵活性。对于Direct3D,程序员可以将3D图形功能揉合在Windows程序中,以充分利用其始终存在的硬件加速性能,同时,程序员们并不需要针对特定的硬件编写特殊的代码.
我们来了解一下托管DirectX常用的命名空间:
Microsoft.DirectX:父名字空间,包含了所有公共代码
Microsoft.DirectX.Direct3D: Direct3D图形API和D3DX帮助类(Helper Library)
那么就让我们开始用C#写DirectX程序吧。但是在开始编写之前,有些事情你应该知道:
首先,你需要一个代码编辑器和运行环境。我们在这里推荐:M$ Visual studio2005作为开发环境,功能很强大,第二: 我们需要下载并安装相应版本的DirectX SDK,这个可以从Microsoft的官方站点上免费获得,最新的DirectX SDK (April 2007)大约是441MB.
下载的相关页面http://msdn.microsoft.com/directx。下载了相应的SDK后,我们就可以开始利用它进行DirectX开发了。至于怎么装M$ Visual studio2005 和 DirectX SDK,就不用我在这里罗嗦了吧?
详细步骤如下:
1:打开M$ Visual studio2005, 建立一个c#应用程序项目
2:点 项目--〉添加引用-〉把Microsoft.DirectX, Microsoft.DirectX.Driect3D, Microsoft.DirectX.Direct3DX 3个.dll文件添加到工程中.
3 在工程的Form1.cs中最开始添加代码,引入如下命名空间:
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;
在项目解决方案中删除program.cs文件,在Form1.cs中添加如下代码:
public Form1()
{
InitializeComponent();
this.ClientSize = new Size(800, 600); //设置窗口大小
this.Text = "Direct3D Tutorial----MyDirect3DApplication";//设置窗口的标题
}
private void OnResetDevice( object sender, EventArgs e)
{
//渲染对象初始化
}
/// <summary>Initializes DirectX graphics</summary>
/// <returns>true on success, false on failure</returns>
private bool InitializeGraphics()
{
// 设置设备的各种常用参数
PresentParameters presentParameters = new PresentParameters();
presentParameters.SwapEffect = SwapEffect.Discard;
presentParameters.Windowed = true;
presentParameters.EnableAutoDepthStencil = true;
presentParameters.AutoDepthStencilFormat = DepthFormat.D16;
try
{
device = new Device(0, DeviceType.Hardware, this.Handle, CreateFlags.SoftwareVertexProcessing, presentParameters);
device.DeviceReset += new System.EventHandler(this.OnResetDevice);
this.OnResetDevice(device, null);
return true;
}
catch (DirectXException)
{
return false;
}
}
/// <summary>程序的核心部分----渲染</summary>
private void Render()
{
if (device == null)
{
return;
}
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1.0f, 0);
device.BeginScene();
//此处添加你要渲染的对象
device.EndScene();
device.Present();
}
/// <summary>Application idle event. renders frames.</summary>
/// <param name="sender">Sending object</param>
/// <param name="e">Event arguments</param>
public void OnApplicationIdle( object sender, EventArgs args)
{
while (AppStillIdle)
{
Render();
}
}
// 检测程序是否处于空闲
private bool AppStillIdle
{
get
{
NativeMethods.Message msg;
return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}
/// <summary>
/// The main entry point for the application.
/// 应用程序的主入口点
/// </summary>
[STAThread]
static void Main()
{
using (Form1 form = new Form1())
{
if (!form.InitializeGraphics())
{
MessageBox.Show("很抱歉,不能初始化3D设备!");
form.Dispose();
return;
}
Application.Idle += new EventHandler(form.OnApplicationIdle);
Application.Run(form);
}
}
/// <summary>Native methods</summary>
public class NativeMethods
{
/// <summary>Windows Message</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
public IntPtr hWnd;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
}
保存,运行,你会看到一个蓝色的窗口,那就是我们创建的Direct3D程序了,怎么样?不是很难吧?
看了上面的代码,感觉是否有很多地方还不是很明白?那好,我们再来仔细分析这个程序的流程.
首先,我们知道,程序运行需要一个main()函数,通常main()函数是位于program.cs文件中的,现在我们要改写了它,把它移到Form1.cs中, 那它到底做了些什么事情呢?我们知道,它生成了一个Form1对象,然后调用form的InitializeGraphics()方法判断图形初始化是否成功,其实InitializeGraphics()方法的主要功能就是根据一些设定的设备参数以及根据当前机器的硬件性能来生成一个设备对象device,同时调用OnResetDevice(),OnResetDevice()的主要作用是对要渲染的对象进行初始化,当然,在这个InitializeGraphics()里,我们没有做详细的硬件检测,假想它的机器还不是那么可怜.然后main()函数调用了应用程序的Idle事件,表示在应用程序完成处理即将进入空闲状态时调用Render()方法,进行渲染,那我们再来看Render()做了什么:
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1.0f, 0);
作用是:清除当前屏幕的对象和Z缓冲,并将屏幕的背景颜色设置为蓝色
device.BeginScene();//我要开始绘图了啊
device.EndScene();//我绘图结束了
device.Present();//作用是:将所绘制的对象显示在屏幕上
好了,现在大家该明白流程了:main()->初始化图形设备->对需要渲染的对象进行初始化->进行渲染
到目前为止,整个框架就建好了.剩下的就是如何在//.......处添加你要渲染的对象了,下次我们将重点讨论device.