DirectX Graphics Infrastructure (DXGI) 全屏设置相关问题
原文地址: https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx
未完待续。。。
DXGI是在Windows Vista时被引入,封装了Direct3D10,10.1,11和11.1所需的底层工作。从一个Direct3D 9图形程序员的角度来看,DXGI封装了大多数枚举、交换链的创建等以前封装在Direct3D 9 APIs 中的代码。当你移植一个应用程序到DXGI、Direct3D10.X和Direct3D 11.X时,你需要考虑一些注意事项以确保程序可以顺利的运行。
全屏相关问题:
从Direct3D 9过度到DXGI和Direct3D 10.x或Direct3D 11.x时,当从窗口模式转换到全屏模式所伴随的问题通常可能会让起开发者头痛,主要的问题是Direct3D 9应用程序不像DXGI应用程序需要更深入的接近window styles和 window states。当切换模式的代码在DXGI中运行时经常引起一些并非预期的效果。
通常,Direct3D 9应用程序通过设置前台缓存的分辨率迫使设备进入全屏独占模式,然后设置后台缓存的分辨率相匹配。使用了一个单独的途径改变窗体的尺寸,因为程序不得不被window process管理并且任何时候都将接收到一个WM_SIZE处理消息。
DXGI试图通过合并这两部分处理以简化该操作。例如,当窗口模式下窗体的边框被拖拽时,应用程序会接受到一个WM_SIZE 处理消息,DXGI捕获此消息并自动改变前台缓存的大小。应用程序只需使用WM_SIZE传递的尺寸参数并调用IDXGISwapChain::ResizeBuffers 重置后台缓冲的尺寸。相似的,当窗体在全屏和窗口模式之间切换时,应用程序可简单的调用 IDXGISwapChain::SetFullscreenState 。DXGI重置前台缓冲大小以匹配刚刚的全屏模式操作,并且发送一个WM_SIZE message到应用程序,应用程序再次调用ResizeBuffers函数,就像之前窗体的边框被拖拽一样。
SharpDX代码实例:
//全屏切换触发事件
void renderForm_KeyDown(object sender, KeyEventArgs e)
{
if (SwapChain.IsFullScreen)
{
if (e.KeyCode == Keys.Escape)
{
SwapChain.IsFullScreen = false;
} }
else
{
if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.Enter)
{
SwapChain.IsFullScreen = true;
}
}
} //WM_SIZE事件
void renderForm_ClientSizeChanged(object sender, EventArgs e)
{ if (renderForm.ClientSize.Width != 0 && renderForm.ClientSize.Height != 0)//最小化时尺寸为0
{
backBufferWidth = renderForm.ClientSize.Width;
backBufferHeight = renderForm.ClientSize.Height; Disposer.RemoveAndDispose(ref backBufferTexture);
Disposer.RemoveAndDispose(ref backBufferTargetView); // SwapChain.ResizeBuffers(1, backBufferWidth, backBufferHeight, Format.R8G8B8A8_UNorm, SwapChainFlags.None); backBufferTexture = Texture2D.FromSwapChain<Texture2D>(SwapChain, 0);
backBufferTargetView = new RenderTargetView(device, backBufferTexture);
device.ImmediateContext.Rasterizer.SetViewport(new ViewportF(0, 0, backBufferWidth, backBufferHeight, 0.0f, 1.0f));
}
}
之前论述的方法遵循一个非常特殊方式,DXGI通过设置默认的桌面分辨率作为全屏模式。然而许多应用程序切换一个预设的分辨率到全屏模式,这种情况下,DXGI提供 IDXGISwapChain::ResizeTarget 函数。这个函数应在调用 SetFullscreenState 之前调用。虽然这些方法可以通过相反的顺序调用(先调用SetFullscreenState , 随后调用 ResizeTarget),这样做会导致一个额外的WM_SIZE处理消息在应用程序中触发。(这样做也会引起闪烁,因为DXGI可能会在两个模式之间强制执行)。在调用SetFullscreenState后,再次通过被重置的DXGI_MODE_DESC 的成员变量RefreshRate 调用ResizeTarget 是一个明智的操作。这意味着在DXGI中是一个无操作的命令,但是它可以避免接下来讨论的刷新率问题。
在全屏模式中,窗口桌面管理(DWM)是无效的,DXGI会以更轻量的方式代替窗口模式下的区域传输呈现后台缓冲区中的内容。这种性能的开销得到释放。然而,我们还没有谈到如何在确定条件下确保以轻量的方式代替区域的传输模式。这种情况下前台缓冲和后台缓冲必须尺寸相同。如果应用程序正确的处理了WM_SIZE处理消息,这显然不是问题,同样格式也必须完全相同。
对大部分应用程序来说问题是刷新率,在调用 ResizeTarget 时所指定的刷新率必须是交换链使用的 IDXGIOutput 的刷新率, DXGI_MODE_DESC 被传入ResizeTarget函数后其成员RefreshRate 的值会被DXGI自动重置计算。不要假定确切刷新率值会被支持。通常,开发者选择60HZ作为刷新率,并不了解显示器的刷新率是大约60,000 / 1,001 Hz。如果刷新率不符合期望的60HZ,DXGI会强制进行区域传输代替全屏的轻量传输。
最后一个问题是开发者经常面对如何在全屏模式下改变分辨率。调用 ResizeTarget 和SetFullscreenState 有时会成功,但是全屏分辨率是桌面的分辨率,同样,开发者可能会在全屏模式下创建指定的分辨率,我们发现DXGI会忽略我们传入的指定分辨率。除非特别指出,全屏交换链会使用默认桌面的分辨率。当创建全屏分辨率的交换链,DXGI_SWAP_CHAIN_DESC 的Flags成员结构体必须设置为DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH 覆盖默认参数。这个flag同样也需要被传入到 ResizeTarget 中动态的开启或者禁用。
DirectX Graphics Infrastructure (DXGI) 全屏设置相关问题的更多相关文章
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- WebView中的视频全屏的相关操作
近期工作中,基本一直在用WebView,今天就把它整理下: WebView 顾名思义,就是放一个网页,一个看起来十分简单,可是用起来不是那么简单的控件. 首先你肯定要定义,初始化一个webview,事 ...
- Android 无标题 全屏设置
标题栏和状态栏 Android程序默认情况下是包含状态栏和标题栏的. 在Eclipse中新建一个Android程序,运行后显示如下: 图中标出了状态栏(显示时间.电池电量.网络等)和标题栏(显示应用的 ...
- 继承了AppCompatActivity的全屏设置
v7下全屏设置:getSupportActionBar().hide();getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ...
- Android继承AppCompatActivity实现全屏设置
转载 2016年05月25日 13:20:25 标签: android / style / android studio / 继承 4839 Android studio创建新项目后Activity默 ...
- Android 无标题、全屏设置
一.在主题中设置无标题.全屏 (一):直接设置主题: android:theme="@android:style/Theme.NoTitleBar.Fullscreen" // ...
- Mac浏览器全屏设置
在 mac 升级之后,以往点击放大的按钮,现在显示的效果是全屏:
- android 全屏设置
更改styles.xml文件 <!-- 去掉标题栏 --> <style name="AppTheme" parent="Theme.AppCompat ...
- body全屏css/网页全屏设置/全屏样式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
随机推荐
- 开源word操作组件DocX的记录
开源word操作组件DocX的记录 使用开源word操作组件DocX的记录 1.DocX简介 1.1 简介 DocX是一个在不需要安装word的情况下对word进行操作的开源轻量级.net组件,是由爱 ...
- matlab图像类型转换以及uint8、double、im2double、im2uint8和mat2gray等说明
转自:http://blog.csdn.net/fx677588/article/details/53301740 1. matlab图像保存说明 matlab中读取图片后保存的数据是uint8类型( ...
- Ant快速入门(三)-----定义生成文件
适应Ant的关键就是编写生成文件,生成文件定义了该项目的各个生成任务(以target来表示,每个target表示一个生成任务),并定义生成任务之间的依赖关系. Ant生成文件的默认名为build.xm ...
- Solr In Action 笔记(1) 之 Key Solr Concepts
Solr In Action 笔记(1) 之 Key Solr Concepts 题记:看了下<Solr In Action>还是收益良多的,只是奈何没有中文版,只能查看英语原版有点类,第 ...
- cocos2d-x lua脚本开发 1
自从开始关注OpenResty之后,逐渐关注Lua语言,发现这个语言真真是容易让人喜爱的语言.偶然间发现了cocos2d-x,还支持lua,所以果断尝试一下. 这里是在cocos2d-x官方网站下载了 ...
- 用extern关键字使程序更加清晰
一.基础研究 之前基于tcc.tlink实现一个新的编译连接工具cc.exe,用到的文件有cs.lib.c0s.obj.main.obj,其中main.obj是我们自己加入的文件,它可以实现开始显示彩 ...
- ClipDrawable 资源
ClipDrawable 代表从其他位图上截取的一个“图片片段”. 示例: main.xml <?xml version="1.0" encoding="utf-8 ...
- COJ 1002 WZJ的数据结构(二)(splay模板)
我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...
- (转)C++ 编程规范
转载地址:http://www.cnblogs.com/len3d/archive/2008/02/01/1061902.html C/C++编码规范 今天人们越来越明白软件设计更多地是一种工程,而不 ...
- cannot be resolved to a type in same package 问题解决
在 STS 上,一个类引用在相同 package 中另一个类,但是报 cannot be resolved to a type 错误. 解决方法 : Alternatively, you can hi ...