創建一個設備
通常可以用標準的Direct3D方法CreateDevice()創建一個Direct3D設備,這個方法需要一個有效的顯示適配器、設備類型(硬件抽象層設備或參考設備)、窗口句柄、運行標志(軟件/硬件頂點運算模式和其他驅動標志)和提交參數。更重要的是,結構體
D3DPRESENT_PARAMETERS有許多成員指定了后臺緩沖區的設置、多重采樣設置、交換效果、窗口模式、深度緩沖區設置、刷新頻率、提交間隔和提交標志等。
為所有的參數選擇合適的設置是比較繁瑣的,DXUT框架使用函數DXUTCreateDevice()簡化了Direct3D設備的創建,該函數的聲明如下:
Creates a Direct3D 9 or Direct3D 10 device.
HRESULT DXUTCreateDevice(
bool bWindowed ,
INT nSuggestedWidth ,
INT nSuggestedHeight
) ;
Parameters
- bWindowed
- [in] If TRUE, the application will start in
windowed mode; if FALSE, the application will start in full-screen mode. The
default value is TRUE.
- nSuggestedWidth
- [in] The requested initial width of the
application's back buffer. The actual width may be adjusted to fit device
and operating system constraints. The default value is 0.
- nSuggestedHeight
- [in] The requested initial height of the
application's back buffer. The actual height may be adjusted to fit device
and operating system constraints. The default value is 0. If both
nSuggestedWidth and nSuggestedHeight are zero, the dimension of the client
area of the window is used.
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 creates a new Direct3D 9 or Direct3D 10
device for the application. DXUT will pick the best device for the application
based upon what is availble on the system and which Direct3D API version(s) the
application supports. The API version(s) that the application supports is
detrimined by which device callbacks are set. This logic can be overridden by
calling DXUTSetD3DVersionSupport. If both Direct3D 9 and Direct3D 10 are
availble on the system and both are supported by the application, then DXUT will
favor Direct3D 10.
Alternately, the application can use the
DXUTCreateDeviceFromSettings or handle device creation and pass the desired
device to DXUT by using the DXUTSetD3D9Device or DXUTSetD3D10Device function. If
neither DXUTCreateDevice , DXUTCreateDeviceFromSettings ,
nor DXUTSetD3D9Device or DXUTSetD3D10Device
have been called before calling DXUTMainLoop, DXUT will automatically call
DXUTCreateDevice using the default parameter values.
The application can call this method after a device has
already been created to change the current device.
If a device is successfully found, the
LPDXUTCALLBACKMODIFYDEVICESETTINGS callback will be called to allow the
application to examine or change the device settings before the device is
created. This allows an application to modify the device creation settings as it
sees fit.
通過這個簡單的調用,DXUT框架創建了一個使用默認設置的Direct3D設備,它可以在大多數情況下使用,默認的設備創建設置如下表所示:
Direct3D創建標志 |
描述 |
DXUTCreateDevice的默認值 |
函數CheckDeviceFormat()的參數AdapterFormat |
適配器表面格式 |
當前桌面顯示模式,如果桌面顯示模式不足32位,則使用D3DFMT_X8R8G8B8 |
IDirect3D9::CreateDevice()的參數Adapter |
顯示適配器編號 |
D3DADAPTER_DEFAULT |
D3DPRESENT_PARAMETERS.BackBufferCount |
后臺緩沖區數目 |
2,表示有兩個后臺緩沖區,可實現3倍緩沖。 |
D3DPRESENT_PARAMETERS.BackBufferFormat |
后臺緩沖區格式 |
桌面顯示模式,如果桌面顯示模式不足32位,則使用D3DFMT_X8R8G8B8 |
D3DPRESENT_PARAMETERS.AutoDepthStencilFormat |
設備將自動創建的深度模板表面的深度格式 |
如果后臺緩沖區格式小于等于16位,則使用D3DFMT_D16,否則使用D3DFMT_D32。 |
IDirect3D9::CreateDevice()函數的參數DeviceType |
設備類型 |
若D3DDEVTYPE_HAL可行,則使用之,否則使用D3DDEVTYPE_REF,若二者均不可行,則創建失敗。 |
D3DPRESENT_PARAMETERS.MultiSampleQuality |
多重采樣數量 |
MultiSampleQuality = 0表示禁用多重采樣 |
D3DPRESENT_PARAMETERS.Flags |
提交參數標志 |
D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL |
D3DPRESENT_PARAMETERS.PresentationInterval |
提交間隔 |
窗口模式下為D3DPRESENT_INTERVAL_IMMEDIATE,全屏模式下為D3DPRESENT_INTERVAL_DEFAULT。 |
D3DPRESENT_PARAMETERS.FullScreen_RefreshRateInHz |
顯示適配器刷新屏幕的頻率 |
0,表示當前桌面設置的刷新頻率。 |
D3DPRESENT_PARAMETERS.BackBufferWidth和BackBufferHeight |
顯示器分辨率 |
在窗口模式下為640 x
480,全屏模式下為桌面分辨率。 |
D3DPRESENT_PARAMETERS.SwapEffect |
交換效果 |
D3DSWAPEFFECT_DISCARD |
IDirect3D9::CreateDevice()的參數BehaviorFlags |
頂點運算標志 |
如果硬件支持,就使用D3DCREATE_HARDWARE_VERTEXPROCESSING,否則使用D3DCREATE_SOFTWARE_VERTEXPROCESSING。 |
D3DPRESENT_PARAMETERS.Windowed |
窗口模式或全屏模式 |
TRUE,表示窗口模式 |
IDirect3D9::CreateDevice()的參數hFocusWindow |
創建窗口的句柄 |
DXUTSetWindow函數的參數hWndFocus |
D3DPRESENT_PARAMETERS.hDeviceWindow |
設備窗口的句柄 |
DXUTSetWindow的參數hWndDeviceFullScreen或hWndDeviceWindowed |
D3DPRESENT_PARAMETERS.EnableAutoDepthStencil |
深度模板緩沖區創建標志 |
TRUE,表示自動創建深度模板緩沖區 |
選擇最好的設備設置
在應用程序中,可以使用DXUTSetCallbackD3D9DeviceAcceptable設置回調函數IsDeviceAcceptable()幫助DXUT框架為應用程序選擇最好的設備,該函數的聲明如下:
Sets the Direct3D 9 device acceptable callback
function.
VOID DXUTSetCallbackD3D9DeviceAcceptable(
LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallback ,
void* pUserContext
) ;
Parameters
- pCallback
- [in] Pointer to a
LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE callback function. If the callback
function is supplied, it will be called after the Direct3D 9 device .
- pUserContext
- [in] Pointer to a user-defined value which is
passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the
callback function. The default value is NULL
Return Values
No return value.
Remarks
This function only needs to be called if the
application supports rendering with Direct3D 9 device.
The LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE
callback function is the appropriate location for the application to.
LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE
Application-defined callback function, called by DXUT
to build an enumerated list of all possible Direct3D 9 devices. DXUT then
selects the best device for creation among this list. This callback function
allows the application to prevent unwanted devices from being added to the list.
bool LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE(
D3DCAPS9* pCaps ,
D3DFORMAT AdapterFormat ,
D3DFORMAT BackBufferFormat ,
bool bWindowed ,
void* pUserContext
) ;
Parameters
- pCaps
- [in] Pointer to the D3DCAPS9 capabilities of the
Direct3D 9 device
- AdapterFormat
- [in] Format of the Direct3D 9 adapter
- BackBufferFormat
- [in] Format of the Direct3D 9 backbuffer
- bWindowed
- [in] Indicates windowed mode. TRUE if the
application runs windowed; FALSE if the application runs full-screen.
- pUserContext
- [in] Pointer to a user-defined value which is
passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the
callback function. The default value is NULL
Return Values
Program the application to return TRUE if the device
settings are acceptable. If not, the application should return FALSE.
Remarks
This function's parameters describe a set of unique
valid device settings that could be used to create a device. The application can
examine and reject this set if desired.
All possible unique valid combinations of the following
device settings are sent to this callback function:
- pCaps
- AdapterFormat
- BackBufferFormat
- bWindowed
After the application rejects the unwanted device
settings combinations, DXUT picks the best of the remaining combinations and
uses that best combination to create the device. Before creating the device,
DXUT calls LPDXUTCALLBACKMODIFYDEVICESETTINGS to allow the application to change
any of the device creation settings.
應用程序可以使用這個回調函數拒絕任何硬件不支持或不想要的組合。例如,應用程序可以使用下列代碼拒絕16位后臺緩沖區格式以及所有至少不支持像素渲染2.0版本的設備:
bool CALLBACK IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext)
{
if(pCaps->PixelShaderVersion < D3DPS_VERSION(2, 0))
return false;
if(BackBufferFormat == D3DFMT_X1R5G5B5 || BackBufferFormat == D3DFMT_R5G6B5)
return false;
return true;
}
在回調函數IsD3D9DeviceAcceptable()被每種設置的組合調用之后,框架把這些可以接受的組合分級,并從中選出最優的使用。較高級別的組合包括:
(1)D3DDEVTYPE_HAL,為了得到硬件加速。
(2)如果該應用程序運行在全屏模式下,該框架會選擇桌面格式所對應的適配器格式,這樣從窗口到全屏模式的轉換就快多了。例外的是,如果桌面顯示模式不足32位,該框架會選擇D3DFMT_X8R8G8B8。
(3)適配器格式所對應的后臺緩沖區格式。
示例程序中,選擇設備設置的核心代碼如下:
//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false.
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext)
{
// Typically want to skip back buffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3D9Object();
/*
HRESULT CheckDeviceFormat(
UINT Adapter,
D3DDEVTYPE DeviceType,
D3DFORMAT AdapterFormat,
DWORD Usage,
D3DRESOURCETYPE RType,
D3DFORMAT CheckFormat
);
/*/
if(FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat,
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat)))
{
return false;
}
return true;
}
IDirect3D9::CheckDeviceFormat
Determines whether a surface format is available as a
specified resource type and can be used as a texture, depth-stencil buffer, or
render target, or any combination of the three, on a device representing this
adapter.
HRESULT CheckDeviceFormat(
UINT Adapter ,
D3DDEVTYPE DeviceType ,
D3DFORMAT AdapterFormat ,
DWORD Usage ,
D3DRESOURCETYPE RType ,
D3DFORMAT CheckFormat
) ;
Parameters
- Adapter
- [in] Ordinal number denoting the display adapter
to query. D3DADAPTER_DEFAULT is always the primary display adapter. This
method returns D3DERR_INVALIDCALL when this value equals or exceeds the
number of display adapters in the system.
- DeviceType
- [in] Member of the D3DDEVTYPE enumerated type,
identifying the device type.
- AdapterFormat
- [in] Member of the D3DFORMAT enumerated type,
identifying the format of the display mode into which the adapter will be
placed.
- Usage
- [in] Requested usage options for the surface.
Usage options are any combination of D3DUSAGE and D3DUSAGE_QUERY constants
(only a subset of the D3DUSAGE constants are valid for
IDirect3D9::CheckDeviceFormat; see the table on the D3DUSAGE
page).
- RType
- [in] Resource type requested for use with the
queried format. Member of D3DRESOURCETYPE.
- CheckFormat
- [in] Format of the surfaces which may be used, as
defined by Usage. Member of D3DFORMAT .
Return Values
If the format is compatible with the specified device
for the requested usage, this method returns D3D_OK.
D3DERR_INVALIDCALL is returned if Adapter equals or
exceeds the number of display adapters in the system, or if DeviceType is
unsupported.
D3DERR_NOTAVAILABLE is returned if the format is not
acceptable to the device for this usage.
Remarks
Here are some examples using
IDirect3D9::CheckDeviceFormat to check for hardware support of:
- An off-screen plain surface format - Specify Usage
= 0 and RType = D3DRTYPE_SURFACE.
- A depth-stencil format - The following snippet
tests for the passed in depth-stencil format:
BOOL IsDepthFormatExisting( D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat )
{
HRESULT hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
AdapterFormat,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
DepthFormat);
return SUCCEEDED( hr );
}
See Selecting a Device (Direct3D 9) for more detail
on the enumeration process.
- Can this texture be rendered in a particular
format - Given the current display mode, this example shows how to verify
that the texture format is compatible with the specific back-buffer format:
BOOL IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat )
{
HRESULT hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
AdapterFormat,
0,
D3DRTYPE_TEXTURE,
TextureFormat);
return SUCCEEDED( hr );
}
- Alpha blending in a pixel shader - Set Usage to
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING . Expect this to
fail for all floating-point render targets.
- Autogeneration of mipmaps - Set Usage to
D3DUSAGE_AUTOGENMIPMAP . If the mipmap automatic generation fails,
the application will get a non-mipmapped texture. Calling this method is
considered a hint, so this method can return D3DOK_NOAUTOGEN (a valid
success code) if the only thing that fails is the mipmap generation. For
more information about mipmap generation, see Automatic Generation of
Mipmaps (Direct3D 9).
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING |
Query the
resource to verify support for post pixel shader blending support. If
IDirect3D9::CheckDeviceFormat fails with
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, post pixel blending operations
are not supported. These include alpha test, pixel fog, render-target
blending, color write enable, and dithering. |