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> ...
随机推荐
- poj 3592 Instantaneous Transference
http://poj.org/problem?id=3592 #include <cstdio> #include <cstring> #include <algorit ...
- android中几种常见的尺寸
获取屏幕宽高尺寸的三种代码形式 在Android上,目前我知道的获取屏幕尺寸的方法有三种不同的代码形式 方法1.在Activity中最常见的调用方式 WindowManager windowManag ...
- Linux2.6内核--对块IO层操作的讨论
当一个块被调入内存时(也就是说,在读入后或等待写出时),它要存储在缓冲区中.每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示.块包含一个或多个扇区,但大小不能超过一页,所以一页可以容 ...
- P2P风险淮安样本:5000万连锁漩涡牵出银行内案
春节后第一个工作周,来自南京的投资人李宏(化名)频繁游走于两个维权群,因为在江苏淮安的网贷平台投资经历,他结识了136名P2P投资人. 在他们的QQ群里,每个投资人的备注均为网名+投资额,如他自己的“ ...
- JavaScript中依赖注入详细解析
计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的 ...
- Cgroup - Linux 内存资源管理
Hi ,我是 Zorro .这是我的微博地址,我会不定期在这里更新文章,如果你有兴趣,可以来关注我呦. 另外,我的其他联系方式: Email: mini.jerry@gmail.com QQ: 300 ...
- fedora19安装jdk
1.下载安装包 去oracle下载jdk-7u45-linux-i586.rpm 2. 更改权限 #chmod 777jdk-7u45-linux-i586.rpm 3. 安装 #rpm -ivh j ...
- Java多线程编程(二)
在 Java多线程编程(一) 中的多线程并没有返回值,本文将介绍带返回值的多线程. 要想有返回值,则需要实现新的接口Callable而不再是Runnable接口,实现的方法也改为call()方法,执行 ...
- Maven assembly插件输出文件乱码问题
使用Maven的<artifactId>maven-assembly-plugin</artifactId>插件导致输出的XML配置文件源文件的中文注释变成乱码,排查了多个地方 ...
- Microsoft Dynamics CRM4.0编程---说明
Introduction(说明) If your organization has customers, you need a software system to help you manage y ...