首页 > 代码库 > DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx

    我本意是记录下学习笔记,但可能写成了翻译,但这也没有办法的事,MSDN的写作风格就是简单凝练,缺少参考索引,所以看MSDN往往也就是读完正文,点点加有超链接的名词,顶多再跑跑例程而已。

    Microsoft DirectX Graphics Infrastructure(DXGI)是从WIndows Vista时代开始引入的一个子系统,它封装了一些Direct3D 10, 10.1, 11和11.1需要的低层次(low-level)任务。对于使用Direct3D 9的程序员,DXGI包括绝大部分之前打包进Direct3D 9 的enumeration,生成swap-chain和presentation相关API。当你要把应用迁移到DXGI,Direct3D 10.x和Direct3D 11.x,你必须充分考察一些事项以保证程序正常运行。

    这篇文章主要讨论以下事项:

  • 全屏相关琐事
  • 多显示器
  • 窗口样式和DXGI
  • 多线程和DXGI
  • 伽马(Gamma)和DXGI
  • DXGI 1.1
  • DXGI 1.2

全屏相关琐事

    从Direct3D 9迁移到DXGI、Direct3D 10.x或者Direct3D 11.x,会给窗口模式到全屏模式转换的操作带来很多状况。这主要是因为Direct3D 9不像使用DXGI的程序那样需要那么多的手动操作,DXGI给开发者提供了很多可以追踪窗口样式和状态的细节操作。当古老的模式转换程序在新平台运行的时候,总是会引起一些意想不到的问题。

    Direct3D 9通常通过设置front buffer分辨率来转换窗口模式到全屏模式,并强迫设备进入全屏独占模式再设置back buffer与其匹配。还有一条单独路径用于处理窗口尺寸,因为它们必须处理窗口进程接收到的WM_SIZE信号。

    DXGI结合了两种情况的处理,试图简化处理流程。例如窗口模式下边缘被拉扯时,应用接收到WM_SIZE信号。DXGI拦截该信号,并修改front buffer。开发者只需要针对back buffer调用IDXGISwapChain::ResizeBuffers调整尺寸与随WM_SIZE信号所传入参数一致。当应用需要在全屏及窗口模式间切换时,只需调用IDXGISwapChain:SetFullscreenState。DXGI自动调整front buffer并发送WM_SIZE信号。应用再次调用ResizeBuffers,就像窗口边缘被拖拽时一样。

    上述解释的方法论使用了一条独特的路径。DXGI默认设置桌面分辨率为全屏分辨率。但很多应用要为全屏切换到某个特殊分辨率。DXGI为这种情况准备了IDXGISwapChain::ResizeTarget。在调用SetFullscreenState之前调用。虽然可以以相反的顺序调用,但会多发送WM_SIZE一次,课程会引起闪烁。在调用SetFullScreenState之后还是要调用ResizeTarget,只不过参数DXGI_MODE_DESC的RefreshRate子项设为空。这是个非操作指令,但这可以避免刷新率相关的琐事,我们接下来就聊聊这个。

    全屏模式时,桌面窗口管理器是禁用的。此时DXGI不会像窗口模式那样用blit,而是使用翻转去显示back buffer。如果特定的需求不满足,效益是不明确的。为了确定DXGI会用翻转代替blit,front buffer和back buffer必须保持一致。如果此前应用正确处理了WM_SIZE,两个buffer格式必然一直,也就没什么好担心的了。

DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记