请注意
示例框架选择的最小尺寸为640x480并不意味着在全屏模式下它就会选择最小的尺寸。在全屏模式下,示例框架选择最好的可用尺寸,它一般是当前桌面的大小(通常不是640x480的)。
在符合框架组件需求的受到支持的模式被添加到列表中后,当前的显示模式就会被添加进来,因为这个模式肯定受到支持。最后,通过实现icomparer接口,这些模式会被排序。见列表5。
列表5:对显示模式进行排序
public class displaymodesorter : icomparer
{
/// 比较两种显示模式
public int compare(object x, object y)
{
displaymode d1 = (displaymode)x;
displaymode d2 = (displaymode)y;
if (d1.width > d2.width)
return +1;
if (d1.width < d2.width)
return -1;
if (d1.height > d2.height)
return +1;
if (d1.height < d2.height)
return -1;
if (d1.format > d2.format)
return +1;
if (d1.format < d2.format)
return -1;
if (d1.refreshrate > d2.refreshrate)
return +1;
if (d1.refreshrate < d2.refreshrate)
return -1;
// 它们一定相同,所以返回0
return 0;
}
}
icomparer接口允许我们在数组或集合上执行简单的、快速排序算法。这个接口提供的唯一的方法是compare,它必须返回整型值--也就是如果左边的数据项大于右边的就返回+1,如果左边的数据项小于右边的就返回-1,如果相等就返回0。你可以看到,在上面的实现中,显示模式的宽度有最高的优先级,接着是高度、格式和刷新率。这个次序规定了在比较两种模式(例如1280x1024和1280x768)的时候正确的操作方法。
这些模式被排序之后,就调用enumeratedevices方法。列表6显示了这个方法。
列表6:列举设备类型
private static void enumeratedevices(enumadapterinformation adapterinfo,
arraylist adapterformatlist)
{
// 在查找设备类型的时候忽略任何异常
directxexception.ignoreexceptions();
// 列举每个direct3d设备类型
for(uint i = 0; i < devicetypearray.length; i++)
{
// 建立一个新设备信息对象
enumdeviceinformation deviceinfo = new enumdeviceinformation();
// 存储该类型
deviceinfo.devicetype = devicetypearray[i];
// 试图获取其性能
deviceinfo.caps = manager.getdevicecaps((int)adapterinfo.adapterordinal, deviceinfo.devicetype);
// 获取该设备上每个设备组合的信息
enumeratedevicecombos( adapterinfo, deviceinfo, adapterformatlist);
// 我们有设备组合吗?
if (deviceinfo.devicesettingslist.count > 0)
{
// 有,把它添加到列表中
adapterinfo.deviceinfolist.add(deviceinfo);
}
}
// 打开异常处理开关
directxexception.enableexceptions();
}
查看这段代码的时候,你必须注意两个非常重要的信息。你能猜到是哪两个吗?如果你猜的是对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);
}
}
}
总结
在本文中,你开始建立了第一个游戏项目,并且看到了示例框架的一些内容。你看到了大量的列举系统中可能支持的设备组合的代码。这个示例框架是你在未来编写游戏的一个重要的出发点。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器