本文来告诉大家如何在上一篇博客创建的窗口里面使用 Sharpdx 初始化,然后设置窗口颜色
本文是 SharpDX 系列博客,更多博客请点击SharpDX 系列
在C# 从零开始写 SharpDx 应用 初始化dx修改颜色已经创建了一个窗口,现在需要在这个窗口初始化。因为是从零开始写,所以需要非常多细节,我觉得一篇文章是很难全部告诉大家,所以分为了系列的文章。从零开始写有利于大家了解一个渲染框架是如何做出来,并且从底层优化渲染,当然这个方法就是学习的时间会比较长。我会在文章去掉很多细节放在后面的博客讲,让大家先知道总体是如何做的。
创建资源
第一步是需要添加一个方法 InitializeDeviceResources
用来初始化资源,这里初始化的就是设备的资源。在 dx 的渲染是需要紧密绑定设备。
这个方法就是写在KikuSimairme
类里,关于这个类的代码在C# 控制台创建 Sharpdx 窗口
// 其他被忽略的代码
private void InitializeDeviceResources()
{
}
创建一个可以画出来的类需要先创建显示模式描述,通过显示描述创建交换链描述,交换链描述创建设备和交换链,通过交换链和设备可以创建可以画出来的类,在这个类就可以画出无聊的图形,按照创建的顺序,我将文章分为多个部分,下面先来窗口模式描述
模式描述
首先需要创建一个描述显示模式,模式描述使用的是 ModeDescription
类,可以使用 new 的方式创建。在 dx 里很多的类都只能通过工厂创建,可以通过 new 创建的类一般都是描述的类。为什么需要描述的类?因为如果直接创建一个类需要传入大量的参数,那么这个写法将会很难,而且存在很多属性,只可以在构造的时候进行设置,不能在构造之后设置。为了方便开发,所以就将多个参数分为不同的类,这些类就是描述类。下面创建的是模式显示描述
using SharpDX.Direct3D;
using SharpDX.DXGI;
// 其他忽略的代码
class KikuSimairme : IDisposable
// 其他忽略的代码
private void InitializeDeviceResources()
{
ModeDescription backBufferDesc =
new ModeDescription(Width, Height, new Rational(60, 1), Format.R8G8B8A8_UNorm);
}
通过 ModeDescription 就可以描述创建的模式是什么,前两个参数是表示缓存的大小,在很多的情况,这个值都和显示的大小相同。
第三个参数就是表示刷新率,这里使用的就是 1/60
也就是 60hz
最后一个参数设置的是像素格式,这里使用 8 位的 RGBA 格式,使用一个无符号的 32 位整数表示,在设置格式是很重要,请仔细看自己的设置,因为我就告诉了一位小伙伴看着他将模式的格式写错了。如果有安装 Resharper 就可以按下 RGBA 快速找到这个属性
更多关于 ModeDescription 请看 DXGI_MODE_DESC
这里的 backBufferDesc 是在描述后台缓冲区,后台缓冲区的作用是防止动画中出现闪烁,可以这样看,在用户看到一个白纸的时候,一边有个人在这个白纸上画东西,这时用户就会看到画东西的闪烁。如果有两张纸,给用户看一张纸,在另一张纸上画,画完就把这张纸给用户,把刚才的纸拿来画下一个动画。通过这个方式就可以减少用户看到闪烁。这个不给用户看到的纸就是后台缓冲区(back buffer)。
交换链描述
下面可以来创建交换链的描述,交换链就是用来交换后台缓冲和显示的类,创建这个类需要先创建描述类,创建的方法是使用 new 的方式创建SwapChainDescription
类,同样是为了减少创建交换链的输入参数,所以将很多参数放在这个类,创建描述类的时候就需要将上面创建的模式描述类传进来,请使用这个代码
// 其他忽略的代码
class KikuSimairme : IDisposable
// 其他忽略的代码
private void InitializeDeviceResources()
// 其他忽略的代码
SwapChainDescription swapChainDesc = new SwapChainDescription()
{
ModeDescription = backBufferDesc,
SampleDescription = new SampleDescription(1, 0),
Usage = Usage.RenderTargetOutput,
BufferCount = 1,
OutputHandle = _renderForm.Handle,
IsWindowed = true
};
先来解释一下参数。
交换链的 ModeDescription 就是上面定义的 backBufferDesc
多重采用 SampleDescription 用来优化图片,是一种用于采样和平衡渲染像素的创建亮丽色彩变化之间的平滑过渡的一种技术,这里设置等级 1 也就是关闭多重采样,需要传入两个参数一个是Count 指定每个像素的采样数量,一个是Quality指定希望得到的质量级别,参见DXGI_SAMPLE_DESC structure,在这里质量级别越高,占用的系统资源就越多。
Usage 设置 CPU 访问缓冲的权限,这里设置可以访问 RenderTarget 输出,请看 DXGI_USAGE
后缓冲数量 BufferCount 建议设置一个,设置一个就是双缓冲。两个缓冲区已经足够用了。
OutputHandle 获取渲染窗口句柄
IsWindowed 这个值设置是否希望是全屏,如果是 true 就是窗口。现在软件还没写好,如果这时全屏可能就无法退出,建议先设置这个值为 true 不然难以直接退出。但是我还是设置了全屏,原因是本金鱼有两个屏幕,所以可以让软件退出
现在已经创建交换链,但是我里面很多设置没有告诉大家还有哪些可以设置
这里有很多都需要在微软官方才可以看到,因为本文是简单的博客,不会在本文介绍。
为什么需要设置交换链?因为在刚才已经说了防止用户看到闪烁需要使用两个缓冲,如何把前台缓冲区和后台缓冲区交换就需要用到交换链。
私有变量
刚才是在 InitializeDevice