⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3d游戏编程入门经典.txt

📁 3D游戏编程入门经典.教你三天回3D、、3D游戏编程入门经典
💻 TXT
📖 第 1 页 / 共 5 页
字号:
 adapterinfo.adapterinformation = ai.information; // information

 // get list of all display modes on this adapter.

 // also build a temporary list of all display adapter formats.

 adapterformatlist.clear();

 // now check to see which formats are supported

 for(int i = 0; i < allowedformats.length; i++)

 {

 // check each of the supported display modes for this format

 for each(displaymode dm in ai.supporteddisplaymodes [allowedformats[i]])

 {

 if ( (dm.width < minimumwidth) ||

 (dm.height < minimumheight) ||

  maximumwidth) ||

  maximumheight) ||

 (dm.refreshrate < minimumrefresh) ||

  maximumrefresh) ) 

 {

 continue; // this format isn’t valid

 }

 // add this to the list

 adapterinfo.displaymodelist.add(dm);

 // add this to the format list if it doesn’t already exist

 if (!adapterformatlist.contains(dm.format))

 {

 adapterformatlist.add(dm.format);

 }

 }

 }

 // get the adapter display mode

 displaymode currentadaptermode = ai.currentdisplaymode;

 // check to see if this format is in the list

 if (!adapterformatlist.contains(currentadaptermode.format))

 {

 adapterformatlist.add(currentadaptermode.format);

 }

 // sort the display mode list

 adapterinfo.displaymodelist.sort(sorter);

 // get information for each device with this adapter

 enumeratedevices(adapterinfo, adapterformatlist);

 // if there was at least one device on the adapter and it’s compatible,

 // add it to the list

  0)

 {

 adapterinformationlist.add(adapterinfo);

 }

 }

 manager类中的adapters属性是一个集合,包含了关于系统中每一个“适配器(adapter)”的信息。术语“适配器”稍微有些用词不当,但基本的定义是显示器能够连接的任何设备。例如,假设您有一个ati radeon 9800 xt图形卡。这里只有一个图形卡,但是可以将两个不同的显示器连接到它上面(分别通过视频图形适配器[vga]端口和后面的数字可视接口[dvi]端口连接)。连接两个显示器后,这个卡将具有两个适配器,即两个不同的设备。

 提示:

 通过将设备创建为一个适配器组,可以让单个卡在所有“不同”设备间共享资源。该方法具有几个限制。关于该主题的更多信息,请参考directx文档。

 该循环至少有一个迭代,具体依赖于您的系统。在存储了当前活动适配器的基本信息之后,代码需要找该适配器在全屏模式中支持的所有显示模式。您将注意到,可以直接利用当前正在枚举的适配器信息来枚举所支持的显示模式,这就是该段代码实际做的工作。

 当枚举一种显示模式时,首先检查它是否位于某个特定范围之中。大多数设备支持广泛的模式,但当前不会使用到其中很多种模式。多年以前,您可能看到过一些运行在320×200全屏窗口中的游戏,但在今天已经没有这样的游戏(除非您碰巧在玩一个手持机,例如gameboy advance)。样本框架所选择的默认最小尺寸是640×480的窗口,没有设置最大尺寸。

 警告:

 样本框架选择了640×480作为最小尺寸,但是这不意味着在全屏模式中样本框架将选择这一最小尺寸。对于全屏模式,框架选择最常用的尺寸,往往是桌面的当前尺寸(它很可能不是640×480)。

 在满足框架需求的支持模式添加到程序清单后,添加当前显示模式,因为该模式总是被支持的。最后,icomparer接口的一个实现对这些模式排序。如程序清单3.5所示。

 程序清单3.5  排序显示模式

 public class displaymodesorter : icomparer

 {

 ///  

 /// compare two display modes

 ///  

 public int compare(object x, object y)

 {

 displaymode d1 = (displaymode)x;

 displaymode d2 = (displaymode)y;

  d2.width)

 return +1;

 if (d1.width < d2.width)

 return -1;

  d2.height)

 return +1;

 if (d1.height < d2.height)

 return -1;

  d2.format)

 return +1;

 if (d1.format < d2.format)

 return -1;

  d2.refreshrate)

 return +1;

 if (d1.refreshrate < d2.refreshrate)

 return -1;

 // they must be the same, return 0

 return 0;

 }

 }

 icomparer接口允许对数组或者集合执行一个简单快速的排序算法。该接口提供的惟一方法是compare方法,该方法返回一个整型值:如果左边的项大于右边的项,则返回+1;如果左边的项小于右边的项,则返回–1;如果两个项相等,则返回0。在该实现中,显示模式的宽度具有最高优先级,然后是高度、格式和刷新率。当比较诸如1280×1024和1280×768这样的两种模式时,这种顺序保证了比较的正确性。

 模式排序后,调用enumeratedevices方法。您可以在程序清单3.6中看到该    方法。

 程序清单3.6  枚举设备类型

 private static void enumeratedevices(enumadapterinformation adapterinfo,

 arraylist adapterformatlist)

 {

 // ignore any exceptions while looking for these device types

 directxexception.ignoreexceptions();

 // enumerate each direct3d device type

 for(uint i = 0; i < devicetypearray.length; i++)

 {

 // create a new device information object

 enumdeviceinformation deviceinfo = new enumdeviceinformation();

 // store the type

 deviceinfo.devicetype = devicetypearray[i];

 // try to get the capabilities

 deviceinfo.caps = manager.getdevicecaps(

 (int)adapterinfo.adapterordinal, deviceinfo.devicetype);

 // get information about each device combination on this device

 enumeratedevicecombos(adapterinfo,deviceinfo, 

                  adapterformatlist);

 // do we have any device combinations?

  0)

 {

 // yes, add it

 adapterinfo.deviceinfolist.add(deviceinfo);

 }

 }

 // turn exception handling back on

 directxexception.enableexceptions();

 }

 在查看这段代码时,应当注意两点。您能够猜到它们是什么吗?如果您猜到是对directxexception类的调用,则您将赢得重奖。第一个调用关闭了managed directx程序集中异常的抛出。您可能希望知道这么做的目的,答案是性能的提高。捕获和抛出异常是非常昂贵的操作,该代码段具有大量抛出异常的项。您系望枚举代码能够快速地执行,因此所有发生的异常都被忽略。在该函数结束后,恢复标准的异常处理。这段代码看上去非常简短,因此您很可能会问:“为什么这段代码易于抛出异常?”

 我非常高兴您能够问这个问题,幸而,我恰好有一个好的答案。最常见的情形是设备不支持directx 9。或许您没有升级视频驱动,或许当前的视频驱动没有必要的代码路径。这可能是当前卡本身太老无法使用directx 9。很多时候,可以通过包含一个不支持directx 9的pci显卡,来允许系统的multimon功能。

 该方法中的代码尝试获得这个适配器的功能,并枚举它的各种组合,并且尝试获得每一种可利用的设备类型的信息。可能的设备类型如下:

 ●       硬件—— 最常见的设备类型。绘图由硬件(显卡)处理。

 ●       引用—— 不管是否存在具有处理能力的硬件都能够以direct3d运行库所支持的任意设置绘图的设备。所有的处理以软件形式完成,这意味着在游戏中这种设备类型非常慢。

 ●       软件—— 除非已经编写了一个软件rasterizer(如果是这样,您的能力已经超出了本书所教授的内容),您将不会使用该选项。

 假设在枚举期间发现某种设备设置的组合,则将它存储在一个列表中。枚举类存储的少量列表将在后面样本框架创建设备时被使用。如程序清单3.7所示的enumeratedevicecombos方法。

 程序清单3.7  枚举设备组合

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -