![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SN0ATN2cDMlRjNxATO4ADNyYTN1UmZ3QmNxImZ0kTMz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
【題外話開始】
找了下,網上用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初始化上下文的方法全仍在自定義的方法裡友善調用,增加可讀行。
【閑話開始】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畫個簡單三角形