自批:读者注意,以下都是肤浅之谈,诚不足作为参考。
今天查了一下Managed DirectX 9.0的情况。据我所知现在有三种DirectX开发方式:C-C++/COM Raw-Interface、VB/COM Component、.Net/Managed DirectX;其中当然是使用COM的原始接口方式最快,其实目前我并不看好Managed DirectX,总体感觉其接口目前还处于不稳定状态,简直就是一片一片的subject to change/deprecated--! 使用这种方式的商业游戏也几乎没有,而且托管方式又为程序的加速增加了一层额外的burden,尤其是在现在普遍对托管方式执行效率不是那么了解的环境下,但是我还是很好奇号称未来DirectX开发潮流的Managed DirectX究竟能有多快,至少应该要比GDI+快吧,至少应该要比Flash快吧,汗.... 小试了一把2D的,M$现在推荐大家使用Direct3D里面的2D渲染接口,也就是Texture + Sprite + Direct3DDevice方式,M$到底是M$,果然有够激进的: ) 而传统的DirectDraw接口在DX7.0之后已经开始被M$亮黄牌了——has been deprecated,9.0c SDK里面的资料已严重不全,但还是有Managed的接口支持,下面是个Managed DirectDraw的简明实例,C#写的,保证稳定: ) 需要Managed DirectX的Assembly。至于使用感受么...hmmm....原有的DDraw有的缺点Managed DDraw都有,对错误流程控制要求高、消息循环交互性要求高、多任务友好程度需要额外注意(100% CPU占有率)、需要进行Surface Lost控制.....中个痛苦,试试便知: ) 据说Direct3D里这些方面都是由DX自动管理的,不知效果如何,过两天我再写个Direct3D方式的2D实例。
BTW,罗嗦一句,经试验发现,Managed DirectX 9里面的GraphicsStream类数据操作效率不要太高,显然是经过刻意优化的,像我这种又喜欢直接改写显存又懒的人总算找到救命稻草了,哈哈
#define FULLSCREEN
![](/Images/OutliningIndicators/None.gif)
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
![](/Images/OutliningIndicators/None.gif)
using Microsoft.DirectX.DirectDraw;
![](/Images/OutliningIndicators/None.gif)
namespace MDDraw
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public class AppForm : System.Windows.Forms.Form
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
乱七八糟#region 乱七八糟
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if( disposing )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (components != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//
// AppForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "AppForm";
this.Text = "Managed DirectDraw";
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.AppForm_KeyPress);
![](/Images/OutliningIndicators/InBlock.gif)
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
public AppForm()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// Windows 窗体设计器支持所必需的
InitializeComponent();
![](/Images/OutliningIndicators/InBlock.gif)
#if FULLSCREEN
FormBorderStyle = FormBorderStyle.None;
#else
FormBorderStyle = FormBorderStyle.Sizable;
#endif
![](/Images/OutliningIndicators/InBlock.gif)
InitDirectDraw();
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//////////////////////////////////////////////////////////////////////////////////////////////////
private Device display;
private Surface front = null;
private Surface back = null;
private Surface title = null;
private Clipper clip = null;
string titlescreen = "../../02.bmp";
![](/Images/OutliningIndicators/InBlock.gif)
private void InitDirectDraw()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
初始化DirectDrawDevice#region 初始化DirectDrawDevice
SurfaceDescription description = new SurfaceDescription();
display = new Device();
![](/Images/OutliningIndicators/InBlock.gif)
#if FULLSCREEN
display.SetCooperativeLevel(this, CooperativeLevelFlags.FullscreenExclusive);
display.SetDisplayMode(1024, 768, 32, 0, false);
#else
display.SetCooperativeLevel(this, CooperativeLevelFlags.Normal);
#endif
#endregion
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
初始化Primary Surface#region 初始化Primary Surface
description.SurfaceCaps.PrimarySurface = true;
#if FULLSCREEN
description.SurfaceCaps.Flip = true;
description.SurfaceCaps.Complex = true;
description.BackBufferCount = 1;
![](/Images/OutliningIndicators/InBlock.gif)
front = new Surface(description, display);
#else
front = new Surface(description, display);
#endif
#endregion
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
初始化Backup Surface#region 初始化Backup Surface
description.Clear();
#if FULLSCREEN
SurfaceCaps caps = new SurfaceCaps();
caps.BackBuffer = true;
![](/Images/OutliningIndicators/InBlock.gif)
back = front.GetAttachedSurface(caps);
#else
description.Width = front.SurfaceDescription.Width;
description.Height = front.SurfaceDescription.Height;
description.SurfaceCaps.OffScreenPlain = true;
![](/Images/OutliningIndicators/InBlock.gif)
back = new Surface(description, display);
#endif
#endregion
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
初始化裁剪器#region 初始化裁剪器
clip = new Clipper(display);
clip.Window = this;
#if FULLSCREEN
#else
front.Clipper = clip;
back.Clipper=clip;
#endif
#endregion
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
初始化Off-Screen Surface#region 初始化Off-Screen Surface
description.Clear();
title = new Surface(titlescreen, description, display);
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Draw()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (front == null || this.WindowState == FormWindowState.Minimized)
return;
if (!display.TestCooperativeLevel())
return; //非常关键! 没有这句话必Crash!
![](/Images/OutliningIndicators/InBlock.gif)
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
绘制或者切换Primary Surface#region 绘制或者切换Primary Surface
#if FULLSCREEN
back.Draw(new Rectangle(0,0,1024,768),title,new Rectangle(0,0,1024,768),DrawFlags.Wait);
back.DrawText(0, 0, "Press ENTER or ESC to exit.", false);
#else
Point p=this.PointToScreen(new Point(0,0));
int srcw=Width>1024?1024:Width;
int srch=Height>1024?1024:Height;
back.Draw(new Rectangle(p.X,p.Y,this.Width,this.Height),title,new Rectangle(0,0,srcw,srch),DrawFlags.Wait);
back.DrawText(p.X, p.Y, "Press ENTER or ESC to exit.", false);
#endif
#if FULLSCREEN
front.Flip(back, FlipFlags.Wait);
#else
front.Draw(back, DrawFlags.Wait);
#endif
#endregion
}
catch(WasStillDrawingException)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
catch(CannotCreateDeviceContextException)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
catch(SurfaceLostException)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RestoreSurfaces();
}
catch(Exception e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Close();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private void RestoreSurfaces()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
display.RestoreAllSurfaces();
SurfaceDescription description = new SurfaceDescription();
title.Dispose();
title = null;
title = new Surface(titlescreen,description, display);
}
catch (WrongModeException e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
catch (UnsupportedModeException e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
catch (Exception e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Close();
}
return;
}
![](/Images/OutliningIndicators/InBlock.gif)
private void AppForm_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (e.KeyChar==(char)13 || e.KeyChar==(char)27)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.Close();
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class App
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
[STAThread]
static void Main()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
AppForm frm=new AppForm();
frm.Show();
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
消息循环#region 消息循环
while(frm.Created)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Thread.Sleep(1000/60); //近似60fps即可,防止CPU 100%占用
frm.Draw();
//分派完当前消息队列中所有的消息方退出,避免某些窗口中间状态
Application.DoEvents();
}
#endregion
}
}
}