翻译 managed DirectX9(第二章)

  作者:clayman
仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
Blog:http://blog.csdn.net/soilwork
[email protected]

第二章 选择正确的 Device
        如今,市场里有大量不同类型的显示卡,记住每种显卡所支持的特性几乎时不可能的。你应该询问 device ,让它告诉你它所支持的特性。我们接下来将讨论:
                   枚举系统里所有的适配器( adapter
                   枚举每一个 device 所支持的格式
                   确定所列举的设备功能
 
 
枚举系统里的适配器
      如今的大多数系统都支持多显示器。虽然这还不是主流配置,但多显示器确实很有用,并且变的越来越流行。在过去,这是高端图形卡专有的功能。但现在 ATI nVidia 以及 Matrox 都支持让多台显示器共享一块显卡的多头显示技术。
         Direct3D device 必须指定给每一个适配器。在这里,你可以把“适配器”理解为一块链接了特定显示器的显卡。比如 ATI Radeon 9700 的显卡只是一块物理适配器,但它有两个显示器接口( DVI VGA ),因此,在 Direct3D 里,它有两个适配器。也许你不知道选哪一个,甚至不确定有多少 device 在运行游戏的系统里,那么怎样来检测它们并且选择正确的一个呢?
         Direct3D 里,一个叫做 Manager 的静态类可以简单的完成以上任务:枚举适配器和 device 的信息;获得系统里 device 所支持特性的信息。
         Manager 类最重要的属性就是适配器的列表。在许多地方都会用到这个属性。它有一个“ count ”成员储存了系统里适配器的数量。因此,可以直接用索引访问适配器( e.g. Manager.Adapters[0] , 也可以枚举出系统里所有适配器。
         用一个简单的程序测试一下这个功能,它将以树状结构显示出系统里的适配器,以及他们所支持的显示模式:
1.   创建新的 C# Windows Formd 工程;
2.   添加 DirectX 组件;
3.   创建一个 TreeView 控件,并且占满整个窗口:把 Dock 属性设置为 fill
好了,现在该加入扫描每一个适配器,显示所支持的每一种显示模式的函数了:
Public void LoadGRaphics()
{
         foreach(AdapterInformation ai in Manager.Adapters)
         {
                   treeNode root = new TreeNOde(ai.Information.Description);
                   treeNode driverInfo = new TreeNode(string.Format(“Driver information:{0} – {1}”, ai.Information.DriverName, ai.Information.DriverVersion) );
                   root.Node.Add(driverInfo);
treeNode displayMode – new TreeNodeJ(string.Format(“Vurrent Display Mode:{0} × {1} × {2}”, ai.CurrentDisplayMode.Width, ai.CurrentDisplayMOde.Height, ai.CurrentDisplayuMode.Format) );
                   foreach(DisplayMode dm in ai.SupportedDisplayModes)
                   {
                            treeNode supportedNode = new TreeNode(string.Format(“Supported:{0} × {1} × {2}”, dm.Width, dm.Height, dm.Format) );
                            displayMode.Nodes.Add(supportedNode);
                   }
root.Nodes.Add(displayMode);
treeView1.Node.Add(root);
}
}
虽然代码看起来有一点点多,但它所做的事情实际上是非常简单的。你可以先分开来看看我们都作了些什么。首先,我们枚举系统里的适配器。 C# Foreach 迭代器使这个过程异常的简单。对每一个适配器来说,这个循环都只执行一次,并且用给定的适配器填充 AdapterInformation 结构。观察一下 AdapterInformation 结构,有以下几个成员
Public struct AdapterInformation
{
int adapter;
DisplayMode CurrentDisplayMode;
AdapterDetails Information;
AdapterDetails GetWhqlInformation();
DisplayModeEnumerator SupportedDisplayModes;
         }
这里 adapter 成员指创建 device 时的适配器序数。序数是一个基于 0 的索引,并且序数的个数等于系统里适配器的个数。两个返回 AdapterDetails 结构的成员都使用同一个方法返回同样的结果。对 Information 成员来说, Windows Hardware Quality Labs WHQL )并不返回细节,而 GetWhqlInformation 却可以。获得这些信息要花费一些代价及事件,所以我们把它分成了两部分。
AdapterDetails 结构保存了适配器的大量信息,包括对适配器自身的描述以及驱动信息。虽然这不是一定会用到的,但应用程序却能依次作出对硬件类型的判断。
剩下的两个成员返回 DisplayMode 结构。这些结构包含了大量的显示模式,包括显示的高度和宽度,刷新率以及使用的格式。 CurrentDisplayMode 返回当前的显示模式, SupportedDisplayModes 返回适配器所支持的模式的列表。
So ,我们用从 Information 属性获得的对 device 的描述作为 tree view 的根节点。然后加入了一个表示驱动程序名字以及版本号的子节点。同样也加入了一个显示当前显示模式的子节点,并且在这个子节点下列出了所有支持的显示模式。
运行程序,可以看到包含了所有支持模式的列表。填充 present parameter 结构时,这些模式都能当作正确的后备缓冲格式。每一个枚举出来的模式后面都有一个以固定模式显示的字符串( e.g X8R8G8B8 , 字母和数字交替出现。字母表示了数据的类型,数字表示这种类型的数据所占的位数。下边是常见的字母:
A ―― alpha        B ―― blue           X---unused          L----luminance    R----red     P----palette        G---green
(虽然有很多种格式,但只有几种能正确的用于后备缓冲以及显示模式。可用于后备缓冲的模式包括: A2R10G10B10, A1R5G5B5, A8R8G8B8, X1R5G5B5, X8R8G8B8, R5G5B5; Display formats can be the same as the back buffer formats, with the exception of those that contain an alpha component . The only format that can be used for a display weith alpha is A2R10G10B10 and even then that’s only in full-screen mode.
每种类型所占的位数加起来,就是这种格式的总大小。比如 X8R8G8B8 ,就是 32 位的格式,红、绿、蓝各 8 位,还有 8 位没有使用。
至今为止,我们获得了要创建的适配器序数,要支持的后备缓冲格式,那么关于 device 构造函数的其他参数呢?很幸运, Manager 类有我们所需的一切。
 
 
判断哪一个设备是可用的
manager 类有许多方法可以用来检测你的适配器是否支持一个特定的功能。比如,你需要检测适配器是否支持一种特殊的格式,但又不想枚举所有可能的适配器以及格式,那你就可以用 manager 类来解决这个问题。使用如下的方法:
pubic static System.Boolean CheckDeviceType(int adapter, DeviceType checkType, Format DisplayFormat, Format backBufferFormat, bool windowed, int result)
这个方法可以快速的检测出 device 是否支持你将要使用的格式。第一个参数是你要检测的适配器序数;第二个是要检测的 device 类型,但这个值大多数情况下都被设置为 DeviceType.Fardware 。接着指定将使用的后备缓冲类型和显示格式,以及是否需要全屏显示。最后一个参数是可选的,如果使用的话他将返回关于这个方法的一个整数(即 COM 中的 HRESULT )。如果这是一个有效的设备,则方法返回 true ,否则为 false 。当你预先知道要使用的格式使,这个方法是很有用的。
(应该注意到,在窗口模式,后备缓冲的格式不一定要匹配于显示格式,只要你的硬件支持适当的颜色转换就可以了。不论你的硬件是否支持这种功能, CheckDeviceType 方法都会返回适当的结果,应该使用 manager 类的 CheckDeviceFormatConversion 方法来判断是否支持这种转换。也可以在窗口模式下使用 Format.Unknown 。全屏模式下不需要这种转换。)
 
 
检测 Device 的功能( capabilities
我们把每一个 device 能完全用硬件实现的功能都叫做“ capability ”,或简称做“ Cap ”。 Direct3D 有一个 Caps 结构可以列出 device 所支持的每一种可能的 capabilities 。创建了 device 之后,就可以使用 device Caps 属性来检测他所支持的特性,但如果在创建设备之你就想知道 device 所支持的特性该怎么办呢?自然, Manager 类也有一个方法能完成这个任务。
现在,先前的程序里加一点点代码来获得系统里每一种适配器的 capabilities 。我们将不再使用 tree view 来显示这些 capabilities ,应为这可能包含了数百种 capabilities 。最好的方法是使用一个 text box 。回到 windows form 的设计模式,把 tree view Dock 属性改为“ Left ”,把宽度改为现在的一半;入 text box 控件,把 Dock 属性设置为“ Fill ”, Multiline 设置为 true Scrollbars 设置为“ both ”。
现在你可能想为程序添加一个钩子( hook ),这样在选择了一个适配器之后, textbox 里的数据也会更新。使用 tree view AfterSelect 事件,添加如下代码:
private void treeView_1AfterSelect(object sender, System.Windows.Forms.TreeViewEcentArgs e)
{
         if (e.Node.Parent == null)
         {      
                   textBox1.Text = e.Node.Text + “Capabilities: /r/n/r/n” + Manager.GetDeviceCaps(e.Node.Indes, DeviceType.Hardware).ToString().Replace(“/n”, “/r/n”);
         }
}

如你所见,相当简单。运行一下看看结果吧。
翻译 managed DirectX9(第二章)_第1张图片

你可能感兴趣的:(exception,windows,manager,tree,textbox,Direct3D)