x_jun DX11-01 課后習題
在x_jun 的DX11 入門教程里面留了一些作業(yè),本篇文章是第一篇文章的課后作業(yè)
原文鏈接 :DirectX11 With Windows SDK--01 DirectX11初始化
嘗試修改項目代碼,讓窗口內(nèi)的顯示變紅
這個問題比較簡單 我們找到 DrawScene() 函數(shù)把static float blue[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
這個代碼段改為static float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
即可,記得修改參數(shù)某些電腦可能有多于一個的顯示適配器(顯卡)。首先要通過
CreateDXGIFactory
創(chuàng)建IDXGIFactory
,然后使用IDXGIFactory::EnumAdapters
來枚舉顯示適配器。嘗試通過這種方式查看你的電腦有多少個顯示適配器(IDXGIAdapter)
,并察看它們的信息。
這個問題首先我在D3DApp::InitDirect3D()
函數(shù)的最后,按照問題的提示 添加了如下代碼// 先創(chuàng)建Factory 和 adapter ComPtr<IDXGIFactory> Factory = nullptr; ComPtr<IDXGIAdapter> adapter = nullptr; // 根據(jù)函數(shù)的要求添加參數(shù) CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(Factory.GetAddressOf())); // 枚舉顯示適配器 可以修改一下 數(shù)字 枚舉 Factory->EnumAdapters(0, adapter.GetAddressOf()); // 通過 GetDesc函數(shù)去獲取 adapter的描述,需要填充一個 DXGI_ADAPTER_DESC DXGI_ADAPTER_DESC apDesc; adapter->GetDesc(&apDesc); // 輸出 Description // 把WCHAR 類型轉(zhuǎn)為char 需要添加 #include <comdef.h>頭文件 _bstr_t b(apDesc.Description); const char* s = b; // 這個是格式化輸出 可以在輸出中打印字符 要是用這個先要添加 最下面的宏 OUTINFO_1_PARAM("IDXGIAdapter----DEBUG----%s\n", s); // OUTINFO 系列的宏定義 (百度的) //輸出調(diào)試信息--在DebugView軟件里面看調(diào)試信息 #define OUTINFO_0_PARAM(fmt) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt));OutputDebugStringA(sOut);} #define OUTINFO_1_PARAM(fmt,var) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var);OutputDebugStringA(sOut);} #define OUTINFO_2_PARAM(fmt,var1,var2) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var1,var2);OutputDebugStringA(sOut);} #define OUTINFO_3_PARAM(fmt,var1,var2,var3) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var1,var2,var3);OutputDebugStringA(sOut);}
運行程序我們就能到看詳細信息了 如圖所示:
一個顯示適配器可能關聯(lián)了多個輸出設備
(IDXGIOutput)
,你可以使用IDXGIAdapter::EnumOutputs
方法來枚舉出特定的輸出,嘗試觀察它們的信息
緊跟著在上一個問題的代碼后面添加ComPtr<IDXGIOutput> output = nullptr; // 嘗試修改函數(shù)中的數(shù)字 觀察控制臺輸出 adapter->EnumOutputs(0, output.GetAddressOf()); DXGI_OUTPUT_DESC outDesc; output->GetDesc(&outDesc); _bstr_t out(outDesc.DeviceName); const char* o = out; OUTINFO_1_PARAM("IDXGIOutput---DEBUG----- %s\n", o);
我的輸出如下
對于給定的像素格式,一個輸出設備可以支持許多種顯示模式
(DXGI_MODE_DESC)
,通過它可以看到全屏寬度、高度、刷新率。嘗試使用IDXGIOutput::GetDisplayModeList
方法觀察所有支持的模式(傳遞DXGI_FORMAT_R8G8B8A8_UNORM
格式進去)。
在下面添加代碼UINT num = 0; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; UINT flags = DXGI_ENUM_MODES_INTERLACED; output->GetDisplayModeList(format, flags, &num, 0); DXGI_MODE_DESC* pDescs = new DXGI_MODE_DESC[num]; output->GetDisplayModeList(format, flags, &num, pDescs); OUTINFO_1_PARAM("dasda-%d\n",pDescs->Width);
通過debug 斷點調(diào)試我們可以發(fā)現(xiàn)如圖
默認情況下的窗口程序是可以通過ALT+ENTER來進入/退出全屏的。此外,我們可以通過
IDXGISwapChain
來動態(tài)設置窗口全屏屬性,找到對應的方法并嘗試一下。m_pSwapChain->SetFullscreenState(true, nullptr);
現(xiàn)在嘗試指定顯示適配器來創(chuàng)建D3D設備。通過
CreateDXGIFactory
函數(shù)來創(chuàng)建IDXGIFactory
,通常它會包含接口IDXGIFactory1
,但有可能它也會包含接口IDXGIFactory2。在沒有創(chuàng)建D3D設備的情況下,這種方式就可以幫助我們了解是否可以創(chuàng)建出Direct3D 11.1的設備。為了能夠指定顯示適配器來創(chuàng)建D3D11設備,我們需要將D3D_DRIVER_TYPE
強行設置為D3D_DRIVER_TYPE_UNKNOWN
,否則在創(chuàng)建設備的時候會得到如下報錯信息:DX ERROR: D3D11CreateDevice: When creating a device from an existing adapter (i.e. pAdapter is non-NULL), DriverType must be D3D_DRIVER_TYPE_UNKNOWN. [ INITIALIZATION ERROR #3146141: ]
找到InitDirect3D()
函數(shù)在遍歷驅(qū)動類型數(shù)組的for循環(huán)上面添加
```cpp ComPtr<IDXGIAdapter> dxgiAdapter = nullptr; ComPtr<IDXGIFactory> dxgiFactory = nullptr; CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(dxgiFactory.GetAddressOf())); dxgiFactory->EnumAdapters(0, dxgiAdapter.GetAddressOf()); //修改D3D11CreateDevice() 函數(shù) 將第一個參數(shù)設置為 dxgiAdapter.Get() ```
學習圖形學