【题外话开始】
找了下,网上用QT来DirectX11绘制的文章少的可怜,仅有的一些很多坑都没讲。仅此文章让大家少踩坑,毕竟题主我只是想学习下DirectX,然后被各种死板的初始化搞得头大。
先上一张简单的清空屏幕为骚粉色的完成效果图,太简单了大佬别笑我,哈哈,主要记录下配置上下文的繁琐工序,熟悉原理之后完全可以直接copy,嘿嘿。
由于上下文配置好多,单独拿出来一章记录,下一个章节再记录简单的画三角形
文章有很多我自己的理解,有误之处请大佬斧正,感激
GitHUB源码下载:
https://github.com/xybgame/QtLearnDirectX11/tree/master/XYBDirectX11Learn01github.com【题外话结束】
【前奏开始】
在Qt中创建DirectX窗口需要用到QWidget,(QT老手可以跳过前奏,前奏只是QT的配置,这一步太简单了。写一下主要是给希望只用QT做DirectX,入个门的同学看滴)
先创建我们自定义的DxWindow类,让他继承自QWidget,包含directx的头文件,以及在pro里面引入相应的lib库,如下图,配置环境上一节已经讲过了,这里不多赘述。
要是嫌这个类文件创建的麻烦,可以直接创建Qt Item Model让QT自动生成一个类文件,然后自己改改就行,如果不太会可以看我的Qt小技巧的文章里面有讲。
然后点开ui配置文件。
拖一个QWidget进入窗体,然后最大化布局点一下,把widget命名为W_DxWindow,如下图片
右击我们的窗口 提升为... (这里这布操作,就是告诉QT,我们要创建的窗口部件需要使用我们刚刚自定义的继承自QWidget类的DxWindow来显示以及初始化)
然后跑一下,我们就成功启动了一个带自定义的QWidget的窗体,现在什么都没显示,是因为没有配置DirectX
【前奏结束】
【闲话开始】
现在就可以到激动人心愉快的 directX上下文创建踩坑环节咯。
【闲话结束】
【正题开始】
在.h里面重写下面几个标红的QWidget方法,下划线标出来的那个方法return nullprt是为了禁用
QWidget本身QT自带的绘制。画红圈的方法就是我们需要运行初始化Init 和Update更新DirectX11的地方了,其余的方法是我自定义的,我会把Dx初始化上下文的方法全仍在自定义的方法里方便调用,增加可读行。
.cpp如下 第一个标注很重要,这是启用我们自定义的DX渲染用的,必须加上
【闲话开始】DX创建上下文基本都是死挨死板的,如果对原理有些理解的话可以直接赋值代码就行。【闲话结束】
【正题开始】
然后在头文件中添加以下变量:可以直接复制我的,每个具体干嘛的我在注释里写了,有特别重要的会在文章中特别说明介绍
float
好,下面就开始初始化了。
----InitD3D方法中写入,为了方便大家阅读,解释我写到了每行注释上:
void
DirectX里面Desc后缀的都是用来描述某个东西的结构体,用来告诉Dx我们传给你的数据是要做什么的,也有一些是用来控制管线状态的。下面是一些详细注释
注释1:
bufferDesc.RefreshRate也是一个结构体
Numerator=60,Denominator=1 表示刷新60fps
注释2:
Count:多重采样的取平均值的像素个数,因为我不使用多重采样所以设置为1,表示渲染的时候直接输出屏幕每个点的1个像素的颜色值到屏幕上即可
Quality:这是采样的质量,不使用则设置为0,关闭即可
注释3:
IDXGIAdapter *pAdapter:创建设备时使用的视频适配器指针,使用NULL表示使用默认的适配器.
* D3D_DRIVER_TYPE DriverType:描述驱动类型的枚举体,主要是说明使用什么方式去实现Direct3D特征.一般我们常用两种:D3D_DRIVER_TYPE_HARDWARE以及D3D_DRIVER_TYPE_SOFTWARE。其他的参数可以查看MSDN对该枚举体的描述
* HMODULE Software:该参数指向一个DLL,该DLL实现了软件光栅化处理。如果上一个参数设为D3D_DRIVER_TYPE_SOFTWARE,则不可以设为NULL,否则就取NULL。
* UINT Flags:描述用于创建设备的参数,它的取值定义在D3D11_CREATE_DEVICE_FLAG枚举体中,可以按位OR进行结合,一般设为0就可以了
* D3D_FEATURE_LEVEL *pFeatureLevels:目标功能级别集合,就是之前我们创建的数组
* UINT FeatyreLevels:这里输入上一个数组中元素的个数。
* UINT SKDVersion:Direct3D的版本号,我们使用D3D11_SDK_VERSION即可
* DXGI_SWAP_CHAIN_DESC *pSwapChainDesc:毫无疑问,这里填我们之前描述交换链时使用的结构体.
* IDXGISwapChain **ppSwapChain:待初始化的交换链接口.
* ID3D11Device **ppDevice:待初始化的设备接口.
* D3D_FEATURE_LEVEL *pFeatureLevel:这是一个输出参数,它指向刚才输入的数组中第一个被设备支持的目标功能级别.这个可以用来作判断哪一个功能级别可以匹配。一般我们不需要,把它设为NULL.
* ID3D11DeviceContext **ppImmediateContext:待初始化的立即执行上下文.
————————————————
注:这个函数,我从网上找到了一个详细注释的,原文出处链接:
CSDN-专业IT技术社区-登录blog.csdn.net版权声明:本文为CSDN博主「寒江雪1719」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
注释4:
宏定义,安全释放,如下
#define XYB_SafeDel(obj)
obj->Release();
obj=0;
--ReiszeD3D() 函数,当窗口大小改变需要刷新下面的东西,具体参数意义,上面以及给出,不再赘述
void
--RenderUpdate()用来更新我们的shader的,这里只需要清空下屏幕颜色,清楚成功就代表Dx创建完美咯~,下面一节我会记录下如何用shader画个三角形
void DxWindow::paintEvent(QPaintEvent *event)
{
RenderUpdate();
//(注释5)每帧更新完都需要交换下前后台的缓冲区,把后台画好的东西显示到屏幕上
m_swapChain->Present(0,0);
}
void DxWindow::RenderUpdate()
{
//这边把屏幕颜色清除为灰色就行,清除成功窗口就代表了窗口成功创建咯。
m_d3dDevContext->ClearRenderTargetView(m_renderTargetView,bgcolor);
}
注释5:
前后台缓冲区大概意义如下图,画的太丑不要在意
原创文章,转载注
下一节,记录用DX画个简单三角形