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> ...
随机推荐
- 一个jpa动态模糊查询的实现
最近一直在是用spring data jpa,使用起来确实方便,如果是单表的操作基本上通过方法名都可以实现,下面是一个 Specification 实现动态模糊查询的例子这个查询是通过JpaSpeci ...
- JS学习之页面加载
1.window.opener.location.reload(); 意思是让打开的父窗口刷新.window.opener指的是本窗口的父窗口,window.opener.location.h ...
- ExtJS 4 组件详解
ExtJS 4 的应用界面是由很多小部件组合而成的,这些小部件被称作"组件(Component)",所有组件都是Ext.Component的子类,Ext.Component提供了生 ...
- Sleep的问题
先上全部源码: using System; using System.Threading; namespace MoveServices { public static class MoveWorke ...
- bing---iis how to process http request
http://msdn.microsoft.com/en-us/library/ms524901(v=vs.90).aspx http://msdn.microsoft.com/en-us/magaz ...
- Windows消息编程(写的不错,有前因后果)
本文主要包括以下内容: 1.简单理解Windows的消息2.通过一个简单的Win32程序理解Windows消息3.通过几个Win32程序实例进一步深入理解Windows消息4.队列消息和非队列消息5. ...
- 如何让Qt 的程序等待一段时间(等待的同时,还让主界面刷新图片)good
后面这种方法可以不影响其他线程的响应,又可以达到等待的目的. 测试的一个小例子: class Widget : public QWidget { Q_OBJECT public: Widget(QWi ...
- Sum Root to Leaf Numbers——LeetCode
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...
- 多线程爬虫Java调用wget下载文件,独立线程读取输出缓冲区
写了个抓取appstore的,要抓取大量的app,本来是用httpclient,但是效果不理想,于是直接调用wget下载,但是由于标准输出.错误输出的原因会导致卡住,另外wget也会莫名的卡住. 所以 ...
- UVa 11292 - Dragon of Loowater(排序贪心)
Once upon a time, in the Kingdom of Loowater, a minor nuisance turned into a major problem.The shore ...