您的位置:首页 > 其它

第一次亲密接触

2007-05-24 00:11 316 查看
2007-5-23 第一次亲密接触
这几天在网上看了一个系列文章的开头两章,按指示作出了一个hello world似的程序。
网址:(中文)

http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/gamedevelopmentbeginning.mspx?mfr=true

(英文) http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx 还是像以前看到的那样,利用 OnPaint 来实现游戏循环。并且通过代码确保 Windows 只使用 OnPaint 事件处理程序来

重画屏幕:
this.SetStyle ( ControlStyles.AllPaintingInWmPaint|ControlStyles.Opaque, true );
在第二篇中,终于接触到了DirectX,搞了十多天,终于有点起步了。
对于DirectX而言,将图形硬件(适配器 Adapter)抽象成设备(Device),这样程序就可以通过Device来操作,而不论实际

的显示设备是什么。DirectX 支持三种类型的设备:Hardware、References 和 Software。
对于游戏程序而言,需要在任何时候都有一个可用的设备,因此,在所有代码之前就应该准备好Device对象。而如下的

代码则实现该目标:


// Get the ordinal for the default adapter


int adapterOrdinal = Manager.Adapters.Default.Adapter;


// Get our device capabilities so we can check them to set up the CreateFlags


Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);


CreateFlags createFlags;


// Check the capabilities of the graphcis card is capable of


// performing the vertex-processing operations


// The HardwareVertexProcessing choice is the best


if (caps.DeviceCaps.SupportsHardwareTransformAndLight)




...{


createFlags = CreateFlags.HardwareVertexProcessing;


}


else




...{


createFlags = CreateFlags.SoftwareVertexProcessing;


}


// If the graphics card supports vertex processing check if the device can


// do rasterization, matrix transformations, and lighting and shading operations


// This combination provides the fastest game experience


if (caps.DeviceCaps.SupportsPureDevice && createFlags == CreateFlags.HardwareVertexProcessing)




...{


createFlags |= CreateFlags.PureDevice;


}


// Set up the PresentParameters which determine how the device behaves


PresentParameters presentParams = new PresentParameters();


presentParams.SwapEffect = SwapEffect.Discard;


// Make sure we are in windowed mode when we are debugging


#if DEBUG


presentParams.Windowed = true;


#endif


// Now create the device


device = new Device(adapterOrdinal, DeviceType.Hardware, this, createFlags, presentParams);



如同注释所述,该代码分成四部分。
1. 第一行代码只是获取默认适配器的名称(通常为 0)。与赌它为零不同,更安全的做法是使用 Manager 类来获取默

认适配器的名称。如果由于某种原因使得默认适配器的实际名称为 2,则采用这种方法不会出现问题。

2. 接下来的一节代码用于确定传递给 Device 构造函数的 CreateFlags 枚举的设置,以及哪个设置控制设备创建后的

行为。我们再次使用 Manager 来获取默认适配器的功能(简称为 Caps)列表。然后使用此功能列表来确定是在硬件中执行

顶点处理(较快),还是在软件中执行(较慢,但保证始终工作)。这其实用词不当,因为 SoftwareVertexProcessing 实

际指使用 CPU 而 HardwareVertexProcessing 指使用 GPU。然后执行另一个检查,查看适配器是否支持纯设备,即图形卡可

以处理光栅化、矩阵转换以及打光和阴影计算。如果设备可以,而且前一个检查确定我们可以使用硬件顶点处理,则将

PureDevice 设置添加到 CreateFlags 枚举中。HardwareVertexProcessing 和 PureDevice 的组合为我们提供可能的最佳性

能,所以如果可能,要尽量使用它。

3. 创建设备需要的最后一个参数是 PresentParameters 对象。这个对象确定设备向屏幕显示数据的方式,因此得名。

首先我们设置 SwapEffect 枚举,它确定缓冲和设备如何相互联系。我们通过选择 Discard 选项来简单地选择放弃后台缓冲

区,直接写入到前台缓冲区。在 If 语句中,我们确定应用程序是否在调试模式下运行。如果处于调试模式,我们不希望在

全屏模式下运行(这是默认情况),因为它使调试非常困难。使用这种方法确定配置好于对其硬编码而在发布游戏时忘了切

换回来。

4. 最后一步是真正创建设备。我们传入默认适配器的序号、想要将设备绑定到的窗口、设备类型,然后传入前面创建的

CreateFlags 和 PresentParameters 对象。

这段代码的实际结果就是使我们拥有一个有效的设备,可以用它在屏幕上进行绘制。
OK,终于可以在程序中使用DirectX了,总算有点兴奋的感觉了。

最后完成的代码如下:


using System;


using System.Collections.Generic;


using System.ComponentModel;


using System.Data;


using System.Drawing;


using System.Text;


using System.Windows.Forms;


using Microsoft.Samples.DirectX.UtilityToolkit;


using Microsoft.DirectX;


using Microsoft.DirectX.Direct3D;




namespace BattleTank2005




...{


public class GameEngine : Form




...{


private double deltaTime;


private Device device;




private const DeviceType _deviceType = DeviceType.Reference;






/**//// <summary>


/// Required designer variable.


/// </summary>


private System.ComponentModel.IContainer components = null;






/**//// <summary>


/// Clean up any resources being used.


/// </summary>


/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>


protected override void Dispose(bool disposing)




...{


if (disposing && (components != null))




...{


components.Dispose();


}


base.Dispose(disposing);


}






Windows Form Designer generated code#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.SuspendLayout();


//


// GameEngine


//


this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);


this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;


this.ClientSize = new System.Drawing.Size(292, 266);


this.Name = "GameEngine";


this.Text = "GameEngine";


this.ResumeLayout(false);




}




#endregion




public GameEngine()




...{


InitializeComponent();


this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);




// Get the ordinal for the default adapter


int adapterOrdinal = Manager.Adapters.Default.Adapter;




// Get our device capabilities so we can check them to set up the CreateFlags


Caps caps = Manager.GetDeviceCaps(adapterOrdinal, _deviceType);


CreateFlags createFlags;


// Check the capabilities of the graphcis card is capable of


// performing the vertex-processing operations


// The HardwareVertexProcessing choice is the best


if (caps.DeviceCaps.SupportsHardwareTransformAndLight)




...{


createFlags = CreateFlags.HardwareVertexProcessing;


}


else




...{


createFlags = CreateFlags.SoftwareVertexProcessing;


}


// If the graphics card supports vertex processing check if the device can


// do rasterization, matrix transformations, and lighting and shading operations


// This combination provides the fastest game experience


if (caps.DeviceCaps.SupportsPureDevice && createFlags == CreateFlags.HardwareVertexProcessing)




...{


createFlags |= CreateFlags.PureDevice;


}


// Set up the PresentParameters which determine how the device behaves


PresentParameters presentParams = new PresentParameters();


presentParams.SwapEffect = SwapEffect.Discard;


// Make sure we are in windowed mode when we are debugging


#if DEBUG


presentParams.Windowed = true;


#endif


// Now create the device


device = new Device(


adapterOrdinal,


_deviceType,


this,


createFlags,


presentParams


);






}




protected override void OnPaint(PaintEventArgs e)




...{


deltaTime = FrameworkTimer.GetElapsedTime();


this.Text = string.Format("The framerate is {0}", FrameRate.CalculateFrameRate());






FrameworkTimer.Start();


device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0); device.Present();


this.Invalidate();


}


}




public class FrameRate




...{


public static int CalculateFrameRate()




...{


if (System.Environment.TickCount - lastTick >= 1000)




...{


lastFrameRate = frameRate;


frameRate = 0;


lastTick = System.Environment.TickCount;


}


frameRate++;


return lastFrameRate;


}


private static int lastTick;


private static int lastFrameRate;


private static int frameRate;






}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: