技术开发 频道

Visual C#编写3D游戏框架示例

  

  查看这段代码的时候,你必须注意两个非常重要的信息。你能猜到是哪两个吗?如果你猜的是对DirectXException类的调用那就对了。第一个调用关闭了受控DirectX部件内部任何异常的产生。你可能会怀疑这样做的优点,实际上这样做是出于性能的考虑。捕捉和抛出异常是很昂贵的操作,而这段代码可能产生大量的异常。你可能希望尽快地执行列举过程,因此过程中产生的任何异常都被简单地忽略了,在这个函数执行完之后,就恢复正常的异常处理过程。这段代码看起来相当简洁,你可能会问"这段代码为什么倾向于产生异常呢"?
 
  我有一个很好的答案:大多数情形是某种设备不支持DirectX 9。也许你没有升级显卡驱动程序或当前的显卡驱动程序所需要的必要代码路径不正确;也可能是由于显卡本身太老了,没有能力支持DirectX 9;有时候一些人通过包含不支持DirectX 9的PCI显卡激活了系统中的多监视器模式。
 
  这个方法中的代码试图得到这个适配器的性能信息并列举出不同的组合方式,并且它试图获取每个可用的设备的这些信息。可能的设备类型包括:
 
  · 硬件(Hardware)--建立的最常见的设备类型。呈现过程由硬件(显卡)来完成。
  · 引用(Reference)--这种设备不管硬件是否能够执行处理过程,可以呈现Direct3D运行时支持的任何设置。所有的处理过程在软件中进行,这意味着在游戏中这种设备类型很慢。
  · 软件(Software)--除非你编写了光栅化程序(rasterizer),否则永远不会使用这个选项。
 
假设在列举过程中找到了某些设备组合,就把它存储到列表中。列举类存储了少量的列表,示例框架在以后可以使用它们。列表7是EnumerateDeviceCombos方法。

  列表7:列举设备组合

private static void EnumerateDeviceCombos(EnumAdapterInformation adapterInfo, EnumDeviceInformation deviceInfo, ArrayList adapterFormatList) {  // 查找这种设备支持哪种适配器格式  for each(Format adapterFormat in adapterFormatList)  {   for(int i = 0; i < backbufferFormatsArray.Length; i++)   {    bool windowed = false;    do    {     if ((!windowed) && (adapterInfo.displayModeList.Count == 0))      continue;     if (!Manager.CheckDeviceType((int)adapterInfo.AdapterOrdinal,         deviceInfo.DeviceType, adapterFormat,         backbufferFormatsArray[i], windowed))      continue; // 不支持的     // 我们需要加速象素阴影混合吗?     if (isPostPixelShaderBlendingRequired)     {       if (!Manager.CheckDeviceFormat(          (int)adapterInfo.AdapterOrdinal,          deviceInfo.DeviceType, adapterFormat,          Usage.QueryPostPixelShaderBlending,          ResourceType.Textures, backbufferFormatsArray[i]))        continue; // 不支持的     }     // 如果提供了某个应用程序回调函数,就要确保这个设备受到该应用程序的支持     if (deviceCreationInterface != null)     {      if (!deviceCreationInterface.IsDeviceAcceptable(deviceInfo.Caps,         adapterFormat, backbufferFormatsArray[i],windowed))       continue; // 应用程序不喜欢这个设备     }     EnumDeviceSettingsCombo deviceCombo = new EnumDeviceSettingsCombo();     // 存储信息     deviceCombo.AdapterOrdinal = adapterInfo.AdapterOrdinal;     deviceCombo.DeviceType = deviceInfo.DeviceType;     deviceCombo.AdapterFormat = adapterFormat;     deviceCombo.BackBufferFormat = backbufferFormatsArray[i];     deviceCombo.IsWindowed = windowed;     BuildDepthStencilFormatList(deviceCombo);     BuildMultiSampleTypeList(deviceCombo);     if (deviceCombo.multiSampleTypeList.Count == 0)     {      continue;     }     BuildConflictList(deviceCombo);     BuildPresentIntervalList(deviceInfo, deviceCombo);     deviceCombo.adapterInformation = adapterInfo;     deviceCombo.deviceInformation = deviceInfo;     // 把组合添加到设备列表中     deviceInfo.deviceSettingsList.Add(deviceCombo);     windowed = !windowed;    }    while (windowed);   }  } }
  
  总结
 
  在本文中,你开始建立了第一个游戏项目,并且看到了示例框架的一些内容。你看到了大量的列举系统中可能支持的设备组合的代码。这个示例框架是你在未来编写游戏的一个重要的出发点。
0
相关文章