深入Managed DirectX9(四)

转载 2006年05月23日 23:27:00

深入Managed DirectX9(四)

 
 

选择正确的Device
  The number of possible permutations when cretion a device is quite staggering. 如今,市场里有大量不同类型的显示卡,记住每种显卡所支持的特性几乎时不可能的。你应该询问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”);
    }
}
如你所见,相当简单。运行一下看看结果吧。


NVMain运行机制深入了解之七

NVM 时序模型 在DRAM主存系统中,假设一个完整的读周期或者写周期的行为是近乎相同的。由于DRAM使用电容充电原理,从DRAM阵列读数据造成电容中数据损坏,所以对于一个简单的读周期,数据必须被r...
  • zgl07
  • zgl07
  • 2014年12月11日 16:19
  • 1285

[Java]深入理解Java Class文件格式(四)

前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, 介绍了常量池中的两种类型的数据项, 分别是 CONSTANT_Utf8_infoCONSTANT_Nam...
  • szwangdf
  • szwangdf
  • 2014年05月12日 14:20
  • 1473

Directx9.0编程学习笔记二(Direcx接口的初始化)

在代码中加入以下两条预处理语句: #include "d3dx9.h" //Driect9.0的头文件 #pragma comment(lib,"d3d9.lib") 初始化DirectX首先要声明以...
  • lishunihaoa
  • lishunihaoa
  • 2016年06月09日 00:40
  • 146

深入理解Git (四) -微命令下篇

6 git commit-tree  这个命令可以用来生成commit对象,commit对象是tree对象的扩展,除了指引tree对象外,还有一些额外的信息,比如此次commit的info,谁comm...
  • hongchangfirst
  • hongchangfirst
  • 2015年08月12日 15:11
  • 1199

Directx9.0 学习教程5 光照

光照   1.      首先需要定义这样的顶点结构   struct CUSTOMVERTEX { D3DXVECTOR3position; // 顶点 D3DXVECTOR...
  • cq361106306
  • cq361106306
  • 2014年09月29日 18:45
  • 2156

DirectX9 10 11对比区别摘抄整理

dx8使得可编程的硬件进入管线成为了双重构造。对于DirectX 9的顶点处理与像素处理,则被真正的可编程处理器调换。而在向DirectX 10的转移为了实现更灵活的可编程性,需要GPU架构进行根本的...
  • skyell
  • skyell
  • 2015年03月08日 11:53
  • 1499

SpringMVC结合Mybatis事务失效的问题

这几天一直在写自己的代码,碰到了事务
  • ckao7470
  • ckao7470
  • 2014年06月29日 00:38
  • 3797

Spark修炼之道(高级篇)——Spark源码阅读:第八节 Task执行

Task执行在上一节中,我们提到在Driver端CoarseGrainedSchedulerBackend中的launchTasks方法向Worker节点中的Executor发送启动任务命令,该命令的...
  • lovehuangjiaju
  • lovehuangjiaju
  • 2015年10月29日 12:00
  • 4641

《深入理解计算机系统》1-4章总结

经过1个月断断续续的学习,已学习完《深入理解计算机系统》第四章,不得不说这本书确实无愧经典之名,能带给自己更深层次对编程的理解,现总结下现阶段的学习与体会: 第一章主要为后面个章节做了铺垫,其...
  • steinliber
  • steinliber
  • 2015年07月25日 09:51
  • 685

Directx9.0 学习教程3 -图形学之创建点 线 三角形 等

1、首先 介绍点的表示方法 struct CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0....
  • cq361106306
  • cq361106306
  • 2014年09月28日 15:29
  • 1544
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入Managed DirectX9(四)
举报原因:
原因补充:

(最多只允许输入30个字)