文档章节

【转贴】DXUT编程指南(四):通过DXUT使用设备

rise-worlds
 rise-worlds
发布于 2016/06/20 13:35
字数 2158
阅读 0
收藏 0

通过DXUT使用设备
DirectX设备的创建在DXUT中得到了改进。你可以让你的应用程序直接创建设备而其它有框架提供的特征仍然可用。
创建设备
选择最佳的设备设置
修改可用的设备设置
降为软件顶点处理
使用你自己的设备

创建设备
典型地,你将通过标准的Direct3D方法创建设备
HRESULT CreateDevice(
    UINT                  Adapter,
    D3DDEVTYPE            DeviceType,
    HWND                  hFocusWindow,
    DWORD                 BehaviorFlags,
    D3DPRESENT_PARAMETERS *pPresentationParameters,
    IDirect3DDevice9      **ppReturnedDeviceInterface
);
这个方法需要有效的适配器,设备类型(HAL or REF),窗口句柄,行为标志(software/hardware vertex processing 和其它驱动标志),以及呈现参数(presentation parameters).此外,D3DPRESENT_PARAMETER结构体还拥有大量的成员指定后备缓冲区,多重采样设定,交换效果,窗口模式,深度模版缓冲,刷新率,呈现间隔,以及呈现标志。
为所有这些参数选择有效的设定是具有挑战性的。框架通过DXUTCreateDevice函数简化了这一选择过程。
HRESULT DXUTCreateDevice(
    UINT AdapterOrdinal  = D3DADAPTER_DEFAULT,
    BOOL bWindowed       = TRUE,
    INT nSuggestedWidth  = 640,
    INT nSuggestedHeight = 480,
    LPDXUTCALLBACKISDEVICEACCEPTABLE pCallbackIsDeviceAcceptable     = NULL,
    LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings = NULL
);
最基本的用法是全部使用缺省参数调用:
DXUTCreateDevice();
通过这样的调用框架使用缺省设置创建一个在大多数情况下可用的设备。缺省的设置如下:

Direct3D Creation Flag Description Default Value from DXUTCreateDevice
AdapterFormat parameter of CheckDeviceFormat Adapter surface format. Desktop display mode, or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.
Adapter parameter of IDirect3D9::CreateDevice Display adapter ordinal. D3DADAPTER_DEFAULT
D3DPRESENT_PARAMETERS. BackBufferCount Number of back buffers. 2, indicating triple buffering.
D3DPRESENT_PARAMETERS. BackBufferFormat Back buffer format. Desktop display mode, or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.
D3DPRESENT_PARAMETERS. AutoDepthStencilFormat Depth format of the automatic depth-stencil surface that the device will create. D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.
The DeviceType parameter of IDirect3D9::CreateDevice Enumerated type of the device. D3DDEVTYPE_HAL if available, otherwise D3DDEVTYPE_REF or failure code if neither is available.
D3DPRESENT_PARAMETERS. MultiSampleQuality Quality level. MultiSampleQuality = 0, indicating multisampling is disabled.
D3DPRESENT_PARAMETERS. Flags Presentation parameters flags. D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
D3DPRESENT_PARAMETERS. PresentationInterval Presentation interval. D3DPRESENT_INTERVAL_IMMEDIATE for windowed mode, or D3DPRESENT_INTERVAL_DEFAULT for full-screen mode.
D3DPRESENT_PARAMETERS. FullScreen_RefreshRateInHz Rate at which the display adapter refreshes the screen. 0, indicating windowed mode.
D3DPRESENT_PARAMETERS. BackBufferWidth and .BackBufferHeight Display mode resolution. 640 x 480 pixels for windowed mode, or the desktop resolution for full-screen mode.
D3DPRESENT_PARAMETERS. AutoDepthStencilFormat Stencil format of the automatic depth-stencil surface that the device will create. D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.
D3DPRESENT_PARAMETERS. SwapEffect Swap effect. D3DSWAPEFFECT_DISCARD
BehaviorFlags parameter of IDirect3D9::CreateDevice Vertex processing flags. D3DCREATE_HARDWARE_VERTEXPROCESSING if supported, otherwise D3DCREATE_SOFTWARE_VERTEXPROCESSING.
D3DPRESENT_PARAMETERS. Windowed Windowed or full-screen mode. true, indicating windowed mode.
hFocusWindow parameter of CreateDevice Handle to the created window (see Using Application Windows with DXUT). hWndFocus parameter of DXUTSetWindow
D3DPRESENT_PARAMETERS. hDeviceWindow Handle to the device window. hWndDeviceFullScreen or hWndDeviceWindowed parameters of DXUTSetWindow
D3DPRESENT_PARAMETERS. EnableAutoDepthStencil Depth-stencil buffer creation flag. true.

应用程序可以通过参数传递给CreateDevice来更多的控制设备的创建,这将比使用缺省的方式更好。例如,你可以通过nSuggestedWidth and nSuggestedHeight参数改变窗口的尺寸。
DXUTCreateDevice(
    D3DADAPTER_DEFAULT,
    false,
    1024,
    786,
    NULL,
    NULL,
    NULL
);
要得到更多的控制权,应用程序可以使用这两个可选的回调函数,LPDXUTCALLBACKISDEVICEACCEPTABLE and LPDXUTCALLBACKMODIFYDEVICESETTINGS.

选择最佳的设备设置
你可以使用IsDeviceAcceptable回调函数帮助框架为你的应用程序选择最佳的设备设置,就像下面的代码:
bool CALLBACK IsDeviceAcceptable(
D3DCAPS9*     pCaps,
D3DFORMAT     AdapterFormat,
D3DFORMAT     BackBufferFormat,
bool          bWindowed,
void*         pUserContext )
{
    // TODO: return true for acceptable settings and false otherwise.
    return true;
}
这个回调函数的模型基于LPDXUTCALLBACKISDEVICEACCEPTABLE原型(This callback function is modeled on the prototype LPDXUTCALLBACKISDEVICEACCEPTABLE),框架为每个唯一的以下5个设置的有效组合调用这个函数一次:
D3DDEVTYPE DeviceType;
UINT       AdapterOrdinal;
D3DFORMAT  AdapterFormat;
D3DFORMAT  BackBufferFormat;
bool       Windowed;
注意适配器序号和设备类型没有直接的传入回调函数,而是分别作为D3DCAPS9结构体的成员。
通过这个回调函数,应用程序可以拒绝任何它不支持的或不想要的组合。例如,应用程序可以使用下面的代码拒绝16bits的后备缓冲区格式和所有至少不能支持像素着色器PS_2_0的设备:
bool CALLBACK IsDeviceAcceptable(
    D3DCAPS9*     pCaps,
    D3DFORMAT     AdapterFormat,
    D3DFORMAT     BackBufferFormat,
    bool          bWindowed )
{
    if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
     return false;
    if( BackBufferFormat == D3DFMT_X1R5G5B5 || BackBufferFormat == D3DFMT_R5G6B5 )
        return false;
    return true;
}

为每个唯一的组合调用回调函数后,框架排列剩下的可用组合,并选择它们当中最好的。排名较高的如下:
D3DDEVTYPE_HAL,获取硬件加速
如果应用程序以全屏模式显示,框架更趋向于使用匹配桌面格式的适配器格式,这样可以在全屏与窗口之间快速切换。例外的是,如果桌面显示模式小于32位,框架更趋向于D3DFMT_X8R8G8B8.
匹配适配器格式的后备缓冲区格式
在选择了这些排名高的组合后,要创建设备,行为标志和呈现参数仍然是需要的。对于这些设置,Direct3D使用上面表中的缺省值。

修改可用的设备设置
应用程序可以通过使用第二个可选的回调函数修改对框架可用的设置,这个函数是ModifyDeviceSettings:
bool CALLBACK ModifyDeviceSettings(
    DXUTDeviceSettings* pDeviceSettings,
    const D3DCAPS9*     pCaps )
{
    // TODO: Include device creation requirements here. 
    // 返回真创建设备返回False保持当前设置
    return true;
}
这个函数是基于原型LPDXUTCALLBACKMODIFYDEVICESETTINGS的。DXUTDeviceSettings结构体被框架定义为:
struct DXUTDeviceSettings
{
    UINT       AdapterOrdinal;
    D3DDEVTYPE DeviceType;
    D3DFORMAT  AdapterFormat;
    DWORD      BehaviorFlags;
    D3DPRESENT_PARAMETERS pp;
};

这个结构体包含了创建设备所需要的所有东西,除了窗口句柄,它被假定为先前创建的窗口的句柄。框架用有效的数据填充这个结构体,然后允许应用程序通过ModifyDeviceSettings回调函数改变设备创建的选择。
在这个回调函数中,应用程序可以在DXUTDeviceSettings结构体中改变行为标志以及呈现参数,乃至结构体中任何其它的东西。如果应用程序在回调函数中什么都不改变,设备会成功的创建。然而,对设备创建设置的任何改变都需要被设备支持,否则可能会导致设备创建失败。
比如,如果应用程序需要一个D3DFMT_D24S8的深度模板缓冲区格式,就必须验证设备是否支持,就像下面的代码:
bool CALLBACK ModifyDeviceSettings(
    DXUTDeviceSettings* pDeviceSettings,
    const D3DCAPS9*     pCaps )
{
    IDirect3D9* pD3D = DXUTGetD3DObject();
    if( SUCCEEDED( pD3D->CheckDeviceFormat(
         pDeviceSettings->AdapterOrdinal,
         pDeviceSettings->DeviceType,
         pDeviceSettings->AdapterFormat,
         D3DUSAGE_DEPTHSTENCIL,
         D3DRTYPE_SURFACE,
         D3DFMT_D24S8 ) ) )
    {
     if( SUCCEEDED( pD3D->CheckDepthStencilMatch(
             pDeviceSettings->AdapterOrdinal,
             pDeviceSettings->DeviceType,
             pDeviceSettings->AdapterFormat,
             pDeviceSettings->pp.BackBufferFormat,
             D3DFMT_D24S8 ) ) )
     {
         pDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D24S8;
     }
    }
   
    return true;
}

候选的方案是,回调函数可以使用框架的CD3DEnumeration 对象验证D3DFMT_D24S8是否被支持:
 bool CALLBACK ModifyDeviceSettings(
    DXUTDeviceSettings* pDeviceSettings,
    const D3DCAPS9*     pCaps )
{
    CD3DEnumeration *pEnum = DXUTGetEnumeration();
    CD3DEnumDeviceSettingsCombo *pCombo;
 
    pCombo = pEnum->GetDeviceSettingsCombo( pDeviceSettings );
 
    if( pCombo->depthStencilFormatList.Contains( D3DFMT_D24S8 ) )
        pDeviceSettings->pp.AutoDepthStencilFormat = D3DFMT_D24S8;
       
    return true;
}

应用程序修改了设备的设置后,框架就会用新的设置创建设备。
DirectX April 2005 SDK Update中的更新,ModifyDeviceSettings 回调函数返回了一个bool值。如果应用程序返回true框架继续正常的创建设备。如果返回false框架不改变设备并且保持当前的设备,如果已经有一个存在的话。这允许应用程序能够拒绝框架将设备改变到程序不能使用的请求。例如,在多监视器的缺省配置下,在监视器之间拖动窗口会导致框架改变设备。然而,如果应用程序不能使用其它的设备的话,它应当可以拒绝改变,并继续使用当前的设备。

回降到软件顶点处理
如果你设置一个Direct3D设备到支持像素处理却不支持顶点处理的硬件,你会因此需要改变行为标志。为了确保正确地降到软件顶点处理,谨防你不能拒绝一个基于IsDeviceAcceptable回调函数中顶点着色器版本的设备,并确保行为标志在ModifyDeviceSettings 回调函数中被正确调整。这儿有一个例子演示怎样做这些事情。
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings,
                                    const D3DCAPS9* pCaps )
{
    // If device doesn't support HW T&L or doesn't support 1.1 vertex
    // shaders in HW, then switch to SWVP.
    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
    {
        pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    else
    {
        pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    }
   
    return true;
}

使用你自己的设备
你没有必要依赖于框架来创建Direct3D设备。应用程序自己可以创建设备并将他传递给框架使用。就像应用程序可以覆盖框架的window creation 设置。简单的使用你想要的设置创建一个设备,然后调用 DXUTSetDevice函数让框架在你的设备上渲染。
注意:如果应用程序创建了不依赖于框架的设备,那么应用程序也必须在主循环执行完以后亲自的通过cleanup 释放设备接口。
另请参阅
通过DXUT作更高级的设备选择



李锦俊 2006-11-22 11:35 发表评论

本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/08/31/877256.html

rise-worlds

rise-worlds

粉丝 2
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
如何使用DXUT框架

DXUT是什么? DXUT即DirectX Utility Library,它是微软为DirectX Samples写的一个框架,有了这个框架,Sample的构建就方便多了,这个框架实际上抽取了构建Sample的公共代码,比如处理窗口消...

吞吞吐吐的
2017/10/12
0
0
DirectX11--HR宏关于dxerr库的替代方案

DirectX11 With Windows SDK完整目录 欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报。 综述 参考文章:https://blogs.msdn.microsoft.com/chuckw/2012/04/24/...

X_Jun
2018/12/24
0
0
DXUT

DXUT 是一个建立在 Direct3D 之上的一个层,简化 了 Windows 和 Direct3D 的 API。它能帮助开发者建立一个更健壮、更易于生成的示例,原型,工具或游戏,...

大胖森
2015/04/30
555
0
Direct3D学习(三):光影贴图

刚看完了DXUT,拿来练练手 这个框架却实方便啊,终于不用写那些令人恶心的API函数了 光影贴图,说白了就是在纹理上表现出来光影效果,并不是实时计算的,所以适用于固定的场影平面,如地面,...

长平狐
2012/11/12
72
0
云计算、大数据、编程语言学习指南下载,100+技术课程免费学!这份诚意满满的新年技术大礼包,你Get了吗?

近年来,新技术发展迅速。互联网行业持续高速增长,平均薪资水平持续提升,互联网技术学习已俨然成为学生、在职人员都感兴趣的“业余项目”。 阿里云大学作为阿里云泛云生态人才培养的平台,...

阿里云柳璃
02/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Python应用:python链表示例

前言 python链表应用源码示例,需要用到python os模块方法、函数和类的应用。 首先,先简单的来了解下什么是链表?链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是...

python小白1
27分钟前
1
0
Source Insight加载源码

Source Insight是一个图形化的源代码查看工具(当然也可以作为编译工具)。如果一个项目的源代码较多,此工具可以很方便地查找到源代码自建的依赖关系。 1.创建工程 下图为Snort源代码的文件...

天王盖地虎626
28分钟前
0
0
nginx-rtmp-module的缺陷分析(二)

nginx-rtmp-module使用指令push和pull来relay媒体流数据,以便分布式部署服务。 当nginx-rtmp-module作为边缘服务器(一般不会向边缘服务器推流)时,使用pull从源服务器获取媒体流数据,俗称...

YoungSagit
29分钟前
0
0
代理模式

保护代理和虚拟代理 虚拟代理 把开销大的操作等到需要执行创建的时候再去执行创建 var myImage = +function () { var imgNode = document.createElement('img'); docume......

莫西摩西
36分钟前
2
0
从国企到互联网,程序员六年四段工作经历,一份被很多 HR都 刷掉的简历!

程序员,六年,四段工作经历,这也许是一份会被很多 HR 刷掉的简历。 从学生时代至今,我经历了两次大的方向转型和一次大的技术转型: 从偏理论推导的数学科学到重工程实践的计算机学科,从「...

我最喜欢三大框架
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部