DirectX 使用 Vortice 从零开始控制台创建 Direct2D1 窗口修改颜色( 五 )


再设置是否进入全屏模式,对于现在很多游戏和应用,都可以使用设置窗口进入最大化的全屏模式 , 这里就设置不进入全屏
// 设置是否全屏DXGI.SwapChainFullscreenDescription fullscreenDescription = new DXGI.SwapChainFullscreenDescription{Windowed = true};设置了参数 , 就可以创建交换链 。可以通过 HWnd 窗口句柄创建,也可以创建和 UWP 对接的 CreateSwapChainForCoreWindow 方式,也可以通过 DirectComposition 的 CreateSwapChainForComposition 创建 。本文这里采用 CreateSwapChainForHwnd 创建,关联窗口
DXGI.IDXGISwapChain1 swapChain =dxgiFactory2.CreateSwapChainForHwnd(d3D11Device1, hWnd, swapChainDescription, fullscreenDescription);附带禁止按下 alt+enter 进入全屏,这是可选的
// 不要被按下 alt+enter 进入全屏dxgiFactory2.MakeWindowAssociation(hWnd, DXGI.WindowAssociationFlags.IgnoreAltEnter);这就完成了最重要的交换链的创建 , 以上完成之后,即可让 D3D 的内容绘制在窗口上 。接下来准备再加上 D2D 的绘制
创建 D2D 绘制如下图,通过 D3D 承载 D2D 的内容 。以上完成了 D3D 的初始化,接下来可以通过 DXGI 辅助创建 D2D 的 ID2D1RenderTarget 画布

DirectX 使用 Vortice 从零开始控制台创建 Direct2D1 窗口修改颜色

文章插图
如上图的框架,想要使用 D2D 之前,需要先解决让 D2D 绘制到哪 。让 D2D 绘制的输出,可以是一个 IDXGISurface 对象 。通过 CreateDxgiSurfaceRenderTarget 方法既可以在 IDXGISurface 创建 ID2D1RenderTarget 对象,让绘制可以输出 。而 IDXGISurface 可以从 ID3D11Texture2D 获取到 。通过交换链的 GetBuffer 方法可以获取到 ID3D11Texture2D 对象
本文将按照这个步骤 , 创建 ID2D1RenderTarget 画布 。除了以上步骤之外,还有其他的方法,详细还请看官方文档的转换框架
按照惯例创建 D2D 需要先创建工厂
// 对接 D2D 需要创建工厂D2D.ID2D1Factory1 d2DFactory = D2D.D2D1.D2D1CreateFactory<D2D.ID2D1Factory1>();先从交换链获取到 ID3D11Texture2D 对象,通过 IDXGISwapChain1 的 GetBuffer 获取交换链的一个后台缓存
D3D11.ID3D11Texture2D backBufferTexture = swapChain.GetBuffer<D3D11.ID3D11Texture2D>(0);接着使用 QueryInterface 将 ID3D11Texture2D 转换为 IDXGISurface 对象
DXGI.IDXGISurface dxgiSurface = backBufferTexture.QueryInterface<DXGI.IDXGISurface>();获取到 IDXGISurface 即可通过 D2D 工厂创建 ID2D1RenderTarget 画布
var renderTargetProperties = new D2D.RenderTargetProperties(PixelFormat.Premultiplied);D2D.ID2D1RenderTarget d2D1RenderTarget =d2DFactory.CreateDxgiSurfaceRenderTarget(dxgiSurface, renderTargetProperties);这里获取到的 ID2D1RenderTarget 就是可以用来方便绘制 2D 的画布
修改颜色最简单的绘制方式就是使用 Clear 方法修改颜色 。本文只是告诉大家如何进行初始化,不会涉及到如何使用 D2D 绘制的内容
在开始调用 Clear 方法之前,需要先调用 BeginDraw 方法,告诉 DX 开始绘制 。完成绘制 , 需要调用 EndDraw 方法告诉 DX 绘制完成 。这里必须明确的是,在对 ID2D1RenderTarget 调用各个绘制方法时,不是方法调用完成就渲染完成的,这些方法只是收集绘制指令,而不是立刻进行渲染
var renderTarget = d2D1RenderTarget;// 开始绘制逻辑renderTarget.BeginDraw();// 随意创建颜色var color = new Color4((byte)Random.Shared.Next(255), (byte)Random.Shared.Next(255),(byte)Random.Shared.Next(255));renderTarget.Clear(color);renderTarget.EndDraw();以上代码使用随意的颜色清理,调用 Clear 时,将会让整个 ID2D1RenderTarget 使用给定的颜色清理,也就是修改颜色
在完成之后,调用一下交换链的 Present 和等待刷新
swapChain.Present(1, DXGI.PresentFlags.None);// 等待刷新d3D11DeviceContext1.Flush();调用交换链的 Present 函数在屏幕上显示渲染缓冲区的内容 swapChain.Present(1, PresentFlags.None); 是等待垂直同步,在刷新完成在完成这个方法 , 第一个参数是同步间隔,第二个参数是演示的标志
尝试运行一下代码,就可以看到创建出了一个窗口,窗口的设置了一个诡异的颜色
这就是入门级的使用 Vortice 从零开始控制台创建窗口,在窗口上使用 D2D 绘制的方法
在完成初始化的逻辑之后,就可以使用 D2D 绘制复杂的界面了 。在 ID2D1RenderTarget 可以方便调用各个方法进行绘制,如绘制矩形 , 画圆等 。详细请看 C# 从零开始写 SharpDx 应用 绘制基础图形
本文有部分代码没有贴出,可以通过以下方法获取本文使用的项目 。如果发现自己照着写,跑不起来,推荐使用本文的项目跑一下对比代码

推荐阅读