天行健 君子当自强而不息

DXUT框架剖析(8)

DXUT框架与错误处理

Direct3D API的设计使程序能比较容易地处理各种错误,尽管大多数Direct3D API函数返回HTRSULT值,但只有一部分函数返回设备错误,如D3DERR_DEVICELOST或D3DERR_DRIVERINTERNALERROR。但是通常的Direct3D应用程序使用多种API函数,当传递的参数不合要求时,将返回D3DERR_INVALIDCALL。

当开发Direct3D应用程序时,应该检查所有的API调用是否成功,如果出现一个没有预测到的失败调用,应用程序应立即给出通知或记录该错误。使用这种方法,开发人员能很快发现哪些API函数的调用是不正确的。一个正确调用Direct3D API函数的应用程序应能安全地忽略大多数Direct3D API函数的失败调用,除了一些关键性的API函数,如Present()或TestCooperativeLevel(),这些函数返回的错误应用程序不能忽略。

通过仅处理最重要的Direct3D错误,可以提高运行速度并使应用程序代码更健壮,因为代码中需要处理错误的地方并不多。对于为数不多的几个API函数的失败调用,必须予以适当处理。

框架中错误的处理对应Direct3D API中如何设计错误的处理,对于各种各样的错误,如丢失媒体(missing media),应用程序能通知用户并终止。对于每一帧都将调用的大多数API函数,错误仅在调试时向开发人员显示一个错误消息框来处理,而在发布时这些错误都被忽略了。框架用在DXUT.h中定义的几个宏来完成这一操作:

#if defined(DEBUG) || defined(_DEBUG)
#ifndef V
#define V(x) { hr = (x); if( FAILED(hr) ) { DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } }
#endif
#ifndef V_RETURN
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, true ); } }
#endif
#else
#ifndef V
#define V(x) { hr = (x); }
#endif
#ifndef V_RETURN
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return hr; } }
#endif
#endif

当使用vs.net时,如果想跳到出错代码所在的行,只需简单地双击调试输出窗口中输出的错误信息行即可。

 

选择最可行的设备

DXUT使用高度灵活的方法从枚举集合中选择最好的设备,这个设备枚举和分级系统可以通过调用函数DXUTFindValidDeviceSettings()独立于框架使用,该函数的声明如下:

Finds valid device settings to be used to create a new device.

HRESULT DXUTFindValidDeviceSettings(
DXUTDeviceSettings * pOut,
DXUTDeviceSettings * pIn,
DXUTMatchOptions * pMatchOptions
);

Parameters

pOut
[out] Pointer to a DXUTDeviceSettings structure that contains valid settings for the new device.
pIn
[in] Pointer to a DXUTDeviceSettings structure that contains desired settings for the new device. The default value is NULL.
pMatchOptions
[in] Pointer to a DXUTMatchOptions structure that contains flags describing how to use the device settings when choosing valid output device settings. Optimal device settings will be created based upon the match values in DXUTMatchOptions. If NULL, the function acts as if all members of this structure were DXUTMT_IGNORE_INPUT, meaning that the function will return valid device settings as close as possible to default device settings. See Remarks. The default value is NULL.

Return Values

If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes in DXUTERR.

Remarks

This function attempts to find valid device settings based upon the input device settings, given by pIn. For each device setting, a match option in the DXUTDeviceSettings structure specifies how the function makes decisions. The function works for both Direct3D 9 and Direct3D 10 device settings.

This function is internally by DXUT used when toggling between full screen and windowed modes, when selecting between HAL and REF device types, and inside DXUTCreateDevice.


DXUTMatchOptions

Describes match options for finding valid device settings using the DXUTFindValidDeviceSettings function. Each member of this structure corresponds to a setting described by the DXUTDeviceSettings structure.

Default values are used when a member is set to DXUTMT_IGNORE_INPUT. See Remarks.

typedef struct DXUTMatchOptions {
DXUT_MATCH_TYPE eAPIVersion;
DXUT_MATCH_TYPE eAdapterOrdinal;
DXUT_MATCH_TYPE eOutput;
DXUT_MATCH_TYPE eDeviceType;
DXUT_MATCH_TYPE eWindowed;
DXUT_MATCH_TYPE eAdapterFormat;
DXUT_MATCH_TYPE eVertexProcessing;
DXUT_MATCH_TYPE eResolution;
DXUT_MATCH_TYPE eBackBufferFormat;
DXUT_MATCH_TYPE eBackBufferCount;
DXUT_MATCH_TYPE eMultiSample;
DXUT_MATCH_TYPE eSwapEffect;
DXUT_MATCH_TYPE eDepthFormat;
DXUT_MATCH_TYPE eStencilFormat;
DXUT_MATCH_TYPE ePresentFlags;
DXUT_MATCH_TYPE eRefreshRate;
DXUT_MATCH_TYPE ePresentInterval;
} DXUTMatchOptions, *LPDXUTMatchOptions;

Members

eAPIVersion
Match type for the API version.
eAdapterOrdinal
Match type for the display adapter ordinal.
eOutput
Match type for the adapter output ordinal.
eDeviceType
Match type for the enumerated type of the device. If set to DXUTMT_IGNORE_INPUT, then the default value is D3DDEVTYPE_HAL.
eWindowed
Match type for the windowed or full-screen mode. if set to DXUTMT_IGNORE_INPUT, then the default value is windowed mode (TRUE).
eAdapterFormat
Match type for the adapter surface format. If set to DXUTMT_IGNORE_INPUT, then the default value is the desktop display mode, or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.
eVertexProcessing
Match type for the vertex processing flags D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, or D3DCREATE_SOFTWARE_VERTEXPROCESSING. if set to DXUTMT_IGNORE_INPUT, then the default value is D3DCREATE_HARDWARE_VERTEXPROCESSING.
eResolution
Match type for the display mode resolution. if set to DXUTMT_IGNORE_INPUT, then the default value is 640 x 480 pixels for windowed mode, or the desktop resolution for full-screen mode.
eBackBufferFormat
Match type for the back buffer format. if BackBufferFormat is set to DXUTMT_IGNORE_INPUT, then the default value is to match the adapter format.
eBackBufferCount
Match type for the number of back buffers. if BackBufferCount is set to DXUTMT_IGNORE_INPUT, then the default value is 2 for triple buffering.
eMultiSample
Match type for the quality level. if set to DXUTMT_IGNORE_INPUT, then the default value is to disable multisampling (MultiSampleQuality = 0).
eSwapEffect
Match type for the swap effect. if set to DXUTMT_IGNORE_INPUT, then the default value is D3DSWAPEFFECT_DISCARD.
eDepthFormat
Match type for the depth format of the automatic depth-stencil surface that the device will create. If both eDepthFormat and eStencilFormat are set to DXUTMT_IGNORE_INPUT, then the default value is D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.
eStencilFormat
Match type for the stencil format of the automatic depth-stencil surface that the device will create. if both eDepthFormat and eStencilFormat are set to DXUTMT_IGNORE_INPUT, then the default value is D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.
ePresentFlags
Match type for the presentation parameters flags. if set to DXUTMT_IGNORE_INPUT, then the default value is D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL.
eRefreshRate
Match type for the rate at which the display adapter refreshes the screen. If set to DXUTMT_IGNORE_INPUT, then the default value is 0, indicating windowed mode.
ePresentInterval
Match type for the presentation interval. if set to DXUTMT_IGNORE_INPUT, then the default value is D3DPRESENT_INTERVAL_IMMEDIATE for windowed mode, or D3DPRESENT_INTERVAL_DEFAULT for full-screen mode.

Remarks

For each member of this structure, match options are specified using the constant values of the DXUT_MATCH_TYPE enumeration, as in the following code example.

matchOptions.eResolution = DXUTMT_CLOSEST_TO_INPUT;

To use default device settings instead, use the DXUTMT_IGNORE_INPUT flag as follows:

matchOptions.eResolution = DXUTMT_IGNORE_INPUT;

DXUT_MATCH_TYPE

Describes how to match input device settings when creating a new device with a function.

typedef enum DXUT_MATCH_TYPE
{
DXUTMT_IGNORE_INPUT = 0,
DXUTMT_PRESERVE_INPUT,
DXUTMT_CLOSEST_TO_INPUT,
} DXUT_MATCH_TYPE, *LPDXUT_MATCH_TYPE;

Constants

DXUTMT_IGNORE_INPUT
Ignore the device setting input, and return a device setting as close as possible to a default device setting.
DXUTMT_PRESERVE_INPUT
Return without changing the device setting that was given as input to the function.
DXUTMT_CLOSEST_TO_INPUT
Return a device setting as close as possible to the device setting that was given as input to the function.

假设想要获取一个硬件抽象层设备,其后台缓冲区格式是D3DFMT_A2B10G10R10,如果系统中的硬件抽象层设备不支持这种后台缓冲区格式,但有一个安装好的参考设备支持,那么该函数可以使用该参考设备或根据硬件抽象层设备改变后台缓冲区格式,这都将通过枚举类型DXUT_MATCH_TYPE来控制如何采用设备格式。


posted on 2008-05-16 18:43 lovedday 阅读(1083) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论